X-Git-Url: http://git.eversberg.eu/gitweb.cgi?p=lcr.git;a=blobdiff_plain;f=apppbx.cpp;h=bf7988b81fbaf223de4ad2ac343c9b53e89adb5f;hp=cfaf6cb7e2fbc90f7e5558698f19fc92f8920cb3;hb=5463e1b62a39ce417b610584e3d34a8bc30ac15e;hpb=be404a4926ba076c5e2019b88e790e3f14ff11ff diff --git a/apppbx.cpp b/apppbx.cpp index cfaf6cb..bf7988b 100644 --- a/apppbx.cpp +++ b/apppbx.cpp @@ -72,6 +72,7 @@ EndpointAppPBX::EndpointAppPBX(class Endpoint *epoint, int origin) : EndpointApp 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; @@ -573,6 +574,53 @@ void EndpointAppPBX::set_tone(struct port_list *portlist, const char *tone) } } +/* 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 @@ -829,7 +877,7 @@ foundif: * ports will be created and a setup is sent if everything is ok. otherwhise * the endpoint is destroyed. */ -void EndpointAppPBX::out_setup(void) +void EndpointAppPBX::out_setup(int cfnr) { struct dialing_info dialinginfo; class Port *port; @@ -839,6 +887,7 @@ void EndpointAppPBX::out_setup(void) int cause = CAUSE_RESSOURCEUNAVAIL; const char *p; char cfp[64]; + struct interface *interface; struct mISDNport *mISDNport; char portname[32]; char *dirname; @@ -851,6 +900,7 @@ void EndpointAppPBX::out_setup(void) int channel = 0; int earlyb; int mode = B_MODE_TRANSPARENT; + struct admin_list *admin; /* set bchannel mode */ mode = e_capainfo.source_mode; @@ -938,7 +988,7 @@ void EndpointAppPBX::out_setup(void) p = e_ext.cfnr; if (*p) { /* when cfnr is done, out_setup() will setup the call */ - if (e_cfnr_call_timeout.active) { + if (cfnr) { /* present to forwarded party */ if (e_ext.anon_ignore && e_callerinfo.id[0]) { e_callerinfo.present = INFO_PRESENT_ALLOWED; @@ -962,40 +1012,76 @@ void EndpointAppPBX::out_setup(void) 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 + /* found interface */ + PDEBUG(DEBUG_EPOINT, "EPOINT(%d) calling to interface %s\n", ea_endpoint->ep_serial, ifname); +#ifdef WITH_GSM_BS + 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 - if (!mISDNport->gsm) - 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); - else -#ifdef WITH_GSM - port = new Pgsm(PORT_TYPE_GSM_OUT, mISDNport, portname, &port_settings, channel, mISDNport->ifport->channel_force, mode); -#else - port = NULL; +#ifdef WITH_GSM_MS + 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 + 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"); + FATAL("Failed to create Port instance\n"); PDEBUG(DEBUG_EPOINT, "EPOINT(%d) got port %s\n", ea_endpoint->ep_serial, port->p_name); memset(&dialinginfo, 0, sizeof(dialinginfo)); SCPY(dialinginfo.id, e_dialinginfo.id); 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; @@ -1015,6 +1101,7 @@ void EndpointAppPBX::out_setup(void) 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); @@ -1179,33 +1266,69 @@ void EndpointAppPBX::out_setup(void) 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 + /* found interface */ +#ifdef WITH_GSM_BS + 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 - if (!mISDNport->gsm) - 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); - else -#ifdef WITH_GSM - port = new Pgsm(PORT_TYPE_GSM_OUT, mISDNport, portname, &port_settings, channel, mISDNport->ifport->channel_force, mode); -#else - port = NULL; +#ifdef WITH_GSM_MS + 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 + 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]) @@ -1215,7 +1338,7 @@ void EndpointAppPBX::out_setup(void) 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; @@ -1227,6 +1350,7 @@ void EndpointAppPBX::out_setup(void) 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); @@ -1297,7 +1421,7 @@ int redial_timeout(struct lcr_timer *timer, void *instance, int index) ea->new_state(EPOINT_STATE_OUT_SETUP); /* call special setup routine */ - ea->out_setup(); + ea->out_setup(0); return 0; } @@ -1356,7 +1480,7 @@ int cfnr_call_timeout(struct lcr_timer *timer, void *instance, int index) class EndpointAppPBX *ea = (class EndpointAppPBX *)instance; PDEBUG(DEBUG_EPOINT, "EPOINT(%d) call-forward-busy time has expired, calling the forwarded number: %s.\n", ea->ea_endpoint->ep_serial, ea->e_ext.cfnr); - ea->out_setup(); + ea->out_setup(1); return 0; } @@ -1369,7 +1493,7 @@ int callback_timeout(struct lcr_timer *timer, void *instance, int index) /* epoint is idle, check callback */ PDEBUG(DEBUG_EPOINT, "EPOINT(%d) starting callback.\n", ea->ea_endpoint->ep_serial); ea->new_state(EPOINT_STATE_OUT_SETUP); - ea->out_setup(); + ea->out_setup(0); } return 0; @@ -1459,7 +1583,6 @@ void EndpointAppPBX::port_setup(struct port_list *portlist, int message_type, un 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); @@ -1468,6 +1591,7 @@ void EndpointAppPBX::port_setup(struct port_list *portlist, int message_type, un 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)); @@ -1475,16 +1599,9 @@ void EndpointAppPBX::port_setup(struct port_list *portlist, int message_type, un // 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 */ @@ -1612,6 +1729,8 @@ void EndpointAppPBX::port_setup(struct port_list *portlist, int message_type, un /* port MESSAGE_INFORMATION */ void EndpointAppPBX::port_information(struct port_list *portlist, int message_type, union parameter *param) { + struct lcr_msg *message; + logmessage(message_type, param, portlist->port_id, DIRECTION_IN); /* ignore information message without digit information */ @@ -1648,7 +1767,13 @@ void EndpointAppPBX::port_information(struct port_list *portlist, int message_ty /* keypad when connected */ if (e_state == EPOINT_STATE_CONNECT || e_state == EPOINT_STATE_IN_ALERTING) { - if (e_ext.keypad || e_enablekeypad) { + if (e_enablekeypad) { + message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, message_type); + memcpy(&message->param, param, sizeof(union parameter)); + message_put(message); + return; + } + if (e_ext.keypad) { PDEBUG(DEBUG_EPOINT, "EPOINT(%d) keypad information received during connect: %s.\n", ea_endpoint->ep_serial, param->information.id); /* processing keypad function */ if (param->information.id[0] == '0') { @@ -1696,6 +1821,7 @@ void EndpointAppPBX::port_information(struct port_list *portlist, int message_ty void EndpointAppPBX::port_dtmf(struct port_list *portlist, int message_type, union parameter *param) { time_t now; + struct lcr_msg *message; time(&now); @@ -1726,6 +1852,12 @@ NOTE: vbox is now handled due to overlap state /* check for *X# sequence */ if (e_state == EPOINT_STATE_CONNECT || e_state == EPOINT_STATE_IN_ALERTING) { + if (e_enablekeypad) { + message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, message_type); + memcpy(&message->param, param, sizeof(union parameter)); + message_put(message); + return; + } if (e_dtmf_time+3 < now) { /* the last digit was too far in the past to be a sequence */ if (param->dtmf == '*') @@ -1945,7 +2077,6 @@ void EndpointAppPBX::port_connect(struct port_list *portlist, int message_type, 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); @@ -1973,16 +2104,8 @@ void EndpointAppPBX::port_connect(struct port_list *portlist, int message_type, 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]) @@ -2027,7 +2150,8 @@ void EndpointAppPBX::port_connect(struct port_list *portlist, int message_type, /* 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_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)); @@ -2526,6 +2650,18 @@ void EndpointAppPBX::port_resume(struct port_list *portlist, int message_type, u } +/* port MESSAGE_ENABLEKEYPAD */ +void EndpointAppPBX::port_enablekeypad(struct port_list *portlist, int message_type, union parameter *param) +{ + struct lcr_msg *message; + + logmessage(message_type, param, portlist->port_id, DIRECTION_IN); + + message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_ENABLEKEYPAD); + memcpy(&message->param, param, sizeof(union parameter)); + message_put(message); +} + /* port sends message to the endpoint */ @@ -2546,17 +2682,6 @@ void EndpointAppPBX::ea_message_port(unsigned int port_id, int message_type, uni // 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) { @@ -2713,6 +2838,12 @@ void EndpointAppPBX::ea_message_port(unsigned int port_id, int message_type, uni break; #endif + /* PORT requests DTMF */ + case MESSAGE_ENABLEKEYPAD: + PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') requests DTMF/KEYPAD.\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id); + port_enablekeypad(portlist, message_type, param); + break; + default: PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received a wrong message: %d\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id, message_type); @@ -3126,6 +3257,7 @@ void EndpointAppPBX::join_setup(struct port_list *portlist, int message_type, un 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) { @@ -3138,7 +3270,7 @@ void EndpointAppPBX::join_setup(struct port_list *portlist, int message_type, un new_state(EPOINT_STATE_OUT_SETUP); /* call special setup routine */ - out_setup(); + out_setup(0); } /* join MESSAGE_mISDNSIGNAL */ @@ -3154,6 +3286,19 @@ void EndpointAppPBX::join_mISDNsignal(struct port_list *portlist, int message_ty } } +/* 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) { @@ -3208,6 +3353,19 @@ void EndpointAppPBX::join_notify(struct port_list *portlist, int message_type, u } } +/* join MESSAGE_DTMF */ +void EndpointAppPBX::join_dtmf(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_DTMF); + memcpy(&message->param, param, sizeof(union parameter)); + message_put(message); + portlist = portlist->next; + } +} + /* JOIN sends messages to the endpoint */ void EndpointAppPBX::ea_message_join(unsigned int join_id, int message_type, union parameter *param) @@ -3222,21 +3380,6 @@ void EndpointAppPBX::ea_message_join(unsigned int join_id, int message_type, uni 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 */ @@ -3326,23 +3469,11 @@ void EndpointAppPBX::ea_message_join(unsigned int join_id, int message_type, uni 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 */ @@ -3400,6 +3531,12 @@ void EndpointAppPBX::ea_message_join(unsigned int join_id, int message_type, uni end_trace(); break; + /* JOIN sends a DTMF message */ + case MESSAGE_DTMF: + PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received dtmf.\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id); + join_dtmf(portlist, message_type, param); + break; + default: PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received a wrong message: #%d\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id, message_type); } @@ -3419,7 +3556,7 @@ int match_list(char *list, char *item) while(42) { /* eliminate white spaces */ - while (*list <= ' ') + while (*list > '\0' && *list <= ' ') list++; if (*list == ',') { list++; @@ -3469,7 +3606,7 @@ void EndpointAppPBX::pick_join(char *extensions) break; } } - if ((port->p_type==PORT_TYPE_DSS1_NT_OUT || port->p_type==PORT_TYPE_DSS1_TE_OUT || port->p_type==PORT_TYPE_GSM_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; @@ -3661,7 +3798,7 @@ void EndpointAppPBX::join_join(void) PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: our port doesn't exist anymore.\n", ea_endpoint->ep_serial); return; } - if ((our_port->p_type&PORT_CLASS_mISDN_MASK) != PORT_CLASS_mISDN_DSS1) { + if ((our_port->p_type & PORT_CLASS_mISDN_MASK) != PORT_CLASS_DSS1) { PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: our port is not isdn.\n", ea_endpoint->ep_serial); return; } @@ -3859,7 +3996,7 @@ int EndpointAppPBX::check_external(const char **errstr, class Port **port) *errstr = "No Call"; return(1); } - if (((*port)->p_type&PORT_CLASS_mISDN_MASK)!=PORT_CLASS_mISDN_DSS1) { /* port is not external isdn */ + if (((*port)->p_type & PORT_CLASS_mISDN_MASK) != PORT_CLASS_DSS1) { /* port is not external isdn */ PDEBUG(DEBUG_EPOINT, "EPOINT(%d) 2nd endpoint has not an external port.\n", ea_endpoint->ep_serial); *errstr = "No Ext Call"; return(1);