diff --git a/Makefile.am b/Makefile.am index 26e575c..8da7b3f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -46,7 +46,7 @@ INSTALLATION_DEFINES = \ if ENABLE_MISDN MISDN_INCLUDE = -DWITH_MISDN -DWITH_CRYPT -MISDN_SOURCE = mISDN.cpp dss1.cpp loop.c crypt.cpp remote.cpp joinremote.cpp +MISDN_SOURCE = mISDN.cpp dss1.cpp crypt.cpp MISDN_LIB = -lmisdn endif @@ -116,18 +116,15 @@ if ENABLE_ASTERISK_CHANNEL_DRIVER noinst_PROGRAMS = chan_lcr.so chan_lcr_so_SOURCES = chan_lcr_so_LDFLAGS = -shared -chan_lcr_so_LDADD = chan_lcr.po bchannel.po options.po callerid.po select.po +chan_lcr_so_LDADD = chan_lcr.po options.po callerid.po select.po # List chan_lcr specific sources for make dist -EXTRA_chan_lcr_so_SOURCES = chan_lcr.c chan_lcr.h bchannel.c bchannel.h +EXTRA_chan_lcr_so_SOURCES = chan_lcr.c chan_lcr.h chan_lcr.po: chan_lcr.c chan_lcr.h $(CC) $(INCLUDES) $(AST_CFLAGS) $(CPPFLAGS) $(CFLAGS) -D_GNU_SOURCE -fPIC -c $< -o $@ -bchannel.po: bchannel.c bchannel.h - $(CC) $(INCLUDES) -D_GNU_SOURCE $(CPPFLAGS) $(CFLAGS) -fPIC -c $< -o $@ - callerid.po: callerid.c callerid.h $(CC) $(INCLUDES) -D_GNU_SOURCE $(CPPFLAGS) $(CFLAGS) -fPIC -c $< -o $@ @@ -149,7 +146,7 @@ INCLUDES = $(all_includes) $(MISDN_INCLUDE) $(GSM_INCLUDE) $(SS5_INCLUDE) $(SIP_ 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 \ + port.cpp vbox.cpp remote.cpp \ $(MISDN_SOURCE) $(GSM_SOURCE) $(SS5_SOURCE) $(SIP_SOURCE) \ endpoint.cpp endpointapp.cpp \ appbridge.cpp apppbx.cpp route.c action.cpp action_efi.cpp action_vbox.cpp extension.c mail.c \ @@ -168,7 +165,7 @@ noinst_HEADERS = \ message.h callerid.h socket_server.h port.h vbox.h endpoint.h endpointapp.h \ appbridge.h apppbx.h route.h extension.h join.h joinpbx.h lcrsocket.h -noinst_HEADERS += myisdn.h mISDN.h dss1.h loop.h crypt.h remote.h joinremote.h +noinst_HEADERS += myisdn.h mISDN.h dss1.h crypt.h remote.h noinst_HEADERS += ss5.h ss5_encode.h ss5_decode.h noinst_HEADERS += mncc.h gsm.h gsm_audio.h gsm_bs.h gsm_ms.h noinst_HEADERS += ie.cpp sip.h @@ -184,7 +181,7 @@ EXTRA_DIST = default debian $(TONEDIRS) install-data-hook: @fns='strcpy strncpy strcat strncat sprintf snprintf' ; \ files=$$( find $(srcdir) -type f -name "*.c*" \ - | $(GREP) -v -e chan_lcr.c -e bchannel.c -e callerid.c ) ; \ + | $(GREP) -v -e chan_lcr.c -e callerid.c ) ; \ test -z "$$files" || { for fn in $$fns ; do \ $(GREP) -n $$fn $$files ; if test $$? = 0 ; then \ ( echo "dont use $$fn, use makro instead." ; exit -1 ) ; \ diff --git a/action.cpp b/action.cpp index 6d6e964..7b60126 100644 --- a/action.cpp +++ b/action.cpp @@ -15,9 +15,9 @@ extern char **environ; /* - * process init 'internal' / 'external' / 'remote' / 'vbox-record' / 'partyline'... + * process init 'internal' / 'external' / 'vbox-record' / 'partyline'... */ -int EndpointAppPBX::_action_init_call(char *remote) +void EndpointAppPBX::action_init_call(void) { class Join *join; @@ -25,47 +25,16 @@ int EndpointAppPBX::_action_init_call(char *remote) if (ea_endpoint->ep_join_id) { if (options.deb & DEBUG_EPOINT) PERROR("EPOINT(%d): We already have a call instance, this should never happen!\n", ea_endpoint->ep_serial); - return(0); + return; } /* create join */ PDEBUG(DEBUG_EPOINT, "EPOINT(%d): Creating new join instance.\n", ea_endpoint->ep_serial); -#ifdef WITH_MISDN - if (remote) { - struct port_list *portlist = ea_endpoint->ep_portlist; - struct admin_list *admin; - - admin = admin_first; - while(admin) { - if (admin->remote_name[0] && !strcmp(admin->remote_name, remote)) - break; - admin = admin->next; - } - if (!admin) { - /* resource not available */ - trace_header("ACTION remote (not available)", DIRECTION_NONE); - add_trace("application", NULL, "%s", remote); - end_trace(); - message_disconnect_port(portlist, CAUSE_OUTOFORDER, LOCATION_PRIVATE_LOCAL, ""); - new_state(EPOINT_STATE_OUT_DISCONNECT); - set_tone(portlist,"cause_1b"); - return(0); - } - join = new JoinRemote(ea_endpoint->ep_serial, remote, admin->sock); - } else -#endif - join = new JoinPBX(ea_endpoint); + join = new JoinPBX(ea_endpoint); if (!join) FATAL("No memoy for Join instance.\n"); ea_endpoint->ep_join_id = join->j_serial; - return(1); -} -void EndpointAppPBX::action_init_call(void) -{ - _action_init_call(NULL); -} -void EndpointAppPBX::action_init_remote(void) -{ + return; } /* @@ -222,6 +191,9 @@ void EndpointAppPBX::action_dialing_external(void) if ((rparam = routeparam(e_action, PARAM_PREFIX))) SPRINT(dialinginfo.id, "%s%s", rparam->string_value, e_extdialing); + if ((rparam = routeparam(e_action, PARAM_CONTEXT))) + SCPY(dialinginfo.context, rparam->string_value); + /* process keypad */ if ((rparam = routeparam(e_action, PARAM_KEYPAD))) { SCPY(dialinginfo.keypad, dialinginfo.id); @@ -333,78 +305,6 @@ void EndpointAppPBX::action_dialing_external(void) } -void EndpointAppPBX::action_dialing_remote(void) -{ - struct route_param *rparam; - struct port_list *portlist = ea_endpoint->ep_portlist; - struct lcr_msg *message; - struct capa_info capainfo; - struct caller_info callerinfo; - struct redir_info redirinfo; - struct dialing_info dialinginfo; - char context[128] = ""; - char remote[32]; - - if (!ea_endpoint->ep_join_id) { - /* no join yet, sending setup */ - if (!(rparam = routeparam(e_action, PARAM_APPLICATION))) { - trace_header("ACTION remote (no application given)", DIRECTION_NONE); - end_trace(); - new_state(EPOINT_STATE_OUT_DISCONNECT); - message_disconnect_port(portlist, CAUSE_SERVICEUNAVAIL, LOCATION_PRIVATE_LOCAL, ""); - set_tone(portlist, "cause_3f"); - return; - } - SCPY(remote, rparam->string_value); - if (!_action_init_call(remote)) - return; - - /* create bearer/caller/dialinginfo */ - memcpy(&capainfo, &e_capainfo, sizeof(capainfo)); - memcpy(&callerinfo, &e_callerinfo, sizeof(callerinfo)); - memcpy(&redirinfo, &e_redirinfo, sizeof(redirinfo)); - memset(&dialinginfo, 0, sizeof(dialinginfo)); - - if ((rparam = routeparam(e_action, PARAM_CONTEXT))) { - SCPY(context, rparam->string_value); - } - if ((rparam = routeparam(e_action, PARAM_EXTEN))) { - SCPY(dialinginfo.id, rparam->string_value); - dialinginfo.ntype = INFO_NTYPE_UNKNOWN; - } else { - SCPY(dialinginfo.id, e_extdialing); - } - e_extdialing = e_dialinginfo.id + strlen(e_dialinginfo.id); - /* send setup to remote */ - trace_header("ACTION remote (setup)", DIRECTION_NONE); - add_trace("number", NULL, dialinginfo.id); - add_trace("remote", NULL, remote); - if (context[0]) - add_trace("context", NULL, context); - end_trace(); - message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_SETUP); - memcpy(&message->param.setup.dialinginfo, &dialinginfo, sizeof(struct dialing_info)); - memcpy(&message->param.setup.redirinfo, &redirinfo, sizeof(struct redir_info)); - memcpy(&message->param.setup.callerinfo, &callerinfo, sizeof(struct caller_info)); - memcpy(&message->param.setup.capainfo, &capainfo, sizeof(struct capa_info)); - SCPY(message->param.setup.context, context); - message_put(message); - } else { - /* send overlap digits */ - trace_header("ACTION remote (dialing)", DIRECTION_NONE); - add_trace("number", NULL, e_extdialing); - end_trace(); - if (e_extdialing[0]) { - message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_INFORMATION); - memcpy(&message->param.information, &e_dialinginfo, sizeof(struct dialing_info)); - SCPY(message->param.information.id, e_extdialing); - e_extdialing = e_dialinginfo.id + strlen(e_dialinginfo.id); - message_put(message); - } - } -} - - /* * process dialing the "am" and record */ @@ -2277,12 +2177,6 @@ void EndpointAppPBX::process_dialing(int timeout) e_action = &action_internal; goto process_action; } - /* check for chan call */ - if (!strncmp(e_dialinginfo.id, "remote:", 7)) { - e_extdialing = e_dialinginfo.id+7; - e_action = &action_remote; - goto process_action; - } /* check for vbox call */ if (!strncmp(e_dialinginfo.id, "vbox:", 5)) { e_extdialing = e_dialinginfo.id+5; diff --git a/appbridge.cpp b/appbridge.cpp index e94de02..b69d47b 100644 --- a/appbridge.cpp +++ b/appbridge.cpp @@ -136,6 +136,24 @@ fail: /* create port for interface */ SPRINT(portname, "%s-%d-out", interface_out->name, 0); memset(&port_settings, 0, sizeof(port_settings)); +#ifdef WITH_MISDN + if (interface_out->remote) { + struct admin_list *admin; + admin = admin_first; + while(admin) { + if (admin->remote_name[0] && !strcmp(admin->remote_name, interface_out->remote_app)) + break; + admin = admin->next; + } + if (!admin) { + trace_header("INTERFACE (remote not connected)", DIRECTION_NONE); + add_trace("application", NULL, "%s", interface_out->remote_app); + end_trace(); + goto fail; + } + port = new Premote(PORT_TYPE_REMOTE_OUT, portname, &port_settings, interface_out, admin->sock); + } else +#endif #ifdef WITH_SIP if (interface_out->sip) { port = new Psip(PORT_TYPE_SIP_OUT, portname, &port_settings, interface_out); @@ -156,7 +174,6 @@ fail: #ifdef WITH_MISDN struct mISDNport *mISDNport; int channel = 0; - struct admin_list *admin; int earlyb; int mode = B_MODE_TRANSPARENT; @@ -176,23 +193,7 @@ fail: 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); + 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); diff --git a/apppbx.cpp b/apppbx.cpp index 2c926f6..8a8d3e9 100644 --- a/apppbx.cpp +++ b/apppbx.cpp @@ -615,8 +615,8 @@ void EndpointAppPBX::out_setup(int cfnr) struct port_settings port_settings; #ifdef WITH_MISDN int channel = 0; - struct admin_list *admin; #endif + struct admin_list *admin; int earlyb; int mode = B_MODE_TRANSPARENT; @@ -741,6 +741,23 @@ void EndpointAppPBX::out_setup(int cfnr) } /* found interface */ PDEBUG(DEBUG_EPOINT, "EPOINT(%d) calling to interface %s\n", ea_endpoint->ep_serial, ifname); + if (interface->remote) { + admin = admin_first; + while(admin) { + if (admin->remote_name[0] && !strcmp(admin->remote_name, interface->remote_app)) + break; + admin = admin->next; + } + if (!admin) { + trace_header("INTERFACE (remote not connected)", DIRECTION_NONE); + add_trace("application", NULL, "%s", interface->remote_app); + end_trace(); + continue; + } + SPRINT(portname, "%s-%d-out", interface->name, 0); + port = new Premote(PORT_TYPE_REMOTE_OUT, portname, &port_settings, interface, admin->sock); + earlyb = (interface->is_earlyb == IS_YES); + } else #ifdef WITH_GSM_BS if (interface->gsm_bs) { SPRINT(portname, "%s-%d-out", interface->name, 0); @@ -779,22 +796,7 @@ void EndpointAppPBX::out_setup(int cfnr) 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); + 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); @@ -1021,6 +1023,23 @@ void EndpointAppPBX::out_setup(int cfnr) continue; } /* found interface */ + if (interface->remote) { + admin = admin_first; + while(admin) { + if (admin->remote_name[0] && !strcmp(admin->remote_name, interface->remote_app)) + break; + admin = admin->next; + } + if (!admin) { + trace_header("INTERFACE (remote not connected)", DIRECTION_NONE); + add_trace("application", NULL, "%s", interface->remote_app); + end_trace(); + continue; + } + SPRINT(portname, "%s-%d-out", interface->name, 0); + port = new Premote(PORT_TYPE_REMOTE_OUT, portname, &port_settings, interface, admin->sock); + earlyb = (interface->is_earlyb == IS_YES); + } else #ifdef WITH_GSM_BS if (interface->gsm_bs) { SPRINT(portname, "%s-%d-out", interface->name, 0); @@ -1060,22 +1079,7 @@ void EndpointAppPBX::out_setup(int cfnr) 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); + 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); @@ -1568,8 +1572,7 @@ void EndpointAppPBX::port_information(struct port_list *portlist, int message_ty } if (e_action) if (e_action->index==ACTION_OUTDIAL - || e_action->index==ACTION_EXTERNAL - || e_action->index==ACTION_REMOTE) { + || e_action->index==ACTION_EXTERNAL) { if (!e_extdialing) set_tone(portlist, "dialing"); else if (!e_extdialing[0]) diff --git a/apppbx.h b/apppbx.h index c3d2d68..58d7ebd 100644 --- a/apppbx.h +++ b/apppbx.h @@ -258,13 +258,10 @@ class EndpointAppPBX : public EndpointApp struct route_param *routeparam(struct route_action *action, unsigned long long id); /* init / dialing / hangup */ - int _action_init_call(char *remote); void action_init_call(void); - void action_init_remote(void); void action_dialing_internal(void); void action_dialing_external(void); void action_dialing_h323(void); - void action_dialing_remote(void); void action_dialing_vbox_record(void); void action_init_partyline(void); void action_hangup_call(void); diff --git a/bchannel.c b/bchannel.c deleted file mode 100644 index bfc2238..0000000 --- a/bchannel.c +++ /dev/null @@ -1,720 +0,0 @@ -/*****************************************************************************\ -** ** -** Linux Call Router ** -** ** -**---------------------------------------------------------------------------** -** Copyright: Andreas Eversberg ** -** ** -** mISDN channel handlin for remote application ** -** ** -\*****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -int __af_isdn = MISDN_AF_ISDN; -#include - -#define HAVE_ATTRIBUTE_always_inline 1 -#define HAVE_ARPA_INET_H 1 -#define HAVE_TIMERSUB 1 - -#include -#include -#include - -/* Choose if you want to have chan_lcr for Asterisk 1.4.x or CallWeaver 1.2.x */ -/* #define LCR_FOR_CALLWEAVER */ - -#ifdef LCR_FOR_CALLWEAVER -#include -#include -#include -#include -#endif - -#include "extension.h" -#include "message.h" -#include "lcrsocket.h" -#include "cause.h" -#include "select.h" -#include "bchannel.h" -#include "chan_lcr.h" -#include "callerid.h" -#include "options.h" - - -#ifndef ISDN_PID_L4_B_USER -#define ISDN_PID_L4_B_USER 0x440000ff -#endif - -pid_t bchannel_pid; - -enum { - BSTATE_IDLE, - BSTATE_ACTIVATING, - BSTATE_ACTIVE, - BSTATE_DEACTIVATING, -}; - -static void bchannel_send_queue(struct bchannel *bchannel); - -int bchannel_initialize(void) -{ - return 0; -} - -void bchannel_deinitialize(void) -{ -} - -/* - * send control information to the channel (dsp-module) - */ -static void ph_control(int sock, unsigned int c1, unsigned int c2, char *trace_name, int trace_value, int b_mode) -{ - unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)]; - struct mISDNhead *ctrl = (struct mISDNhead *)buffer; - unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN); - int ret; - - if (b_mode != 0 && b_mode != 2) - return; - - CDEBUG(NULL, NULL, "Sending PH_CONTROL %s %x,%x\n", trace_name, c1, c2); - ctrl->prim = PH_CONTROL_REQ; - ctrl->id = 0; - *d++ = c1; - *d++ = c2; - ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0); - if (ret < 0) - CERROR(NULL, NULL, "Failed to send to socket %d\n", sock); -} - -static void ph_control_block(int sock, unsigned int c1, void *c2, int c2_len, char *trace_name, int trace_value, int b_mode) -{ - unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len]; - struct mISDNhead *ctrl = (struct mISDNhead *)buffer; - unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN); - int ret; - - if (b_mode != 0 && b_mode != 2) - return; - - CDEBUG(NULL, NULL, "Sending PH_CONTROL (block) %s %x\n", trace_name, c1); - ctrl->prim = PH_CONTROL_REQ; - ctrl->id = 0; - *d++ = c1; - memcpy(d, c2, c2_len); - ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0); - if (ret < 0) - CERROR(NULL, NULL, "Failed to send to socket %d\n", sock); -} - -static int bchannel_handle(struct lcr_fd *fd, unsigned int what, void *instance, int index); - -/* - * create stack - */ -int bchannel_create(struct bchannel *bchannel, int mode, int queue) -{ - int ret; - struct sockaddr_mISDN addr; - - if (bchannel->b_sock > -1) { - CERROR(bchannel->call, NULL, "Socket already created for handle 0x%x\n", bchannel->handle); - return 0; - } - - /* open socket */ - bchannel->b_mode = (mode & 3); - switch(bchannel->b_mode) { - case 0: - CDEBUG(bchannel->call, NULL, "Open DSP audio\n"); - bchannel->b_sock = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_L2DSP); - break; - case 1: - CDEBUG(bchannel->call, NULL, "Open audio\n"); - bchannel->b_sock = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_RAW); - break; - case 2: - CDEBUG(bchannel->call, NULL, "Open DSP HDLC\n"); - bchannel->b_sock = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_L2DSPHDLC); - break; - case 3: - CDEBUG(bchannel->call, NULL, "Open HDLC\n"); - bchannel->b_sock = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_HDLC); - break; - } - if (bchannel->b_sock < 0) { - CERROR(bchannel->call, NULL, "Failed to open bchannel-socket for handle 0x%x with mISDN-DSP layer. Did you load mISDN_dsp.ko?\n", bchannel->handle); - return 0; - } - - /* register fd */ - memset(&bchannel->lcr_fd, 0, sizeof(bchannel->lcr_fd)); - bchannel->lcr_fd.fd = bchannel->b_sock; - register_fd(&bchannel->lcr_fd, LCR_FD_READ | LCR_FD_EXCEPT, bchannel_handle, bchannel, 0); - - /* bind socket to bchannel */ - addr.family = AF_ISDN; - addr.dev = (bchannel->handle>>8); - addr.channel = bchannel->handle & 0xff; - ret = bind(bchannel->b_sock, (struct sockaddr *)&addr, sizeof(addr)); - if (ret < 0) { - CERROR(bchannel->call, NULL, "Failed to bind bchannel-socket for handle 0x%x with mISDN-DSP layer. (port %d, channel %d) Did you load mISDN_dsp.ko?\n", bchannel->handle, addr.dev, addr.channel); - unregister_fd(&bchannel->lcr_fd); - close(bchannel->b_sock); - bchannel->b_sock = -1; - return 0; - } - - /* queue */ - if (bchannel->b_mode == 1 && queue) { - bchannel->nodsp_queue_out = 0; - bchannel->nodsp_queue_in = queue * 8; - if (bchannel->nodsp_queue_in > QUEUE_BUFFER_MAX-1) - bchannel->nodsp_queue_in = QUEUE_BUFFER_MAX-1; - bchannel->nodsp_queue = bchannel->nodsp_queue_in; /* store initial load */ - memset(&bchannel->nodsp_queue_buffer, (options.law=='a')?0x2a:0xff, QUEUE_BUFFER_SIZE); - bchannel->queue_sent = 0; - } else - bchannel->nodsp_queue = 0; - - return 1; -} - - -/* - * activate / deactivate request - */ -void bchannel_activate(struct bchannel *bchannel, int activate) -{ - struct mISDNhead act; - int ret; - - /* activate bchannel */ - CDEBUG(bchannel->call, NULL, "%sActivating B-channel.\n", activate?"":"De-"); - switch(bchannel->b_mode) { - case 0: - case 2: - act.prim = (activate)?DL_ESTABLISH_REQ:DL_RELEASE_REQ; - break; - case 1: - case 3: - act.prim = (activate)?PH_ACTIVATE_REQ:PH_DEACTIVATE_REQ; - break; - } - act.id = 0; - ret = sendto(bchannel->b_sock, &act, MISDN_HEADER_LEN, 0, NULL, 0); - if (ret < 0) - CERROR(bchannel->call, NULL, "Failed to send to socket %d\n", bchannel->b_sock); - - bchannel->b_state = (activate)?BSTATE_ACTIVATING:BSTATE_DEACTIVATING; -} - - -/* - * set features - */ -static void bchannel_activated(struct bchannel *bchannel) -{ - int sock; - - sock = bchannel->b_sock; - - /* set dsp features */ - if (bchannel->b_txdata) - ph_control(sock, (bchannel->b_txdata)?DSP_TXDATA_ON:DSP_TXDATA_OFF, 0, "DSP-TXDATA", bchannel->b_txdata, bchannel->b_mode); - if (bchannel->b_delay && bchannel->b_mode == 0) - ph_control(sock, DSP_DELAY, bchannel->b_delay, "DSP-DELAY", bchannel->b_delay, bchannel->b_mode); - if (bchannel->b_tx_dejitter && bchannel->b_mode == 0) - ph_control(sock, (bchannel->b_tx_dejitter)?DSP_TX_DEJITTER:DSP_TX_DEJ_OFF, 0, "DSP-TX_DEJITTER", bchannel->b_tx_dejitter, bchannel->b_mode); - if (bchannel->b_tx_gain && bchannel->b_mode == 0) - ph_control(sock, DSP_VOL_CHANGE_TX, bchannel->b_tx_gain, "DSP-TX_GAIN", bchannel->b_tx_gain, bchannel->b_mode); - if (bchannel->b_rx_gain && bchannel->b_mode == 0) - ph_control(sock, DSP_VOL_CHANGE_RX, bchannel->b_rx_gain, "DSP-RX_GAIN", bchannel->b_rx_gain, bchannel->b_mode); - if (bchannel->b_pipeline[0] && bchannel->b_mode == 0) - ph_control_block(sock, DSP_PIPELINE_CFG, bchannel->b_pipeline, strlen(bchannel->b_pipeline)+1, "DSP-PIPELINE", 0, bchannel->b_mode); - if (bchannel->b_conf) - ph_control(sock, DSP_CONF_JOIN, bchannel->b_conf, "DSP-CONF", bchannel->b_conf, bchannel->b_mode); - if (bchannel->b_echo) - ph_control(sock, DSP_ECHO_ON, 0, "DSP-ECHO", 1, bchannel->b_mode); - if (bchannel->b_tone && bchannel->b_mode == 0) - ph_control(sock, DSP_TONE_PATT_ON, bchannel->b_tone, "DSP-TONE", bchannel->b_tone, bchannel->b_mode); - if (bchannel->b_rxoff) - ph_control(sock, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1, bchannel->b_mode); -// if (bchannel->b_txmix && bchannel->b_mode == 0) -// ph_control(sock, DSP_MIX_ON, 0, "DSP-MIX", 1, bchannel->b_mode); - if (bchannel->b_dtmf && bchannel->b_mode == 0) - ph_control(sock, DTMF_TONE_START, 0, "DSP-DTMF", 1, bchannel->b_mode); - if (bchannel->b_bf_len && bchannel->b_mode == 0) - ph_control_block(sock, DSP_BF_ENABLE_KEY, bchannel->b_bf_key, bchannel->b_bf_len, "DSP-CRYPT", bchannel->b_bf_len, bchannel->b_mode); - if (bchannel->b_conf) - ph_control(sock, DSP_CONF_JOIN, bchannel->b_conf, "DSP-CONF", bchannel->b_conf, bchannel->b_mode); - - bchannel->b_state = BSTATE_ACTIVE; -} - -/* - * destroy stack - */ -void bchannel_destroy(struct bchannel *bchannel) -{ - if (bchannel->b_sock > -1) { - unregister_fd(&bchannel->lcr_fd); - close(bchannel->b_sock); - bchannel->b_sock = -1; - } - bchannel->b_state = BSTATE_IDLE; -} - - -/* - * whenever we get audio data from bchannel, we process it here - */ -static void bchannel_receive(struct bchannel *bchannel, unsigned char *buffer, int len) -{ - struct mISDNhead *hh = (struct mISDNhead *)buffer; - unsigned char *data = buffer + MISDN_HEADER_LEN; - unsigned int cont = *((unsigned int *)data); - unsigned char *d; - int i; - struct bchannel *remote_bchannel; - int ret; - - if (hh->prim == PH_CONTROL_IND) { - /* non dsp -> ignore ph_control */ - if (bchannel->b_mode == 1 || bchannel->b_mode == 3) - return; - if (len < 4) { - CERROR(bchannel->call, NULL, "SHORT READ OF PH_CONTROL INDICATION\n"); - return; - } - if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL) { - if (bchannel->call) - lcr_in_dtmf(bchannel->call, cont & DTMF_TONE_MASK); - return; - } - switch(cont) { - case DSP_BF_REJECT: - CERROR(bchannel->call, NULL, "Blowfish crypt rejected.\n"); - break; - - case DSP_BF_ACCEPT: - CDEBUG(bchannel->call, NULL, "Blowfish crypt enabled.\n"); - break; - - default: - CDEBUG(bchannel->call, NULL, "Unhandled bchannel control 0x%x.\n", cont); - } - return; - } - if (hh->prim == PH_DATA_REQ) { - if (!bchannel->b_txdata) { - /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */ - CDEBUG(bchannel->call, NULL, "ignoring tx data, because 'txdata' is turned off\n"); - return; - } - return; - } - if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND) { - CERROR(bchannel->call, NULL, "Bchannel received unknown primitve: 0x%lx\n", hh->prim); - return; - } - /* if calls are bridged, but not via dsp (no b_conf), forward here */ - if (!bchannel->b_conf - && bchannel->call - && bchannel->call->bridge_call - && bchannel->call->bridge_call->bchannel) { - remote_bchannel = bchannel->call->bridge_call->bchannel; -#if 0 - int i = 0; - char string[4096] = ""; - while(i < len) { - sprintf(string+strlen(string), " %02x", data[i]); - i++; - } - CDEBUG(remote_bchannel->call, NULL, "Forwarding packet%s\n", string); -#endif - hh->prim = PH_DATA_REQ; - hh->id = 0; - ret = sendto(remote_bchannel->b_sock, buffer, MISDN_HEADER_LEN+len, 0, NULL, 0); - if (ret < 0) - CERROR(remote_bchannel->call, NULL, "Failed to send to socket %d\n", bchannel->b_sock); - return; - } - /* calls will not process any audio data unless - * the call is connected OR interface features audio during call setup. - */ - - /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */ - if (bchannel->b_rxoff) { - CDEBUG(bchannel->call, NULL, "ignoring data, because rx is turned off\n"); - return; - } - - if (!bchannel->call) { - CDEBUG(bchannel->call, NULL, "ignoring data, because no call associated with bchannel\n"); - return; - } - if (!bchannel->call->audiopath) { - /* return, because we have no audio from port */ - return; - } - - if (bchannel->call->pipe[1] < 0) { - /* nobody there */ - return; - } - - /* if no hdlc */ - if (bchannel->b_mode == 0 || bchannel->b_mode == 1) { - d = data; - for (i = 0; i < len; i++) { - *d = flip_bits[*d]; - d++; - } - } - - - len = write(bchannel->call->pipe[1], data, len); - if (len < 0) - goto errout; - - return; - errout: - close(bchannel->call->pipe[1]); - bchannel->call->pipe[1] = -1; - CDEBUG(bchannel->call, NULL, "broken pipe on bchannel pipe\n"); -} - - -/* - * transmit data to bchannel - */ -void bchannel_transmit(struct bchannel *bchannel, unsigned char *data, int len) -{ - unsigned char buff[1024 + MISDN_HEADER_LEN], *p = buff + MISDN_HEADER_LEN; - struct mISDNhead *frm = (struct mISDNhead *)buff; - int ret; - int i; - int space, in; - - if (bchannel->b_state != BSTATE_ACTIVE) - return; - if (len > 1024 || len < 1) - return; - if (data) { - switch(bchannel->b_mode) { - case 0: - for (i = 0; i < len; i++) - *p++ = flip_bits[*data++]; - frm->prim = DL_DATA_REQ; - break; - case 1: - for (i = 0; i < len; i++) - *p++ = flip_bits[*data++]; - frm->prim = PH_DATA_REQ; - break; - case 2: - memcpy(p, data, len); - frm->prim = DL_DATA_REQ; - break; - case 3: - memcpy(p, data, len); - frm->prim = PH_DATA_REQ; - break; - } - } else - memset(p, flip_bits[(options.law=='a')?0x2a:0xff], len); - frm->id = 0; -#ifdef SEAMLESS_TEST - unsigned char test_tone[8] = {0x2a, 0x24, 0xb4, 0x24, 0x2a, 0x25, 0xb5, 0x25}; - p = buff + MISDN_HEADER_LEN; - for (i = 0; i < len; i++) - *p++ = test_tone[(bchannel->test + i) & 7]; - bchannel->test = (bchannel->test + len) & 7; -#endif - if (bchannel->nodsp_queue) { - space = (bchannel->nodsp_queue_out - bchannel->nodsp_queue_in - 1) & (QUEUE_BUFFER_SIZE - 1); - if (len > space) { - CERROR(bchannel->call, NULL, "Queue buffer overflow, space is %d, len is %d.\n", space, len); - return; - } - p = buff + MISDN_HEADER_LEN; - in = bchannel->nodsp_queue_in; - for (i = 0; i < len; i++) { - bchannel->nodsp_queue_buffer[in] = *p++; - in = (in + 1) & (QUEUE_BUFFER_SIZE - 1); - } - bchannel->nodsp_queue_in = in; - if (bchannel->queue_sent == 0) /* if there is no pending data */ - bchannel_send_queue(bchannel); - return; - } - ret = sendto(bchannel->b_sock, buff, MISDN_HEADER_LEN+len, 0, NULL, 0); - if (ret < 0) - CERROR(bchannel->call, NULL, "Failed to send to socket %d\n", bchannel->b_sock); -} - - -/* - * in case of a send queue, we send from that queue rather directly - */ -static void bchannel_send_queue(struct bchannel *bchannel) -{ - unsigned char buff[1024 + MISDN_HEADER_LEN], *p = buff + MISDN_HEADER_LEN; - struct mISDNhead *frm = (struct mISDNhead *)buff; - int ret; - int i; - int len, out; - - len = (bchannel->nodsp_queue_in - bchannel->nodsp_queue_out) & (QUEUE_BUFFER_SIZE - 1); - if (len == 0) - return; /* mISDN driver received all load */ -#if 0 - printf("%4d:(%s|%s)\n", bchannel->nodsp_queue_out, - "----------------------------------------------------------------"+64-len/(8192/64), - " "+len/(8192/64)); -#endif - if (len > 1024) - len = 1024; - frm->prim = PH_DATA_REQ; - frm->id = 0; - out = bchannel->nodsp_queue_out; - for (i = 0; i < len; i++) { - *p++ = bchannel->nodsp_queue_buffer[out]; - out = (out + 1) & (QUEUE_BUFFER_SIZE - 1); - } - bchannel->nodsp_queue_out = out; - ret = sendto(bchannel->b_sock, buff, MISDN_HEADER_LEN+len, 0, NULL, 0); - if (ret < 0) - CERROR(bchannel->call, NULL, "Failed to send to socket %d\n", bchannel->b_sock); - else - bchannel->queue_sent = 1; -} - - -/* - * join bchannel - */ -void bchannel_join(struct bchannel *bchannel, unsigned short id) -{ - int sock; - - sock = bchannel->b_sock; - if (id) { - bchannel->b_conf = (id<<16) + bchannel_pid; - bchannel->b_rxoff = 1; - } else { - bchannel->b_conf = 0; - bchannel->b_rxoff = 0; - } - if (bchannel->b_state == BSTATE_ACTIVE) { - ph_control(sock, DSP_RECEIVE_OFF, bchannel->b_rxoff, "DSP-RX_OFF", bchannel->b_conf, bchannel->b_mode); - ph_control(sock, DSP_CONF_JOIN, bchannel->b_conf, "DSP-CONF", bchannel->b_conf, bchannel->b_mode); - } -} - - -/* - * dtmf bchannel - */ -void bchannel_dtmf(struct bchannel *bchannel, int on) -{ - int sock; - - sock = bchannel->b_sock; - bchannel->b_dtmf = on; - if (bchannel->b_state == BSTATE_ACTIVE && bchannel->b_mode == 0) - ph_control(sock, on?DTMF_TONE_START:DTMF_TONE_STOP, 0, "DSP-DTMF", 1, bchannel->b_mode); -} - - -/* - * blowfish bchannel - */ -void bchannel_blowfish(struct bchannel *bchannel, unsigned char *key, int len) -{ - int sock; - - sock = bchannel->b_sock; - memcpy(bchannel->b_bf_key, key, len); - bchannel->b_bf_len = len; - if (bchannel->b_state == BSTATE_ACTIVE) - ph_control_block(sock, DSP_BF_ENABLE_KEY, bchannel->b_bf_key, bchannel->b_bf_len, "DSP-CRYPT", bchannel->b_bf_len, bchannel->b_mode); -} - - -/* - * pipeline bchannel - */ -void bchannel_pipeline(struct bchannel *bchannel, char *pipeline) -{ - int sock; - - sock = bchannel->b_sock; - strncpy(bchannel->b_pipeline, pipeline, sizeof(bchannel->b_pipeline)-1); - if (bchannel->b_state == BSTATE_ACTIVE) - ph_control_block(sock, DSP_PIPELINE_CFG, bchannel->b_pipeline, strlen(bchannel->b_pipeline)+1, "DSP-PIPELINE", 0, bchannel->b_mode); -} - - -/* - * gain bchannel - */ -void bchannel_gain(struct bchannel *bchannel, int gain, int tx) -{ - int sock; - - sock = bchannel->b_sock; - if (tx) - bchannel->b_tx_gain = gain; - else - bchannel->b_rx_gain = gain; - if (bchannel->b_state == BSTATE_ACTIVE && bchannel->b_mode == 0) - ph_control(sock, (tx)?DSP_VOL_CHANGE_TX:DSP_VOL_CHANGE_RX, gain, (tx)?"DSP-TX_GAIN":"DSP-RX_GAIN", gain, bchannel->b_mode); -} - - -/* - * main loop for processing messages from mISDN - */ -static int bchannel_handle(struct lcr_fd *fd, unsigned int what, void *instance, int index) -{ - struct bchannel *bchannel = (struct bchannel *)instance; - int ret; - unsigned char buffer[2048+MISDN_HEADER_LEN]; - struct mISDNhead *hh = (struct mISDNhead *)buffer; - - ret = recv(bchannel->b_sock, buffer, sizeof(buffer), 0); - if (ret >= (int)MISDN_HEADER_LEN) { - switch(hh->prim) { - /* after a confim, we can send more from queue */ - case PH_DATA_CNF: - if (bchannel->nodsp_queue) { - bchannel->queue_sent = 0; - bchannel_send_queue(bchannel); - } - break; - - /* we receive audio data, we respond to it AND we send tones */ - case PH_DATA_IND: - case PH_DATA_REQ: - case DL_DATA_IND: - case PH_CONTROL_IND: - bchannel_receive(bchannel, buffer, ret-MISDN_HEADER_LEN); - break; - - case PH_ACTIVATE_IND: - case DL_ESTABLISH_IND: - case PH_ACTIVATE_CNF: - case DL_ESTABLISH_CNF: - CDEBUG(bchannel->call, NULL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", bchannel->b_sock); - bchannel_activated(bchannel); - break; - - case PH_DEACTIVATE_IND: - case DL_RELEASE_IND: - case PH_DEACTIVATE_CNF: - case DL_RELEASE_CNF: - CDEBUG(bchannel->call, NULL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", bchannel->b_sock); -// bchannel_deactivated(bchannel); - break; - - default: - CERROR(bchannel->call, NULL, "child message not handled: prim(0x%x) socket(%d) data len(%d)\n", hh->prim, bchannel->b_sock, ret - MISDN_HEADER_LEN); - } - } else { -// if (ret < 0 && errno != EWOULDBLOCK) - CERROR(bchannel->call, NULL, "Read from socket %d failed with return code %d\n", bchannel->b_sock, ret); - } - - /* if we received at least one b-frame, we will return 1 */ - return 0; -} - - -/* - * bchannel channel handling - */ -struct bchannel *bchannel_first = NULL; -struct bchannel *find_bchannel_handle(unsigned int handle) -{ - struct bchannel *bchannel = bchannel_first; - - while(bchannel) { - if (bchannel->handle == handle) - break; - bchannel = bchannel->next; - } - return bchannel; -} - -#if 0 -struct bchannel *find_bchannel_ref(unsigned int ref) -{ - struct bchannel *bchannel = bchannel_first; - - while(bchannel) { - if (bchannel->ref == ref) - break; - bchannel = bchannel->next; - } - return bchannel; -} -#endif - -struct bchannel *alloc_bchannel(unsigned int handle) -{ - struct bchannel **bchannelp = &bchannel_first; - - while(*bchannelp) - bchannelp = &((*bchannelp)->next); - - *bchannelp = (struct bchannel *)calloc(1, sizeof(struct bchannel)); - if (!*bchannelp) - return NULL; - (*bchannelp)->handle = handle; - (*bchannelp)->b_state = BSTATE_IDLE; - (*bchannelp)->b_sock = -1; - - return *bchannelp; -} - -void free_bchannel(struct bchannel *bchannel) -{ - struct bchannel **temp = &bchannel_first; - - while(*temp) { - if (*temp == bchannel) { - *temp = (*temp)->next; - if (bchannel->b_sock > -1) - bchannel_destroy(bchannel); - if (bchannel->call) { - if (bchannel->call->bchannel) - bchannel->call->bchannel = NULL; - } - free(bchannel); - return; - } - temp = &((*temp)->next); - } -} - - diff --git a/bchannel.h b/bchannel.h deleted file mode 100644 index 55ce323..0000000 --- a/bchannel.h +++ /dev/null @@ -1,69 +0,0 @@ -/*****************************************************************************\ -** ** -** Linux Call Router ** -** ** -**---------------------------------------------------------------------------** -** Copyright: Andreas Eversberg ** -** ** -** mISDN channel handlin for remote application ** -** ** -\*****************************************************************************/ - -/* this test produces a test tone to test gaps in audio stream */ -//#define SEAMLESS_TEST - -#define QUEUE_BUFFER_SIZE 8192 /* must be the power of two */ -#define QUEUE_BUFFER_MAX 4096 /* half of size */ - -struct bchannel { - struct bchannel *next; - struct chan_call *call; /* link to call process */ - unsigned int handle; /* handle for stack id */ - int b_sock; /* socket for b-channel */ - struct lcr_fd lcr_fd; /* socket register */ - int b_mode; /* dsp, raw, dsphdlc */ - int b_state; - int b_txdata; - int b_delay; - int b_tx_dejitter; - int b_tx_gain, b_rx_gain; - char b_pipeline[256]; - unsigned int b_conf; - int b_echo; - int b_tone; - int b_rxoff; - // int b_txmix; - int b_dtmf; - int b_bf_len; - unsigned char b_bf_key[128]; - int nodsp_queue; /* enables nodsp_queue_buffer */ - unsigned char nodsp_queue_buffer[QUEUE_BUFFER_SIZE]; - /* buffer for seamless transmission */ - unsigned int nodsp_queue_in, nodsp_queue_out; - /* in and out pointers */ - int queue_sent; /* data for mISDN was not confrmed yet */ -#ifdef SEAMLESS_TEST - int test; -#endif -}; - - -extern struct bchannel *bchannel_first; -extern pid_t bchannel_pid; - -int bchannel_initialize(void); -void bchannel_deinitialize(void); -void bchannel_destroy(struct bchannel *bchannel); -int bchannel_create(struct bchannel *channel, int mode, int queue); -void bchannel_activate(struct bchannel *channel, int activate); -void bchannel_transmit(struct bchannel *channel, unsigned char *data, int len); -void bchannel_join(struct bchannel *channel, unsigned short id); -void bchannel_dtmf(struct bchannel *channel, int on); -void bchannel_blowfish(struct bchannel *bchannel, unsigned char *key, int len); -void bchannel_pipeline(struct bchannel *bchannel, char *pipeline); -void bchannel_gain(struct bchannel *bchannel, int gain, int tx); -struct bchannel *find_bchannel_handle(unsigned int handle); -//struct bchannel *find_bchannel_ref(unsigned int ref); -struct bchannel *alloc_bchannel(unsigned int handle); -void free_bchannel(struct bchannel *channel); - diff --git a/chan_lcr.c b/chan_lcr.c index 4e93db1..1c3500b 100644 --- a/chan_lcr.c +++ b/chan_lcr.c @@ -177,7 +177,6 @@ struct ast_channel; #include "lcrsocket.h" #include "cause.h" #include "select.h" -#include "bchannel.h" #include "options.h" #include "chan_lcr.h" @@ -195,7 +194,6 @@ static struct ast_frame nullframe = { AST_FRAME_NULL, }; #endif int lcr_debug=1; -int mISDN_created=1; char lcr_type[]="lcr"; @@ -297,11 +295,6 @@ void free_call(struct chan_call *call) close(call->pipe[0]); if (call->pipe[1] > -1) close(call->pipe[1]); - if (call->bchannel) { - if (call->bchannel->call != call) - CERROR(call, NULL, "Linked bchannel structure has no link to us.\n"); - call->bchannel->call = NULL; - } if (call->bridge_call) { if (call->bridge_call->bridge_call != call) CERROR(call, NULL, "Linked call structure has no link to us.\n"); @@ -373,7 +366,8 @@ int send_message(int message_type, unsigned int ref, union parameter *param) CDEBUG(NULL, NULL, "Ignoring message %d, because socket is closed.\n", message_type); return -1; } - CDEBUG(NULL, NULL, "Sending %s to socket. (ref=%d)\n", messages_txt[message_type], ref); + if (message_type != MESSAGE_TRAFFIC) + CDEBUG(NULL, NULL, "Sending %s to socket. (ref=%d)\n", messages_txt[message_type], ref); adminp = &admin_first; while(*adminp) @@ -393,7 +387,8 @@ int send_message(int message_type, unsigned int ref, union parameter *param) if (!wake_global) { wake_global = 1; char byte = 0; - write(wake_pipe[1], &byte, 1); + int rc; + rc = write(wake_pipe[1], &byte, 1); } return 0; @@ -405,8 +400,8 @@ int send_message(int message_type, unsigned int ref, union parameter *param) void apply_opt(struct chan_call *call, char *data) { union parameter newparam; - char string[1024], *p = string, *opt, *key; - int gain, i; + char string[1024], *p = string, *opt;//, *key; +// int gain, i; if (!data[0]) return; // no opts @@ -437,12 +432,9 @@ void apply_opt(struct chan_call *call, char *data) break; } CDEBUG(call, call->ast, "Option 'n' (no DTMF).\n"); - if (call->dsp_dtmf) { - call->dsp_dtmf = 0; - if (call->bchannel) - bchannel_dtmf(call->bchannel, 0); - } + call->dsp_dtmf = 0; break; +#if 0 case 'c': if (opt[1] == '\0') { CERROR(call, call->ast, "Option 'c' (encrypt) expects key parameter.\n", opt); @@ -490,6 +482,7 @@ void apply_opt(struct chan_call *call, char *data) if (call->bchannel) bchannel_blowfish(call->bchannel, call->bf_key, call->bf_len); break; +#endif case 'h': if (opt[1] != '\0') { CERROR(call, call->ast, "Option 'h' (HDLC) expects no parameter.\n", opt); @@ -516,6 +509,7 @@ void apply_opt(struct chan_call *call, char *data) CDEBUG(call, call->ast, "Option 'q' (queue).\n"); call->nodsp_queue = atoi(opt+1); break; +#if 0 case 'e': if (opt[1] == '\0') { CERROR(call, call->ast, "Option 'e' (echo cancel) expects parameter.\n", opt); @@ -526,6 +520,7 @@ void apply_opt(struct chan_call *call, char *data) if (call->bchannel) bchannel_pipeline(call->bchannel, call->pipeline); break; +#endif case 'f': if (opt[1] == '\0') { CERROR(call, call->ast, "Option 'f' (faxdetect) expects parameter.\n", opt); @@ -582,6 +577,7 @@ void apply_opt(struct chan_call *call, char *data) CDEBUG(call, call->ast, "Option 's' (inband DTMF).\n"); call->inband_dtmf = 1; break; +#if 0 case 'v': if (opt[1] != 'r' && opt[1] != 't') { CERROR(call, call->ast, "Option 'v' (volume) expects parameter.\n", opt); @@ -603,6 +599,7 @@ void apply_opt(struct chan_call *call, char *data) bchannel_gain(call->bchannel, call->tx_gain, 1); } break; +#endif case 'k': if (opt[1] != '\0') { CERROR(call, call->ast, "Option 'k' (keypad) expects no parameter.\n", opt); @@ -616,13 +613,6 @@ void apply_opt(struct chan_call *call, char *data) CERROR(call, call->ast, "Option '%s' unknown.\n", opt); } } - - /* re-open, if bchannel is created */ - if (call->bchannel && call->bchannel->b_sock > -1) { - bchannel_destroy(call->bchannel); - if (bchannel_create(call->bchannel, ((call->nodsp || call->faxdetect > 0)?1:0) + ((call->hdlc)?2:0), call->nodsp_queue)) - bchannel_activate(call->bchannel, 1); - } } /* @@ -761,19 +751,12 @@ static void bridge_message_if_bridged(struct chan_call *call, int message_type, } /* - * send release message to LCR and import bchannel if exported + * send release message to LCR */ -static void send_release_and_import(struct chan_call *call, int cause, int location) +static void send_release(struct chan_call *call, int cause, int location) { union parameter newparam; - /* importing channel */ - if (call->bchannel) { - memset(&newparam, 0, sizeof(union parameter)); - newparam.bchannel.type = BCHANNEL_RELEASE; - newparam.bchannel.handle = call->bchannel->handle; - send_message(MESSAGE_BCHANNEL, call->ref, &newparam); - } /* sending release */ memset(&newparam, 0, sizeof(union parameter)); newparam.disconnectinfo.cause = cause; @@ -865,6 +848,15 @@ CDEBUG(call, ast, "Got 'sending complete', but extension '%s' will not match at goto start; } + /* send setup acknowledge to lcr */ + if (call->state != CHAN_LCR_STATE_IN_DIALING) { + memset(&newparam, 0, sizeof(union parameter)); + send_message(MESSAGE_OVERLAP, call->ref, &newparam); + } + + /* change state */ + call->state = CHAN_LCR_STATE_IN_DIALING; + /* if can match */ CDEBUG(call, ast, "Extensions may match, if more digits are dialed.\n"); return; @@ -875,6 +867,15 @@ CDEBUG(call, ast, "Got 'sending complete', but extension '%s' will not match at #else if (!*ast_channel_exten(ast)) { #endif + /* send setup acknowledge to lcr */ + if (call->state != CHAN_LCR_STATE_IN_DIALING) { + memset(&newparam, 0, sizeof(union parameter)); + send_message(MESSAGE_OVERLAP, call->ref, &newparam); + } + + /* change state */ + call->state = CHAN_LCR_STATE_IN_DIALING; + /* if can match */ CDEBUG(call, ast, "There is no 's' extension (and we tried to match it implicitly). Extensions may match, if more digits are dialed.\n"); return; @@ -885,7 +886,7 @@ CDEBUG(call, ast, "Got 'sending complete', but extension '%s' will not match at release: /* release lcr */ CDEBUG(call, ast, "Releasing due to extension missmatch.\n"); - send_release_and_import(call, cause, LOCATION_PRIVATE_LOCAL); + send_release(call, cause, LOCATION_PRIVATE_LOCAL); call->ref = 0; /* release asterisk */ #if ASTERISK_VERSION_NUM < 110000 @@ -957,7 +958,7 @@ static void lcr_in_setup(struct chan_call *call, int message_type, union paramet if (!ast) { /* release */ CERROR(call, NULL, "Failed to create Asterisk channel - releasing.\n"); - send_release_and_import(call, CAUSE_RESSOURCEUNAVAIL, LOCATION_PRIVATE_LOCAL); + send_release(call, CAUSE_RESSOURCEUNAVAIL, LOCATION_PRIVATE_LOCAL); /* remove call */ free_call(call); return; @@ -978,8 +979,8 @@ static void lcr_in_setup(struct chan_call *call, int message_type, union paramet if (param->setup.dialinginfo.id) #if ASTERISK_VERSION_NUM < 110000 strncpy(ast->exten, param->setup.dialinginfo.id, AST_MAX_EXTENSION-1); - if (param->setup.context[0]) - strncpy(ast->context, param->setup.context, AST_MAX_CONTEXT-1); + if (param->setup.dialinginfo.context[0]) + strncpy(ast->context, param->setup.dialinginfo.context, AST_MAX_CONTEXT-1); else strncpy(ast->context, param->setup.callerinfo.interface, AST_MAX_CONTEXT-1); #else @@ -1236,7 +1237,8 @@ static void lcr_in_proceeding(struct chan_call *call, int message_type, union pa if (!wake_global) { wake_global = 1; char byte = 0; - write(wake_pipe[1], &byte, 1); + int rc; + rc = write(wake_pipe[1], &byte, 1); } strncat(call->queue_string, "P", sizeof(call->queue_string)-1); } @@ -1257,7 +1259,8 @@ static void lcr_in_alerting(struct chan_call *call, int message_type, union para if (!wake_global) { wake_global = 1; char byte = 0; - write(wake_pipe[1], &byte, 1); + int rc; + rc = write(wake_pipe[1], &byte, 1); } strncat(call->queue_string, "R", sizeof(call->queue_string)-1); } @@ -1268,19 +1271,10 @@ static void lcr_in_alerting(struct chan_call *call, int message_type, union para */ static void lcr_in_connect(struct chan_call *call, int message_type, union parameter *param) { - union parameter newparam; - CDEBUG(call, call->ast, "Incomming connect (answer) from LCR.\n"); /* change state */ call->state = CHAN_LCR_STATE_CONNECT; - /* request bchannel */ - if (!call->bchannel) { - CDEBUG(call, call->ast, "Requesting B-channel. (ref=%d)\n", call->ref); - memset(&newparam, 0, sizeof(union parameter)); - newparam.bchannel.type = BCHANNEL_REQUEST; - send_message(MESSAGE_BCHANNEL, call->ref, &newparam); - } /* copy connectinfo */ memcpy(&call->connectinfo, ¶m->connectinfo, sizeof(struct connect_info)); /* queue event to asterisk */ @@ -1288,7 +1282,8 @@ static void lcr_in_connect(struct chan_call *call, int message_type, union param if (!wake_global) { wake_global = 1; char byte = 0; - write(wake_pipe[1], &byte, 1); + int rc; + rc = write(wake_pipe[1], &byte, 1); } strncat(call->queue_string, "N", sizeof(call->queue_string)-1); } @@ -1318,7 +1313,7 @@ static void lcr_in_disconnect(struct chan_call *call, int message_type, union pa } #endif /* release lcr with same cause */ - send_release_and_import(call, call->cause, call->location); + send_release(call, call->cause, call->location); call->ref = 0; /* change to release state */ call->state = CHAN_LCR_STATE_RELEASE; @@ -1333,7 +1328,8 @@ static void lcr_in_disconnect(struct chan_call *call, int message_type, union pa if (!wake_global) { wake_global = 1; char byte = 0; - write(wake_pipe[1], &byte, 1); + int rc; + rc = write(wake_pipe[1], &byte, 1); } strcpy(call->queue_string, "H"); // overwrite other indications } else { @@ -1371,7 +1367,8 @@ static void lcr_in_release(struct chan_call *call, int message_type, union param if (!wake_global) { wake_global = 1; char byte = 0; - write(wake_pipe[1], &byte, 1); + int rc; + rc = write(wake_pipe[1], &byte, 1); } strcpy(call->queue_string, "H"); } else { @@ -1418,7 +1415,8 @@ static void lcr_in_information(struct chan_call *call, int message_type, union p if (!wake_global) { wake_global = 1; char byte = 0; - write(wake_pipe[1], &byte, 1); + int rc; + rc = write(wake_pipe[1], &byte, 1); } strncat(call->queue_string, param->information.id, sizeof(call->queue_string)-1); } @@ -1435,18 +1433,8 @@ static void lcr_in_information(struct chan_call *call, int message_type, union p */ static void lcr_in_notify(struct chan_call *call, int message_type, union parameter *param) { - union parameter newparam; - CDEBUG(call, call->ast, "Incomming notify from LCR. (notify=%d)\n", param->notifyinfo.notify); - /* request bchannel, if call is resumed and we don't have it */ - if (param->notifyinfo.notify == INFO_NOTIFY_USER_RESUMED && !call->bchannel && call->ref) { - CDEBUG(call, call->ast, "Reqesting bchannel at resume. (ref=%d)\n", call->ref); - memset(&newparam, 0, sizeof(union parameter)); - newparam.bchannel.type = BCHANNEL_REQUEST; - send_message(MESSAGE_BCHANNEL, call->ref, &newparam); - } - if (!call->ast) return; /* use bridge to forware message not supported by asterisk */ @@ -1483,18 +1471,17 @@ static void lcr_in_pattern(struct chan_call *call, int message_type, union param call->has_pattern = 1; /* request bchannel */ - if (!call->bchannel) { - CDEBUG(call, call->ast, "Requesting B-channel. (ref=%d)\n", call->ref); - memset(&newparam, 0, sizeof(union parameter)); - newparam.bchannel.type = BCHANNEL_REQUEST; - send_message(MESSAGE_BCHANNEL, call->ref, &newparam); - } + CDEBUG(call, call->ast, "Requesting audio path (ref=%d)\n", call->ref); + memset(&newparam, 0, sizeof(union parameter)); + send_message(MESSAGE_AUDIOPATH, call->ref, &newparam); + /* queue PROGRESS, because tones are available */ if (call->ast && call->pbx_started) { if (!wake_global) { wake_global = 1; char byte = 0; - write(wake_pipe[1], &byte, 1); + int rc; + rc = write(wake_pipe[1], &byte, 1); } strncat(call->queue_string, "T", sizeof(call->queue_string)-1); } @@ -1524,7 +1511,8 @@ void lcr_in_dtmf(struct chan_call *call, int val) if (!wake_global) { wake_global = 1; char byte = 0; - write(wake_pipe[1], &byte, 1); + int rc; + rc = write(wake_pipe[1], &byte, 1); } strncat(call->queue_string, digit, sizeof(call->queue_string)-1); } @@ -1534,103 +1522,12 @@ void lcr_in_dtmf(struct chan_call *call, int val) */ int receive_message(int message_type, unsigned int ref, union parameter *param) { - struct bchannel *bchannel; struct chan_call *call; union parameter newparam; + int rc = 0; memset(&newparam, 0, sizeof(union parameter)); - /* handle bchannel message*/ - if (message_type == MESSAGE_BCHANNEL) { - switch(param->bchannel.type) { - case BCHANNEL_ASSIGN: - CDEBUG(NULL, NULL, "Received BCHANNEL_ASSIGN message. (handle=%08lx) for ref %d\n", param->bchannel.handle, ref); - if ((bchannel = find_bchannel_handle(param->bchannel.handle))) { - CERROR(NULL, NULL, "bchannel handle %x already assigned.\n", (int)param->bchannel.handle); - return -1; - } - /* create bchannel */ - bchannel = alloc_bchannel(param->bchannel.handle); - if (!bchannel) { - CERROR(NULL, NULL, "alloc bchannel handle %x failed.\n", (int)param->bchannel.handle); - return -1; - } - - /* configure channel */ - bchannel->b_tx_gain = param->bchannel.tx_gain; - bchannel->b_rx_gain = param->bchannel.rx_gain; - strncpy(bchannel->b_pipeline, param->bchannel.pipeline, sizeof(bchannel->b_pipeline)-1); - if (param->bchannel.crypt_len && param->bchannel.crypt_len <= sizeof(bchannel->b_bf_key)) { - bchannel->b_bf_len = param->bchannel.crypt_len; - memcpy(bchannel->b_bf_key, param->bchannel.crypt, param->bchannel.crypt_len); - } - bchannel->b_txdata = 0; - bchannel->b_tx_dejitter = 1; - - /* in case, ref is not set, this bchannel instance must - * be created until it is removed again by LCR */ - /* link to call */ - call = find_call_ref(ref); - if (call) { - bchannel->call = call; - call->bchannel = bchannel; - if (call->dsp_dtmf) - bchannel_dtmf(bchannel, 1); - if (call->bf_len) - bchannel_blowfish(bchannel, call->bf_key, call->bf_len); - if (call->pipeline[0]) - bchannel_pipeline(bchannel, call->pipeline); - if (call->rx_gain) - bchannel_gain(bchannel, call->rx_gain, 0); - if (call->tx_gain) - bchannel_gain(bchannel, call->tx_gain, 1); - if (call->bridge_id) { - CDEBUG(call, call->ast, "Join bchannel, because call is already bridged.\n"); - bchannel_join(bchannel, call->bridge_id); - } - /* ignore all dsp features, if it is a loopback interface */ - if (param->bchannel.isloopback) - call->nodsp = 1; - - /* create only, if call exists, othewhise it bchannel is freed below... */ - if (bchannel_create(bchannel, ((call->nodsp || call->faxdetect > 0)?1:0) + ((call->hdlc)?2:0), call->nodsp_queue)) - bchannel_activate(bchannel, 1); - } - /* acknowledge */ - newparam.bchannel.type = BCHANNEL_ASSIGN_ACK; - newparam.bchannel.handle = param->bchannel.handle; - send_message(MESSAGE_BCHANNEL, 0, &newparam); - /* if call has released before bchannel is assigned */ - if (!call) { - newparam.bchannel.type = BCHANNEL_RELEASE; - newparam.bchannel.handle = param->bchannel.handle; - send_message(MESSAGE_BCHANNEL, 0, &newparam); - } - - break; - - case BCHANNEL_REMOVE: - CDEBUG(NULL, NULL, "Received BCHANNEL_REMOVE message. (handle=%08lx)\n", param->bchannel.handle); - if (!(bchannel = find_bchannel_handle(param->bchannel.handle))) { - CERROR(NULL, NULL, "Bchannel handle %x not assigned.\n", (int)param->bchannel.handle); - return -1; - } - /* unklink from call and destroy bchannel */ - free_bchannel(bchannel); - - /* acknowledge */ - newparam.bchannel.type = BCHANNEL_REMOVE_ACK; - newparam.bchannel.handle = param->bchannel.handle; - send_message(MESSAGE_BCHANNEL, 0, &newparam); - - break; - - default: - CDEBUG(NULL, NULL, "Received unknown bchannel message %d.\n", param->bchannel.type); - } - return 0; - } - /* handle new ref */ if (message_type == MESSAGE_NEWREF) { if (param->newref.direction) { @@ -1671,9 +1568,9 @@ int receive_message(int message_type, unsigned int ref, union parameter *param) else if (call->state == CHAN_LCR_STATE_RELEASE) { /* send release */ if (call->cause) - send_release_and_import(call, call->cause, call->location); + send_release(call, call->cause, call->location); else - send_release_and_import(call, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL); + send_release(call, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL); /* free call */ free_call(call); return 0; @@ -1748,11 +1645,21 @@ int receive_message(int message_type, unsigned int ref, union parameter *param) call->audiopath = param->audiopath; break; + case MESSAGE_TRAFFIC: // if remote audio connected or hold + { + unsigned char *p = param->traffic.data; + int i, len = param->traffic.len; + for (i = 0; i < len; i++, p++) + *p = flip_bits[*p]; + } + rc = write(call->pipe[1], param->traffic.data, param->traffic.len); + break; + default: CDEBUG(call, call->ast, "Message %d from LCR unhandled.\n", message_type); break; } - return 0; + return rc; } /* @@ -1788,15 +1695,12 @@ again: if (!wake_global) { wake_global = 1; char byte = 0; - write(wake_pipe[1], &byte, 1); + int rc; + rc = write(wake_pipe[1], &byte, 1); } strcpy(call->queue_string, "H"); call = call->next; } - - /* release all bchannels */ - while(bchannel_first) - free_bchannel(bchannel_first); } void close_socket(void); @@ -1940,8 +1844,9 @@ void close_socket(void) static int wake_event(struct lcr_fd *fd, unsigned int what, void *instance, int index) { char byte; + int rc; - read(wake_pipe[0], &byte, 1); + rc = read(wake_pipe[0], &byte, 1); wake_global = 0; @@ -2065,8 +1970,6 @@ static void *chan_thread(void *arg) memset(&socket_retry, 0, sizeof(socket_retry)); add_timer(&socket_retry, handle_retry, NULL, 0); - bchannel_pid = getpid(); - /* open socket the first time */ handle_retry(NULL, NULL, 0); @@ -2483,8 +2386,6 @@ static int lcr_call(struct ast_channel *ast, char *dest, int timeout) /* send MESSAGE_NEWREF */ memset(&newparam, 0, sizeof(union parameter)); newparam.newref.direction = 0; /* request from app */ - if (!strcmp(call->interface, "pbx")) - newparam.newref.mode = 1; send_message(MESSAGE_NEWREF, 0, &newparam); /* set hdlc if capability requires hdlc */ @@ -2697,13 +2598,6 @@ static int lcr_answer(struct ast_channel *ast) call->state = CHAN_LCR_STATE_CONNECT; } /* change state */ - /* request bchannel */ - if (!call->bchannel) { - CDEBUG(call, ast, "Requesting B-channel.\n"); - memset(&newparam, 0, sizeof(union parameter)); - newparam.bchannel.type = BCHANNEL_REQUEST; - send_message(MESSAGE_BCHANNEL, call->ref, &newparam); - } /* enable keypad */ // memset(&newparam, 0, sizeof(union parameter)); // send_message(MESSAGE_ENABLEKEYPAD, call->ref, &newparam); @@ -2751,13 +2645,13 @@ static int lcr_hangup(struct ast_channel *ast) CDEBUG(call, ast, "Releasing ref and freeing call instance.\n"); #if ASTERISK_VERSION_NUM < 110000 if (ast->hangupcause > 0) - send_release_and_import(call, ast->hangupcause, LOCATION_PRIVATE_LOCAL); + send_release(call, ast->hangupcause, LOCATION_PRIVATE_LOCAL); #else if (ast_channel_hangupcause(ast) > 0) - send_release_and_import(call, ast_channel_hangupcause(ast), LOCATION_PRIVATE_LOCAL); + send_release(call, ast_channel_hangupcause(ast), LOCATION_PRIVATE_LOCAL); #endif else - send_release_and_import(call, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL); + send_release(call, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL); /* remove call */ free_call(call); if (!pthread_equal(tid, chan_tid)) { @@ -2785,8 +2679,11 @@ static int lcr_hangup(struct ast_channel *ast) static int lcr_write(struct ast_channel *ast, struct ast_frame *fr) { + union parameter newparam; struct chan_call *call; struct ast_frame * f = fr; + unsigned char *p, *q; + int len, l; #if ASTERISK_VERSION_NUM < 100000 #ifdef AST_1_8_OR_HIGHER @@ -2852,8 +2749,18 @@ static int lcr_write(struct ast_channel *ast, struct ast_frame *fr) } return -1; } - if (call->bchannel && f->samples) - bchannel_transmit(call->bchannel, *((unsigned char **)&(f->data)), f->samples); + len = f->samples; + p = *((unsigned char **)&(f->data)); + q = newparam.traffic.data; + memset(&newparam, 0, sizeof(union parameter)); + while (len) { + l = (len > sizeof(newparam.traffic.data)) ? sizeof(newparam.traffic.data) : len; + newparam.traffic.len = l; + len -= l; + for (; l; l--) + *q++ = flip_bits[*p++]; + send_message(MESSAGE_TRAFFIC, call->ref, &newparam); + } ast_mutex_unlock(&chan_lock); if (f != fr) { ast_frfree(f); @@ -3051,12 +2958,9 @@ static int lcr_indicate(struct ast_channel *ast, int cond, const void *data, siz case AST_CONTROL_PROGRESS: CDEBUG(call, ast, "Received indicate AST_CONTROL_PROGRESS from Asterisk.\n"); /* request bchannel */ - if (!call->bchannel) { - CDEBUG(call, ast, "Requesting B-channel.\n"); - memset(&newparam, 0, sizeof(union parameter)); - newparam.bchannel.type = BCHANNEL_REQUEST; - send_message(MESSAGE_BCHANNEL, call->ref, &newparam); - } + CDEBUG(call, ast, "Requesting audio path.\n"); + memset(&newparam, 0, sizeof(union parameter)); + send_message(MESSAGE_AUDIOPATH, call->ref, &newparam); break; case -1: CDEBUG(call, ast, "Received indicate -1.\n"); @@ -3224,6 +3128,7 @@ enum ast_bridge_result lcr_bridge(struct ast_channel *ast1, /* get bridge id and join */ bridge_id = new_bridge_id(); +#if 0 call1->bridge_id = bridge_id; if (call1->bchannel) bchannel_join(call1->bchannel, bridge_id); @@ -3231,6 +3136,11 @@ enum ast_bridge_result lcr_bridge(struct ast_channel *ast1, call2->bridge_id = bridge_id; if (call2->bchannel) bchannel_join(call2->bchannel, bridge_id); +#else + printf("FIXME"); + exit(0); +#endif + } else if (call1->nodsp && call2->nodsp) CDEBUG(NULL, NULL, "Both calls use no DSP, bridging in channel driver.\n"); @@ -3331,15 +3241,11 @@ enum ast_bridge_result lcr_bridge(struct ast_channel *ast1, #endif if (call1 && call1->bridge_id) { call1->bridge_id = 0; - if (call1->bchannel) - bchannel_join(call1->bchannel, 0); if (call1->bridge_call) call1->bridge_call->bridge_call = NULL; } if (call2 && call1->bridge_id) { call2->bridge_id = 0; - if (call2->bchannel) - bchannel_join(call2->bchannel, 0); if (call2->bridge_call) call2->bridge_call->bridge_call = NULL; } @@ -3546,20 +3452,6 @@ int load_module(void) ast_mutex_init(&chan_lock); ast_mutex_init(&log_lock); - if (bchannel_initialize()) { - CERROR(NULL, NULL, "Unable to open mISDN device\n"); - close_socket(); - - #ifdef LCR_FOR_ASTERISK - return AST_MODULE_LOAD_DECLINE; - #endif - - #ifdef LCR_FOR_CALLWEAVER - return 0; - #endif - } - mISDN_created = 1; - #if ASTERISK_VERSION_NUM < 100000 lcr_tech.capabilities = (options.law=='a')?AST_FORMAT_ALAW:AST_FORMAT_ULAW; #else @@ -3572,7 +3464,6 @@ int load_module(void) #endif if (ast_channel_register(&lcr_tech)) { CERROR(NULL, NULL, "Unable to register channel class\n"); - bchannel_deinitialize(); close_socket(); #ifdef LCR_FOR_ASTERISK @@ -3605,13 +3496,17 @@ int load_module(void) " Use queue size in miliseconds for optarg. (try 250)\n" " f - Adding fax detection. It it timeouts, mISDN_dsp is used.\n" " Use time to detect for optarg.\n" +#if 0 " c - Make crypted outgoing call, optarg is keyindex.\n" " e - Perform echo cancelation on this channel.\n" +#endif " Takes mISDN pipeline option as optarg.\n" " s - Send Non Inband DTMF as inband.\n" " r - re-buffer packets (160 bytes). Required for some SIP-phones and fax applications.\n" +#if 0 " vr - rxgain control\n" " vt - txgain control\n" +#endif " Volume changes at factor 2 ^ optarg.\n" " k - use keypad to dial this call.\n" "\n" @@ -3635,7 +3530,6 @@ int load_module(void) if ((pthread_create(&chan_tid, NULL, chan_thread, NULL)<0)) { /* failed to create thread */ - bchannel_deinitialize(); close_socket(); ast_channel_unregister(&lcr_tech); @@ -3672,11 +3566,6 @@ int unload_module(void) ast_unregister_application("lcr_config"); - if (mISDN_created) { - bchannel_deinitialize(); - mISDN_created = 0; - } - if (lcr_sock >= 0) { close(lcr_sock); lcr_sock = -1; diff --git a/chan_lcr.h b/chan_lcr.h index 8caa48e..345f769 100644 --- a/chan_lcr.h +++ b/chan_lcr.h @@ -9,8 +9,6 @@ ** ** \*****************************************************************************/ -/* structure for all calls */ -struct bchannel; struct chan_call { struct chan_call *next; /* link to next call instance */ int state; /* current call state CHAN_LCR_STATE */ @@ -19,8 +17,6 @@ struct chan_call { void *ast; /* current asterisk channel */ int pbx_started; /* indicates if pbx que is available */ - struct bchannel *bchannel; - /* reference to bchannel, if set */ int audiopath; /* audio is available */ int cause, location; diff --git a/default/interface.conf b/default/interface.conf index 24ec3b2..f6af8df 100644 --- a/default/interface.conf +++ b/default/interface.conf @@ -184,6 +184,8 @@ # An internal extension does not receive tones ("earlyb"), but sends them. #[ast] #remote asterisk +#exten from-lcr +##note: The following keyword means that this interface is an LCR internal extension #extension ##screen-in % 209 #earlyb no diff --git a/default/options.conf b/default/options.conf index 6e5ba13..9ee0860 100644 --- a/default/options.conf +++ b/default/options.conf @@ -109,12 +109,3 @@ # This feature is temporarily for test purpose. Don't enable it #polling -# Two Loopback interfaces for audio transfer between GSM/Asterisk and mISDN. -# The first interface must provide B-channels for each GSM call or channel -# instance, the seond interface links them to LCR. -# Use 30 B-channels unless you need more due to more instances. -# -> Load with: "modprobe mISDN_l1loop pri=1 nchannel=30" -# By default "mISDN_l1loop.1" and "mISDN_l1loop.2" is used. -#loopback-ext mISDN_l1loop.1 -#loopback-lcr mISDN_l1loop.2 - diff --git a/interface.c b/interface.c index 0264f46..587fc62 100644 --- a/interface.c +++ b/interface.c @@ -327,7 +327,6 @@ static int inter_portname(struct interface *interface, char *filename, int line, return(-1); #else struct interface_port *ifport, **ifportp; - struct interface *searchif; /* goto end of chain */ ifport = interface->ifport; @@ -336,22 +335,6 @@ static int inter_portname(struct interface *interface, char *filename, int line, ifport = ifport->next; } - /* check for port already assigned, but not for shared loop interface */ - searchif = interface_newlist; - if (!!strcmp(value, options.loopback_lcr)) - { - while(searchif) { - ifport = searchif->ifport; - while(ifport) { - if (!strcasecmp(ifport->portname, value)) { - SPRINT(interface_error, "Error in %s (line %d): port '%s' already used above.\n", filename, line, value); - return(-1); - } - ifport = ifport->next; - } - searchif = searchif->next; - } - } /* alloc port substructure */ ifport = (struct interface_port *)MALLOC(sizeof(struct interface_port)); memuse++; @@ -1096,7 +1079,6 @@ static int inter_ss5(struct interface *interface, char *filename, int line, char #endif static int inter_remote(struct interface *interface, char *filename, int line, char *parameter, char *value) { - struct interface_port *ifport; struct interface *searchif; if (!value[0]) { @@ -1105,27 +1087,26 @@ static int inter_remote(struct interface *interface, char *filename, int line, c } searchif = interface_newlist; while(searchif) { - ifport = searchif->ifport; - while(ifport) { - if (ifport->remote && !strcmp(ifport->remote_app, value)) { - SPRINT(interface_error, "Error in %s (line %d): port '%s' already uses remote application '%s'.\n", filename, line, ifport->portname, value); - return(-1); - } - ifport = ifport->next; + if (interface->remote && !strcmp(interface->remote_app, value)) { + SPRINT(interface_error, "Error in %s (line %d): interface '%s' already uses remote application '%s'.\n", filename, line, interface->name, value); + return(-1); } searchif = searchif->next; } - /* set portname */ - if (inter_portname(interface, filename, line, (char *)"portname", options.loopback_lcr)) - return(-1); - /* goto end of chain again to set application name */ - ifport = interface->ifport; - while(ifport->next) - ifport = ifport->next; - ifport->remote = 1; - SCPY(ifport->remote_app, value); + interface->remote = 1; + SCPY(interface->remote_app, value); + + return(0); +} +static int inter_context(struct interface *interface, char *filename, int line, char *parameter, char *value) +{ + if (!value[0]) { + SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects application context as value.\n", filename, line, parameter); + return(-1); + } + SCPY(interface->remote_context, value); return(0); } @@ -1325,6 +1306,8 @@ struct interface_param interface_param[] = { {"remote", &inter_remote, "", "Sets up an interface that communicates with the remote application.\n" "Use \"asterisk\" to use chan_lcr as remote application."}, + {"context", &inter_context, "", + "Give context for calls to application."}, {"shutdown", &inter_shutdown, "", "Interface will not be loaded when processing interface.conf"}, diff --git a/interface.h b/interface.h index a310a92..40c89f6 100644 --- a/interface.h +++ b/interface.h @@ -52,8 +52,6 @@ struct interface_port { int l1hold; /* hold layer 1 (1=on, 0=off) */ int l2hold; /* hold layer 2 (1=force, -1=disable, 0=default) */ unsigned int ss5; /* set, if SS5 signalling enabled, also holds feature bits */ - int remote; /* interface is a remote app interface */ - char remote_app[32]; /* name of remote application */ int channel_force; /* forces channel by protocol */ int nodtmf; /* disables DTMF */ struct select_channel *out_channel; /* list of channels to select */ @@ -106,6 +104,9 @@ struct interface { char pipeline[256]; /* filter pipeline */ unsigned char bf_key[56]; /* filter blowfish */ int bf_len; /* filter length of blowfish */ + int remote; /* interface is a remote app interface */ + char remote_app[32]; /* name of remote application */ + char remote_context[128]; /* context feld to use for remote application */ #ifdef WITH_GSM_BS int gsm_bs; /* interface is an GSM BS interface */ #if 0 diff --git a/join.h b/join.h index 331dbc7..afbe5a0 100644 --- a/join.h +++ b/join.h @@ -9,7 +9,7 @@ ** ** \*****************************************************************************/ -enum { JOIN_TYPE_NONE, JOIN_TYPE_PBX, JOIN_TYPE_REMOTE}; +enum { JOIN_TYPE_NONE, JOIN_TYPE_PBX}; /* join * diff --git a/joinpbx.cpp b/joinpbx.cpp index 9290657..ea2651b 100644 --- a/joinpbx.cpp +++ b/joinpbx.cpp @@ -499,9 +499,6 @@ int joinpbx_countrelations(unsigned int join_id) if (!join) return(0); - if (join->j_type == JOIN_TYPE_REMOTE) - return(2); - if (join->j_type != JOIN_TYPE_PBX) return(0); joinpbx = (class JoinPBX *)join; diff --git a/joinremote.cpp b/joinremote.cpp deleted file mode 100644 index c828400..0000000 --- a/joinremote.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/*****************************************************************************\ -** ** -** Linux Call Router ** -** ** -**---------------------------------------------------------------------------** -** Copyright: Andreas Eversberg ** -** ** -** join functions for remote application ** -** ** -\*****************************************************************************/ - -#include "main.h" -//#define __u8 unsigned char -//#define __u16 unsigned short -//#define __u32 unsigned int - -extern unsigned int new_remote; - -/* - * constructor for a new join - * the join will have a relation to the calling endpoint - */ -JoinRemote::JoinRemote(unsigned int serial, char *remote_name, int remote_id) : Join() -{ - union parameter param; - - SCPY(j_remote_name, remote_name); - j_remote_id = remote_id; - j_type = JOIN_TYPE_REMOTE; - j_remote_ref = new_remote++; - - PDEBUG(DEBUG_JOIN, "Constructor(new join) ref=%d\n", j_remote_ref); - - j_epoint_id = serial; /* this is the endpoint, if created by epoint */ - if (j_epoint_id) - PDEBUG(DEBUG_JOIN, "New remote join connected to endpoint id %lu and application %s (ref=%d)\n", j_epoint_id, remote_name, j_remote_ref); - - /* send new ref to remote socket */ - memset(¶m, 0, sizeof(union parameter)); - if (serial) - param.newref.direction = 1; /* new ref from lcr */ - if (admin_message_from_lcr(j_remote_id, j_remote_ref, MESSAGE_NEWREF, ¶m)<0) - FATAL("No socket with remote application '%s' found, this shall not happen. because we already created one.\n", j_remote_name); -} - - -/* - * join descructor - */ -JoinRemote::~JoinRemote() -{ -} - -void JoinRemote::message_epoint(unsigned int epoint_id, int message_type, union parameter *param) -{ - /* if endpoint has just been removed, but still a message in the que */ - if (epoint_id != j_epoint_id) - return; - - PDEBUG(DEBUG_JOIN, "Message %d of endpoint %d from LCR to remote (ref=%d)\n", message_type, j_epoint_id, j_remote_ref); - - /* look for Remote's interface */ - if (admin_message_from_lcr(j_remote_id, j_remote_ref, message_type, param)<0) { - PERROR("No socket with remote application '%s' found, this shall not happen. Closing socket shall cause release of all joins.\n", j_remote_name); - return; - } - - if (message_type == MESSAGE_RELEASE) { - delete this; - return; - } -} - -void JoinRemote::message_remote(int message_type, union parameter *param) -{ - struct lcr_msg *message; - - PDEBUG(DEBUG_JOIN, "Message %d of endpoint %d from remote to LCR (ref=%d)\n", message_type, j_epoint_id, j_remote_ref); - - /* create relation if no relation exists */ - if (!j_epoint_id) { - class Endpoint *epoint; - - if (!(epoint = new Endpoint(0, j_serial))) - FATAL("No memory for Endpoint instance\n"); - j_epoint_id = epoint->ep_serial; - PDEBUG(DEBUG_JOIN, "Created endpoint %d\n", j_epoint_id); - epoint->ep_app = new_endpointapp(epoint, 1, EAPP_TYPE_PBX); // outgoing - } - -#ifdef WITH_MISDN - /* set serial on bchannel message - * also ref is given, so we send message with ref */ - if (message_type == MESSAGE_BCHANNEL) { - message_bchannel_from_remote(this, param->bchannel.type, param->bchannel.handle); - return; - } -#endif - - /* cannot just forward, because param is not of container "struct lcr_msg" */ - message = message_create(j_serial, j_epoint_id, JOIN_TO_EPOINT, message_type); - memcpy(&message->param, param, sizeof(message->param)); - message_put(message); - - if (message_type == MESSAGE_RELEASE) { - delete this; - return; - } -} - - - diff --git a/joinremote.h b/joinremote.h deleted file mode 100644 index a933466..0000000 --- a/joinremote.h +++ /dev/null @@ -1,26 +0,0 @@ -/*****************************************************************************\ -** ** -** Linux Call Router ** -** ** -**---------------------------------------------------------------------------** -** Copyright: Andreas Eversberg ** -** ** -** join header file for Asterisk interface ** -** ** -\*****************************************************************************/ - -class JoinRemote : public Join -{ - public: - JoinRemote(unsigned int serial, char *remote_name, int remote_id); - ~JoinRemote(); - void message_epoint(unsigned int epoint_id, int message, union parameter *param); - void message_remote(int message_type, union parameter *param); - - unsigned int j_remote_ref; - int j_remote_id; - char j_remote_name[32]; - unsigned int j_epoint_id; -}; - - diff --git a/lcradmin.c b/lcradmin.c index f8a1ac8..bd029e8 100644 --- a/lcradmin.c +++ b/lcradmin.c @@ -743,18 +743,6 @@ const char *admin_state(int sock, char *argv[]) color(yellow); addstr("dact'ing"); break; - case B_STATE_EXPORTING: - color(yellow); - addstr("exp'ing "); - break; - case B_STATE_REMOTE: - color(green); - addstr("remote "); - break; - case B_STATE_IMPORTING: - color(yellow); - addstr("imp'ing "); - break; } if (m[i].u.i.port[j]) { /* search for port */ diff --git a/loop.c b/loop.c deleted file mode 100644 index cbd82e5..0000000 --- a/loop.c +++ /dev/null @@ -1,153 +0,0 @@ -/*****************************************************************************\ -** ** -** LCR ** -** ** -**---------------------------------------------------------------------------** -** Copyright: Andreas Eversberg ** -** ** -** loopback interface functions ** -** ** -\*****************************************************************************/ - -#include "main.h" - -struct mISDNloop mISDNloop = { -1, 0 }; - -void mISDNloop_close(void) -{ - if (mISDNloop.sock > -1) - close(mISDNloop.sock); - mISDNloop.sock = -1; -} - -int mISDNloop_open() -{ - int ret; - int cnt; - unsigned long on = 1; - struct sockaddr_mISDN addr; - struct mISDN_devinfo devinfo; - int pri, bri; - - /* already open */ - if (mISDNloop.sock > -1) - return 0; - - PDEBUG(DEBUG_PORT, "Open external interface of loopback.\n"); - - /* check port counts */ - ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt); - if (ret < 0) { - fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret); - return(ret); - } - - if (cnt <= 0) { - PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n"); - return -EIO; - } - mISDNloop.port = mISDN_getportbyname(mISDNsocket, cnt, options.loopback_ext); - if (mISDNloop.port < 0) { - PERROR_RUNTIME("Port name '%s' not found, did you load loopback interface?.\n", options.loopback_ext); - return mISDNloop.port; - } - /* get protocol */ - bri = pri = 0; - devinfo.id = mISDNloop.port; - ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo); - if (ret < 0) { - PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", mISDNloop.port, ret); - return ret; - } - if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0)) { - bri = 1; - } - if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1)) { - pri = 1; - } - if (!bri && !pri) { - PERROR_RUNTIME("loop port %d does not support TE PRI or TE BRI.\n", mISDNloop.port); - } - /* open socket */ - if ((mISDNloop.sock = socket(PF_ISDN, SOCK_DGRAM, (pri)?ISDN_P_TE_E1:ISDN_P_TE_S0)) < 0) { - PERROR_RUNTIME("loop port %d failed to open socket.\n", mISDNloop.port); - mISDNloop_close(); - return mISDNloop.sock; - } - /* set nonblocking io */ - if ((ret = ioctl(mISDNloop.sock, FIONBIO, &on)) < 0) { - PERROR_RUNTIME("loop port %d failed to set socket into nonblocking io.\n", mISDNloop.port); - mISDNloop_close(); - return ret; - } - /* bind socket to dchannel */ - memset(&addr, 0, sizeof(addr)); - addr.family = AF_ISDN; - addr.dev = mISDNloop.port; - addr.channel = 0; - if ((ret = bind(mISDNloop.sock, (struct sockaddr *)&addr, sizeof(addr))) < 0) { - PERROR_RUNTIME("loop port %d failed to bind socket. (name = %s errno=%d)\n", mISDNloop.port, options.loopback_ext, errno); - mISDNloop_close(); - return (ret); - } - - return 0; -} - -int loop_hunt_bchannel(class PmISDN *port, struct mISDNport *mISDNport) -{ - int channel; - int i; - char map[mISDNport->b_num]; - struct interface *interface; - struct interface_port *ifport; - - chan_trace_header(mISDNport, port, "CHANNEL SELECTION (setup)", DIRECTION_NONE); - add_trace("channel", "reserved", "%d", mISDNport->b_reserved); - if (mISDNport->b_reserved >= mISDNport->b_num) { // of out chan.. - add_trace("conclusion", NULL, "all channels are reserved"); - end_trace(); - return(-34); // no channel - } - - /* map all used ports of shared loopback interface */ - memset(map, 0, sizeof(map)); - interface = interface_first; - while(interface) { - ifport = interface->ifport; - while(ifport) { - if (!strcmp(ifport->portname, options.loopback_lcr)) { - i = 0; - while(i < mISDNport->b_num) { - if (mISDNport->b_port[i]) - map[i] = 1; - i++; - } - } - ifport = ifport->next; - } - interface = interface->next; - } - - /* find channel */ - i = 0; - channel = 0; - while(i < mISDNport->b_num) { - if (!map[i]) { - channel = i+1+(i>=15); - break; - } - i++; - } - if (!channel) { - add_trace("conclusion", NULL, "no channel available"); - end_trace(); - return(-6); // channel unacceptable - } - add_trace("conclusion", NULL, "channel available"); - add_trace("connect", "channel", "%d", channel); - end_trace(); - return(channel); -} - - diff --git a/loop.h b/loop.h deleted file mode 100644 index cb2ad05..0000000 --- a/loop.h +++ /dev/null @@ -1,12 +0,0 @@ - -struct mISDNloop { - int sock; /* loopback interface external side */ - int port; /* port number for external side */ -}; - -extern mISDNloop mISDNloop; - -void mISDNloop_close(void); -int mISDNloop_open(); -int loop_hunt_bchannel(class PmISDN *port, struct mISDNport *mISDNport); - diff --git a/mISDN.cpp b/mISDN.cpp index ed2b4eb..39ccc35 100644 --- a/mISDN.cpp +++ b/mISDN.cpp @@ -147,8 +147,6 @@ PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_setti p_m_dtmf = !mISDNport->ifport->nodtmf; memset(&p_m_timeout, 0, sizeof(p_m_timeout)); add_timer(&p_m_timeout, mISDN_timeout, this, 0); - p_m_remote_ref = 0; /* channel shall be exported to given remote */ - p_m_remote_id = 0; /* remote admin socket */ SCPY(p_m_pipeline, mISDNport->ifport->interface->pipeline); /* audio */ @@ -568,22 +566,6 @@ It may be linked to a Port class, that likes to reactivate it. See above. After deactivating bchannel, and if not used, the bchannel becomes idle again. -Also the bchannel may be exported, but only if the state is or becomes idle: - -- B_STATE_EXPORTING -The bchannel assignment has been sent to the remove application. - -- B_STATE_REMOTE -The bchannel assignment is acknowledged by the remote application. - -- B_STATE_IMPORTING -The bchannel is re-imported by mISDN port object. - -- B_STATE_IDLE -See above. -After re-importing bchannel, and if not used, the bchannel becomes idle again. - - A bchannel can have the following events: - B_EVENT_USE @@ -598,33 +580,8 @@ The bchannel is not required by Port class anymore - B_EVENT_DEACTIVATED The bchannel becomes inactive. -- B_EVENT_EXPORTED -The bchannel is now used by remote application. - -- B_EVENT_IMPORTED -The bchannel is not used by remote application. - -- B_EVENT_EXPORTREQUEST -The bchannel shall be exported to the remote application. - -- B_EVENT_IMPORTREQUEST -The bchannel is released from the remote application. - All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class. -if an export request is receive by remote application, p_m_remote_* is set. -the b_remote_*[index] indicates if and where the channel is exported to. (set from the point on, where export is initiated, until imported is acknowledged.) -- set on export request from remote application (if port is assigned) -- set on channel use, if requested by remote application (p_m_remote_*) -- cleared on drop request - -the bchannel will be exported with ref and stack given. remote application uses the ref to link bchannel to the call. -the bchannel will be imported with stack given only. remote application must store stack id with the bchannel process. -the bchannel import/export is acknowledged with stack given. - -if exporting, b_remote_*[index] is set to the remote socket id. -if importing has been acknowledged. b_remote_*[index] is cleared. - */ /* @@ -639,19 +596,14 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event) class PmISDN *b_port = mISDNport->b_port[i]; int state = mISDNport->b_state[i]; int timer = -1; // no change - unsigned int p_m_remote_ref = 0; - unsigned int p_m_remote_id = 0; int p_m_tx_gain = 0; int p_m_rx_gain = 0; char *p_m_pipeline = NULL; unsigned char *p_m_crypt_key = NULL; int p_m_crypt_key_len = 0; int p_m_crypt_key_type = 0; - unsigned int portid = (mISDNport->portnum<<8) + i+1+(i>=15); if (b_port) { - p_m_remote_id = b_port->p_m_remote_id; - p_m_remote_ref = b_port->p_m_remote_ref; p_m_tx_gain = b_port->p_m_tx_gain; p_m_rx_gain = b_port->p_m_rx_gain; p_m_pipeline = b_port->p_m_pipeline; @@ -667,140 +619,38 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event) FATAL("bchannel must be linked to a Port class\n"); switch(state) { case B_STATE_IDLE: - if (p_m_remote_ref) { - /* export bchannel */ - message_bchannel_to_remote(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type, 0); - chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE); - add_trace("type", NULL, "assign"); - add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff); - end_trace(); - state = B_STATE_EXPORTING; - mISDNport->b_remote_id[i] = p_m_remote_id; - mISDNport->b_remote_ref[i] = p_m_remote_ref; - } else { - /* create stack and send activation request */ - if (_bchannel_create(mISDNport, i)) { - _bchannel_activate(mISDNport, i, 1, 0); - state = B_STATE_ACTIVATING; - timer = B_TIMER_ACTIVATING; - } + /* create stack and send activation request */ + if (_bchannel_create(mISDNport, i)) { + _bchannel_activate(mISDNport, i, 1, 0); + state = B_STATE_ACTIVATING; + timer = B_TIMER_ACTIVATING; } break; case B_STATE_ACTIVATING: - case B_STATE_EXPORTING: /* do nothing, because it is already activating */ break; - case B_STATE_DEACTIVATING: - case B_STATE_IMPORTING: - /* do nothing, because we must wait until we can reactivate */ - break; - default: /* problems that might ocurr: * B_EVENT_USE is received when channel already in use. - * bchannel exported, but not freed by other port */ PERROR("Illegal event %d at state %d, please correct.\n", event, state); } break; - case B_EVENT_EXPORTREQUEST: - /* special case where the bchannel is requested by remote */ - if (!p_m_remote_ref) { - PERROR("export request without remote channel set, please correct.\n"); - break; - } - switch(state) { - case B_STATE_IDLE: - /* in case, the bchannel is exported right after seize_bchannel */ - /* export bchannel */ - /* p_m_remote_id is set, when this event happens. */ - message_bchannel_to_remote(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type, 0); - chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE); - add_trace("type", NULL, "assign"); - add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff); - end_trace(); - state = B_STATE_EXPORTING; - mISDNport->b_remote_id[i] = p_m_remote_id; - mISDNport->b_remote_ref[i] = p_m_remote_ref; - break; - - case B_STATE_ACTIVATING: - case B_STATE_EXPORTING: - /* do nothing, because it is already activating */ - break; - - case B_STATE_DEACTIVATING: - case B_STATE_IMPORTING: - /* do nothing, because we must wait until we can reactivate */ - break; - - case B_STATE_ACTIVE: - /* bchannel is active, so we deactivate */ - _bchannel_activate(mISDNport, i, 0, 0); - state = B_STATE_DEACTIVATING; - timer = B_TIMER_DEACTIVATING; - break; - - default: - /* problems that might ocurr: - * ... when channel already in use. - * bchannel exported, but not freed by other port - */ - PERROR("Illegal event %d at state %d, please correct.\n", event, state); - } - break; - - case B_EVENT_IMPORTREQUEST: - /* special case where the bchannel is released by remote */ - if (p_m_remote_ref) { - PERROR("import request with remote channel set, please correct.\n"); - break; - } - switch(state) { - case B_STATE_IDLE: - case B_STATE_ACTIVE: - /* bchannel is not exported */ - break; - - case B_STATE_ACTIVATING: - case B_STATE_EXPORTING: - /* do nothing because we must wait until bchanenl is active before deactivating */ - break; - - case B_STATE_REMOTE: - /* bchannel is exported, so we re-import */ - message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0, 0); - chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE); - add_trace("type", NULL, "remove"); - add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff); - end_trace(); - state = B_STATE_IMPORTING; - break; - - case B_STATE_DEACTIVATING: - case B_STATE_IMPORTING: - /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */ - break; - - default: - PERROR("Illegal event %d at state %d, please correct.\n", event, state); - } - break; case B_EVENT_ACTIVATED: timer = 0; switch(state) { case B_STATE_ACTIVATING: - if (b_port && !p_m_remote_id) { + if (b_port) { /* bchannel is active and used by Port class, so we configure bchannel */ _bchannel_configure(mISDNport, i); state = B_STATE_ACTIVE; b_port->p_m_load = 0; } else { - /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */ + /* bchannel is active, but not used anymore (or has wrong stack config), so we deactivate */ _bchannel_activate(mISDNport, i, 0, 0); state = B_STATE_DEACTIVATING; timer = B_TIMER_DEACTIVATING; @@ -812,31 +662,6 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event) } break; - case B_EVENT_EXPORTED: - switch(state) { - case B_STATE_EXPORTING: - if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i]) { - /* remote export done */ - state = B_STATE_REMOTE; - } else { - /* bchannel is now exported, but we need bchannel back - * OR bchannel is not used anymore - * OR bchannel has been exported to an obsolete ref, - * so reimport, to later export to new remote */ - message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0, 0); - chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE); - add_trace("type", NULL, "remove"); - add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff); - end_trace(); - state = B_STATE_IMPORTING; - } - break; - - default: - PERROR("Illegal event %d at state %d, please correct.\n", event, state); - } - break; - case B_EVENT_DROP: if (!b_port) FATAL("bchannel must be linked to a Port class\n"); @@ -846,7 +671,6 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event) break; case B_STATE_ACTIVATING: - case B_STATE_EXPORTING: /* do nothing because we must wait until bchanenl is active before deactivating */ break; @@ -857,18 +681,7 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event) timer = B_TIMER_DEACTIVATING; break; - case B_STATE_REMOTE: - /* bchannel is exported, so we re-import */ - message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0, 0); - chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE); - add_trace("type", NULL, "remove"); - add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff); - end_trace(); - state = B_STATE_IMPORTING; - break; - case B_STATE_DEACTIVATING: - case B_STATE_IMPORTING: /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */ break; @@ -888,22 +701,11 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event) _bchannel_destroy(mISDNport, i); state = B_STATE_IDLE; if (b_port) { - /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */ - if (p_m_remote_ref) { - message_bchannel_to_remote(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type, 0); - chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE); - add_trace("type", NULL, "assign"); - add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff); - end_trace(); - state = B_STATE_EXPORTING; - mISDNport->b_remote_id[i] = p_m_remote_id; - mISDNport->b_remote_ref[i] = p_m_remote_ref; - } else { - if (_bchannel_create(mISDNport, i)) { - _bchannel_activate(mISDNport, i, 1, 0); - state = B_STATE_ACTIVATING; - timer = B_TIMER_ACTIVATING; - } + /* bchannel is now deactivate, but is requied by Port class, so we reactivate */ + if (_bchannel_create(mISDNport, i)) { + _bchannel_activate(mISDNport, i, 1, 0); + state = B_STATE_ACTIVATING; + timer = B_TIMER_ACTIVATING; } } break; @@ -913,39 +715,6 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event) } break; - case B_EVENT_IMPORTED: - switch(state) { - case B_STATE_IMPORTING: - state = B_STATE_IDLE; - mISDNport->b_remote_id[i] = 0; - mISDNport->b_remote_ref[i] = 0; - if (b_port) { - /* bchannel is now imported, but is requied by Port class, so we reactivate / export */ - if (p_m_remote_ref) { - message_bchannel_to_remote(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type, 0); - chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE); - add_trace("type", NULL, "assign"); - add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff); - end_trace(); - state = B_STATE_EXPORTING; - mISDNport->b_remote_id[i] = p_m_remote_id; - mISDNport->b_remote_ref[i] = p_m_remote_ref; - } else { - if (_bchannel_create(mISDNport, i)) { - _bchannel_activate(mISDNport, i, 1, 0); - state = B_STATE_ACTIVATING; - timer = B_TIMER_ACTIVATING; - } - } - } - break; - - default: - /* ignore, because not assigned */ - ; - } - break; - case B_EVENT_TIMEOUT: timer = 0; switch(state) { @@ -1084,101 +853,6 @@ void PmISDN::drop_bchannel(void) p_m_b_exclusive = 0; } -/* process bchannel export/import message from join */ -void message_bchannel_from_remote(class JoinRemote *joinremote, int type, unsigned int handle) -{ - class Endpoint *epoint; - class Port *port; - class PmISDN *isdnport; - struct mISDNport *mISDNport; - int i, ii; - - switch(type) { - case BCHANNEL_REQUEST: - /* find the port object for the join object ref */ - if (!(epoint = find_epoint_id(joinremote->j_epoint_id))) { - PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial); - return; - } - if (!epoint->ep_portlist) { - PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial); - return; - } - if (epoint->ep_portlist->next) { - PERROR("join %d has enpoint %d with more than one port. this shall not happen to remote joins.\n", joinremote->j_serial, epoint->ep_serial); - } - if (!(port = find_port_id(epoint->ep_portlist->port_id))) { - PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial); - return; - } - if ((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN) { - PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial); - } - isdnport = (class PmISDN *)port; - - /* assign */ - if (isdnport->p_m_remote_id) { - PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial); - break; - } - mISDNport = isdnport->p_m_mISDNport; - i = isdnport->p_m_b_index; - chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE); - add_trace("type", NULL, "export request"); - end_trace(); - isdnport->p_m_remote_ref = joinremote->j_remote_ref; - isdnport->p_m_remote_id = joinremote->j_remote_id; - if (mISDNport && i>=0) { - bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST); - } - break; - - case BCHANNEL_RELEASE: - case BCHANNEL_ASSIGN_ACK: - case BCHANNEL_REMOVE_ACK: - /* find mISDNport for stack ID */ - mISDNport = mISDNport_first; - while(mISDNport) { - i = 0; - ii = mISDNport->b_num; - while(i < ii) { - if ((unsigned int)(mISDNport->portnum<<8)+i+1+(i>=15) == handle) - break; - i++; - } - if (i != ii) - break; - mISDNport = mISDNport->next; - } - if (!mISDNport) { - PERROR("received assign/remove ack for bchannel's handle=%x, but handle does not exist in any mISDNport structure.\n", handle); - break; - } - - if (type!=BCHANNEL_RELEASE) { - /* ack */ - chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE); - add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack"); - end_trace(); - bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED); - } else { - /* release */ - isdnport = mISDNport->b_port[i]; - chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE); - add_trace("type", NULL, "import request"); - end_trace(); - if (isdnport) { - isdnport->p_m_remote_ref = 0; - isdnport->p_m_remote_id = 0; - } - bchannel_event(mISDNport, i, B_EVENT_IMPORTREQUEST); - } - break; - default: - PERROR("received wrong bchannel message type %d from remote\n", type); - } -} - /* * handler @@ -1843,98 +1517,96 @@ static int mISDN_upqueue(struct lcr_fd *fd, unsigned int what, void *instance, i mISDNport = mISDNport_first; while(mISDNport) { /* handle queued up-messages (d-channel) */ - if (!mISDNport->isloopback) { - while ((mb = mdequeue(&mISDNport->upqueue))) { - l3m = &mb->l3; - switch(l3m->type) { - case MPH_ACTIVATE_IND: - if (mISDNport->l1link != 1) { - l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN); - end_trace(); - mISDNport->l1link = 1; - } - break; - - case MPH_DEACTIVATE_IND: - if (mISDNport->l1link != 0) { - l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN); - end_trace(); - mISDNport->l1link = 0; - } - break; + while ((mb = mdequeue(&mISDNport->upqueue))) { + l3m = &mb->l3; + switch(l3m->type) { + case MPH_ACTIVATE_IND: + if (mISDNport->l1link != 1) { + l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN); + end_trace(); + mISDNport->l1link = 1; + } + break; + + case MPH_DEACTIVATE_IND: + if (mISDNport->l1link != 0) { + l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN); + end_trace(); + mISDNport->l1link = 0; + } + break; - case MPH_INFORMATION_IND: - PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name); - switch (l3m->pid) { - case L1_SIGNAL_LOS_ON: - mISDNport->los = 1; - break; - case L1_SIGNAL_LOS_OFF: - mISDNport->los = 0; - break; - case L1_SIGNAL_AIS_ON: - mISDNport->ais = 1; - break; - case L1_SIGNAL_AIS_OFF: - mISDNport->ais = 0; - break; - case L1_SIGNAL_RDI_ON: - mISDNport->rdi = 1; - break; - case L1_SIGNAL_RDI_OFF: - mISDNport->rdi = 0; - break; - case L1_SIGNAL_SLIP_TX: - mISDNport->slip_tx++; - break; - case L1_SIGNAL_SLIP_RX: - mISDNport->slip_rx++; - break; - } + case MPH_INFORMATION_IND: + PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name); + switch (l3m->pid) { + case L1_SIGNAL_LOS_ON: + mISDNport->los = 1; break; + case L1_SIGNAL_LOS_OFF: + mISDNport->los = 0; + break; + case L1_SIGNAL_AIS_ON: + mISDNport->ais = 1; + break; + case L1_SIGNAL_AIS_OFF: + mISDNport->ais = 0; + break; + case L1_SIGNAL_RDI_ON: + mISDNport->rdi = 1; + break; + case L1_SIGNAL_RDI_OFF: + mISDNport->rdi = 0; + break; + case L1_SIGNAL_SLIP_TX: + mISDNport->slip_tx++; + break; + case L1_SIGNAL_SLIP_RX: + mISDNport->slip_rx++; + break; + } + break; - case MT_L2ESTABLISH: - l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN); + case MT_L2ESTABLISH: + l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN); + add_trace("tei", NULL, "%d", l3m->pid); + end_trace(); + mISDNport->l2link = 1; + if (l3m->pid < 128) + mISDNport->l2mask[l3m->pid >> 3] |= (1 << (l3m->pid & 7)); + if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) { + if (mISDNport->l2establish.active) { + unsched_timer(&mISDNport->l2establish); + PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n"); + } + } + break; + + case MT_L2RELEASE: + if (l3m->pid < 128) + mISDNport->l2mask[l3m->pid >> 3] &= ~(1 << (l3m->pid & 7)); + if (!mISDNport->l2establish.active) { + l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN); add_trace("tei", NULL, "%d", l3m->pid); end_trace(); - mISDNport->l2link = 1; - if (l3m->pid < 128) - mISDNport->l2mask[l3m->pid >> 3] |= (1 << (l3m->pid & 7)); - if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) { - if (mISDNport->l2establish.active) { - unsched_timer(&mISDNport->l2establish); - PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n"); - } - } - break; - - case MT_L2RELEASE: - if (l3m->pid < 128) - mISDNport->l2mask[l3m->pid >> 3] &= ~(1 << (l3m->pid & 7)); - if (!mISDNport->l2establish.active) { - l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN); - add_trace("tei", NULL, "%d", l3m->pid); - end_trace(); - /* down if not nt-ptmp */ - if (!mISDNport->ntmode || mISDNport->ptp) - mISDNport->l2link = 0; - } - if (!mISDNport->isloopback && (!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) { - if (!mISDNport->l2establish.active && mISDNport->l2hold) { - PDEBUG(DEBUG_ISDN, "set timer and establish.\n"); - schedule_timer(&mISDNport->l2establish, 5, 0); - mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL); - } - } - break; - - default: - /* l3-data is sent to LCR */ - stack2manager(mISDNport, l3m->type, l3m->pid, l3m); + /* down if not nt-ptmp */ + if (!mISDNport->ntmode || mISDNport->ptp) + mISDNport->l2link = 0; } - /* free message */ - free_l3_msg(l3m); + if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) { + if (!mISDNport->l2establish.active && mISDNport->l2hold) { + PDEBUG(DEBUG_ISDN, "set timer and establish.\n"); + schedule_timer(&mISDNport->l2establish, 5, 0); + mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL); + } + } + break; + + default: + /* l3-data is sent to LCR */ + stack2manager(mISDNport, l3m->type, l3m->pid, l3m); } + /* free message */ + free_l3_msg(l3m); } mISDNport = mISDNport->next; } @@ -1946,7 +1618,7 @@ static int l2establish_timeout(struct lcr_timer *timer, void *instance, int i) { struct mISDNport *mISDNport = (struct mISDNport *)instance; - if (!mISDNport->isloopback && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) { + if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) { PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum); mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL); schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */ @@ -2107,7 +1779,6 @@ struct mISDNport *mISDNport_open(struct interface_port *ifport) int force_nt = ifport->nt; int l1hold = ifport->l1hold; int l2hold = ifport->l2hold; - int loop = 0; int ss5 = ifport->ss5; int i, cnt; int pri, bri, pots; @@ -2116,16 +1787,6 @@ struct mISDNport *mISDNport_open(struct interface_port *ifport) struct mISDN_devinfo devinfo; unsigned int protocol, prop; - loop = 0; -//printf("%s == %s\n", ifport->portname, options.loopback_int); - if (!strcmp(ifport->portname, options.loopback_lcr)) - loop = 1; - - if (loop) { - if (mISDNloop_open()) - return NULL; - } - /* check port counts */ ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt); if (ret < 0) { @@ -2140,10 +1801,7 @@ struct mISDNport *mISDNport_open(struct interface_port *ifport) if (port < 0) { port = mISDN_getportbyname(mISDNsocket, cnt, ifport->portname); if (port < 0) { - if (loop) - PERROR_RUNTIME("Port name '%s' not found, did you load loopback interface?.\n", ifport->portname); - else - PERROR_RUNTIME("Port name '%s' not found, use 'misdn_info' tool to list all existing ports.\n", ifport->portname); + PERROR_RUNTIME("Port name '%s' not found, use 'misdn_info' tool to list all existing ports.\n", ifport->portname); return(NULL); } // note: 'port' has still the port number @@ -2257,15 +1915,14 @@ struct mISDNport *mISDNport_open(struct interface_port *ifport) mISDNportp = &((*mISDNportp)->next); mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport)); add_timer(&mISDNport->l2establish, l2establish_timeout, mISDNport, 0); - if (loop | ss5) { - /* loop/ss5 link is always active */ + if (ss5) { + /* ss5 link is always active */ mISDNport->l1link = 1; mISDNport->l2link = 1; } else { mISDNport->l1link = -1; mISDNport->l2link = -1; } - mISDNport->isloopback = loop; pmemuse++; *mISDNportp = mISDNport; @@ -2307,56 +1964,23 @@ struct mISDNport *mISDNport_open(struct interface_port *ifport) if (l2hold) // supports layer 2 hold prop |= (1 << MISDN_FLG_L2_HOLD); /* open layer 3 and init upqueue */ - if (loop) { - unsigned long on = 1; - struct sockaddr_mISDN addr; - - if (devinfo.nrbchan < 8) { - printf("loop port %d has a low number of bchannels. (only %d) remember that all interfaces that requires a loopback could run out of channels\n", port, devinfo.nrbchan); -// mISDNport_close(mISDNport); -// return(NULL); - } - - if ((mISDNport->lcr_sock = socket(PF_ISDN, SOCK_DGRAM, (bri) ? ISDN_P_TE_S0 : ISDN_P_TE_E1)) < 0) { - PERROR_RUNTIME("loop port %d failed to open socket.\n", port); - mISDNport_close(mISDNport); - return(NULL); - } - /* set nonblocking io */ - if (ioctl(mISDNport->lcr_sock, FIONBIO, &on) < 0) { - PERROR_RUNTIME("loop port %d failed to set socket into nonblocking io.\n", port); - mISDNport_close(mISDNport); - return(NULL); - } - /* bind socket to dchannel */ - memset(&addr, 0, sizeof(addr)); - addr.family = AF_ISDN; - addr.dev = port; - addr.channel = 0; - if (bind(mISDNport->lcr_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - PERROR_RUNTIME("loop port %d failed to bind socket. (errno %d)\n", port, errno); - mISDNport_close(mISDNport); - return(NULL); - } - } else { - /* queue must be initializes, because l3-thread may send messages during open_layer3() */ - mqueue_init(&mISDNport->upqueue); - mISDNport->ml3 = open_layer3(port, protocol, prop , do_layer3, mISDNport); - if (!mISDNport->ml3) { - mqueue_purge(&mISDNport->upqueue); - PERROR_RUNTIME("open_layer3() failed for port %d\n", port); - start_trace(port, - ifport->interface, - NULL, - NULL, - DIRECTION_NONE, - CATEGORY_CH, - 0, - "PORT (open failed)"); - end_trace(); - mISDNport_close(mISDNport); - return(NULL); - } + /* queue must be initializes, because l3-thread may send messages during open_layer3() */ + mqueue_init(&mISDNport->upqueue); + mISDNport->ml3 = open_layer3(port, protocol, prop , do_layer3, mISDNport); + if (!mISDNport->ml3) { + mqueue_purge(&mISDNport->upqueue); + PERROR_RUNTIME("open_layer3() failed for port %d\n", port); + start_trace(port, + ifport->interface, + NULL, + NULL, + DIRECTION_NONE, + CATEGORY_CH, + 0, + "PORT (open failed)"); + end_trace(); + mISDNport_close(mISDNport); + return(NULL); } SCPY(mISDNport->name, devinfo.name); @@ -2378,7 +2002,7 @@ struct mISDNport *mISDNport_open(struct interface_port *ifport) } /* if ptp, pull up the link */ - if (!mISDNport->isloopback && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) { + if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) { mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL); l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT); add_trace("tei", NULL, "%d", 0); @@ -2491,18 +2115,12 @@ void mISDNport_close(struct mISDNport *mISDNport) del_timer(&mISDNport->l2establish); /* close layer 3, if open */ - if (!mISDNport->isloopback && mISDNport->ml3) { + if (mISDNport->ml3) { close_layer3(mISDNport->ml3); } - /* close gsm socket, if open */ - if (mISDNport->isloopback && mISDNport->lcr_sock > -1) { - close(mISDNport->lcr_sock); - } - /* purge upqueue */ - if (!mISDNport->isloopback) - mqueue_purge(&mISDNport->upqueue); + mqueue_purge(&mISDNport->upqueue); /* remove from list */ mISDNportp = &mISDNport_first; diff --git a/mISDN.h b/mISDN.h index 90890b3..0803698 100644 --- a/mISDN.h +++ b/mISDN.h @@ -18,15 +18,11 @@ extern int mISDNdevice; extern int mISDNsocket; enum { - B_EVENT_USE, /* activate/export bchannel */ - B_EVENT_EXPORTREQUEST, /* remote app requests bchannel */ - B_EVENT_IMPORTREQUEST, /* remote app releases bchannel */ + B_EVENT_USE, /* activate bchannel */ B_EVENT_ACTIVATED, /* DL_ESTABLISH received */ - B_EVENT_DROP, /* deactivate/re-import bchannel */ + B_EVENT_DROP, /* deactivate bchannel */ B_EVENT_DEACTIVATED, /* DL_RELEASE received */ - B_EVENT_EXPORTED, /* BCHANNEL_ASSIGN received */ - B_EVENT_IMPORTED, /* BCHANNEL_REMOVE received */ - B_EVENT_TIMEOUT, /* timeout for bchannel state */ + B_EVENT_TIMEOUT, /* timeout happed during (de)activation */ }; /* mISDN port structure list */ @@ -59,14 +55,9 @@ struct mISDNport { int b_mode[128]; /* B_MODE_* */ int b_state[128]; /* statemachine, 0 = IDLE */ struct lcr_timer b_timer[128]; /* timer for bchannel state machine */ - int b_remote_id[128]; /* the socket currently exported (0=none) */ - unsigned int b_remote_ref[128]; /* the ref currently exported */ int locally; /* local causes are sent as local causes not remote */ int los, ais, rdi, slip_rx, slip_tx; - int lcr_sock; /* socket of loopback on LCR side */ - int isloopback; /* will be set on open, in case it is a loopback if */ - /* ss5 */ unsigned int ss5; /* set, if SS5 signalling enabled, also holds feature bits */ }; @@ -103,7 +94,6 @@ void ph_control_block(struct mISDNport *mISDNport, unsigned int handle, unsigned void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, const char *msgtext, int direction); void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned int prim, int direction); void bchannel_event(struct mISDNport *mISDNport, int i, int event); -void message_bchannel_from_remote(class JoinRemote *joinremote, int type, unsigned int handle); /* mISDN port classes */ @@ -164,8 +154,6 @@ class PmISDN : public Port int p_m_b_mode; /* bchannel mode */ int p_m_hold; /* if port is on hold */ struct lcr_timer p_m_timeout; /* timeout of timers */ - unsigned int p_m_remote_ref; /* join to export bchannel to */ - int p_m_remote_id; /* sock to export bchannel to */ int p_m_inband_send_on; /* triggers optional send function */ int p_m_inband_receive_on; /* triggers optional receive function */ diff --git a/main.c b/main.c index 95388a0..8efd316 100644 --- a/main.c +++ b/main.c @@ -627,12 +627,6 @@ exit is done when interface is down sip_exit(); #endif -#ifdef WITH_MISDN - /* close loopback, if used by GSM or remote */ - if (mISDNloop.sock > -1) - mISDNloop_close(); -#endif - /* display memory leak */ #define MEMCHECK(a, b) \ if (b) { \ diff --git a/main.h b/main.h index 8d8b448..0c117e3 100644 --- a/main.h +++ b/main.h @@ -149,11 +149,10 @@ void debug(const char *file, const char *function, int line, const char *prefix, #include "callerid.h" #include "route.h" #include "port.h" +#include "remote.h" #ifdef WITH_MISDN #include "mISDN.h" #include "dss1.h" -#include "loop.h" -#include "remote.h" #endif #if defined WITH_GSM_BS || defined WITH_GSM_MS #include "gsm.h" @@ -175,7 +174,6 @@ void debug(const char *file, const char *function, int line, const char *prefix, #include "vbox.h" #include "join.h" #include "joinpbx.h" -#include "joinremote.h" #include "cause.h" #include "alawulaw.h" #include "tones.h" diff --git a/message.h b/message.h index 82df9d5..464285f 100644 --- a/message.h +++ b/message.h @@ -126,23 +126,13 @@ enum { /* isdnsignal */ mISDNSIGNAL_DELAY, /* use delay or adaptive jitter */ }; -enum { /* bchannel assignment */ - BCHANNEL_REQUEST, /* application requests bchannel */ - BCHANNEL_RELEASE, /* application releases bchannel */ - BCHANNEL_ASSIGN, /* bchannel assigned by LCR */ - BCHANNEL_ASSIGN_ACK, /* application acknowledges */ - BCHANNEL_REMOVE, /* bchannel removed by LCR */ - BCHANNEL_REMOVE_ACK, /* application acknowledges */ -}; enum { B_STATE_IDLE, /* not open */ B_STATE_ACTIVATING, /* DL_ESTABLISH sent */ B_STATE_ACTIVE, /* channel active */ B_STATE_DEACTIVATING, /* DL_RELEASE sent */ - B_STATE_EXPORTING, /* BCHANNEL_ASSIGN sent */ - B_STATE_REMOTE, /* bchannel assigned to remote application */ - B_STATE_IMPORTING, /* BCHANNEL_REMOVE sent */ }; + enum { B_MODE_TRANSPARENT, /* normal transparent audio */ B_MODE_HDLC, /* hdlc data mode */ @@ -194,6 +184,7 @@ struct dialing_info { int sending_complete; /* end of dialing */ char display[84]; /* display information */ char keypad[33]; /* send keypad facility */ + char context[32]; /* asterisk context */ }; /* call-info structure CONNECT */ @@ -288,7 +279,6 @@ struct message_setup { struct useruser_info useruser; /* user-user */ struct progress_info progress; /* info on call progress */ struct rtp_info rtpinfo; /* info about RTP peer */ - char context[128]; /* asterisk context */ }; /* call-info structure PARK */ @@ -346,7 +336,11 @@ struct param_bchannel { struct param_newref { int direction; /* who requests a refe? */ - int mode; /* 0 = direct-mode, 1 = PBX mode */ +}; + +struct param_traffic { + int len; /* how much data */ + unsigned char data[160]; /* 20ms */ }; /* structure of message parameter */ @@ -374,6 +368,7 @@ union parameter { struct param_bchannel bchannel; /* MESSAGE_BCHANNEL */ struct param_newref newref; /* MESSAGE_NEWREF */ unsigned int bridge_id; /* MESSAGE_BRIDGE */ + struct param_traffic traffic; /* MESSAGE_TRAFFIC */ }; enum { /* message flow */ @@ -427,6 +422,7 @@ enum { /* messages between entities */ MESSAGE_HELLO, /* hello message for remote application */ MESSAGE_NEWREF, /* special message to create and inform ref */ MESSAGE_BRIDGE, /* control port bridge */ + MESSAGE_TRAFFIC, /* exchange bchannel traffic */ }; #define MESSAGES static const char *messages_txt[] = { \ @@ -462,6 +458,7 @@ enum { /* messages between entities */ "MESSAGE_HELLO", \ "MESSAGE_NEWREF", \ "MESSAGE_BRIDGE", \ + "MESSAGE_TRAFFIC", \ }; diff --git a/options.c b/options.c index 760cfb3..081e2c5 100644 --- a/options.c +++ b/options.c @@ -36,8 +36,6 @@ struct options options = { -1, /* socket user (-1= no change) */ -1, /* socket group (-1= no change) */ 1, /* use polling of main loop */ - "mISDN_l1loop.1", /* GSM/Asterisk side */ - "mISDN_l1loop.2", /* LCR side */ }; char options_error[256]; @@ -237,22 +235,6 @@ int read_options(char *options_error) } else if (!strcmp(option,"polling")) { options.polling = 1; - } else - if (!strcmp(option,"loopback-ext")) { - if (param[0]==0) { - UPRINT(options_error, "Error in %s (line %d): parameter for option %s missing.\n",filename,line, option); - goto error; - } - SCPY(options.loopback_ext, param); - - } else - if (!strcmp(option,"loopback-lcr")) { - if (param[0]==0) { - UPRINT(options_error, "Error in %s (line %d): parameter for option %s missing.\n",filename,line, option); - goto error; - } - SCPY(options.loopback_lcr, param); - } else { UPRINT(options_error, "Error in %s (line %d): wrong option keyword %s.\n", filename,line,option); goto error; diff --git a/options.h b/options.h index 7ea5166..574cd68 100644 --- a/options.h +++ b/options.h @@ -30,8 +30,6 @@ struct options { int socketuser; /* socket chown to this user */ int socketgroup; /* socket chgrp to this group */ int polling; - char loopback_ext[64]; /* loopback interface GSM side */ - char loopback_lcr[64]; /* loopback interface LCR side */ }; extern struct options options; diff --git a/port.h b/port.h index 6757e9b..4833ad7 100644 --- a/port.h +++ b/port.h @@ -19,11 +19,11 @@ #define PORT_CLASS_DSS1_NT 0x1110 #define PORT_CLASS_DSS1_TE 0x1120 #define PORT_CLASS_SS5 0x1300 -#define PORT_CLASS_REMOTE 0x1400 #define PORT_CLASS_SIP 0x2000 #define PORT_CLASS_GSM 0x3000 #define PORT_CLASS_GSM_BS 0x3100 #define PORT_CLASS_GSM_MS 0x3200 +#define PORT_CLASS_REMOTE 0x4000 #define PORT_CLASS_MASK 0xf000 #define PORT_CLASS_mISDN_MASK 0xff00 #define PORT_CLASS_DSS1_MASK 0xfff0 @@ -47,8 +47,8 @@ #define PORT_TYPE_SS5_OUT 0x1312 #define PORT_TYPE_SS5_IDLE 0x1313 /* remote */ -#define PORT_TYPE_REMOTE_IN 0x1411 -#define PORT_TYPE_REMOTE_OUT 0x1412 +#define PORT_TYPE_REMOTE_IN 0x4001 +#define PORT_TYPE_REMOTE_OUT 0x4002 /* SIP */ #define PORT_TYPE_SIP_IN 0x2001 #define PORT_TYPE_SIP_OUT 0x2002 diff --git a/remote.cpp b/remote.cpp index e7b9009..43c9233 100644 --- a/remote.cpp +++ b/remote.cpp @@ -16,24 +16,25 @@ unsigned int new_remote = 1000; /* * constructor */ -Premote::Premote(int type, struct mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive, int mode, int remote_id) : PmISDN(type, mISDNport, portname, settings, channel, exclusive, mode) +Premote::Premote(int type, char *portname, struct port_settings *settings, struct interface *interface, int remote_id) : Port(type, portname, settings) { union parameter param; - p_callerinfo.itype = (mISDNport->ifport->interface->extension)?INFO_ITYPE_ISDN_EXTENSION:INFO_ITYPE_ISDN; - p_m_r_ref = new_remote++; - SCPY(p_m_r_remote_app, mISDNport->ifport->remote_app); - p_m_r_handle = 0; + p_callerinfo.itype = (interface->extension)?INFO_ITYPE_ISDN_EXTENSION:INFO_ITYPE_ISDN; + p_r_ref = new_remote++; + SCPY(p_r_remote_app, interface->remote_app); + SCPY(p_r_interface_name, interface->name); + p_r_tones = (interface->is_tones == IS_YES); /* send new ref to remote socket */ memset(¶m, 0, sizeof(union parameter)); if (type == PORT_TYPE_REMOTE_OUT) param.newref.direction = 1; /* new ref from lcr */ - p_m_r_remote_id = remote_id; - if (admin_message_from_lcr(p_m_r_remote_id, p_m_r_ref, MESSAGE_NEWREF, ¶m) < 0) - FATAL("No socket with remote application '%s' found, this shall not happen. because we already created one.\n", mISDNport->ifport->remote_app); + p_r_remote_id = remote_id; + if (admin_message_from_lcr(p_r_remote_id, p_r_ref, MESSAGE_NEWREF, ¶m) < 0) + FATAL("No socket with remote application '%s' found, this shall not happen. because we already created one.\n", p_r_remote_app); - PDEBUG(DEBUG_GSM, "Created new RemotePort(%s).\n", portname); + PDEBUG(DEBUG_PORT, "Created new RemotePort(%s).\n", portname); } @@ -42,17 +43,7 @@ Premote::Premote(int type, struct mISDNport *mISDNport, char *portname, struct p */ Premote::~Premote() { - /* need to remote (import) external channel from remote application */ - if (p_m_r_handle) { - message_bchannel_to_remote(p_m_r_remote_id, p_m_r_ref, BCHANNEL_REMOVE, p_m_r_handle, 0, 0, 0, 0, 0, 0, 1); - chan_trace_header(p_m_mISDNport, this, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE); - add_trace("type", NULL, "remove"); - add_trace("channel", NULL, "%d.%d", p_m_r_handle>>8, p_m_r_handle&0xff); - end_trace(); - } - - PDEBUG(DEBUG_GSM, "Destroyed Remote process(%s).\n", p_name); - + PDEBUG(DEBUG_PORT, "Destroyed Remote process(%s).\n", p_name); } /* @@ -60,32 +51,18 @@ Premote::~Premote() */ int Premote::message_epoint(unsigned int epoint_id, int message_type, union parameter *param) { - struct lcr_msg *message; - int channel; - int ret; struct epoint_list *epointlist; - if (PmISDN::message_epoint(epoint_id, message_type, param)) + if (Port::message_epoint(epoint_id, message_type, param)) return 1; if (message_type == MESSAGE_SETUP) { - ret = channel = hunt_bchannel(); - if (ret < 0) - goto no_channel; - /* open channel */ - ret = seize_bchannel(channel, 1); - if (ret < 0) { - no_channel: - message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE); - message->param.disconnectinfo.cause = 34; - message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL; - message_put(message); - new_state(PORT_STATE_RELEASE); - delete this; + struct interface *interface; + interface = getinterfacebyname(p_r_interface_name); + if (!interface) { + PERROR("Cannot find interface %s.\n", p_r_interface_name); return 0; } - bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE); - /* attach only if not already */ epointlist = p_epointlist; while(epointlist) { @@ -97,23 +74,34 @@ int Premote::message_epoint(unsigned int epoint_id, int message_type, union para epointlist_new(epoint_id); /* set context to pbx */ - SCPY(param->setup.context, "pbx"); + if (!param->setup.dialinginfo.context[0]) { + if (interface->remote_context[0]) + SCPY(param->setup.dialinginfo.context, interface->remote_context); + else + SCPY(param->setup.dialinginfo.context, "lcr"); + } + } /* look for Remote's interface */ - if (admin_message_from_lcr(p_m_r_remote_id, p_m_r_ref, message_type, param)<0) { - PERROR("No socket with remote application '%s' found, this shall not happen. Closing socket shall cause release of all remote ports.\n", p_m_mISDNport->ifport->remote_app); + if (admin_message_from_lcr(p_r_remote_id, p_r_ref, message_type, param)<0) { + PERROR("No socket with remote application '%s' found, this shall not happen. Closing socket shall cause release of all remote ports.\n", p_r_remote_app); return 0; } +#if 0 /* enable audio path */ if (message_type == MESSAGE_SETUP) { union parameter newparam; memset(&newparam, 0, sizeof(union parameter)); - admin_message_from_lcr(p_m_r_remote_id, p_m_r_ref, MESSAGE_PATTERN, &newparam); + admin_message_from_lcr(p_r_remote_id, p_r_ref, MESSAGE_PATTERN, &newparam); newparam.audiopath = 1; - admin_message_from_lcr(p_m_r_remote_id, p_m_r_ref, MESSAGE_AUDIOPATH, &newparam); + admin_message_from_lcr(p_r_remote_id, p_r_ref, MESSAGE_AUDIOPATH, &newparam); } +#endif + + if (message_type == MESSAGE_CONNECT) + new_state(PORT_STATE_CONNECT); if (message_type == MESSAGE_RELEASE) { new_state(PORT_STATE_RELEASE); @@ -128,93 +116,81 @@ void Premote::message_remote(int message_type, union parameter *param) { class Endpoint *epoint; struct lcr_msg *message; - int channel; - int ret; + struct interface *interface; + + switch (message_type) { + case MESSAGE_TRAFFIC: + bridge_tx(param->traffic.data, param->traffic.len); + break; + + case MESSAGE_SETUP: + interface = getinterfacebyname(p_r_interface_name); + if (!interface) { + PERROR("Cannot find interface %s.\n", p_r_interface_name); + return; + } - if (message_type == MESSAGE_SETUP) { /* enable audio path */ - union parameter newparam; - memset(&newparam, 0, sizeof(union parameter)); - admin_message_from_lcr(p_m_r_remote_id, p_m_r_ref, MESSAGE_PATTERN, &newparam); - newparam.audiopath = 1; - admin_message_from_lcr(p_m_r_remote_id, p_m_r_ref, MESSAGE_AUDIOPATH, &newparam); + if (interface->is_tones == IS_YES) { + union parameter newparam; + memset(&newparam, 0, sizeof(union parameter)); + admin_message_from_lcr(p_r_remote_id, p_r_ref, MESSAGE_PATTERN, &newparam); + newparam.audiopath = 1; + admin_message_from_lcr(p_r_remote_id, p_r_ref, MESSAGE_AUDIOPATH, &newparam); + } /* set source interface */ param->setup.callerinfo.itype = p_callerinfo.itype; - param->setup.callerinfo.isdn_port = p_m_portnum; - SCPY(param->setup.callerinfo.interface, p_m_mISDNport->ifport->interface->name); + SCPY(param->setup.callerinfo.interface, interface->name); - ret = channel = hunt_bchannel(); - if (ret < 0) - goto no_channel; - - /* open channel */ - ret = seize_bchannel(channel, 1); - if (ret < 0) { - no_channel: - message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE); - message->param.disconnectinfo.cause = 34; - message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL; - message_put(message); - new_state(PORT_STATE_RELEASE); - delete this; - return; - } - bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE); - /* create endpoint */ if (p_epointlist) FATAL("Incoming call but already got an endpoint.\n"); if (!(epoint = new Endpoint(p_serial, 0))) FATAL("No memory for Endpoint instance\n"); - epoint->ep_app = new_endpointapp(epoint, 0, p_m_mISDNport->ifport->interface->app); //incoming + epoint->ep_app = new_endpointapp(epoint, 0, interface->app); //incoming epointlist_new(epoint->ep_serial); - } + /* FALL THROUGH: */ + default: + if (message_type == MESSAGE_CONNECT) + new_state(PORT_STATE_CONNECT); + /* cannot just forward, because param is not of container "struct lcr_msg" */ + message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, message_type); + memcpy(&message->param, param, sizeof(message->param)); + message_put(message); - /* set serial on bchannel message - * also ref is given, so we send message with ref */ - if (message_type == MESSAGE_BCHANNEL) { - int i = p_m_b_index; - unsigned int portid = (mISDNloop.port<<8) + i+1+(i>=15); - switch (param->bchannel.type) { - case BCHANNEL_REQUEST: - p_m_r_handle = portid; - message_bchannel_to_remote(p_m_r_remote_id, p_m_r_ref, BCHANNEL_ASSIGN, portid, 0, 0, 0, 0, 0, 0, 1); - chan_trace_header(p_m_mISDNport, this, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE); - add_trace("type", NULL, "assign"); - add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff); - end_trace(); - break; - case BCHANNEL_RELEASE: - p_m_r_handle = 0; - message_bchannel_to_remote(p_m_r_remote_id, p_m_r_ref, BCHANNEL_REMOVE, portid, 0, 0, 0, 0, 0, 0, 1); - chan_trace_header(p_m_mISDNport, this, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE); - add_trace("type", NULL, "remove"); - add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff); - end_trace(); - break; + if (message_type == MESSAGE_RELEASE) { + new_state(PORT_STATE_RELEASE); + delete this; + return; } - return; - } - - /* cannot just forward, because param is not of container "struct lcr_msg" */ - message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, message_type); - memcpy(&message->param, param, sizeof(message->param)); - message_put(message); - - if (message_type == MESSAGE_RELEASE) { - new_state(PORT_STATE_RELEASE); - delete this; - return; } } -/* select free bchannel from loopback interface */ -int Premote::hunt_bchannel(void) +/* receive from remote Port instance */ +int Premote::bridge_rx(unsigned char *data, int len) { - return loop_hunt_bchannel(this, p_m_mISDNport); + union parameter newparam; + int l; + + /* don't send tones, if not enabled or not connected */ + if (!p_r_tones + && p_state != PORT_STATE_CONNECT) + return 0; + + memset(&newparam, 0, sizeof(union parameter)); + /* split, if exeeds data size */ + while(len) { + l = (len > (int)sizeof(newparam.traffic.data)) ? sizeof(newparam.traffic.data) : len; + newparam.traffic.len = l; + len -= l; + memcpy(newparam.traffic.data, data, l); + data += l; + admin_message_from_lcr(p_r_remote_id, p_r_ref, MESSAGE_TRAFFIC, &newparam); + } + + return 0; } - diff --git a/remote.h b/remote.h index f39245b..eba9b2c 100644 --- a/remote.h +++ b/remote.h @@ -1,20 +1,21 @@ /* GSM port class */ -class Premote : public PmISDN +class Premote : public Port { public: - Premote(int type, struct mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive, int mode, int remote_id); + Premote(int type, char *portname, struct port_settings *settings, struct interface *interface, int remote_id); ~Premote(); - unsigned int p_m_r_ref; - int p_m_r_remote_id; /* remote instance (socket) */ - char p_m_r_remote_app[32]; - unsigned int p_m_r_handle; /* 0, if no bchannel is exported */ + unsigned int p_r_ref; + int p_r_remote_id; /* remote instance (socket) */ + char p_r_remote_app[32]; + char p_r_interface_name[64]; + int p_r_tones; int message_epoint(unsigned int epoint_id, int message_id, union parameter *param); void message_remote(int message_type, union parameter *param); - int hunt_bchannel(void); + int bridge_rx(unsigned char *data, int len); }; diff --git a/route.c b/route.c index 5b42f58..c57de22 100644 --- a/route.c +++ b/route.c @@ -251,7 +251,7 @@ struct param_defs param_defs[] = { struct action_defs action_defs[] = { { ACTION_EXTERNAL, "extern", &EndpointAppPBX::action_init_call, &EndpointAppPBX::action_dialing_external, &EndpointAppPBX::action_hangup_call, - PARAM_CONNECT | PARAM_PREFIX | PARAM_COMPLETE | PARAM_TYPE | PARAM_CAPA | PARAM_BMODE | PARAM_INFO1 | PARAM_HLC | PARAM_EXTHLC | PARAM_PRESENT | PARAM_INTERFACES | PARAM_CALLERID | PARAM_CALLERIDTYPE | PARAM_KEYPAD | PARAM_TIMEOUT, + PARAM_CONNECT | PARAM_PREFIX | PARAM_COMPLETE | PARAM_TYPE | PARAM_CAPA | PARAM_BMODE | PARAM_INFO1 | PARAM_HLC | PARAM_EXTHLC | PARAM_PRESENT | PARAM_INTERFACES | PARAM_CALLERID | PARAM_CALLERIDTYPE | PARAM_KEYPAD | PARAM_CONTEXT | PARAM_TIMEOUT, "Call is routed to extern number as dialed."}, { ACTION_INTERNAL, "intern", &EndpointAppPBX::action_init_call, &EndpointAppPBX::action_dialing_internal, &EndpointAppPBX::action_hangup_call, @@ -261,10 +261,6 @@ struct action_defs action_defs[] = { "outdial", &EndpointAppPBX::action_init_call, &EndpointAppPBX::action_dialing_external, &EndpointAppPBX::action_hangup_call, PARAM_CONNECT | PARAM_PREFIX | PARAM_COMPLETE | PARAM_TYPE | PARAM_CAPA | PARAM_BMODE | PARAM_INFO1 | PARAM_HLC | PARAM_EXTHLC | PARAM_PRESENT | PARAM_INTERFACES | PARAM_CALLERID | PARAM_CALLERIDTYPE | PARAM_KEYPAD | PARAM_TIMEOUT, "Same as 'extern'"}, - { ACTION_REMOTE, - "remote", &EndpointAppPBX::action_init_remote, &EndpointAppPBX::action_dialing_remote, &EndpointAppPBX::action_hangup_call, - PARAM_CONNECT | PARAM_APPLICATION | PARAM_CONTEXT | PARAM_EXTEN | PARAM_TIMEOUT, - "Call is routed to Remote application, like Asterisk."}, { ACTION_VBOX_RECORD, "vbox-record",&EndpointAppPBX::action_init_call, &EndpointAppPBX::action_dialing_vbox_record, &EndpointAppPBX::action_hangup_call, PARAM_CONNECT | PARAM_EXTENSION | PARAM_ANNOUNCEMENT | PARAM_TIMEOUT, @@ -2409,14 +2405,6 @@ struct route_action action_internal = { 0, }; -struct route_action action_remote = { - NULL, - NULL, - ACTION_REMOTE, - 0, - 0, -}; - struct route_action action_vbox = { NULL, NULL, diff --git a/route.h b/route.h index 1606410..c6ca347 100644 --- a/route.h +++ b/route.h @@ -156,36 +156,35 @@ enum { /* defines when a statement should be executed */ #define ACTION_EXTERNAL 0 #define ACTION_INTERNAL 1 #define ACTION_OUTDIAL 2 -#define ACTION_REMOTE 3 -#define ACTION_VBOX_RECORD 4 -#define ACTION_PARTYLINE 5 -#define ACTION_LOGIN 6 -#define ACTION_CALLERID 7 -#define ACTION_CALLERIDNEXT 8 -#define ACTION_FORWARD 9 -#define ACTION_REDIAL 10 -#define ACTION_REPLY 11 -#define ACTION_POWERDIAL 12 -#define ACTION_CALLBACK 13 -#define ACTION_ABBREV 14 -#define ACTION_TEST 15 -#define ACTION_PLAY 16 -#define ACTION_VBOX_PLAY 17 -#define ACTION_CALCULATOR 18 -#define ACTION_TIMER 19 -#define ACTION_GOTO 20 -#define ACTION_MENU 21 -#define ACTION_DISCONNECT 22 -#define ACTION_RELEASE 23 -#define ACTION_DEFLECT 24 -#define ACTION_SETFORWARD 25 -#define ACTION_EXECUTE 26 -#define ACTION_FILE 27 -#define ACTION_PICK 28 -#define ACTION_PASSWORD 29 -#define ACTION_PASSWORD_WRITE 30 -#define ACTION_NOTHING 31 -#define ACTION_EFI 32 +#define ACTION_VBOX_RECORD 3 +#define ACTION_PARTYLINE 4 +#define ACTION_LOGIN 5 +#define ACTION_CALLERID 6 +#define ACTION_CALLERIDNEXT 7 +#define ACTION_FORWARD 8 +#define ACTION_REDIAL 9 +#define ACTION_REPLY 10 +#define ACTION_POWERDIAL 11 +#define ACTION_CALLBACK 12 +#define ACTION_ABBREV 13 +#define ACTION_TEST 14 +#define ACTION_PLAY 15 +#define ACTION_VBOX_PLAY 16 +#define ACTION_CALCULATOR 17 +#define ACTION_TIMER 18 +#define ACTION_GOTO 19 +#define ACTION_MENU 20 +#define ACTION_DISCONNECT 21 +#define ACTION_RELEASE 22 +#define ACTION_DEFLECT 23 +#define ACTION_SETFORWARD 24 +#define ACTION_EXECUTE 25 +#define ACTION_FILE 26 +#define ACTION_PICK 27 +#define ACTION_PASSWORD 28 +#define ACTION_PASSWORD_WRITE 29 +#define ACTION_NOTHING 30 +#define ACTION_EFI 31 struct route_cond { /* an item */ struct route_cond *next; /* next entry */ diff --git a/socket_server.c b/socket_server.c index cb3b293..0f7f6d0 100644 --- a/socket_server.c +++ b/socket_server.c @@ -76,23 +76,17 @@ int admin_init(void) /* * free connection - * also releases all remote joins */ void free_connection(struct admin_list *admin) { struct admin_queue *response; void *temp; -#ifdef WITH_MISDN union parameter param; - class Join *join, *joinnext; - struct mISDNport *mISDNport; - int i, ii; class Port *port, *portnext; class Premote *remote; -#endif struct admin_list **adminp; - /* free remote joins */ + /* free remote ports */ if (admin->remote_name[0]) { start_trace(-1, NULL, @@ -104,45 +98,13 @@ void free_connection(struct admin_list *admin) "REMOTE APP release"); add_trace("app", "name", "%s", admin->remote_name); end_trace(); -#ifdef WITH_MISDN - /* release all exported channels */ - mISDNport = mISDNport_first; - while(mISDNport) { - i = 0; - ii = mISDNport->b_num; - while(i < ii) { - if (mISDNport->b_remote_id[i] == admin->sock) { - mISDNport->b_state[i] = B_STATE_IDLE; - unsched_timer(&mISDNport->b_timer[i]); - mISDNport->b_remote_id[i] = 0; - mISDNport->b_remote_ref[i] = 0; - } - i++; - } - mISDNport = mISDNport->next; - } -#endif -#ifdef WITH_MISDN - /* release join */ - join = join_first; - while(join) { - joinnext = join->next; - if (join->j_type==JOIN_TYPE_REMOTE) if (((class JoinRemote *)join)->j_remote_id == admin->sock) { - memset(¶m, 0, sizeof(param)); - param.disconnectinfo.cause = CAUSE_OUTOFORDER; - param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL; - ((class JoinRemote *)join)->message_remote(MESSAGE_RELEASE, ¶m); - /* join is now destroyed, so we go to next join */ - } - join = joinnext; - } /* release remote port */ port = port_first; while(port) { portnext = port->next; if ((port->p_type & PORT_CLASS_MASK) == PORT_CLASS_REMOTE) { remote = (class Premote *) port; - if (remote->p_m_r_remote_id == admin->sock) { + if (remote->p_r_remote_id == admin->sock) { memset(¶m, 0, sizeof(param)); param.disconnectinfo.cause = CAUSE_OUTOFORDER; param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL; @@ -152,7 +114,6 @@ void free_connection(struct admin_list *admin) } port = portnext; } -#endif } if (admin->sock >= 0) { @@ -290,9 +251,6 @@ int admin_route(struct admin_queue **responsep) case ACTION_EXTERNAL: apppbx->e_action = &action_external; break; - case ACTION_REMOTE: - apppbx->e_action = &action_remote; - break; case ACTION_VBOX_RECORD: apppbx->e_action = &action_vbox; break; @@ -617,13 +575,9 @@ void admin_call_response(int adminid, int message, const char *connected, int ca */ int admin_message_to_lcr(struct admin_msg *msg, struct admin_list *admin) { -#ifdef WITH_MISDN - struct mISDNport *mISDNport; class Port *port; class Premote *remote = NULL; /* make GCC happy */ - class Join *join; - class JoinRemote *joinremote = NULL; /* make GCC happy */ -#endif + struct interface *interface; struct admin_list *temp; /* hello message */ @@ -664,104 +618,52 @@ int admin_message_to_lcr(struct admin_msg *msg, struct admin_list *admin) return(-1); } -#ifdef WITH_MISDN /* new join. the reply (NEWREF assignment) is sent from constructor */ if (msg->type == MESSAGE_NEWREF) { - if (msg->param.newref.mode) { - char name[32]; - /* find remote port */ - mISDNport = mISDNport_first; - while(mISDNport) { - if (mISDNport->ifport->remote && !strcmp(mISDNport->ifport->remote_app, admin->remote_name)) - break; - mISDNport = mISDNport->next; - } - if (!mISDNport) { - union parameter param; - - /* create new join instance */ - join = joinremote = new JoinRemote(0, admin->remote_name, admin->sock); // must have no serial, because no endpoint is connected - if (!join) { - FATAL("No memory for remote join instance\n"); - return(-1); - } - memset(¶m, 0, sizeof(union parameter)); - param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL; - param.disconnectinfo.cause = CAUSE_RESSOURCEUNAVAIL; - admin_message_from_lcr(joinremote->j_remote_id, joinremote->j_remote_ref, MESSAGE_RELEASE, ¶m); - return 0; - } - /* creating port object, transparent until setup with hdlc */ - SPRINT(name, "%s-%s-in", mISDNport->ifport->interface->name, mISDNport->ifport->remote_app); - if (!(remote = new Premote(PORT_TYPE_REMOTE_IN, mISDNport, name, NULL, 0, 0, B_MODE_TRANSPARENT, admin->sock))) - - FATAL("Cannot create Port instance.\n"); - } else { - /* create new join instance */ - join = new JoinRemote(0, admin->remote_name, admin->sock); // must have no serial, because no endpoint is connected - if (!join) { - FATAL("No memory for remote join instance\n"); - return(-1); - } + char name[32]; + /* find remote port */ + interface = interface_first; + while(interface) { + if (interface->remote && !strcmp(interface->remote_app, admin->remote_name)) + break; + interface = interface->next; } - return(0); - } -#endif + if (!interface) { + union parameter param; -#ifdef WITH_MISDN - /* bchannel message - * no ref given for *_ack */ - if (msg->type == MESSAGE_BCHANNEL) - if (msg->param.bchannel.type == BCHANNEL_ASSIGN_ACK - || msg->param.bchannel.type == BCHANNEL_REMOVE_ACK - || msg->param.bchannel.type == BCHANNEL_RELEASE) { - /* no ref, but address */ - message_bchannel_from_remote(NULL, msg->param.bchannel.type, msg->param.bchannel.handle); + memset(¶m, 0, sizeof(union parameter)); + param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL; + param.disconnectinfo.cause = CAUSE_RESSOURCEUNAVAIL; + admin_message_from_lcr(admin->sock, 0, MESSAGE_RELEASE, ¶m); + return 0; + } + /* creating port object, transparent until setup with hdlc */ + SPRINT(name, "%s-%s-in", interface->name, interface->remote_app); + if (!(remote = new Premote(PORT_TYPE_REMOTE_IN, name, NULL, interface, admin->sock))) + + FATAL("Cannot create Port instance.\n"); return(0); } -#endif - + /* check for ref */ if (!msg->ref) { PERROR("Remote application did not send us a valid ref with a message.\n"); return(-1); } -#ifdef WITH_MISDN - /* find join instance */ - join = join_first; - while(join) { - if (join->j_type == JOIN_TYPE_REMOTE) { - joinremote = (class JoinRemote *)join; - if (joinremote->j_remote_ref == msg->ref) - break; - } - join = join->next; - } - if (join) { - if (admin->sock != joinremote->j_remote_id) { - PERROR("Ref %d belongs to remote application %s, but not to sending application %s.\n", msg->ref, joinremote->j_remote_name, admin->remote_name); - return(-1); - } - /* send message */ - joinremote->message_remote(msg->type, &msg->param); - - return(0); - } - /* find port instance */ port = port_first; while(port) { if ((port->p_type & PORT_CLASS_mISDN_MASK) == PORT_CLASS_REMOTE) { remote = (class Premote *) port; - if (remote->p_m_r_ref == msg->ref) + if (remote->p_r_ref == msg->ref) break; } port = port->next; } if (port) { - if (admin->sock != remote->p_m_r_remote_id) { - PERROR("Ref %d belongs to remote application %s, but not to sending application %s.\n", msg->ref, remote->p_m_r_remote_app, admin->remote_name); + if (admin->sock != remote->p_r_remote_id) { + PERROR("Ref %d belongs to remote application %s, but not to sending application %s.\n", msg->ref, remote->p_r_remote_app, admin->remote_name); return(-1); } @@ -770,7 +672,6 @@ int admin_message_to_lcr(struct admin_msg *msg, struct admin_list *admin) return(0); } -#endif PDEBUG(DEBUG_LOG, "No remote instance found with ref %d. (May have been already released.)\n", msg->ref); return(0); @@ -1058,9 +959,6 @@ int admin_state(struct admin_queue **responsep) /* partyline */ if (join->j_type == JOIN_TYPE_PBX) response->am[num].u.j.partyline = ((class JoinPBX *)join)->j_partyline; - /* remote application */ - if (join->j_type == JOIN_TYPE_REMOTE) - SCPY(response->am[num].u.j.remote, ((class JoinRemote *)join)->j_remote_name); /* */ join = join->next; num++; @@ -1388,24 +1286,3 @@ int admin_handle_con(struct lcr_fd *fd, unsigned int what, void *instance, int i return 0; } -void message_bchannel_to_remote(unsigned int remote_id, unsigned int ref, int type, unsigned int handle, int tx_gain, int rx_gain, char *pipeline, unsigned char *crypt, int crypt_len, int crypt_type, int isloopback) -{ - union parameter param; - - memset(¶m, 0, sizeof(union parameter)); - param.bchannel.isloopback = isloopback; - param.bchannel.type = type; - param.bchannel.handle = handle; - param.bchannel.tx_gain = tx_gain; - param.bchannel.rx_gain = rx_gain; - if (pipeline) - SCPY(param.bchannel.pipeline, pipeline); - if (crypt_len) - memcpy(param.bchannel.crypt, crypt, crypt_len); - param.bchannel.crypt_type = crypt_type; - if (admin_message_from_lcr(remote_id, ref, MESSAGE_BCHANNEL, ¶m)<0) { - PERROR("No socket with remote id %d found, this happens, if the socket is closed before all bchannels are imported.\n", remote_id); - return; - } -} - diff --git a/socket_server.h b/socket_server.h index 9a31b10..cc3565d 100644 --- a/socket_server.h +++ b/socket_server.h @@ -35,7 +35,6 @@ void admin_cleanup(void); void admin_call_response(int adminid, int message, const char *connected, int cause, int location, int notify); int admin_message_to_lcr(struct admin_message *msg, int remote_id); int admin_message_from_lcr(int remote_id, unsigned int ref, int message_type, union parameter *param); -void message_bchannel_to_remote(unsigned int remote_id, unsigned int ref, int type, unsigned int handle, int tx_gain, int rx_gain, char *pipeline, unsigned char *crypt, int crypt_len, int crypt_type, int isloopback);