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 <output interface>" in interface.conf is used.
Without that keyword, incomming calls are handled as usual.
This commit is contained in:
Andreas Eversberg 2012-01-16 09:14:22 +01:00
parent d928442c51
commit 74a7fe54a8
22 changed files with 435 additions and 33 deletions

View File

@ -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)

294
appbridge.cpp Normal file
View File

@ -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 */
}

35
appbridge.h Normal file
View File

@ -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);
};

View File

@ -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;

View File

@ -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 */

View File

@ -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 */

View File

@ -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;
}

View File

@ -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);

View File

@ -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 */

View File

@ -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 */

View File

@ -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, "<destination interface>",
"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> [feature ...]]",

View File

@ -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 */

2
join.h
View File

@ -35,3 +35,5 @@ extern class Join *join_first;
class Join *find_join_id(unsigned int join_id);
extern unsigned int join_serial;

View File

@ -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));

View File

@ -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

3
main.h
View File

@ -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"

View File

@ -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);
}

View File

@ -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);
}

15
sip.cpp
View File

@ -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) */

View File

@ -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);
}
}

View File

@ -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 */

View File

@ -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] == '/')