memset(&e_connectinfo, 0, sizeof(struct connect_info));
memset(&e_redirinfo, 0, sizeof(struct redir_info));
memset(&e_capainfo, 0, sizeof(struct capa_info));
+ memset(&e_rtpinfo, 0, sizeof(struct rtp_info));
e_start = e_stop = 0;
e_origin = origin;
e_ruleset = ruleset_main;
}
}
+/* hunts for the given interface
+ * it does not need to have an mISDNport instance */
+struct interface *EndpointAppPBX::hunt_interface(char *ifname)
+{
+ struct interface *interface;
+ int there_is_an_external = 0;
+
+ interface = interface_first;
+
+ /* first find the given interface or, if not given, one with no extension */
+ checknext:
+ if (!interface) {
+ if (!there_is_an_external && !(ifname && ifname[0])) {
+ trace_header("CHANNEL SELECTION (no external interface specified)", DIRECTION_NONE);
+ add_trace("info", NULL, "Add 'extern' parameter to interface.conf.");
+ end_trace();
+ }
+ return(NULL);
+ }
+
+ /* check for given interface */
+ if (ifname && ifname[0]) {
+ if (!strcasecmp(interface->name, ifname)) {
+ /* found explicit interface */
+ trace_header("CHANNEL SELECTION (found given interface)", DIRECTION_NONE);
+ add_trace("interface", NULL, "%s", ifname);
+ end_trace();
+ goto foundif;
+ }
+ } else {
+ if (interface->external) {
+ there_is_an_external = 1;
+ /* found non extension */
+ trace_header("CHANNEL SELECTION (found external interface)", DIRECTION_NONE);
+ add_trace("interface", NULL, "%s", interface->name);
+ end_trace();
+ goto foundif;
+ }
+ }
+
+ interface = interface->next;
+ goto checknext;
+foundif:
+
+ return interface;
+}
+
/*
* hunts an mISDNport that is available for an outgoing call
int cause = CAUSE_RESSOURCEUNAVAIL;
const char *p;
char cfp[64];
+ struct interface *interface;
struct mISDNport *mISDNport;
char portname[32];
char *dirname;
int channel = 0;
int earlyb;
int mode = B_MODE_TRANSPARENT;
+ struct admin_list *admin;
/* set bchannel mode */
mode = e_capainfo.source_mode;
SCCAT(ifname, *p++);
if (*p == ',')
p++;
- /* found interface */
- PDEBUG(DEBUG_EPOINT, "EPOINT(%d) calling to interface %s\n", ea_endpoint->ep_serial, ifname);
- /* hunt for mISDNport and create Port */
- mISDNport = hunt_port(ifname, &channel);
- if (!mISDNport) {
- trace_header("INTERFACE (not found or busy)", DIRECTION_NONE);
+ /* search interface */
+ interface = hunt_interface(ifname);
+ if (!interface) {
+ trace_header("INTERFACE (not found)", DIRECTION_NONE);
add_trace("interface", NULL, "%s", ifname);
end_trace();
continue;
}
- /* creating INTERNAL port */
- SPRINT(portname, "%s-%d-out", mISDNport->ifport->interface->name, mISDNport->portnum);
-#ifdef WITH_SS5
- if (mISDNport->ss5)
- port = ss5_hunt_line(mISDNport);
- else
-#endif
+ /* found interface */
+ PDEBUG(DEBUG_EPOINT, "EPOINT(%d) calling to interface %s\n", ea_endpoint->ep_serial, ifname);
#ifdef WITH_GSM_BS
- if (mISDNport->gsm_bs)
- port = new Pgsm_bs(PORT_TYPE_GSM_BS_OUT, mISDNport, portname, &port_settings, channel, mISDNport->ifport->channel_force, mode);
- else
+ if (interface->gsm_bs) {
+ SPRINT(portname, "%s-%d-out", interface->name, 0);
+ port = new Pgsm_bs(PORT_TYPE_GSM_BS_OUT, portname, &port_settings, interface);
+ } else
#endif
#ifdef WITH_GSM_MS
- if (mISDNport->gsm_ms)
- port = new Pgsm_ms(PORT_TYPE_GSM_MS_OUT, mISDNport, portname, &port_settings, channel, mISDNport->ifport->channel_force, mode);
- else
+ if (interface->gsm_ms) {
+ SPRINT(portname, "%s-%d-out", interface->name, 0);
+ port = new Pgsm_ms(PORT_TYPE_GSM_MS_OUT, portname, &port_settings, interface);
+ } else
+#endif
+#ifdef WITH_GSM_MS
+ if (interface->sip) {
+ SPRINT(portname, "%s-%d-out", interface->name, 0);
+ port = new Psip(PORT_TYPE_SIP_OUT, portname, &port_settings, interface);
+ } else
+#endif
+ {
+ /* hunt for mISDNport and create Port */
+ mISDNport = hunt_port(ifname, &channel);
+ if (!mISDNport) {
+ trace_header("INTERFACE (busy)", DIRECTION_NONE);
+ add_trace("interface", NULL, "%s", ifname);
+ end_trace();
+ continue;
+ }
+
+ SPRINT(portname, "%s-%d-out", mISDNport->ifport->interface->name, mISDNport->portnum);
+#ifdef WITH_SS5
+ if (mISDNport->ss5)
+ port = ss5_hunt_line(mISDNport);
+ else
#endif
- port = new Pdss1((mISDNport->ntmode)?PORT_TYPE_DSS1_NT_OUT:PORT_TYPE_DSS1_TE_OUT, mISDNport, portname, &port_settings, channel, mISDNport->ifport->channel_force, mode);
+ if (mISDNport->ifport->remote) {
+ admin = admin_first;
+ while(admin) {
+ if (admin->remote_name[0] && !strcmp(admin->remote_name, mISDNport->ifport->remote_app))
+ break;
+ admin = admin->next;
+ }
+ if (!admin) {
+ trace_header("INTERFACE (remote not connected)", DIRECTION_NONE);
+ add_trace("application", NULL, "%s", mISDNport->ifport->remote_app);
+ end_trace();
+ continue;
+ }
+ port = new Premote(PORT_TYPE_REMOTE_OUT, mISDNport, portname, &port_settings, channel, mISDNport->ifport->channel_force, mode, admin->sock);
+ } else
+ port = new Pdss1((mISDNport->ntmode)?PORT_TYPE_DSS1_NT_OUT:PORT_TYPE_DSS1_TE_OUT, mISDNport, portname, &port_settings, channel, mISDNport->ifport->channel_force, mode);
+ }
if (!port)
FATAL("Failed to create Port instance\n");
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) got port %s\n", ea_endpoint->ep_serial, port->p_name);
dialinginfo.itype = INFO_ITYPE_ISDN_EXTENSION;
dialinginfo.ntype = e_dialinginfo.ntype;
/* create port_list relation */
- portlist = ea_endpoint->portlist_new(port->p_serial, port->p_type, mISDNport->earlyb);
+ portlist = ea_endpoint->portlist_new(port->p_serial, port->p_type, interface->is_earlyb == IS_YES);
if (!portlist) {
PERROR("EPOINT(%d) cannot allocate port_list relation\n", ea_endpoint->ep_serial);
delete port;
memcpy(&message->param.setup.redirinfo, &e_redirinfo, sizeof(struct redir_info));
memcpy(&message->param.setup.callerinfo, &e_callerinfo, sizeof(struct caller_info));
memcpy(&message->param.setup.capainfo, &e_capainfo, sizeof(struct capa_info));
+ memcpy(&message->param.setup.rtpinfo, &e_rtpinfo, sizeof(struct rtp_info));
//terminal SCPY(message->param.setup.from_terminal, e_ext.number);
//terminal if (e_dialinginfo.id)
//terminal SCPY(message->param.setup.to_terminal, e_dialinginfo.id);
p++;
/* found number */
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) calling to number '%s' interface '%s'\n", ea_endpoint->ep_serial, number, e_dialinginfo.interfaces[0]?e_dialinginfo.interfaces:"any interface");
- /* hunt for mISDNport and create Port */
- /* hunt for mISDNport and create Port */
- mISDNport = hunt_port(e_dialinginfo.interfaces[0]?e_dialinginfo.interfaces:NULL, &channel);
- if (!mISDNport) {
- trace_header("INTERFACE (too busy)", DIRECTION_NONE);
- add_trace("interface", NULL, "%s", e_dialinginfo.interfaces[0]?e_dialinginfo.interfaces:"any interface");
+ /* search interface */
+ interface = hunt_interface(e_dialinginfo.interfaces[0]?e_dialinginfo.interfaces:NULL);
+ if (!interface) {
+ trace_header("INTERFACE (not found)", DIRECTION_NONE);
+ add_trace("interface", NULL, "%s", ifname);
end_trace();
goto check_anycall_extern;
}
- /* creating EXTERNAL port*/
- SPRINT(portname, "%s-%d-out", mISDNport->ifport->interface->name, mISDNport->portnum);
-#ifdef WITH_SS5
- if (mISDNport->ss5)
- port = ss5_hunt_line(mISDNport);
- else
-#endif
+ /* found interface */
#ifdef WITH_GSM_BS
- if (mISDNport->gsm_bs)
- port = new Pgsm_bs(PORT_TYPE_GSM_BS_OUT, mISDNport, portname, &port_settings, channel, mISDNport->ifport->channel_force, mode);
- else
+ if (interface->gsm_bs) {
+ SPRINT(portname, "%s-%d-out", interface->name, 0);
+ port = new Pgsm_bs(PORT_TYPE_GSM_BS_OUT, portname, &port_settings, interface);
+ } else
#endif
#ifdef WITH_GSM_MS
- if (mISDNport->gsm_ms)
- port = new Pgsm_ms(PORT_TYPE_GSM_MS_OUT, mISDNport, portname, &port_settings, channel, mISDNport->ifport->channel_force, mode);
- else
+ if (interface->gsm_ms) {
+ SPRINT(portname, "%s-%d-out", interface->name, 0);
+ port = new Pgsm_ms(PORT_TYPE_GSM_MS_OUT, portname, &port_settings, interface);
+ } else
+#endif
+#ifdef WITH_GSM_MS
+ if (interface->sip) {
+ SPRINT(portname, "%s-%d-out", interface->name, 0);
+ port = new Psip(PORT_TYPE_SIP_OUT, portname, &port_settings, interface);
+ } else
+#endif
+ {
+ /* hunt for mISDNport and create Port */
+ mISDNport = hunt_port(e_dialinginfo.interfaces[0]?e_dialinginfo.interfaces:NULL, &channel);
+ if (!mISDNport) {
+ trace_header("INTERFACE (too busy)", DIRECTION_NONE);
+ add_trace("interface", NULL, "%s", e_dialinginfo.interfaces[0]?e_dialinginfo.interfaces:"any interface");
+ end_trace();
+ goto check_anycall_extern;
+ }
+ /* creating EXTERNAL port*/
+ SPRINT(portname, "%s-%d-out", mISDNport->ifport->interface->name, mISDNport->portnum);
+#ifdef WITH_SS5
+ if (mISDNport->ss5)
+ port = ss5_hunt_line(mISDNport);
+ else
#endif
- port = new Pdss1((mISDNport->ntmode)?PORT_TYPE_DSS1_NT_OUT:PORT_TYPE_DSS1_TE_OUT, mISDNport, portname, &port_settings, channel, mISDNport->ifport->channel_force, mode);
+ if (mISDNport->ifport->remote) {
+ admin = admin_first;
+ while(admin) {
+ if (admin->remote_name[0] && !strcmp(admin->remote_name, mISDNport->ifport->remote_app))
+ break;
+ admin = admin->next;
+ }
+ if (!admin) {
+ trace_header("INTERFACE (remote not connected)", DIRECTION_NONE);
+ add_trace("application", NULL, "%s", mISDNport->ifport->remote_app);
+ end_trace();
+ continue;
+ }
+ port = new Premote(PORT_TYPE_REMOTE_OUT, mISDNport, portname, &port_settings, channel, mISDNport->ifport->channel_force, mode, admin->sock);
+ } else
+ port = new Pdss1((mISDNport->ntmode)?PORT_TYPE_DSS1_NT_OUT:PORT_TYPE_DSS1_TE_OUT, mISDNport, portname, &port_settings, channel, mISDNport->ifport->channel_force, mode);
+ }
if (!port)
FATAL("No memory for Port instance\n");
- earlyb = mISDNport->earlyb;
+ earlyb = (interface->is_earlyb == IS_YES);
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) created port %s\n", ea_endpoint->ep_serial, port->p_name);
memset(&dialinginfo, 0, sizeof(dialinginfo));
if (e_dialinginfo.keypad[0])
dialinginfo.itype = INFO_ITYPE_ISDN;
dialinginfo.ntype = e_dialinginfo.ntype;
dialinginfo.sending_complete = e_dialinginfo.sending_complete;
- portlist = ea_endpoint->portlist_new(port->p_serial, port->p_type, mISDNport->earlyb);
+ portlist = ea_endpoint->portlist_new(port->p_serial, port->p_type, earlyb);
if (!portlist) {
PERROR("EPOINT(%d) cannot allocate port_list relation\n", ea_endpoint->ep_serial);
delete port;
memcpy(&message->param.setup.redirinfo, &e_redirinfo, sizeof(struct redir_info));
memcpy(&message->param.setup.callerinfo, &e_callerinfo, sizeof(struct caller_info));
memcpy(&message->param.setup.capainfo, &e_capainfo, sizeof(struct capa_info));
+ memcpy(&message->param.setup.rtpinfo, &e_rtpinfo, sizeof(struct rtp_info));
//terminal SCPY(message->param.setup.from_terminal, e_ext.number);
//terminal if (e_dialinginfo.id)
//terminal SCPY(message->param.setup.to_terminal, e_dialinginfo.id);
char buffer[256];
int writeext; /* flags need to write extension after modification */
class Port *port;
- struct interface *interface;
logmessage(message_type, param, portlist->port_id, DIRECTION_IN);
memcpy(&e_dialinginfo, ¶m->setup.dialinginfo, sizeof(e_dialinginfo));
memcpy(&e_redirinfo, ¶m->setup.redirinfo, sizeof(e_redirinfo));
memcpy(&e_capainfo, ¶m->setup.capainfo, sizeof(e_capainfo));
+ memcpy(&e_rtpinfo, ¶m->setup.rtpinfo, sizeof(e_rtpinfo));
/* convert (inter-)national number type */
SCPY(e_dialinginfo.id, numberrize_callerinfo(e_dialinginfo.id, e_dialinginfo.ntype, options.national, options.international));
// e_dtmf = param->setup.dtmf;
/* screen incoming caller id */
- interface = interface_first;
- while(interface) {
- if (!strcmp(e_callerinfo.interface, interface->name)) {
- break;
- }
- interface = interface->next;
- }
- if (interface) {
- do_screen(0, e_callerinfo.id, sizeof(e_callerinfo.id), &e_callerinfo.ntype, &e_callerinfo.present, interface);
- do_screen(0, e_callerinfo.id2, sizeof(e_callerinfo.id2), &e_callerinfo.ntype2, &e_callerinfo.present2, interface);
+ if (e_callerinfo.interface[0]) {
+ do_screen(0, e_callerinfo.id, sizeof(e_callerinfo.id), &e_callerinfo.ntype, &e_callerinfo.present, e_callerinfo.interface);
+ do_screen(0, e_callerinfo.id2, sizeof(e_callerinfo.id2), &e_callerinfo.ntype2, &e_callerinfo.present2, e_callerinfo.interface);
}
/* process extension */
unsigned int port_id = portlist->port_id;
struct port_list *tportlist;
class Port *port;
- struct interface *interface;
time_t now;
logmessage(message_type, param, portlist->port_id, DIRECTION_IN);
time(&now);
e_start = now;
- /* screen incoming connected id */
- interface = interface_first;
- while(interface) {
- if (!strcmp(e_connectinfo.interface, interface->name)) {
- break;
- }
- interface = interface->next;
- }
- if (interface)
- do_screen(0, e_connectinfo.id, sizeof(e_connectinfo.id), &e_connectinfo.ntype, &e_connectinfo.present, interface);
+ if (e_callerinfo.interface[0])
+ do_screen(0, e_connectinfo.id, sizeof(e_connectinfo.id), &e_connectinfo.ntype, &e_connectinfo.present, e_connectinfo.interface);
/* screen connected name */
if (e_ext.name[0])
/* other calls with no caller id (or not available for the extension) and force colp */
if ((e_connectinfo.id[0]=='\0' || (e_connectinfo.present==INFO_PRESENT_RESTRICTED && !e_ext.anon_ignore))&& e_ext.colp==COLP_FORCE) {
e_connectinfo.ntype = INFO_NTYPE_NOTPRESENT;
- if (portlist->port_type==PORT_TYPE_DSS1_TE_OUT
- || portlist->port_type==PORT_TYPE_DSS1_NT_OUT
- || portlist->port_type==PORT_TYPE_GSM_BS_OUT
- || portlist->port_type==PORT_TYPE_GSM_MS_OUT) { /* external extension answered */
+ if ((portlist->port_type & PORT_CLASS_DIR_MASK) == PORT_CLASS_DIR_OUT) {
+ /* external extension answered */
port = find_port_id(portlist->port_id);
if (port) {
SCPY(e_connectinfo.id, nationalize_callerinfo(port->p_dialinginfo.id, &e_connectinfo.ntype, options.national, options.international));
// PDEBUG(DEBUG_EPOINT, "received message %d (terminal %s, caller id %s)\n", message, e_ext.number, e_callerinfo.id);
switch(message_type) {
- case MESSAGE_DATA: /* data from port */
- /* check if there is a call */
- if (!ea_endpoint->ep_join_id)
- break;
- /* continue if only one portlist */
- if (ea_endpoint->ep_portlist->next != NULL)
- break;
- /* forward message */
- message_forward(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, param);
- break;
-
case MESSAGE_TONE_EOF: /* tone is end of file */
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) current tone is now end of file.\n", ea_endpoint->ep_serial);
if (e_action) {
memcpy(&e_dialinginfo, ¶m->setup.dialinginfo, sizeof(e_dialinginfo));
memcpy(&e_redirinfo, ¶m->setup.redirinfo, sizeof(e_redirinfo));
memcpy(&e_capainfo, ¶m->setup.capainfo, sizeof(e_capainfo));
+ memcpy(&e_rtpinfo, ¶m->setup.rtpinfo, sizeof(e_rtpinfo));
/* process (voice over) data calls */
if (e_ext.datacall && e_capainfo.bearer_capa!=INFO_BC_SPEECH && e_capainfo.bearer_capa!=INFO_BC_AUDIO) {
}
}
+/* join MESSAGE_BRIDE */
+void EndpointAppPBX::join_bridge(struct port_list *portlist, int message_type, union parameter *param)
+{
+ struct lcr_msg *message;
+
+ while(portlist) {
+ message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_BRIDGE);
+ memcpy(&message->param, param, sizeof(union parameter));
+ message_put(message);
+ portlist = portlist->next;
+ }
+}
+
/* join MESSAGE_NOTIFY */
void EndpointAppPBX::join_notify(struct port_list *portlist, int message_type, union parameter *param)
{
portlist = ea_endpoint->ep_portlist;
- /* send MESSAGE_DATA to port */
- if (message_type == MESSAGE_DATA) {
- if (join_id == ea_endpoint->ep_join_id) { // still linked with JOIN
- /* skip if no port relation */
- if (!portlist)
- return;
- /* skip if more than one port relation */
- if (portlist->next)
- return;
- /* forward audio data to port */
- message_forward(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, param);
- return;
- }
- }
-
// PDEBUG(DEBUG_EPOINT, "EPOINT(%d) received message %d for active JOIN (terminal %s, caller id %s state=%d)\n", ea_endpoint->ep_serial, message, e_ext.number, e_callerinfo.id, e_state);
switch(message_type) {
/* JOIN SENDS TONE message */
join_mISDNsignal(portlist, message_type, param);
break;
-#if 0
- kann nach dem test gelöscht werden, da eine direkte funktion im join und im mISDN zum austausch der message existiert
- /* JOIN requests bchannel */
- case MESSAGE_BCHANNEL: /* indicates the need of own bchannel access */
- PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received bchannel assignment %d from join.\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id, param->bchannel.type);
- /* only one port is expected to be connected to bchannel */
- if (!portlist)
- break;
- if (portlist->next)
- break;
- e_join_pattern = 1;
- SCPY(e_tone, "");
- set_tone(portlist, NULL);
- message = message_forward(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, param);
- logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
+ /* JOIN sends bridge message */
+ case MESSAGE_BRIDGE: /* bride message to port */
+ PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received bridge message.\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id);
+ join_bridge(portlist, message_type, param);
break;
-#endif
/* JOIN has pattern available */
case MESSAGE_PATTERN: /* indicating pattern available */
while(42) {
/* eliminate white spaces */
- while (*list <= ' ')
+ while (*list > '\0' && *list <= ' ')
list++;
if (*list == ',') {
list++;
break;
}
}
- if ((port->p_type==PORT_TYPE_DSS1_NT_OUT
- || port->p_type==PORT_TYPE_DSS1_TE_OUT
- || port->p_type==PORT_TYPE_GSM_BS_OUT
- || port->p_type==PORT_TYPE_GSM_MS_OUT)
+ if ((portlist->port_type & PORT_CLASS_DIR_MASK) == PORT_CLASS_DIR_OUT
&& port->p_state==PORT_STATE_OUT_ALERTING)
if (match_list(extensions, eapp->e_ext.number)) {
found = eapp;