1 /*****************************************************************************\
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
10 \*****************************************************************************/
14 unsigned int new_remote = 1000;
19 Premote::Premote(int type, char *portname, struct port_settings *settings, struct interface *interface, int remote_id) : Port(type, portname, settings, interface)
21 union parameter param;
23 p_callerinfo.itype = (interface->extension)?INFO_ITYPE_ISDN_EXTENSION:INFO_ITYPE_ISDN;
24 p_r_ref = new_remote++;
25 SCPY(p_r_remote_app, interface->remote_app);
26 p_r_tones = (interface->is_tones == IS_YES);
27 p_r_earlyb = (interface->is_earlyb == IS_YES);
29 /* send new ref to remote socket */
30 memset(¶m, 0, sizeof(union parameter));
31 if (type == PORT_TYPE_REMOTE_OUT)
32 param.newref.direction = 1; /* new ref from lcr */
33 p_r_remote_id = remote_id;
34 if (admin_message_from_lcr(p_r_remote_id, p_r_ref, MESSAGE_NEWREF, ¶m) < 0)
35 FATAL("No socket with remote application '%s' found, this shall not happen. because we already created one.\n", p_r_remote_app);
37 PDEBUG(DEBUG_PORT, "Created new RemotePort(%s).\n", portname);
46 PDEBUG(DEBUG_PORT, "Destroyed Remote process(%s).\n", p_name);
50 * endpoint sends messages to the port
52 int Premote::message_epoint(unsigned int epoint_id, int message_type, union parameter *param)
54 struct epoint_list *epointlist;
56 if (Port::message_epoint(epoint_id, message_type, param))
59 switch (message_type) {
61 struct interface *interface;
62 interface = getinterfacebyname(p_interface_name);
64 PERROR("Cannot find interface %s.\n", p_interface_name);
67 /* attach only if not already */
68 epointlist = p_epointlist;
70 if (epointlist->epoint_id == epoint_id)
72 epointlist = epointlist->next;
75 epointlist_new(epoint_id);
77 /* set context to pbx */
78 if (!param->setup.dialinginfo.context[0]) {
79 if (interface->remote_context[0])
80 SCPY(param->setup.dialinginfo.context, interface->remote_context);
82 SCPY(param->setup.dialinginfo.context, "lcr");
84 memcpy(&p_dialinginfo, ¶m->setup.dialinginfo, sizeof(p_dialinginfo));
85 memcpy(&p_capainfo, ¶m->setup.capainfo, sizeof(p_capainfo));
86 memcpy(&p_callerinfo, ¶m->setup.callerinfo, sizeof(p_callerinfo));
87 memcpy(&p_redirinfo, ¶m->setup.redirinfo, sizeof(p_redirinfo));
89 do_screen(1, p_callerinfo.id, sizeof(p_callerinfo.id), &p_callerinfo.ntype, &p_callerinfo.present, p_interface_name);
90 do_screen(1, p_callerinfo.id2, sizeof(p_callerinfo.id2), &p_callerinfo.ntype2, &p_callerinfo.present2, p_interface_name);
91 do_screen(1, p_redirinfo.id, sizeof(p_redirinfo.id), &p_redirinfo.ntype, &p_redirinfo.present, p_interface_name);
92 memcpy(¶m->setup.callerinfo, &p_callerinfo, sizeof(p_callerinfo));
93 memcpy(¶m->setup.redirinfo, &p_redirinfo, sizeof(p_redirinfo));
95 new_state(PORT_STATE_OUT_SETUP);
98 case MESSAGE_PROCEEDING:
99 new_state(PORT_STATE_IN_PROCEEDING);
102 case MESSAGE_ALERTING:
103 new_state(PORT_STATE_IN_ALERTING);
106 case MESSAGE_CONNECT:
107 memcpy(&p_connectinfo, ¶m->connectinfo, sizeof(p_connectinfo));
108 new_state(PORT_STATE_CONNECT);
110 union parameter newparam;
111 memset(&newparam, 0, sizeof(union parameter));
112 param->traffic.len = 160;
113 admin_message_from_lcr(p_r_remote_id, p_r_ref, MESSAGE_TRAFFIC, param);
117 case MESSAGE_DISCONNECT:
118 new_state(PORT_STATE_OUT_DISCONNECT);
121 case MESSAGE_RELEASE:
122 new_state(PORT_STATE_RELEASE);
126 /* look for Remote's interface */
127 if (admin_message_from_lcr(p_r_remote_id, p_r_ref, message_type, param)<0) {
128 PERROR("No socket with remote application '%s' found, this shall not happen. Closing socket shall cause release of all remote ports.\n", p_r_remote_app);
132 if (message_type == MESSAGE_RELEASE) {
133 new_state(PORT_STATE_RELEASE);
141 void Premote::message_remote(int message_type, union parameter *param)
143 class Endpoint *epoint;
144 struct lcr_msg *message;
145 struct interface *interface;
147 switch (message_type) {
148 case MESSAGE_TRAFFIC:
150 dov_rx(param->traffic.data, param->traffic.len);
153 record(param->traffic.data, param->traffic.len, 0); // from down
155 tap(param->traffic.data, param->traffic.len, 0); // from down
156 bridge_tx(param->traffic.data, param->traffic.len);
157 if (p_tone_name[0]) {
158 read_audio(param->traffic.data, param->traffic.len);
161 record(param->traffic.data, param->traffic.len, 1); // from up
163 tap(param->traffic.data, param->traffic.len, 1); // from up
164 admin_message_from_lcr(p_r_remote_id, p_r_ref, MESSAGE_TRAFFIC, param);
165 } else if (p_dov_tx) {
166 /* use receeived traffic to trigger sending DOV */
167 dov_tx(param->traffic.data, param->traffic.len);
168 admin_message_from_lcr(p_r_remote_id, p_r_ref, MESSAGE_TRAFFIC, param);
173 interface = getinterfacebyname(p_interface_name);
175 PERROR("Cannot find interface %s.\n", p_interface_name);
179 /* enable audio path */
180 if (interface->is_tones == IS_YES) {
181 union parameter newparam;
182 memset(&newparam, 0, sizeof(union parameter));
183 admin_message_from_lcr(p_r_remote_id, p_r_ref, MESSAGE_PATTERN, &newparam);
184 newparam.audiopath = 1;
185 admin_message_from_lcr(p_r_remote_id, p_r_ref, MESSAGE_AUDIOPATH, &newparam);
188 /* set source interface */
189 param->setup.callerinfo.itype = p_callerinfo.itype;
190 SCPY(param->setup.callerinfo.interface, interface->name);
192 /* create endpoint */
194 FATAL("Incoming call but already got an endpoint.\n");
195 if (!(epoint = new Endpoint(p_serial, 0)))
196 FATAL("No memory for Endpoint instance\n");
197 epoint->ep_app = new_endpointapp(epoint, 0, interface->app); //incoming
199 epointlist_new(epoint->ep_serial);
201 memcpy(&p_dialinginfo, ¶m->setup.dialinginfo, sizeof(p_dialinginfo));
202 memcpy(&p_capainfo, ¶m->setup.capainfo, sizeof(p_capainfo));
203 memcpy(&p_callerinfo, ¶m->setup.callerinfo, sizeof(p_callerinfo));
204 memcpy(&p_redirinfo, ¶m->setup.redirinfo, sizeof(p_redirinfo));
206 new_state(PORT_STATE_IN_SETUP);
209 case MESSAGE_PROCEEDING:
210 new_state(PORT_STATE_OUT_PROCEEDING);
213 case MESSAGE_ALERTING:
214 new_state(PORT_STATE_OUT_ALERTING);
217 case MESSAGE_CONNECT:
218 memcpy(&p_connectinfo, ¶m->connectinfo, sizeof(p_connectinfo));
219 new_state(PORT_STATE_CONNECT);
221 union parameter newparam;
222 memset(&newparam, 0, sizeof(union parameter));
223 param->traffic.len = 160;
224 admin_message_from_lcr(p_r_remote_id, p_r_ref, MESSAGE_TRAFFIC, param);
228 case MESSAGE_DISCONNECT:
229 new_state(PORT_STATE_IN_DISCONNECT);
232 case MESSAGE_RELEASE:
233 new_state(PORT_STATE_RELEASE);
237 /* cannot just forward, because param is not of container "struct lcr_msg" */
238 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, message_type);
239 memcpy(&message->param, param, sizeof(message->param));
240 message_put(message);
242 if (message_type == MESSAGE_RELEASE) {
243 new_state(PORT_STATE_RELEASE);
249 /* receive from remote Port instance */
250 int Premote::bridge_rx(unsigned char *data, int len)
252 union parameter newparam;
256 if ((ret = Port::bridge_rx(data, len)))
259 /* send tones, if connected, or if early audio is enabled in proceeding/alerting state */
260 if (p_state != PORT_STATE_CONNECT
262 && (p_state == PORT_STATE_OUT_PROCEEDING
263 || p_state == PORT_STATE_OUT_ALERTING))
265 && (p_state == PORT_STATE_IN_PROCEEDING
266 || p_state == PORT_STATE_IN_ALERTING)))
272 memset(&newparam, 0, sizeof(union parameter));
273 /* split, if exeeds data size */
275 l = (len > (int)sizeof(newparam.traffic.data)) ? sizeof(newparam.traffic.data) : len;
276 newparam.traffic.len = l;
278 memcpy(newparam.traffic.data, data, l);
282 record(data, len, 1); // from up
284 tap(data, len, 1); // from up
285 admin_message_from_lcr(p_r_remote_id, p_r_ref, MESSAGE_TRAFFIC, &newparam);