From d6866316df3f8f9456304af57999d03b9d762268 Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Tue, 21 Feb 2012 11:32:31 +0100 Subject: [PATCH] Added support of mISDN to direct bridge feature Now it is possible to directly bridge: - GSM with SIP - GSM with ISDN - SIP with ISDN --- appbridge.cpp | 111 +++++++++++---------- appbridge.h | 1 - apppbx.cpp | 300 ------------------------------------------------------- apppbx.h | 2 - endpointapp.cpp | 305 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ endpointapp.h | 6 ++ 6 files changed, 368 insertions(+), 357 deletions(-) diff --git a/appbridge.cpp b/appbridge.cpp index 50808ca..b52e125 100644 --- a/appbridge.cpp +++ b/appbridge.cpp @@ -78,55 +78,6 @@ void EndpointAppBridge::trace_header(const char *name, int direction) msgtext); } -/* hunts for the given interface - * it does not need to have an mISDNport instance */ -struct interface *EndpointAppBridge::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; -} - - /* port MESSAGE_SETUP */ void EndpointAppBridge::port_setup(struct port_list *portlist, int message_type, union parameter *param) { @@ -138,6 +89,7 @@ void EndpointAppBridge::port_setup(struct port_list *portlist, int message_type, unsigned int bridge_id; unsigned int source_port_id = portlist->port_id; char portname[64]; + int cause = 47; PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint received setup from='%s' to='%s'\n", ea_endpoint->ep_serial, param->setup.callerinfo.id, param->setup.dialinginfo.id); @@ -156,10 +108,10 @@ void EndpointAppBridge::port_setup(struct port_list *portlist, int message_type, interface_in = interface_in->next; } if (!interface_in) { -fail: PERROR("Cannot find source interface %s.\n", param->setup.callerinfo.interface); +fail: message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_RELEASE); - message->param.disconnectinfo.cause = 47; + message->param.disconnectinfo.cause = cause; message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL; message_put(message); @@ -186,18 +138,69 @@ fail: #ifdef WITH_SIP if (interface_out->sip) { port = new Psip(PORT_TYPE_SIP_OUT, portname, &port_settings, interface_out); - } + } else #endif #ifdef WITH_GSM_BS if (interface_out->gsm_bs) { port = new Pgsm_bs(PORT_TYPE_GSM_BS_OUT, portname, &port_settings, interface_out); - } + } else #endif #ifdef WITH_GSM_MS if (interface_out->gsm_ms) { port = new Pgsm_bs(PORT_TYPE_GSM_MS_OUT, portname, &port_settings, interface_out); - } + } else #endif + { +#ifdef WITH_MISDN + struct mISDNport *mISDNport; + char *ifname = interface_out->name; + int channel = 0; + struct admin_list *admin; + int earlyb; + int mode = B_MODE_TRANSPARENT; + + /* 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(); + cause = 33; + goto fail; + } + + 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(); + cause = 27; + goto fail; + } + 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); + earlyb = mISDNport->earlyb; +#else + trace_header("INTERFACE (has no function)", DIRECTION_NONE); + add_trace("interface", NULL, "%s", ifname); + end_trace(); + cause = 31; + goto fail +#endif + } if (!port) FATAL("Remote interface, but not supported???\n"); portlist = ea_endpoint->portlist_new(port->p_serial, port->p_type, interface_out->is_earlyb == IS_YES); diff --git a/appbridge.h b/appbridge.h index 2e4ea06..bfad94d 100644 --- a/appbridge.h +++ b/appbridge.h @@ -26,7 +26,6 @@ class EndpointAppBridge : public EndpointApp void port_release(struct port_list *portlist, int message_type, union parameter *param); void port_other(struct port_list *portlist, int message_type, union parameter *param); void ea_message_port(unsigned int port_id, int message, union parameter *param); - struct interface *hunt_interface(char *ifname); void trace_header(const char *name, int direction); }; diff --git a/apppbx.cpp b/apppbx.cpp index a61d108..bacdba9 100644 --- a/apppbx.cpp +++ b/apppbx.cpp @@ -584,306 +584,6 @@ 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; -} - - -#ifdef WITH_MISDN -/* - * hunts an mISDNport that is available for an outgoing call - * if no ifname was given, any interface that is not an extension - * will be searched. - */ -struct mISDNport *EndpointAppPBX::hunt_port(char *ifname, int *channel) -{ - struct interface *interface; - struct interface_port *ifport, *ifport_start; - struct select_channel *selchannel; - struct mISDNport *mISDNport; - int index, i; - 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: - - /* see if interface has ports */ - if (!interface->ifport) { - /* no ports */ - trace_header("CHANNEL SELECTION (active ports, skipping)", DIRECTION_NONE); - add_trace("interface", NULL, "%s", interface->name); - end_trace(); - interface = interface->next; - goto checknext; - } - - /* select port by algorithm */ - ifport_start = interface->ifport; - index = 0; - if (interface->hunt == HUNT_ROUNDROBIN) { - while(ifport_start->next && indexhunt_next) { - ifport_start = ifport_start->next; - index++; - } - trace_header("CHANNEL SELECTION (starting round-robin)", DIRECTION_NONE); - add_trace("port", NULL, "%d", ifport_start->portnum); - add_trace("position", NULL, "%d", index); - end_trace(); - } - - /* loop ports */ - ifport = ifport_start; - nextport: - - /* see if port is available */ - if (!ifport->mISDNport) { - trace_header("CHANNEL SELECTION (port not available, skipping)", DIRECTION_NONE); - add_trace("port", NULL, "%d", ifport->portnum); - add_trace("position", NULL, "%d", index); - end_trace(); - goto portbusy; - } - mISDNport = ifport->mISDNport; - - /* see if port is administratively blocked */ - if (ifport->block) { - trace_header("CHANNEL SELECTION (port blocked by admin, skipping)", DIRECTION_NONE); - add_trace("port", NULL, "%d", ifport->portnum); - add_trace("position", NULL, "%d", index); - end_trace(); - goto portbusy; - } - - /* see if link is up on PTP*/ - if (mISDNport->l2hold && mISDNport->l2link<1) { - trace_header("CHANNEL SELECTION (port's layer 2 is down, skipping)", DIRECTION_NONE); - add_trace("port", NULL, "%d", ifport->portnum); - add_trace("position", NULL, "%d", index); - end_trace(); - goto portbusy; - } - - /* check for channel form selection list */ - *channel = 0; -#ifdef WITH_SS5 - if (mISDNport->ss5) { - class Pss5 *port; - port = ss5_hunt_line(mISDNport); - if (port) { - *channel = port->p_m_b_channel; - trace_header("CHANNEL SELECTION (selecting SS5 channel)", DIRECTION_NONE); - add_trace("port", NULL, "%d", ifport->portnum); - add_trace("position", NULL, "%d", index); - add_trace("channel", NULL, "%d", *channel); - end_trace(); - } - } else -#endif - { - selchannel = ifport->out_channel; - while(selchannel) { - switch(selchannel->channel) { - case CHANNEL_FREE: /* free channel */ - if (mISDNport->b_reserved >= mISDNport->b_num) - break; /* all channel in use or reserverd */ - /* find channel */ - i = 0; - while(i < mISDNport->b_num) { - if (mISDNport->b_port[i] == NULL) { - *channel = i+1+(i>=15); - trace_header("CHANNEL SELECTION (selecting free channel)", DIRECTION_NONE); - add_trace("port", NULL, "%d", ifport->portnum); - add_trace("position", NULL, "%d", index); - add_trace("channel", NULL, "%d", *channel); - end_trace(); - break; - } - i++; - } - if (*channel) - break; - trace_header("CHANNEL SELECTION (no channel is 'free')", DIRECTION_NONE); - add_trace("port", NULL, "%d", ifport->portnum); - add_trace("position", NULL, "%d", index); - end_trace(); - break; - - case CHANNEL_ANY: /* don't ask for channel */ - if (mISDNport->b_reserved >= mISDNport->b_num) { - trace_header("CHANNEL SELECTION (cannot ask for 'any' channel, all reserved)", DIRECTION_NONE); - add_trace("port", NULL, "%d", ifport->portnum); - add_trace("position", NULL, "%d", index); - add_trace("total", NULL, "%d", mISDNport->b_num); - add_trace("reserved", NULL, "%d", mISDNport->b_reserved); - end_trace(); - break; /* all channel in use or reserverd */ - } - trace_header("CHANNEL SELECTION (using 'any' channel)", DIRECTION_NONE); - add_trace("port", NULL, "%d", ifport->portnum); - add_trace("position", NULL, "%d", index); - end_trace(); - *channel = CHANNEL_ANY; - break; - - case CHANNEL_NO: /* call waiting */ - trace_header("CHANNEL SELECTION (using 'no' channel, call-waiting)", DIRECTION_NONE); - add_trace("port", NULL, "%d", ifport->portnum); - add_trace("position", NULL, "%d", index); - end_trace(); - *channel = CHANNEL_NO; - break; - - default: - if (selchannel->channel<1 || selchannel->channel==16) { - trace_header("CHANNEL SELECTION (channel out of range)", DIRECTION_NONE); - add_trace("port", NULL, "%d", ifport->portnum); - add_trace("position", NULL, "%d", index); - add_trace("channel", NULL, "%d", selchannel->channel); - end_trace(); - break; /* invalid channels */ - } - i = selchannel->channel-1-(selchannel->channel>=17); - if (i >= mISDNport->b_num) { - trace_header("CHANNEL SELECTION (channel out of range)", DIRECTION_NONE); - add_trace("port", NULL, "%d", ifport->portnum); - add_trace("position", NULL, "%d", index); - add_trace("channel", NULL, "%d", selchannel->channel); - add_trace("channels", NULL, "%d", mISDNport->b_num); - end_trace(); - break; /* channel not in port */ - } - if (mISDNport->b_port[i] == NULL) { - *channel = selchannel->channel; - trace_header("CHANNEL SELECTION (selecting given channel)", DIRECTION_NONE); - add_trace("port", NULL, "%d", ifport->portnum); - add_trace("position", NULL, "%d", index); - add_trace("channel", NULL, "%d", *channel); - end_trace(); - break; - } - break; - } - if (*channel) - break; /* found channel */ - selchannel = selchannel->next; - } - } - - /* if channel was found, return mISDNport and channel */ - if (*channel) { - /* setting next port to start next time */ - if (interface->hunt == HUNT_ROUNDROBIN) { - index++; - if (!ifport->next) - index = 0; - interface->hunt_next = index; - } - - return(mISDNport); - } - - trace_header("CHANNEL SELECTION (skipping, no channel found)", DIRECTION_NONE); - add_trace("port", NULL, "%d", ifport->portnum); - add_trace("position", NULL, "%d", index); - end_trace(); - - portbusy: - /* go next port, until all ports are checked */ - index++; - ifport = ifport->next; - if (!ifport) { - index = 0; - ifport = interface->ifport; - } - if (ifport != ifport_start) - goto nextport; - - if (!ifname) { - interface = interface->next; - goto checknext; - } - - return(NULL); /* no port found */ -} -#endif /* outgoing setup to port(s) * ports will be created and a setup is sent if everything is ok. otherwhise diff --git a/apppbx.h b/apppbx.h index 8b49506..c3d2d68 100644 --- a/apppbx.h +++ b/apppbx.h @@ -236,8 +236,6 @@ class EndpointAppPBX : public EndpointApp void keypad_function(char digit); void set_tone(struct port_list *portlist, const char *tone); void out_setup(int cfnr); - struct mISDNport *hunt_port(char *ifname, int *channel); - struct interface *hunt_interface(char *ifname); char *apply_callerid_display(const char *id, int itype, int ntype, int present, int screen, const char *extension, const char *name); void auth(int job, int bit_num); diff --git a/endpointapp.cpp b/endpointapp.cpp index da797de..a3ad7dd 100644 --- a/endpointapp.cpp +++ b/endpointapp.cpp @@ -64,3 +64,308 @@ class EndpointApp *new_endpointapp(class Endpoint *epoint, int origin, int type) return app; } + +#ifdef WITH_MISDN +/* + * hunts an mISDNport that is available for an outgoing call + * if no ifname was given, any interface that is not an extension + * will be searched. + */ +struct mISDNport *EndpointApp::hunt_port(char *ifname, int *channel) +{ + struct interface *interface; + struct interface_port *ifport, *ifport_start; + struct select_channel *selchannel; + struct mISDNport *mISDNport; + int index, i; + 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: + + /* see if interface has ports */ + if (!interface->ifport) { + /* no ports */ + trace_header("CHANNEL SELECTION (active ports, skipping)", DIRECTION_NONE); + add_trace("interface", NULL, "%s", interface->name); + end_trace(); + interface = interface->next; + goto checknext; + } + + /* select port by algorithm */ + ifport_start = interface->ifport; + index = 0; + if (interface->hunt == HUNT_ROUNDROBIN) { + while(ifport_start->next && indexhunt_next) { + ifport_start = ifport_start->next; + index++; + } + trace_header("CHANNEL SELECTION (starting round-robin)", DIRECTION_NONE); + add_trace("port", NULL, "%d", ifport_start->portnum); + add_trace("position", NULL, "%d", index); + end_trace(); + } + + /* loop ports */ + ifport = ifport_start; + nextport: + + /* see if port is available */ + if (!ifport->mISDNport) { + trace_header("CHANNEL SELECTION (port not available, skipping)", DIRECTION_NONE); + add_trace("port", NULL, "%d", ifport->portnum); + add_trace("position", NULL, "%d", index); + end_trace(); + goto portbusy; + } + mISDNport = ifport->mISDNport; + + /* see if port is administratively blocked */ + if (ifport->block) { + trace_header("CHANNEL SELECTION (port blocked by admin, skipping)", DIRECTION_NONE); + add_trace("port", NULL, "%d", ifport->portnum); + add_trace("position", NULL, "%d", index); + end_trace(); + goto portbusy; + } + + /* see if link is up on PTP*/ + if (mISDNport->l2hold && mISDNport->l2link<1) { + trace_header("CHANNEL SELECTION (port's layer 2 is down, skipping)", DIRECTION_NONE); + add_trace("port", NULL, "%d", ifport->portnum); + add_trace("position", NULL, "%d", index); + end_trace(); + goto portbusy; + } + + /* check for channel form selection list */ + *channel = 0; +#ifdef WITH_SS5 + if (mISDNport->ss5) { + class Pss5 *port; + port = ss5_hunt_line(mISDNport); + if (port) { + *channel = port->p_m_b_channel; + trace_header("CHANNEL SELECTION (selecting SS5 channel)", DIRECTION_NONE); + add_trace("port", NULL, "%d", ifport->portnum); + add_trace("position", NULL, "%d", index); + add_trace("channel", NULL, "%d", *channel); + end_trace(); + } + } else +#endif + { + selchannel = ifport->out_channel; + while(selchannel) { + switch(selchannel->channel) { + case CHANNEL_FREE: /* free channel */ + if (mISDNport->b_reserved >= mISDNport->b_num) + break; /* all channel in use or reserverd */ + /* find channel */ + i = 0; + while(i < mISDNport->b_num) { + if (mISDNport->b_port[i] == NULL) { + *channel = i+1+(i>=15); + trace_header("CHANNEL SELECTION (selecting free channel)", DIRECTION_NONE); + add_trace("port", NULL, "%d", ifport->portnum); + add_trace("position", NULL, "%d", index); + add_trace("channel", NULL, "%d", *channel); + end_trace(); + break; + } + i++; + } + if (*channel) + break; + trace_header("CHANNEL SELECTION (no channel is 'free')", DIRECTION_NONE); + add_trace("port", NULL, "%d", ifport->portnum); + add_trace("position", NULL, "%d", index); + end_trace(); + break; + + case CHANNEL_ANY: /* don't ask for channel */ + if (mISDNport->b_reserved >= mISDNport->b_num) { + trace_header("CHANNEL SELECTION (cannot ask for 'any' channel, all reserved)", DIRECTION_NONE); + add_trace("port", NULL, "%d", ifport->portnum); + add_trace("position", NULL, "%d", index); + add_trace("total", NULL, "%d", mISDNport->b_num); + add_trace("reserved", NULL, "%d", mISDNport->b_reserved); + end_trace(); + break; /* all channel in use or reserverd */ + } + trace_header("CHANNEL SELECTION (using 'any' channel)", DIRECTION_NONE); + add_trace("port", NULL, "%d", ifport->portnum); + add_trace("position", NULL, "%d", index); + end_trace(); + *channel = CHANNEL_ANY; + break; + + case CHANNEL_NO: /* call waiting */ + trace_header("CHANNEL SELECTION (using 'no' channel, call-waiting)", DIRECTION_NONE); + add_trace("port", NULL, "%d", ifport->portnum); + add_trace("position", NULL, "%d", index); + end_trace(); + *channel = CHANNEL_NO; + break; + + default: + if (selchannel->channel<1 || selchannel->channel==16) { + trace_header("CHANNEL SELECTION (channel out of range)", DIRECTION_NONE); + add_trace("port", NULL, "%d", ifport->portnum); + add_trace("position", NULL, "%d", index); + add_trace("channel", NULL, "%d", selchannel->channel); + end_trace(); + break; /* invalid channels */ + } + i = selchannel->channel-1-(selchannel->channel>=17); + if (i >= mISDNport->b_num) { + trace_header("CHANNEL SELECTION (channel out of range)", DIRECTION_NONE); + add_trace("port", NULL, "%d", ifport->portnum); + add_trace("position", NULL, "%d", index); + add_trace("channel", NULL, "%d", selchannel->channel); + add_trace("channels", NULL, "%d", mISDNport->b_num); + end_trace(); + break; /* channel not in port */ + } + if (mISDNport->b_port[i] == NULL) { + *channel = selchannel->channel; + trace_header("CHANNEL SELECTION (selecting given channel)", DIRECTION_NONE); + add_trace("port", NULL, "%d", ifport->portnum); + add_trace("position", NULL, "%d", index); + add_trace("channel", NULL, "%d", *channel); + end_trace(); + break; + } + break; + } + if (*channel) + break; /* found channel */ + selchannel = selchannel->next; + } + } + + /* if channel was found, return mISDNport and channel */ + if (*channel) { + /* setting next port to start next time */ + if (interface->hunt == HUNT_ROUNDROBIN) { + index++; + if (!ifport->next) + index = 0; + interface->hunt_next = index; + } + + return(mISDNport); + } + + trace_header("CHANNEL SELECTION (skipping, no channel found)", DIRECTION_NONE); + add_trace("port", NULL, "%d", ifport->portnum); + add_trace("position", NULL, "%d", index); + end_trace(); + + portbusy: + /* go next port, until all ports are checked */ + index++; + ifport = ifport->next; + if (!ifport) { + index = 0; + ifport = interface->ifport; + } + if (ifport != ifport_start) + goto nextport; + + if (!ifname) { + interface = interface->next; + goto checknext; + } + + return(NULL); /* no port found */ +} +#endif + +/* hunts for the given interface + * it does not need to have an mISDNport instance */ +struct interface *EndpointApp::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; +} + +/* must be overloaded by specific app */ +void EndpointApp::trace_header(const char *name, int direction) +{ +} diff --git a/endpointapp.h b/endpointapp.h index 4147c51..5d6f253 100644 --- a/endpointapp.h +++ b/endpointapp.h @@ -23,6 +23,12 @@ class EndpointApp class Endpoint *ea_endpoint; virtual void ea_message_port(unsigned int port_id, int message, union parameter *param); virtual void ea_message_join(unsigned int join_id, int message, union parameter *param); + virtual void trace_header(const char *name, int direction); + +#ifdef WITH_MISDN + struct mISDNport *hunt_port(char *ifname, int *channel); +#endif + struct interface *hunt_interface(char *ifname); }; class EndpointApp *new_endpointapp(class Endpoint *epoint, int origin, int type); -- 2.13.6