From 74a7fe54a81bb7e996ea45203bbc8cc0ff6b8dda Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Mon, 16 Jan 2012 09:14:22 +0100 Subject: [PATCH] Adding simple bridge application to forward calls without PBX app. Call received on an interface can directly be forwarded to a given destination interface, instead of routing the call through PBX application. This way calls can be forwarded without going through route.conf. Currently only SIP and GSM destinations are supported. Also there are no tones generated, if one side provides no tones, but the other wants to receive them. The keyword "bridge " in interface.conf is used. Without that keyword, incomming calls are handled as usual. --- Makefile.am | 10 +- appbridge.cpp | 294 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ appbridge.h | 35 +++++++ apppbx.cpp | 2 +- dss1.cpp | 3 +- endpoint.h | 1 + endpointapp.cpp | 26 ++++- endpointapp.h | 7 +- gsm_bs.cpp | 14 ++- gsm_ms.cpp | 14 ++- interface.c | 17 +++- interface.h | 2 + join.h | 2 + joinpbx.cpp | 3 +- joinremote.cpp | 3 +- main.h | 3 +- port.cpp | 2 +- remote.cpp | 3 +- sip.cpp | 15 ++- socket_server.c | 6 +- ss5.cpp | 3 +- vbox.cpp | 3 +- 22 files changed, 435 insertions(+), 33 deletions(-) create mode 100644 appbridge.cpp create mode 100644 appbridge.h diff --git a/Makefile.am b/Makefile.am index 629bb50..a5396b3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -134,12 +134,12 @@ endif INCLUDES = $(all_includes) $(GSM_INCLUDE) $(SS5_INCLUDE) $(SIP_INCLUDE) -Wall $(INSTALLATION_DEFINES) lcr_SOURCES = \ - main.c select.c trace.c \ options.c \ tones.c \ alawulaw.c \ cause.c \ interface.c \ message.c \ callerid.c \ socket_server.c \ - port.cpp \ vbox.cpp \ mISDN.cpp \ dss1.cpp \ loop.c remote.cpp \ + main.c select.c trace.c options.c tones.c alawulaw.c cause.c interface.c message.c callerid.c socket_server.c \ + port.cpp vbox.cpp mISDN.cpp dss1.cpp loop.c remote.cpp \ $(GSM_SOURCE) $(SS5_SOURCE) $(SIP_SOURCE) \ - endpoint.cpp \ endpointapp.cpp \ - apppbx.cpp \ route.c \ action.cpp action_efi.cpp \ action_vbox.cpp \ extension.c \ crypt.cpp \ mail.c \ - join.cpp \ joinpbx.cpp \ joinremote.cpp + endpoint.cpp endpointapp.cpp \ + appbridge.cpp apppbx.cpp route.c action.cpp action_efi.cpp action_vbox.cpp extension.c crypt.cpp mail.c \ + join.cpp joinpbx.cpp joinremote.cpp lcr_LDADD = $(LIBCRYPTO) -lmisdn -lpthread $(GSM_LIB) $(SIP_LIB) diff --git a/appbridge.cpp b/appbridge.cpp new file mode 100644 index 0000000..50808ca --- /dev/null +++ b/appbridge.cpp @@ -0,0 +1,294 @@ +/*****************************************************************************\ +** ** +** Linux Call Router ** +** ** +**---------------------------------------------------------------------------** +** Copyright: Andreas Eversberg ** +** ** +** The EndpointAppBridge implements direct bridge between interfaces ** +** ** +\*****************************************************************************/ + + +#include "main.h" + +class EndpointAppBridge *appbridge_first = NULL; + +/* + * EndpointAppBridge constructor + */ +EndpointAppBridge::EndpointAppBridge(class Endpoint *epoint, int origin) : EndpointApp(epoint, origin, EAPP_TYPE_BRIDGE) +{ + class EndpointAppBridge **apppointer; + + /* add application to chain */ + next = NULL; + apppointer = &appbridge_first; + while(*apppointer) + apppointer = &((*apppointer)->next); + *apppointer = this; + + PDEBUG(DEBUG_EPOINT, "Bridge endpoint created\n"); +} + +/* + * EpointAppBridge destructor + */ +EndpointAppBridge::~EndpointAppBridge(void) +{ + class EndpointAppBridge *temp, **tempp; + + /* detach */ + temp =appbridge_first; + tempp = &appbridge_first; + while(temp) { + if (temp == this) + break; + + tempp = &temp->next; + temp = temp->next; + } + if (temp == 0) + FATAL("Endpoint not in endpoint's list.\n"); + *tempp = next; + + PDEBUG(DEBUG_EPOINT, "Bridge endpoint destroyed\n"); +} + + +/* + * trace header for application + */ +void EndpointAppBridge::trace_header(const char *name, int direction) +{ + struct trace _trace; + + char msgtext[sizeof(_trace.name)]; + + SCPY(msgtext, name); + + /* init trace with given values */ + start_trace(-1, + NULL, + "", //numberrize_callerinfo(e_callerinfo.id, e_callerinfo.ntype, options.national, options.international), + "", // e_dialinginfo.id, + direction, + CATEGORY_EP, + ea_endpoint->ep_serial, + 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) +{ + struct interface *interface_in = interface_first; + struct interface *interface_out = interface_first; + struct port_settings port_settings; + class Port *port = NULL; + struct lcr_msg *message; + unsigned int bridge_id; + unsigned int source_port_id = portlist->port_id; + char portname[64]; + + 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); + + if (!ea_endpoint->ep_portlist) { + PERROR("Endpoint has no port in portlist\n"); + return; + } + if (ea_endpoint->ep_portlist->next) { + PDEBUG(DEBUG_EPOINT, "Endpoint already received setup, ignoring.\n"); + return; + } + + while (interface_in) { + if (!strcmp(interface_in->name, param->setup.callerinfo.interface)) + break; + interface_in = interface_in->next; + } + if (!interface_in) { +fail: + PERROR("Cannot find source interface %s.\n", param->setup.callerinfo.interface); + message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_RELEASE); + message->param.disconnectinfo.cause = 47; + message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL; + message_put(message); + + /* destroy endpoint */ + ea_endpoint->ep_use = 0; + trigger_work(&ea_endpoint->ep_delete); + return; + } + + while (interface_out) { + if (!strcmp(interface_out->name, interface_in->bridge_if)) + break; + interface_out = interface_out->next; + } + if (!interface_out) { + PERROR("Cannot find destination interface %s.\n", interface_in->bridge_if); + goto fail; + return; + } + + /* create port for interface */ + SPRINT(portname, "%s-%d-out", interface_out->name, 0); + memset(&port_settings, 0, sizeof(port_settings)); +#ifdef WITH_SIP + if (interface_out->sip) { + port = new Psip(PORT_TYPE_SIP_OUT, portname, &port_settings, interface_out); + } +#endif +#ifdef WITH_GSM_BS + if (interface_out->gsm_bs) { + port = new Pgsm_bs(PORT_TYPE_GSM_BS_OUT, portname, &port_settings, interface_out); + } +#endif +#ifdef WITH_GSM_MS + if (interface_out->gsm_ms) { + port = new Pgsm_bs(PORT_TYPE_GSM_MS_OUT, portname, &port_settings, interface_out); + } +#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); + if (!portlist) + FATAL("EPOINT(%d) cannot allocate port_list relation\n", ea_endpoint->ep_serial); + /* forward setup */ + message_forward(ea_endpoint->ep_serial, port->p_serial, EPOINT_TO_PORT, param); + + /* apply bridge to interfaces */ + /* FIXME: use mISDN bridge for mISDN ports */ + bridge_id = join_serial++; + message = message_create(ea_endpoint->ep_serial, source_port_id, EPOINT_TO_PORT, MESSAGE_BRIDGE); + message->param.bridge_id = bridge_id; + message_put(message); + message = message_create(ea_endpoint->ep_serial, port->p_serial, EPOINT_TO_PORT, MESSAGE_BRIDGE); + message->param.bridge_id = bridge_id; + message_put(message); +} + +/* port MESSAGE_RELEASE */ +void EndpointAppBridge::port_release(struct port_list *portlist, int message_type, union parameter *param) +{ + unsigned int remote; + + PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint received release from port\n"); + + if (!ea_endpoint->ep_portlist || !ea_endpoint->ep_portlist->next) + goto out; + if (ea_endpoint->ep_portlist->port_id == portlist->port_id) + remote = ea_endpoint->ep_portlist->next->port_id; + else + remote = ea_endpoint->ep_portlist->port_id; + /* forward release */ + message_forward(ea_endpoint->ep_serial, remote, EPOINT_TO_PORT, param); + +out: + /* destroy endpoint */ + ea_endpoint->ep_use = 0; + trigger_work(&ea_endpoint->ep_delete); +} + +/* port other messages */ +void EndpointAppBridge::port_other(struct port_list *portlist, int message_type, union parameter *param) +{ + unsigned int remote; + + PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint received message %d from port\n", message_type); + + if (!ea_endpoint->ep_portlist || !ea_endpoint->ep_portlist->next) + return; + if (ea_endpoint->ep_portlist->port_id == portlist->port_id) + remote = ea_endpoint->ep_portlist->next->port_id; + else + remote = ea_endpoint->ep_portlist->port_id; + /* forward release */ + message_forward(ea_endpoint->ep_serial, remote, EPOINT_TO_PORT, param); +} + +/* port sends message to the endpoint + */ +void EndpointAppBridge::ea_message_port(unsigned int port_id, int message_type, union parameter *param) +{ + struct port_list *portlist; + + portlist = ea_endpoint->ep_portlist; + while(portlist) { + if (port_id == portlist->port_id) + break; + portlist = portlist->next; + } + if (!portlist) { + PDEBUG(DEBUG_EPOINT, "EPOINT(%d) warning: port is not related to this endpoint. This may happen, if port has been released after the message was created.\n", ea_endpoint->ep_serial); + return; + } + +// PDEBUG(DEBUG_EPOINT, "received message %d (terminal %s, caller id %s)\n", message, e_ext.number, e_callerinfo.id); + switch(message_type) { + /* PORT sends SETUP message */ + case MESSAGE_SETUP: + port_setup(portlist, message_type, param); + break; + + /* PORT sends RELEASE message */ + case MESSAGE_RELEASE: + port_release(portlist, message_type, param); + break; + + default: + port_other(portlist, message_type, param); + } + + /* Note: this endpoint may be destroyed, so we MUST return */ +} + diff --git a/appbridge.h b/appbridge.h new file mode 100644 index 0000000..2e4ea06 --- /dev/null +++ b/appbridge.h @@ -0,0 +1,35 @@ +/*****************************************************************************\ +** ** +** Linux Call Router ** +** ** +**---------------------------------------------------------------------------** +** Copyright: Andreas Eversberg ** +** ** +** EndpointAppBridge header file ** +** ** +\*****************************************************************************/ + + +extern class EndpointAppBridge *appbridge_first; + +/* structure of an EndpointAppBridge */ +class EndpointAppBridge : public EndpointApp +{ + public: + EndpointAppBridge(class Endpoint *epoint, int origin); + ~EndpointAppBridge(); + + class EndpointAppBridge *next; /* next in list of apps */ + + /* messages */ + void port_setup(struct port_list *portlist, int message_type, union parameter *param); + 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 bf7988b..cf6f840 100644 --- a/apppbx.cpp +++ b/apppbx.cpp @@ -26,7 +26,7 @@ int callback_timeout(struct lcr_timer *timer, void *instance, int index); /* * EndpointAppPBX constructor */ -EndpointAppPBX::EndpointAppPBX(class Endpoint *epoint, int origin) : EndpointApp(epoint, origin) +EndpointAppPBX::EndpointAppPBX(class Endpoint *epoint, int origin) : EndpointApp(epoint, origin, EAPP_TYPE_PBX) { class EndpointAppPBX **apppointer; diff --git a/dss1.cpp b/dss1.cpp index f0834af..6a718ab 100644 --- a/dss1.cpp +++ b/dss1.cpp @@ -729,8 +729,7 @@ void Pdss1::setup_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m) FATAL("Incoming call but already got an endpoint.\n"); if (!(epoint = new Endpoint(p_serial, 0))) FATAL("No memory for Endpoint instance\n"); - if (!(epoint->ep_app = new DEFAULT_ENDPOINT_APP(epoint, 0))) //incoming - FATAL("No memory for Endpoint Application instance\n"); + epoint->ep_app = new_endpointapp(epoint, 0, p_m_mISDNport->ifport->interface->app); //incoming epointlist_new(epoint->ep_serial); /* send setup message to endpoit */ diff --git a/endpoint.h b/endpoint.h index a3080bc..a74da30 100644 --- a/endpoint.h +++ b/endpoint.h @@ -28,6 +28,7 @@ class Endpoint unsigned int ep_serial; /* a unique serial to identify */ /* applocaton relation */ + int ep_app_type; class EndpointApp *ep_app; /* link to application class */ /* port relation */ diff --git a/endpointapp.cpp b/endpointapp.cpp index 158b3d6..da797de 100644 --- a/endpointapp.cpp +++ b/endpointapp.cpp @@ -14,9 +14,10 @@ /* * EndpointApp constructor */ -EndpointApp::EndpointApp(class Endpoint *epoint, int origin) +EndpointApp::EndpointApp(class Endpoint *epoint, int origin, int type) { ea_endpoint = epoint; + ea_type = type; classuse++; } @@ -40,3 +41,26 @@ void EndpointApp::ea_message_join(unsigned int join_id, int message_type, union PDEBUG(DEBUG_EPOINT, "%s: Spare function.\n", __FUNCTION__); } + +/* create endpoint app */ +class EndpointApp *new_endpointapp(class Endpoint *epoint, int origin, int type) +{ + class EndpointApp *app = NULL; + + switch (type) { + case EAPP_TYPE_PBX: + app = new EndpointAppPBX(epoint, origin); + break; + case EAPP_TYPE_BRIDGE: + app = new EndpointAppBridge(epoint, origin); + break; + } + + if (!app) + FATAL("Failed to create endpoint APP (type %d)\n", type); + + epoint->ep_app_type = type; + epoint->ep_app = app; + + return app; +} diff --git a/endpointapp.h b/endpointapp.h index a24faae..4147c51 100644 --- a/endpointapp.h +++ b/endpointapp.h @@ -9,16 +9,21 @@ ** ** \*****************************************************************************/ +#define EAPP_TYPE_PBX 0 +#define EAPP_TYPE_BRIDGE 1 /* structure of an EndpointApp */ class EndpointApp { public: - EndpointApp(class Endpoint *epoint, int origin); + EndpointApp(class Endpoint *epoint, int origin, int type); virtual ~EndpointApp(); + int ea_type; 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); }; +class EndpointApp *new_endpointapp(class Endpoint *epoint, int origin, int type); + diff --git a/gsm_bs.cpp b/gsm_bs.cpp index ed1d2c0..9608be6 100644 --- a/gsm_bs.cpp +++ b/gsm_bs.cpp @@ -212,6 +212,17 @@ void Pgsm_bs::setup_ind(unsigned int msg_type, unsigned int callref, struct gsm_ class Endpoint *epoint; struct lcr_msg *message; struct gsm_mncc *mode, *proceeding, *frame; + struct interface *interface = interface_first; + + while (interface) { + if (!strcmp(interface->name, p_g_interface_name)) + break; + interface = interface->next; + } + if (!interface) { + PERROR("Cannot find interface %s.\n", p_g_interface_name); + return; + } /* process given callref */ gsm_trace_header(p_g_interface_name, this, 0, DIRECTION_IN); @@ -299,8 +310,7 @@ void Pgsm_bs::setup_ind(unsigned int msg_type, unsigned int callref, struct gsm_ FATAL("Incoming call but already got an endpoint.\n"); if (!(epoint = new Endpoint(p_serial, 0))) FATAL("No memory for Endpoint instance\n"); - if (!(epoint->ep_app = new DEFAULT_ENDPOINT_APP(epoint, 0))) //incoming - FATAL("No memory for Endpoint Application instance\n"); + epoint->ep_app = new_endpointapp(epoint, 0, interface->app); //incoming epointlist_new(epoint->ep_serial); /* modify lchan to GSM codec V1 */ diff --git a/gsm_ms.cpp b/gsm_ms.cpp index dbd3351..ae99930 100644 --- a/gsm_ms.cpp +++ b/gsm_ms.cpp @@ -68,6 +68,17 @@ void Pgsm_ms::setup_ind(unsigned int msg_type, unsigned int callref, struct gsm_ class Endpoint *epoint; struct lcr_msg *message; struct gsm_mncc *mode, *proceeding, *frame; + struct interface *interface = interface_first; + + while (interface) { + if (!strcmp(interface->name, p_g_interface_name)) + break; + interface = interface->next; + } + if (!interface) { + PERROR("Cannot find interface %s.\n", p_g_interface_name); + return; + } /* process given callref */ gsm_trace_header(p_g_interface_name, this, 0, DIRECTION_IN); @@ -264,8 +275,7 @@ void Pgsm_ms::setup_ind(unsigned int msg_type, unsigned int callref, struct gsm_ FATAL("Incoming call but already got an endpoint.\n"); if (!(epoint = new Endpoint(p_serial, 0))) FATAL("No memory for Endpoint instance\n"); - if (!(epoint->ep_app = new DEFAULT_ENDPOINT_APP(epoint, 0))) //incoming - FATAL("No memory for Endpoint Application instance\n"); + epoint->ep_app = new_endpointapp(epoint, 0, interface->app); //incoming epointlist_new(epoint->ep_serial); /* modify lchan to GSM codec V1 */ diff --git a/interface.c b/interface.c index 60e058f..89aa582 100644 --- a/interface.c +++ b/interface.c @@ -1072,16 +1072,25 @@ static int inter_remote(struct interface *interface, char *filename, int line, c ifport->remote = 1; SCPY(ifport->remote_app, value); - return(0); } - static int inter_shutdown(struct interface *interface, char *filename, int line, char *parameter, char *value) { interface->shutdown = 1; return(0); } +static int inter_bridge(struct interface *interface, char *filename, int line, char *parameter, char *value) +{ + if (!value || !value[0]) { + SPRINT(interface_error, "Error in %s (line %d): Missing destination interface name.\n", filename, line); + return(-1); + } + interface->app = EAPP_TYPE_BRIDGE; + SCPY(interface->bridge_if, value); + + return(0); +} /* @@ -1230,6 +1239,10 @@ struct interface_param interface_param[] = { "Prevents sending notify messages to this interface. A call placed on hold will\n" "Not affect the remote end (phone or telcom switch).\n" "This parameter must follow a 'port' parameter."}, + {"bridge", &inter_bridge, "", + "Define bridge application for this interface. All calls received on this\n" + "interface will be directly bridged to the given destination interface.\n" + "There will be no PBX application, nor routing."}, #ifdef WITH_SS5 {"ccitt5", &inter_ss5, "[ [feature ...]]", diff --git a/interface.h b/interface.h index ea9cbad..4640187 100644 --- a/interface.h +++ b/interface.h @@ -89,6 +89,8 @@ struct interface_screen { struct interface { struct interface *next; char name[64]; /* name of interface */ + int app; /* application to use for interface (0 = PBX) */ + char bridge_if[64]; /* name of destination interface for bridge application */ int external; /* interface used for external calls */ int extension; /* calls are handled as extension */ int is_tones; /* generate tones */ diff --git a/join.h b/join.h index 442aa5d..331dbc7 100644 --- a/join.h +++ b/join.h @@ -35,3 +35,5 @@ extern class Join *join_first; class Join *find_join_id(unsigned int join_id); +extern unsigned int join_serial; + diff --git a/joinpbx.cpp b/joinpbx.cpp index a98765f..6440f58 100644 --- a/joinpbx.cpp +++ b/joinpbx.cpp @@ -917,8 +917,7 @@ int JoinPBX::out_setup(unsigned int epoint_id, int message_type, union parameter epoint = new Endpoint(0, j_serial); if (!epoint) FATAL("No memory for Endpoint instance\n"); - if (!(epoint->ep_app = new DEFAULT_ENDPOINT_APP(epoint, 1))) // outgoing - FATAL("No memory for Endpoint Application instance\n"); + epoint->ep_app = new_endpointapp(epoint, 1, EAPP_TYPE_PBX); // outgoing relation->epoint_id = epoint->ep_serial; /* send setup message to new endpoint */ //printf("JOLLY DEBUG: %d\n",join_countrelations(j_serial)); diff --git a/joinremote.cpp b/joinremote.cpp index 7c03dcd..dbeb0f9 100644 --- a/joinremote.cpp +++ b/joinremote.cpp @@ -85,8 +85,7 @@ void JoinRemote::message_remote(int message_type, union parameter *param) FATAL("No memory for Endpoint instance\n"); j_epoint_id = epoint->ep_serial; PDEBUG(DEBUG_JOIN, "Created endpoint %d\n", j_epoint_id); - if (!(epoint->ep_app = new DEFAULT_ENDPOINT_APP(epoint, 1))) // outgoing - FATAL("No memory for Endpoint Application instance\n"); + epoint->ep_app = new_endpointapp(epoint, 1, EAPP_TYPE_PBX); // outgoing } /* set serial on bchannel message diff --git a/main.h b/main.h index 9a97f3a..e0b2193 100644 --- a/main.h +++ b/main.h @@ -32,8 +32,6 @@ #define NAME "LCR" -#define DEFAULT_ENDPOINT_APP EndpointAppPBX - #define VERSION_STRING VERSION extern int memuse; @@ -143,6 +141,7 @@ extern "C" { #include "endpoint.h" #include "endpointapp.h" #include "apppbx.h" +#include "appbridge.h" #include "callerid.h" #include "route.h" #include "port.h" diff --git a/port.cpp b/port.cpp index d6b70c8..8fed914 100644 --- a/port.cpp +++ b/port.cpp @@ -1287,7 +1287,7 @@ int Port::bridge_tx(unsigned char *data, int len) if (!remote) return -EINVAL; -// printf("Traffic: %u -> %u (bridge %u)\n", p_serial, to_port->p_serial, p_bridge->bridge_id); +// printf("Traffic: %u -> %u (bridge %u)\n", p_serial, remote->p_serial, p_bridge->bridge_id); return remote->bridge_rx(data, len); } diff --git a/remote.cpp b/remote.cpp index 8d7c0bf..e7b9009 100644 --- a/remote.cpp +++ b/remote.cpp @@ -167,8 +167,7 @@ void Premote::message_remote(int message_type, union parameter *param) FATAL("Incoming call but already got an endpoint.\n"); if (!(epoint = new Endpoint(p_serial, 0))) FATAL("No memory for Endpoint instance\n"); - if (!(epoint->ep_app = new DEFAULT_ENDPOINT_APP(epoint, 0))) //incoming - FATAL("No memory for Endpoint Application instance\n"); + epoint->ep_app = new_endpointapp(epoint, 0, p_m_mISDNport->ifport->interface->app); //incoming epointlist_new(epoint->ep_serial); } diff --git a/sip.cpp b/sip.cpp index 48ce05d..94e9760 100644 --- a/sip.cpp +++ b/sip.cpp @@ -868,6 +868,7 @@ int Psip::message_setup(unsigned int epoint_id, int message_id, union parameter PDEBUG(DEBUG_SIP, "remote ip %08x port %d\n", p_s_rtp_ip_remote, p_s_rtp_port_remote); } else { PDEBUG(DEBUG_SIP, "RTP info not given by remote, so we do our own RTP\n"); + p_s_rtp_bridge = 0; p_s_rtp_payload_type = (options.law=='a') ? RTP_PT_ALAW : RTP_PT_ULAW; /* open local RTP peer (if not bridging) */ @@ -1160,6 +1161,17 @@ void Psip::i_invite(int status, char const *phrase, nua_t *nua, nua_magic_t *mag class Endpoint *epoint; struct lcr_msg *message; uint8_t payload_type; + struct interface *interface = interface_first; + + while (interface) { + if (!strcmp(interface->name, inst->interface_name)) + break; + interface = interface->next; + } + if (!interface) { + PERROR("Cannot find interface %s.\n", inst->interface_name); + return; + } if (sip->sip_from && sip->sip_from->a_url) from = sip->sip_from->a_url->url_user; @@ -1250,8 +1262,7 @@ void Psip::i_invite(int status, char const *phrase, nua_t *nua, nua_magic_t *mag FATAL("Incoming call but already got an endpoint.\n"); if (!(epoint = new Endpoint(p_serial, 0))) FATAL("No memory for Endpoint instance\n"); - if (!(epoint->ep_app = new DEFAULT_ENDPOINT_APP(epoint, 0))) //incoming - FATAL("No memory for Endpoint Application instance\n"); + epoint->ep_app = new_endpointapp(epoint, 0, interface->app); //incoming epointlist_new(epoint->ep_serial); /* send trying (proceeding) */ diff --git a/socket_server.c b/socket_server.c index 2fba2eb..800d18d 100644 --- a/socket_server.c +++ b/socket_server.c @@ -530,7 +530,7 @@ int admin_call(struct admin_list *admin, struct admin_message *msg) if (!(epoint = new Endpoint(0, 0))) FATAL("No memory for Endpoint instance\n"); - if (!(epoint->ep_app = apppbx = new DEFAULT_ENDPOINT_APP(epoint, 1))) // outgoing + if (!(epoint->ep_app = apppbx = new EndpointAppPBX(epoint, 1))) // outgoing FATAL("No memory for Endpoint Application instance\n"); apppbx->e_adminid = admin->sockserial; admin->epointid = epoint->ep_serial; @@ -1246,8 +1246,8 @@ int admin_handle_con(struct lcr_fd *fd, unsigned int what, void *instance, int i /*release endpoint if exists */ if (admin->epointid) { epoint = find_epoint_id(admin->epointid); - if (epoint) { - ((class DEFAULT_ENDPOINT_APP *)epoint->ep_app)-> + if (epoint && epoint->ep_app_type == EAPP_TYPE_PBX) { + ((class EndpointAppPBX *)epoint->ep_app)-> release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0); } } diff --git a/ss5.cpp b/ss5.cpp index a12f936..7157d8f 100644 --- a/ss5.cpp +++ b/ss5.cpp @@ -1694,8 +1694,7 @@ void Pss5::do_setup(char *dial, int complete) FATAL("Incoming call but already got an endpoint.\n"); if (!(epoint = new Endpoint(p_serial, 0))) FATAL("No memory for Endpoint instance\n"); - if (!(epoint->ep_app = new DEFAULT_ENDPOINT_APP(epoint, 0))) //incoming - FATAL("No memory for Endpoint Application instance\n"); + epoint->ep_app = new_endpointapp(epoint, 0, p_m_mISDNport->ifport->interface->app); //incoming epointlist_new(epoint->ep_serial); /* send setup message to endpoit */ diff --git a/vbox.cpp b/vbox.cpp index c8c3012..b0268cc 100644 --- a/vbox.cpp +++ b/vbox.cpp @@ -251,7 +251,8 @@ int VBoxPort::message_epoint(unsigned int epoint_id, int message_id, union param case MESSAGE_SETUP: /* dial-out command received from epoint, answer with connect */ /* get apppbx */ - memcpy(&p_vbox_ext, &((class EndpointAppPBX *)(epoint->ep_app))->e_ext, sizeof(p_vbox_ext)); + if (epoint->ep_app_type == EAPP_TYPE_PBX) + memcpy(&p_vbox_ext, &((class EndpointAppPBX *)(epoint->ep_app))->e_ext, sizeof(p_vbox_ext)); /* extract optional announcement file */ if ((c = strchr(param->setup.dialinginfo.id, ','))) { if (c[1] == '/') -- 2.13.6