From: Super User Date: Wed, 27 Jun 2007 06:23:50 +0000 (+0200) Subject: backup X-Git-Url: http://git.eversberg.eu/gitweb.cgi?p=lcr.git;a=commitdiff_plain;h=e9daaa4ef7ee895e6a8610ebb2166cc99c891a4e backup --- diff --git a/admin_client.c b/admin_client.c index 7e0e603..82b21e9 100644 --- a/admin_client.c +++ b/admin_client.c @@ -26,9 +26,9 @@ #include "admin.h" #include "cause.h" -#define LTEE {addch(ACS_LTEE);addch(ACS_HLINE);addch(ACS_HLINE);} -#define LLCORNER {addch(ACS_LLCORNER);addch(ACS_HLINE);addch(ACS_HLINE);} -#define VLINE {addch(ACS_VLINE);addstr(" ");} +#define LTEE {addch(/*ACS_LTEE*/'t');addch(/*ACS_HLINE*/'q');addch(/*ACS_HLINE*/'q');} +#define LLCORNER {addch(/*ACS_LLCORNER*/'m');addch(/*ACS_HLINE*/'q');addch(/*ACS_HLINE*/'q');} +#define VLINE {addch(/*ACS_VLINE*/'x');addstr(" ");} #define EMPTY {addstr(" ");} //char rotator[] = {'-', '\\', '|', '/'}; int lastlines, lastcols; @@ -485,8 +485,7 @@ char *admin_state(int sock) } off=0; readagain: - if ((len = read(sock, ((unsigned char *)(m))+off, - num*sizeof(struct admin_message)-off)) != num*sizeof(struct admin_message)-off) + if ((len = read(sock, ((unsigned char *)(m))+off, num*sizeof(struct admin_message)-off)) != num*(int)sizeof(struct admin_message)-off) { if (len <= 0) { free(m); @@ -494,7 +493,7 @@ readagain: cleanup_curses(); return("Broken pipe while receiving state infos."); } - if (len < num*sizeof(struct admin_message)) + if (len < num*(int)sizeof(struct admin_message)) { off+=len; goto readagain; @@ -906,7 +905,7 @@ readagain: { move(line++>1?line-1:1, 0); color(blue); - hline(ACS_HLINE, COLS); + hline(/*ACS_HLINE*/'q', COLS); color(white); l = logcur-(LINES-line-2); @@ -947,7 +946,7 @@ readagain: /* displeay head line */ move(1, 0); color(blue); - hline(ACS_HLINE, COLS); + hline(/*ACS_HLINE*/'q', COLS); if (offset) { move(1, 1); @@ -958,7 +957,7 @@ readagain: /* display end */ move(LINES-2, 0); color(white); - hline(ACS_HLINE, COLS); + hline(/*ACS_HLINE*/'q', COLS); move(LINES-1, 0); color(white); SPRINT(buffer, "i = interfaces '%s' c = calls '%s' l = log q = quit +/- = scroll", text_interfaces[show_interfaces], text_calls[show_calls]); @@ -1221,13 +1220,8 @@ char *admin_trace(int sock, int argc, char *argv[]) printf("All given filter values must match. If no filter is given, anything matches.\n\n"); printf("Filters:\n"); printf(" category=\n"); - printf(" 0x01 = L1: layer 1 trace (application view)\n"); - printf(" 0x02 = L2: layer 2 trace (application view)\n"); - printf(" 0x04 = L3: layer 3 trace (application view)\n"); - printf(" 0x08 = CH: channel selection trace\n"); - printf(" 0x10 = EP: endpoint trace\n"); - printf(" 0x20 = AP: application trace\n"); - printf(" 0x40 = RO: routing trace\n"); + printf(" 0x01 = CH: channel object trace\n"); + printf(" 0x02 = EP: endpoint object trace\n"); printf(" port= select only given port for trace\n"); printf(" interface= select only given interface for trace\n"); printf(" caller= select only given caller id for trace\n"); diff --git a/admin_server.c b/admin_server.c index 9ccc18e..756376f 100644 --- a/admin_server.c +++ b/admin_server.c @@ -254,7 +254,14 @@ int admin_route(struct admin_queue **responsep) apppbx->e_callback = 0; apppbx->e_action = NULL; apppbx->release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); - printlog("%3d endpoint ADMIN Kicking due to reload of routing.\n", apppbx->ea_endpoint->ep_serial); + start_trace(0, + NULL, + nationalize(apppbx->e_callerinfo.id, apppbx->e_callerinfo.ntype), + apppbx->e_dialinginfo.number, + DIRECTION_NONE, + CATEGORY_EP, + apppbx->e_serial, + "KICK (reload routing)"); } apppbx->e_action_timeout = NULL; diff --git a/apppbx.cpp b/apppbx.cpp index ddfb2b0..d28ae87 100644 --- a/apppbx.cpp +++ b/apppbx.cpp @@ -140,18 +140,20 @@ EndpointAppPBX::~EndpointAppPBX(void) */ void EndpointAppPBX::trace_header(char *name, int direction) { - char msgtext[sizeof(trace.name)]; + struct trace _trace; + + char msgtext[sizeof(_trace.name)]; SCPY(msgtext, name); /* init trace with given values */ - start_trace(e_serial, + start_trace(ea_endpoint->ep_serial, NULL, - nationalize(e_callerinfo.id, e_callerinfo.ntype), + numberrize_callerinfo(e_callerinfo.id, e_callerinfo.ntype), e_dialinginfo.number, direction, CATEGORY_EP, - e_serial, + ea_endpoint->ep_serial, msgtext); } @@ -181,6 +183,10 @@ void EndpointAppPBX::new_state(int state) void EndpointAppPBX::screen(int out, char *id, int idsize, int *type, int *present) { struct interface *interface; + char *msn1; + struct interface_msn *ifmsn; + struct interface_screen *ifscreen; + char suffix[64]; interface = interface_first; while(interface) @@ -191,7 +197,6 @@ void EndpointAppPBX::screen(int out, char *id, int idsize, int *type, int *prese } interface = interface->next; } -add logging if (interface) { /* screen incoming caller id */ @@ -200,38 +205,50 @@ add logging /* check for MSN numbers, use first MSN if no match */ msn1 = NULL; ifmsn = interface->ifmsn; - while(ifmns) + while(ifmsn) { if (!msn1) - msn1 = ifmns->msn; - if (!strcmp(ifmns->mns, id)) + msn1 = ifmsn->msn; + if (!strcmp(ifmsn->msn, id)) { break; } ifmsn = ifmsn->next; } - if (!ifmns && mns1) // not in list, first msn given + if (ifmsn) + { + trace_header("SCREEN (found in list)", DIRECTION_IN); + add_trace("msn", NULL, "%s", id); + end_trace(); + } + if (!ifmsn && msn1) // not in list, first msn given + { + trace_header("SCREEN (not found in list)", DIRECTION_IN); + add_trace("msn", "given", "%s", id); + add_trace("msn", "used", "%s", msn1); + end_trace(); UNCPY(id, msn1, idsize); - id[idsize-1] = '\0'; + id[idsize-1] = '\0'; + } } /* check screen list */ if (out) - iscreen = interface->ifscreen_out; + ifscreen = interface->ifscreen_out; else - iscreen = interface->ifscreen_in; + ifscreen = interface->ifscreen_in; while (ifscreen) { - if (ifcreen->match_type==-1 || ifscreen->match_type==*type) - if (ifcreen->match_present==-1 || ifscreen->match_present==*present) + if (ifscreen->match_type==-1 || ifscreen->match_type==*type) + if (ifscreen->match_present==-1 || ifscreen->match_present==*present) { - if (strchr(ifcreen->match_id,'%')) + if (strchr(ifscreen->match,'%')) { - if (!strncmp(ifscreen->match_id, id, strchr(ifscreen->match_id,'%')-ifscreen->match_id)) + if (!strncmp(ifscreen->match, id, strchr(ifscreen->match,'%')-ifscreen->match)) break; } else { - if (!strcmp(ifscreen->match_id, id)) + if (!strcmp(ifscreen->match, id)) break; } } @@ -239,26 +256,88 @@ add logging } if (ifscreen) // match { - if (ifscren->result_type != -1) + trace_header("SCREEN (found in list)", out?DIRECTION_OUT:DIRECTION_IN); + switch(*type) + { + case INFO_NTYPE_UNKNOWN: + add_trace("given", "type", "unknown"); + break; + case INFO_NTYPE_SUBSCRIBER: + add_trace("given", "type", "subscriber"); + break; + case INFO_NTYPE_NATIONAL: + add_trace("given", "type", "national"); + break; + case INFO_NTYPE_INTERNATIONAL: + add_trace("given", "type", "international"); + break; + } + switch(*present) + { + case INFO_PRESENT_ALLOWED: + add_trace("given", "present", "allowed"); + break; + case INFO_PRESENT_RESTRICTED: + add_trace("given", "present", "restricted"); + break; + case INFO_PRESENT_NOTAVAIL: + add_trace("given", "present", "not available"); + break; + } + add_trace("given", "id", "%s", id[0]?id:""); + if (ifscreen->result_type != -1) + { *type = ifscreen->result_type; - if (ifscren->result_present != -1) + switch(*type) + { + case INFO_NTYPE_UNKNOWN: + add_trace("used", "type", "unknown"); + break; + case INFO_NTYPE_SUBSCRIBER: + add_trace("used", "type", "subscriber"); + break; + case INFO_NTYPE_NATIONAL: + add_trace("used", "type", "national"); + break; + case INFO_NTYPE_INTERNATIONAL: + add_trace("used", "type", "international"); + break; + } + } + if (ifscreen->result_present != -1) + { *present = ifscreen->result_present; - if (strchr(ifscreen->match_id,'%')) + switch(*present) + { + case INFO_PRESENT_ALLOWED: + add_trace("used", "present", "allowed"); + break; + case INFO_PRESENT_RESTRICTED: + add_trace("used", "present", "restricted"); + break; + case INFO_PRESENT_NOTAVAIL: + add_trace("used", "present", "not available"); + break; + } + } + if (strchr(ifscreen->match,'%')) { - SCPY(suffix, strchr(ifscreen->match_id,'%') - ifscreen->match_id + id); - UNCPY(id, ifscreen->result_id); + SCPY(suffix, strchr(ifscreen->match,'%') - ifscreen->match + id); + UNCPY(id, ifscreen->result, idsize); id[idsize-1] = '\0'; - if (strchr(ifscreen->result_id,'%')) + if (strchr(ifscreen->result,'%')) { - *strchr(ifscreen->result_id,'%') = '\0'; + *strchr(ifscreen->result,'%') = '\0'; UNCAT(id, suffix, idsize); id[idsize-1] = '\0'; } } else { - UNCPY(id, ifscreen->result_id, idsize); + UNCPY(id, ifscreen->result, idsize); id[idsize-1] = '\0'; } + add_trace("used", "id", "%s", id[0]?id:""); + end_trace(); } } } @@ -388,18 +467,18 @@ void EndpointAppPBX::release(int release, int calllocation, int callcause, int p /* cancel callerid if restricted, unless anon-ignore is enabled at extension or port is of type external (so called police gets caller id :)*/ -void apply_callerid_restriction(int anon_ignore, int port_type, char *id, int *ntype, int *present, int *screen, char *voip, char *intern, char *name) +void apply_callerid_restriction(int anon_ignore, int port_type, char *id, int *ntype, int *present, int *screen, char *voip, char *extension, char *name) { - PDEBUG(DEBUG_EPOINT, "id='%s' ntype=%d present=%d screen=%d voip='%s' intern='%s' name='%s'\n", (id)?id:"NULL", (ntype)?*ntype:-1, (present)?*present:-1, (screen)?*screen:-1, (voip)?voip:"NULL", (intern)?intern:"NULL", (name)?name:"NULL"); + PDEBUG(DEBUG_EPOINT, "id='%s' ntype=%d present=%d screen=%d voip='%s' extension='%s' name='%s'\n", (id)?id:"NULL", (ntype)?*ntype:-1, (present)?*present:-1, (screen)?*screen:-1, (voip)?voip:"NULL", (extension)?extension:"NULL", (name)?name:"NULL"); /* caller id is not restricted, so we do nothing */ if (*present != INFO_PRESENT_RESTRICTED) return; /* only extensions are restricted */ - if (!intern) + if (!extension) return; - if (!intern[0]) + if (!extension[0]) return; /* if we enabled anonymouse ignore */ @@ -416,39 +495,39 @@ void apply_callerid_restriction(int anon_ignore, int port_type, char *id, int *n // maybe we should not make voip address anonymous // if (voip) // voip[0] = '\0'; -// maybe it's no fraud to present internal id -// if (intern) -// intern[0] = '\0'; +// maybe it's no fraud to present extension id +// if (extension) +// extension[0] = '\0'; if (name) name[0] = '\0'; } /* used display message to display callerid as available */ -char *EndpointAppPBX::apply_callerid_display(char *id, int itype, int ntype, int present, int screen, char *voip, char *intern, char *name) +char *EndpointAppPBX::apply_callerid_display(char *id, int itype, int ntype, int present, int screen, char *voip, char *extension, char *name) { static char display[81]; display[0] = '\0'; char *cid = numberrize_callerinfo(id, ntype); - PDEBUG(DEBUG_EPOINT, "EPOINT(%d) id='%s' itype=%d ntype=%d present=%d screen=%d voip='%s' intern='%s' name='%s'\n", ea_endpoint->ep_serial, (id)?id:"NULL", itype, ntype, present, screen, (voip)?voip:"NULL", (intern)?intern:"NULL", (name)?name:"NULL"); + PDEBUG(DEBUG_EPOINT, "EPOINT(%d) id='%s' itype=%d ntype=%d present=%d screen=%d voip='%s' extension='%s' name='%s'\n", ea_endpoint->ep_serial, (id)?id:"NULL", itype, ntype, present, screen, (voip)?voip:"NULL", (extension)?extension:"NULL", (name)?name:"NULL"); if (!id) id = ""; if (!voip) voip = ""; - if (!intern) - intern = ""; + if (!extension) + extension = ""; if (!name) name = ""; /* NOTE: is caller is is not available for this extesion, it has been removed by apply_callerid_restriction already */ /* internal extension's caller id */ - if (intern[0] && e_ext.display_int) + if (extension[0] && e_ext.display_int) { if (!display[0]) - SCAT(display, intern); + SCAT(display, extension); if (display[0]) SCAT(display, " "); if (itype == INFO_ITYPE_VBOX) @@ -458,7 +537,7 @@ char *EndpointAppPBX::apply_callerid_display(char *id, int itype, int ntype, int } /* external caller id */ - if (!intern[0] && !voip[0] && e_ext.display_ext) + if (!extension[0] && !voip[0] && e_ext.display_ext) { if (!display[0]) { @@ -686,9 +765,10 @@ void EndpointAppPBX::set_tone(struct port_list *portlist, char *tone) * if no ifname was given, any interface that is not an extension * will be searched. */ -static struct mISDNport *EndpointAppPBX::hunt_port(char *ifname, int *channel) +struct mISDNport *EndpointAppPBX::hunt_port(char *ifname, int *channel) { struct interface *interface; + struct interface_port *ifport, *ifport_start; struct mISDNport *mISDNport; interface = interface_first; @@ -696,7 +776,7 @@ static struct mISDNport *EndpointAppPBX::hunt_port(char *ifname, int *channel) /* first find the given interface or, if not given, one with no extension */ checknext: if (!interface) - return(null); + return(NULL); /* check for given interface */ if (ifname) @@ -1664,12 +1744,8 @@ void EndpointAppPBX::port_setup(struct port_list *portlist, int message_type, un memcpy(&e_capainfo, ¶m->setup.capainfo, sizeof(e_capainfo)); e_dtmf = param->setup.dtmf; - /* screen by interface */ - if (e_callerinfo.interface[0]) - { - /* screen incoming caller id */ - screen(0, e_callerinfo.id, sizeof(e_callerinfo.id), &e_callerinfo.ntype, &e_callerinfo.present); - } + /* screen incoming caller id */ + screen(0, e_callerinfo.id, sizeof(e_callerinfo.id), &e_callerinfo.ntype, &e_callerinfo.present); colp, outclip, outcolp /* process extension */ @@ -2206,12 +2282,8 @@ void EndpointAppPBX::port_connect(struct port_list *portlist, int message_type, e_start = now; - /* screen by interface */ - if (e_callerinfo.interface[0]) - { - /* screen incoming caller id */ - screen(0, e_connectinfo.id, sizeof(e_connectinfo.id), &e_connectinfo.ntype, &e_connectinfo.present); - } + /* screen incoming caller id */ + screen(0, e_connectinfo.id, sizeof(e_connectinfo.id), &e_connectinfo.ntype, &e_connectinfo.present); /* screen connected name */ if (e_ext.name[0]) @@ -3163,12 +3235,8 @@ void EndpointAppPBX::call_connect(struct port_list *portlist, int message_type, { message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_CONNECT); memcpy(&message->param, param, sizeof(union parameter)); - /* screen by interface */ - if (e_connectinfo.interface[0]) - { - /* screen incoming caller id */ - screen(1, e_connectinfo.id, sizeof(e_connectinfo.id), &e_connectinfo.ntype, &e_connectinfo.present); - } + /* screen incoming caller id */ + screen(1, e_connectinfo.id, sizeof(e_connectinfo.id), &e_connectinfo.ntype, &e_connectinfo.present); memcpy(&message->param.connnectinfo, e_connectinfo); /* screen clip if prefix is required */ @@ -3419,12 +3487,8 @@ void EndpointAppPBX::call_setup(struct port_list *portlist, int message_type, un memcpy(&e_redirinfo, ¶m->setup.redirinfo, sizeof(e_redirinfo)); memcpy(&e_capainfo, ¶m->setup.capainfo, sizeof(e_capainfo)); - /* screen by interface */ - if (e_callerinfo.interface[0]) - { - /* screen incoming caller id */ - screen(1, e_callerinfo.id, sizeof(e_callerinfo.id), &e_callerinfo.ntype, &e_callerinfo.present); - } + /* screen incoming caller id */ + screen(1, e_callerinfo.id, sizeof(e_callerinfo.id), &e_callerinfo.ntype, &e_callerinfo.present); /* process (voice over) data calls */ if (e_ext.datacall && e_capainfo.bearer_capa!=INFO_BC_SPEECH && e_capainfo.bearer_capa!=INFO_BC_AUDIO) diff --git a/apppbx.h b/apppbx.h index b9b40c0..d0ec28b 100644 --- a/apppbx.h +++ b/apppbx.h @@ -345,12 +345,14 @@ class EndpointAppPBX : public EndpointApp void message_disconnect_port(struct port_list *portlist, int cause, int location, char *display); void logmessage(struct message *messsage); + void trace_header(char *name, int direction); + void screen(int out, char *id, int idsize, int *type, int *present); }; char *nationalize_callerinfo(char *string, int *type); char *numberrize_callerinfo(char *string, int type); -void apply_callerid_restriction(int anon_ignore, int port_type, char *id, int *ntype, int *present, int *screen, char *h323, char *intern, char *name); +void apply_callerid_restriction(int anon_ignore, int port_type, char *id, int *ntype, int *present, int *screen, char *voip, char *intern, char *name); void send_mail(char *filename, char *callerid, char *callerintern, char *callername, char *vbox_email, int vbox_year, int vbox_mon, int vbox_mday, int vbox_hour, int vbox_min, char *terminal); diff --git a/dss1.cpp b/dss1.cpp index cbb622d..095f8ff 100644 --- a/dss1.cpp +++ b/dss1.cpp @@ -34,7 +34,7 @@ extern "C" { /* * constructor */ -Pdss1::Pdss1(int type, mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive) : PmISDN(type, mISDNport, portname, settings, channel, exclusive) +Pdss1::Pdss1(int type, struct mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive) : PmISDN(type, mISDNport, portname, settings, channel, exclusive) { p_callerinfo.itype = (mISDNport->ifport->interface->extension)?INFO_ITYPE_ISDN:INFO_ITYPE_ISDN_EXTENSION; p_m_d_ntmode = mISDNport->ntmode; @@ -136,126 +136,6 @@ msg_t *create_l2msg(int prim, int dinfo, int size) /* NT only */ exit(-1); } -/* isdn messaging */ -static struct isdn_message { - char *name; - unsigned long value; -} isdn_message[] = { - {"TIMEOUT", CC_TIMEOUT}, - {"SETUP", CC_SETUP}, - {"SETUP_ACK", CC_SETUP_ACKNOWLEDGE}, - {"PROCEEDING", CC_PROCEEDING}, - {"ALERTING", CC_ALERTING}, - {"CONNECT", CC_CONNECT}, - {"CONNECT RES", CC_CONNECT}, - {"CONNECT_ACK", CC_CONNECT_ACKNOWLEDGE}, - {"DISCONNECT", CC_DISCONNECT}, - {"RELEASE", CC_RELEASE}, - {"RELEASE_COMP", CC_RELEASE_COMPLETE}, - {"INFORMATION", CC_INFORMATION}, - {"PROGRESS", CC_PROGRESS}, - {"NOTIFY", CC_NOTIFY}, - {"SUSPEND", CC_SUSPEND}, - {"SUSPEND_ACK", CC_SUSPEND_ACKNOWLEDGE}, - {"SUSPEND_REJ", CC_SUSPEND_REJECT}, - {"RESUME", CC_RESUME}, - {"RESUME_ACK", CC_RESUME_ACKNOWLEDGE}, - {"RESUME_REJ", CC_RESUME_REJECT}, - {"HOLD", CC_HOLD}, - {"HOLD_ACK", CC_HOLD_ACKNOWLEDGE}, - {"HOLD_REJ", CC_HOLD_REJECT}, - {"RETRIEVE", CC_RETRIEVE}, - {"RETRIEVE_ACK", CC_RETRIEVE_ACKNOWLEDGE}, - {"RETRIEVE_REJ", CC_RETRIEVE_REJECT}, - {"FACILITY", CC_FACILITY}, - {"STATUS", CC_STATUS}, - {"RESTART", CC_RESTART}, - {"RELEASE_CR", CC_RELEASE_CR}, - {"NEW_CR", CC_NEW_CR}, - {"DL_ESTABLSIH", DL_ESTABLSIH}, - {"DL_RELEASE", DL_RELEASE}, - {"PH_ACTICATIE", PH_ACTICATIE}, - {"PH_DEACTICATIE", PH_DEACTICATIE}, - - {NULL, 0}, -}; - -static char *isdn_prim[4] = { - " REQUEST", - " CONFIRM", - " INDICATION", - " RESPONSE", -}; - - -/* - * isdn trace header - */ -void Pdss1::l1l2l3_trace_header(unsigned long prim, int direction_out) -{ - int i; - char msgtext[64] = "<>"; - - /* select message and primitive text */ - i = 0; - while(isdn_message[i].name) - { - if (isdn_message[i].value == (prim&0xffffff00)) - { - SCPY(msgtext, isdn_message[i].name); - break; - } - i++; - } - SCAT(msgtext, isdn_prim[prim&0x00000003]); - - /* add direction */ - if (direction && (prim&0xffffff00)!=CC_NEW_CR && (prim&0xffffff00)!=CC_RELEASE_CR) - { - if (p_m_ntmode) - { - if (direction == DIRECTION_OUT) - SCAT(msgtext, " N->U"); - else - SCAT(msgtext, " N<-U"); - } else - { - if (direction == DIRECTION_OUT) - SCAT(msgtext, " U->N"); - else - SCAT(msgtext, " U<-N"); - } - } - - /* init trace with given values */ - start_trace(p_m_mISDNport->portnum, - p_m_mISDNport->ifport->interface, - nationalize(p_callerinfo.id, p_callerinfo.ntype), - p_dialinginfo.number, - direction, - CATEGORY_L3, - p_serial, - msgtext); -} - - -void Pdss1::chan_trace_header(char *msgtext) -{ - int i; - - - /* init trace with given values */ - start_trace(p_m_mISDNport->portnum, - p_m_mISDNport->ifport->interface, - nationalize(p_callerinfo.id, p_callerinfo.ntype), - p_dialinginfo.number, - 0, - CATEGORY_L3, - p_serial, - msgtext); -} - - /* * if we received a first reply to the setup message, * we will check if we have now channel information @@ -282,7 +162,7 @@ int Pdss1::received_first_reply_to_setup(unsigned long prim, int channel, int ex if (p_state != PORT_STATE_OUT_SETUP) return(0); - chan_trace_header("CHANNEL SELECTION (first reply to setup)"); + chan_trace_header(p_m_mISDNport, this, "CHANNEL SELECTION (first reply to setup)", DIRECTION_NONE); add_trace("channel", "request", "%d (forced)", p_m_b_channel); add_trace("channel", "reply", (channel>=0)?"%d":"(none)", channel); @@ -300,7 +180,7 @@ int Pdss1::received_first_reply_to_setup(unsigned long prim, int channel, int ex end_trace(); /* activate our exclusive channel */ - bchannel_activate(p_m_mISDNport, p_m_b_index); + bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_ACTIVATE); } else if (p_m_b_channel) { @@ -310,7 +190,7 @@ int Pdss1::received_first_reply_to_setup(unsigned long prim, int channel, int ex if (p_state != PORT_STATE_OUT_SETUP) return(0); - chan_trace_header("CHANNEL SELECTION (first reply to setup)"); + chan_trace_header(p_m_mISDNport, this, "CHANNEL SELECTION (first reply to setup)", DIRECTION_NONE); add_trace("channel", "request", "%d (suggest)", p_m_b_channel); add_trace("channel", "reply", (channel>=0)?"%d":"(none)", channel); @@ -321,7 +201,7 @@ int Pdss1::received_first_reply_to_setup(unsigned long prim, int channel, int ex add_trace("connect", "channel", "%d", p_m_b_channel); end_trace(); p_m_b_exclusive = 1; // we are done - bchannel_activate(p_m_mISDNport, p_m_b_index); + bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_ACTIVATE); return(0); } @@ -348,7 +228,7 @@ int Pdss1::received_first_reply_to_setup(unsigned long prim, int channel, int ex end_trace(); /* activate channel given by remote */ - bchannel_activate(p_m_mISDNport, p_m_b_index); + bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_ACTIVATE); } else if (p_m_b_reserve) { @@ -358,7 +238,7 @@ int Pdss1::received_first_reply_to_setup(unsigned long prim, int channel, int ex if (p_state != PORT_STATE_OUT_SETUP) return(0); - chan_trace_header("CHANNEL SELECTION (first reply to setup)"); + chan_trace_header(p_m_mISDNport, this, "CHANNEL SELECTION (first reply to setup)", DIRECTION_NONE); add_trace("channel", "request", "any"); add_trace("channel", "reply", (channel>=0)?"%d":"(none)", channel); /* if no channel was replied */ @@ -384,7 +264,7 @@ int Pdss1::received_first_reply_to_setup(unsigned long prim, int channel, int ex end_trace(); /* activate channel given by remote */ - bchannel_activate(p_m_mISDNport, p_m_b_index); + bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_ACTIVATE); } else { /*** we sent 'no channel available' ***/ @@ -392,7 +272,7 @@ int Pdss1::received_first_reply_to_setup(unsigned long prim, int channel, int ex /* if not the first reply, but a connect, we are forced */ if (prim==(CC_CONNECT | INDICATION) && p_state!=PORT_STATE_OUT_SETUP) { - chan_trace_header("CHANNEL SELECTION (connect)"); + chan_trace_header(p_m_mISDNport, this, "CHANNEL SELECTION (connect)", DIRECTION_NONE); add_trace("channel", "request", "no-channel"); add_trace("channel", "reply", (channel>=0)?"%d%s":"(none)", channel, exclusive?" (forced)":""); if (channel > 0) @@ -413,7 +293,7 @@ int Pdss1::received_first_reply_to_setup(unsigned long prim, int channel, int ex p_m_b_exclusive = 1; // we are done /* activate channel given by remote */ - bchannel_activate(p_m_mISDNport, p_m_b_index); + bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_ACTIVATE); return(0); } @@ -421,7 +301,7 @@ int Pdss1::received_first_reply_to_setup(unsigned long prim, int channel, int ex if (p_state != PORT_STATE_OUT_SETUP) return(0); - chan_trace_header("CHANNEL SELECTION (first reply to setup)"); + chan_trace_header(p_m_mISDNport, this, "CHANNEL SELECTION (first reply to setup)", DIRECTION_NONE); add_trace("channel", "request", "no-channel"); add_trace("channel", "reply", (channel>=0)?"%d":"(none)", channel); /* if first reply has no channel, we are done */ @@ -448,15 +328,14 @@ int Pdss1::received_first_reply_to_setup(unsigned long prim, int channel, int ex p_m_b_exclusive = 1; // we are done /* activate channel given by remote */ - bchannel_activate(p_m_mISDNport, p_m_b_index); + bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_ACTIVATE); } return(0); channelerror: dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE, p_m_d_l3id, sizeof(RELEASE_COMPLETE_t), p_m_d_ntmode); - l1l2l3_trace_header(CC_RELEASE_COMPLETE | REQUEST, DIRECTION_OUT); - release_complete = (RELEASE_COMPLETE_t *)(dmsg->data + headerlen); + l1l2l3_trace_header(p_m_mISDNport, this, CC_RELEASE_COMPLETE | REQUEST, DIRECTION_OUT); enc_ie_cause(&release_complete->CAUSE, dmsg, (p_m_d_ntmode)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, -ret); end_trace(); msg_queue_tail(&p_m_mISDNport->downqueue, dmsg); @@ -467,6 +346,135 @@ int Pdss1::received_first_reply_to_setup(unsigned long prim, int channel, int ex /* + * hunt bchannel for incomming setup or retrieve or resume + */ +int Pdss1::hunt_bchannel(int channel, int exclusive) +{ + struct select_channel *selchannel; + struct interface_port *ifport = p_m_mISDNport->ifport; + int i; + + chan_trace_header(p_m_mISDNport, this, "CHANNEL SELECTION (setup)", DIRECTION_NONE); + if (exclusive<0) + exclusive = 0; + if (channel == CHANNEL_NO) + add_trace("channel", "request", "no-channel"); + else + add_trace("channel", "request", (channel>0)?"%d%s":"any", channel, exclusive?" (forced)":""); + if (channel==CHANNEL_NO && p_type==PORT_TYPE_DSS1_TE_IN) + { + add_trace("conclusion", NULL, "incoming call-waiting not supported for TE-mode"); + end_trace(); + return(-6); // channel unacceptable + } + if (channel <= 0) /* not given, no channel, whatever.. */ + channel = CHANNEL_ANY; /* any channel */ + if (p_m_mISDNport->b_reserved >= p_m_mISDNport->b_num) // of out chan.. + { + add_trace("channel", "reserved", "%d", p_m_mISDNport->b_reserved); + add_trace("conclusion", NULL, "all channels are reserved"); + end_trace(); + return(-34); // no channel + } + if (channel == CHANNEL_ANY) + goto get_from_list; + if (channel > 0) + { + /* check for given channel in selection list */ + selchannel = ifport->in_channel; + while(selchannel) + { + if (selchannel->channel == channel || selchannel->channel == CHANNEL_FREE) + break; + selchannel = selchannel->next; + } + if (!selchannel) + channel = 0; + + /* exclusive channel requests must be in the list */ + if (exclusive) + { + if (!channel) + { + add_trace("conclusion", NULL, "exclusively requested channel not in list"); + end_trace(); + return(-6); // channel unacceptable + } + i = selchannel->channel-1-(selchannel->channel>=17); + if (p_m_mISDNport->b_port[i] == NULL) + goto use_channel; + add_trace("conclusion", NULL, "exclusively requested channel is busy"); + end_trace(); + return(-6); // channel unacceptable + } + + /* requested channels in list will be used */ + if (channel) + { + i = selchannel->channel-1-(selchannel->channel>=17); + if (p_m_mISDNport->b_port[i] == NULL) + goto use_channel; + } + + /* if channel is not available or not in list, it must be searched */ + get_from_list: + /* check for first free channel in list */ + channel = 0; + selchannel = ifport->in_channel; + while(selchannel) + { + switch(selchannel->channel) + { + case CHANNEL_FREE: /* free channel */ + add_trace("hunting", "channel", "free"); + if (p_m_mISDNport->b_reserved >= p_m_mISDNport->b_num) + break; /* all channel in use or reserverd */ + /* find channel */ + i = 0; + while(i < p_m_mISDNport->b_num) + { + if (p_m_mISDNport->b_port[i] == NULL) + { + channel = i+1+(i>=15); + break; + } + i++; + } + break; + + default: + add_trace("hunting", "channel", "%d", selchannel->channel); + if (selchannel->channel<1 || selchannel->channel==16) + break; /* invalid channels */ + i = selchannel->channel-1-(selchannel->channel>=17); + if (i >= p_m_mISDNport->b_num) + break; /* channel not in port */ + if (p_m_mISDNport->b_port[i] == NULL) + { + channel = selchannel->channel; + break; + } + break; + } + if (channel) + break; /* found channel */ + selchannel = selchannel->next; + } + if (!channel) + { + add_trace("conclusion", NULL, "no channel available"); + end_trace(); + return(-6); // channel unacceptable + } + } +use_channel: + add_trace("conclusion", NULL, "channel available"); + add_trace("connect", "channel", "%d", p_m_b_channel); + end_trace(); + return(channel); +} + +/* * handles all indications */ /* CC_SETUP INDICATION */ @@ -474,8 +482,11 @@ void Pdss1::setup_ind(unsigned long prim, unsigned long dinfo, void *data) { int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN; SETUP_t *setup = (SETUP_t *)((unsigned long)data + headerlen); - int type, plan, present, screen, reason; - int coding, capability, mode, rate, multi, user, presentation, interpretation, hlc, exthlc; + int calling_type, calling_plan, calling_present, calling_screen; + int called_type, called_plan; + int redir_type, redir_plan, redir_present, redir_screen, redir_reason; + int hlc_coding, hlc_presentation, hlc_interpretation, hlc_hlc, hlc_exthlc; + int bearer_coding, bearer_capability, bearer_mode, bearer_rate, bearer_multi, bearer_user; int exclusive, channel; int ret; msg_t *dmsg; @@ -494,7 +505,7 @@ void Pdss1::setup_ind(unsigned long prim, unsigned long dinfo, void *data) PERROR("fatal software error: l3-stack gives us a process id 0xff00-0xffff\n"); exit(-1); } - l1l2l3_trace_header(CC_NEW_CR | INDICATION, DIRECTION_IN); + l1l2l3_trace_header(p_m_mISDNport, this, CC_NEW_CR | INDICATION, DIRECTION_IN); if (p_m_d_l3id) add_trace("callref", "old", "0x%x", p_m_d_l3id); add_trace("callref", "new", "0x%x", dinfo); @@ -505,7 +516,7 @@ void Pdss1::setup_ind(unsigned long prim, unsigned long dinfo, void *data) p_m_d_ces = setup->ces; } - l1l2l3_trace_header(prim, DIRECTION_IN); + l1l2l3_trace_header(p_m_mISDNport, this, prim, DIRECTION_IN); dec_ie_calling_pn(setup->CALLING_PN, (Q931_info_t *)((unsigned long)data+headerlen), &calling_type, &calling_plan, &calling_present, &calling_screen, (unsigned char *)p_callerinfo.id, sizeof(p_callerinfo.id)); dec_ie_called_pn(setup->CALLED_PN, (Q931_info_t *)((unsigned long)data+headerlen), &called_type, &called_plan, (unsigned char *)p_dialinginfo.number, sizeof(p_dialinginfo.number)); dec_ie_keypad(setup->KEYPAD, (Q931_info_t *)((unsigned long)data+headerlen), (unsigned char *)keypad, sizeof(keypad)); @@ -518,8 +529,8 @@ void Pdss1::setup_ind(unsigned long prim, unsigned long dinfo, void *data) dec_ie_complete(setup->COMPLETE, (Q931_info_t *)((unsigned long)data+headerlen), &p_dialinginfo.sending_complete); dec_ie_redir_nr(setup->REDIR_NR, (Q931_info_t *)((unsigned long)data+headerlen), &redir_type, &redir_plan, &redir_present, &redir_screen, &redir_reason, (unsigned char *)p_redirinfo.id, sizeof(p_redirinfo.id)); dec_ie_channel_id(setup->CHANNEL_ID, (Q931_info_t *)((unsigned long)data+headerlen), &exclusive, &channel); - dec_ie_hlc(setup->HLC, (Q931_info_t *)((unsigned long)data+headerlen), &hlc_coding, &interpretation, &presentation, &hlc, &exthlc); - dec_ie_bearer(setup->BEARER, (Q931_info_t *)((unsigned long)data+headerlen), &bearer_coding, &capability, &mode, &rate, &multi, &user); + dec_ie_hlc(setup->HLC, (Q931_info_t *)((unsigned long)data+headerlen), &hlc_coding, &hlc_interpretation, &hlc_presentation, &hlc_hlc, &hlc_exthlc); + dec_ie_bearer(setup->BEARER, (Q931_info_t *)((unsigned long)data+headerlen), &bearer_coding, &bearer_capability, &bearer_mode, &bearer_rate, &bearer_multi, &bearer_user); end_trace(); /* if blocked, release call */ @@ -527,10 +538,9 @@ void Pdss1::setup_ind(unsigned long prim, unsigned long dinfo, void *data) { RELEASE_COMPLETE_t *release_complete; - printlog("--- port#%d is blocked.\n", mISDNport->ifport->portnum); dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE, dinfo, sizeof(RELEASE_COMPLETE_t), p_m_d_ntmode); - l1l2l3_trace_header(CC_RELEASE_COMPLETE | REQUEST, DIRECTION_OUT); release_complete = (RELEASE_COMPLETE_t *)(dmsg->data + headerlen); + l1l2l3_trace_header(p_m_mISDNport, this, CC_RELEASE_COMPLETE | REQUEST, DIRECTION_OUT); enc_ie_cause(&release_complete->CAUSE, dmsg, (p_m_d_ntmode)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, 27); /* temporary unavailable */ add_trace("reason", NULL, "port blocked"); end_trace(); @@ -541,7 +551,7 @@ void Pdss1::setup_ind(unsigned long prim, unsigned long dinfo, void *data) } /* caller info */ - switch (present) + switch (calling_present) { case 1: p_callerinfo.present = INFO_PRESENT_RESTRICTED; @@ -553,7 +563,7 @@ void Pdss1::setup_ind(unsigned long prim, unsigned long dinfo, void *data) p_callerinfo.present = INFO_PRESENT_ALLOWED; break; } - switch (screen) + switch (calling_screen) { case 0: p_callerinfo.screen = INFO_SCREEN_USER; @@ -562,7 +572,7 @@ void Pdss1::setup_ind(unsigned long prim, unsigned long dinfo, void *data) p_callerinfo.screen = INFO_SCREEN_NETWORK; break; } - switch (type) + switch (calling_type) { case -1: p_callerinfo.ntype = INFO_NTYPE_UNKNOWN; @@ -587,7 +597,7 @@ void Pdss1::setup_ind(unsigned long prim, unsigned long dinfo, void *data) /* dialing information */ SCAT(p_dialinginfo.number, (char *)keypad); - switch (type) + switch (called_type) { case 0x1: p_dialinginfo.ntype = INFO_NTYPE_INTERNATIONAL; @@ -602,7 +612,9 @@ void Pdss1::setup_ind(unsigned long prim, unsigned long dinfo, void *data) p_dialinginfo.ntype = INFO_NTYPE_UNKNOWN; break; } - switch (present) + + /* redir info */ + switch (redir_present) { case 1: p_redirinfo.present = INFO_PRESENT_RESTRICTED; @@ -614,7 +626,7 @@ void Pdss1::setup_ind(unsigned long prim, unsigned long dinfo, void *data) p_redirinfo.present = INFO_PRESENT_ALLOWED; break; } - switch (screen) + switch (redir_screen) { case 0: p_redirinfo.screen = INFO_SCREEN_USER; @@ -623,7 +635,7 @@ void Pdss1::setup_ind(unsigned long prim, unsigned long dinfo, void *data) p_redirinfo.screen = INFO_SCREEN_NETWORK; break; } - switch (reason) + switch (redir_reason) { case 1: p_redirinfo.reason = INFO_REDIR_BUSY; @@ -644,7 +656,7 @@ void Pdss1::setup_ind(unsigned long prim, unsigned long dinfo, void *data) p_redirinfo.reason = INFO_REDIR_UNKNOWN; break; } - switch (type) + switch (redir_type) { case -1: p_redirinfo.ntype = INFO_NTYPE_UNKNOWN; @@ -667,17 +679,17 @@ void Pdss1::setup_ind(unsigned long prim, unsigned long dinfo, void *data) p_redirinfo.isdn_port = p_m_portnum; /* bearer capability */ - switch (capability) + switch (bearer_capability) { case -1: p_capainfo.bearer_capa = INFO_BC_AUDIO; - user = (options.law=='a')?3:2; + bearer_user = (options.law=='a')?3:2; break; default: - p_capainfo.bearer_capa = capability; + p_capainfo.bearer_capa = bearer_capability; break; } - switch (mode) + switch (bearer_mode) { case 2: p_capainfo.bearer_mode = INFO_BMODE_PACKET; @@ -686,169 +698,51 @@ void Pdss1::setup_ind(unsigned long prim, unsigned long dinfo, void *data) p_capainfo.bearer_mode = INFO_BMODE_CIRCUIT; break; } - switch (user) + switch (bearer_user) { case -1: p_capainfo.bearer_info1 = INFO_INFO1_NONE; break; default: - p_capainfo.bearer_info1 = user + 0x80; + p_capainfo.bearer_info1 = bearer_user + 0x80; break; } /* hlc */ - switch (hlc) + switch (hlc_hlc) { case -1: p_capainfo.hlc = INFO_HLC_NONE; break; default: - p_capainfo.hlc = hlc + 0x80; + p_capainfo.hlc = hlc_hlc + 0x80; break; } - switch (exthlc) + switch (hlc_exthlc) { case -1: p_capainfo.exthlc = INFO_HLC_NONE; break; default: - p_capainfo.exthlc = exthlc + 0x80; + p_capainfo.exthlc = hlc_exthlc + 0x80; break; } - /* process channel */ - chan_trace_header("CHANNEL SELECTION (setup)"); - if (exclusive<0) - exclusive = 0; - if (channel == CHANNEL_NO) - add_trace("channel", "request", "no-channel"); - else - add_trace("channel", "request", (channel>0)?"%d%s":"any", channel, exclusive?" (forced)":""); - if (channel==CHANNEL_NO && p_type==PORT_TYPE_DSS1_TE_IN) - { - add_trace("conclusion", NULL, "incoming call-waiting not supported for TE-mode"); - end_trace(); - ret = -6; // channel unacceptable - goto no_channel; - } - if (channel <= 0) /* not given, no channel, whatever.. */ - channel = CHANNEL_ANY; /* any channel */ - if (p_m_mISDNport->b_reserved >= p_m_mISDNport->b_num) // of out chan.. - { - add_trace("channel", "reserved", "%d", p_m_mISDNport->b_reserved); - add_trace("conclusion", NULL, "all channels are reserved"); - end_trace(); - ret = -34; // no channel + /* hunt channel */ + ret = channel = hunt_bchannel(channel, exclusive); + if (ret < 0) goto no_channel; - } - if (channel == CHANNEL_ANY) - goto get_from_list; - if (channel > 0) - { - /* check for given channel in selection list */ - selchannel = ifport->channel_in; - while(selchannel) - { - if (selchannel->channel == channel || selchannel->channel == CHANNEL_FREE) - break; - selchannel = selchannel->next; - } - if (!selchannel) - channel = 0; - - /* exclusive channel requests must be in the list */ - if (exclusive) - { - if (!channel) - { - add_trace("conclusion", NULL, "exclusively requested channel not in list"); - end_trace(); - ret = 6; // unacceptable - goto no_channel; - } - i = selchannel->channel-1-(selchannel->channel>=17); - if (mISDNport->b_port[i] == NULL) - goto use_channel; - add_trace("conclusion", NULL, "exclusively requested channel is busy"); - end_trace(); - ret = 6; // unacceptable - goto no_channel; - } - - /* requested channels in list will be used */ - if (channel) - { - i = selchannel->channel-1-(selchannel->channel>=17); - if (mISDNport->b_port[i] == NULL) - goto use_channel; - } - - /* if channel is not available or not in list, it must be searched */ - get_from_list: - /* check for first free channel in list */ - channel = 0; - selchannel = ifport->channel_in; - while(selchannel) - { - switch(selchannel->channel) - { - case CHANNEL_FREE: /* free channel */ - add_trace("hunting", "channel", "free"); - if (mISDNport->b_inuse >= mISDNport->b_num) - break; /* all channel in use or reserverd */ - /* find channel */ - i = 0; - while(i < mISDNport->b_num) - { - if (mISDNport->b_port[i] == NULL) - { - channel = i+1+(i>=15); - break; - } - i++; - } - break; - - default: - add_trace("hunting", "channel", "%d", selchannel->channel); - if (selchannel->channel<1 || selchannel->channel==16) - break; /* invalid channels */ - i = selchannel->channel-1-(selchannel->channel>=17); - if (i >= mISDNport->b_num) - break; /* channel not in port */ - if (mISDNport->b_port[i] == NULL) - { - channel = selchannel->channel; - break; - } - break; - } - if (channel) - break; /* found channel */ - selchannel = selchannel->next; - } - if (!channel) - { - add_trace("conclusion", NULL, "no channel available"); - end_trace(); - ret = 6; // unacceptable - goto no_channel; - } - } /* open channel */ - use_channel: ret = seize_bchannel(channel, 1); if (ret < 0) { - add_trace("conclusion", NULL, "channel not available"); - end_trace(); no_channel: RELEASE_COMPLETE_t *release_complete; dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE, dinfo, sizeof(RELEASE_COMPLETE_t), p_m_d_ntmode); - l1l2l3_trace_header(CC_RELEASE_COMPLETE | REQUEST, DIRECTION_OUT); release_complete = (RELEASE_COMPLETE_t *)(dmsg->data + headerlen); + l1l2l3_trace_header(p_m_mISDNport, this, CC_RELEASE_COMPLETE | REQUEST, DIRECTION_OUT); enc_ie_cause(&release_complete->CAUSE, dmsg, (p_m_d_ntmode)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, -ret); end_trace(); msg_queue_tail(&p_m_mISDNport->downqueue, dmsg); @@ -856,10 +750,7 @@ void Pdss1::setup_ind(unsigned long prim, unsigned long dinfo, void *data) p_m_delete = 1; return; } - add_trace("conclusion", NULL, "channel available"); - add_trace("connect", "channel", "%d", p_m_b_channel); - end_trace(); - bchannel_activate(p_m_mISDNport, p_m_b_index); + bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_ACTIVATE); /* create endpoint */ if (p_epointlist) @@ -872,8 +763,8 @@ void Pdss1::setup_ind(unsigned long prim, unsigned long dinfo, void *data) RELEASE_COMPLETE_t *release_complete; dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE, dinfo, sizeof(RELEASE_COMPLETE_t), p_m_d_ntmode); - l1l2l3_trace_header(CC_RELEASE_COMPLETE | REQUEST, DIRECTION_OUT); release_complete = (RELEASE_COMPLETE_t *)(dmsg->data + headerlen); + l1l2l3_trace_header(p_m_mISDNport, this, CC_RELEASE_COMPLETE | REQUEST, DIRECTION_OUT); enc_ie_cause(&release_complete->CAUSE, dmsg, (p_m_d_ntmode)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, 41); /* temporary failure */ end_trace(); msg_queue_tail(&p_m_mISDNport->downqueue, dmsg); @@ -916,7 +807,7 @@ void Pdss1::information_ind(unsigned long prim, unsigned long dinfo, void *data) unsigned char keypad[32] = ""; struct message *message; - l1l2l3_trace_header(prim, DIRECTION_IN); + l1l2l3_trace_header(p_m_mISDNport, this, prim, DIRECTION_IN); dec_ie_called_pn(information->CALLED_PN, (Q931_info_t *)((unsigned long)data+headerlen), &type, &plan, (unsigned char *)p_dialinginfo.number, sizeof(p_dialinginfo.number)); dec_ie_keypad(information->KEYPAD, (Q931_info_t *)((unsigned long)data+headerlen), (unsigned char *)keypad, sizeof(keypad)); dec_ie_complete(information->COMPLETE, (Q931_info_t *)((unsigned long)data+headerlen), &p_dialinginfo.sending_complete); @@ -955,7 +846,7 @@ void Pdss1::setup_acknowledge_ind(unsigned long prim, unsigned long dinfo, void int ret; struct message *message; - l1l2l3_trace_header(prim, DIRECTION_IN); + l1l2l3_trace_header(p_m_mISDNport, this, prim, DIRECTION_IN); dec_ie_channel_id(setup_acknowledge->CHANNEL_ID, (Q931_info_t *)((unsigned long)data+headerlen), &exclusive, &channel); dec_ie_progress(setup_acknowledge->PROGRESS, (Q931_info_t *)((unsigned long)data+headerlen), &coding, &location, &progress); end_trace(); @@ -991,7 +882,7 @@ void Pdss1::proceeding_ind(unsigned long prim, unsigned long dinfo, void *data) int notify = -1, type, plan, present; char redir[32]; - l1l2l3_trace_header(prim, DIRECTION_IN); + l1l2l3_trace_header(p_m_mISDNport, this, prim, DIRECTION_IN); dec_ie_channel_id(proceeding->CHANNEL_ID, (Q931_info_t *)((unsigned long)data+headerlen), &exclusive, &channel); dec_ie_progress(proceeding->PROGRESS, (Q931_info_t *)((unsigned long)data+headerlen), &coding, &location, &progress); dec_ie_notify(NULL/*proceeding->NOTIFY*/, (Q931_info_t *)((unsigned long)data+headerlen), ¬ify); @@ -1074,7 +965,7 @@ void Pdss1::alerting_ind(unsigned long prim, unsigned long dinfo, void *data) int notify = -1, type, plan, present; char redir[32]; - l1l2l3_trace_header(prim, DIRECTION_IN); + l1l2l3_trace_header(p_m_mISDNport, this, prim, DIRECTION_IN); dec_ie_channel_id(alerting->CHANNEL_ID, (Q931_info_t *)((unsigned long)data+headerlen), &exclusive, &channel); dec_ie_progress(alerting->PROGRESS, (Q931_info_t *)((unsigned long)data+headerlen), &coding, &location, &progress); dec_ie_notify(NULL/*alerting->NOTIFY*/, (Q931_info_t *)((unsigned long)data+headerlen), ¬ify); @@ -1161,7 +1052,7 @@ void Pdss1::connect_ind(unsigned long prim, unsigned long dinfo, void *data) if (p_m_d_ntmode) p_m_d_ces = connect->ces; - l1l2l3_trace_header(prim, DIRECTION_IN); + l1l2l3_trace_header(p_m_mISDNport, this, prim, DIRECTION_IN); dec_ie_channel_id(connect->CHANNEL_ID, (Q931_info_t *)((unsigned long)data+headerlen), &exclusive, &channel); dec_ie_connected_pn(connect->CONNECT_PN, (Q931_info_t *)((unsigned long)data+headerlen), &type, &plan, &present, &screen, (unsigned char *)p_connectinfo.id, sizeof(p_connectinfo.id)); #ifdef CENTREX @@ -1227,12 +1118,12 @@ void Pdss1::connect_ind(unsigned long prim, unsigned long dinfo, void *data) break; } p_connectinfo.isdn_port = p_m_portnum; - SCPY(p_connectingo.interface, p_m_mISDNport->ifport->interface->name); + SCPY(p_connectinfo.interfaces, p_m_mISDNport->ifport->interface->name); /* send connect acknowledge */ dmsg = create_l3msg(CC_CONNECT | RESPONSE, MT_CONNECT, dinfo, sizeof(CONNECT_ACKNOWLEDGE_t), p_m_d_ntmode); - l1l2l3_trace_header(CC_CONNECT | RESPONSE, DIRECTION_OUT); connect_acknowledge = (CONNECT_ACKNOWLEDGE_t *)(dmsg->data + headerlen); + l1l2l3_trace_header(p_m_mISDNport, this, CC_CONNECT | RESPONSE, DIRECTION_OUT); /* if we had no bchannel before, we send it now */ if (!bchannel_before && p_m_b_channel) enc_ie_channel_id(&connect_acknowledge->CHANNEL_ID, dmsg, 1, p_m_b_channel); @@ -1255,7 +1146,7 @@ void Pdss1::disconnect_ind(unsigned long prim, unsigned long dinfo, void *data) int coding, proglocation, progress; struct message *message; - l1l2l3_trace_header(prim, DIRECTION_IN); + l1l2l3_trace_header(p_m_mISDNport, this, prim, DIRECTION_IN); dec_ie_progress(disconnect->PROGRESS, (Q931_info_t *)((unsigned long)data+headerlen), &coding, &proglocation, &progress); dec_ie_cause(disconnect->CAUSE, (Q931_info_t *)((unsigned long)data+headerlen), &location, &cause); end_trace(); @@ -1271,7 +1162,7 @@ void Pdss1::disconnect_ind(unsigned long prim, unsigned long dinfo, void *data) dmsg = create_l3msg(CC_RELEASE | REQUEST, MT_RELEASE, dinfo, sizeof(RELEASE_t), p_m_d_ntmode); release = (RELEASE_t *)(dmsg->data + headerlen); - l1l2l3_trace_header(CC_RELEASE | REQUEST, DIRECTION_OUT); + l1l2l3_trace_header(p_m_mISDNport, this, CC_RELEASE | REQUEST, DIRECTION_OUT); enc_ie_cause(&release->CAUSE, dmsg, (p_m_d_ntmode)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, 16); /* normal */ add_trace("reason", NULL, "no remote patterns"); end_trace(); @@ -1320,7 +1211,7 @@ void Pdss1::disconnect_ind_i(unsigned long prim, unsigned long dinfo, void *data int location, cause; /* cause */ - l1l2l3_trace_header(prim, DIRECTION_IN); + l1l2l3_trace_header(p_m_mISDNport, this, prim, DIRECTION_IN); if (p_m_d_collect_cause > 0) { add_trace("old-cause", "location", "%d", p_m_d_collect_location); @@ -1369,7 +1260,7 @@ void Pdss1::release_ind(unsigned long prim, unsigned long dinfo, void *data) int location, cause; struct message *message; - l1l2l3_trace_header(prim, DIRECTION_IN); + l1l2l3_trace_header(p_m_mISDNport, this, prim, DIRECTION_IN); dec_ie_cause(release->CAUSE, (Q931_info_t *)((unsigned long)data+headerlen), &location, &cause); end_trace(); @@ -1395,7 +1286,7 @@ void Pdss1::release_ind(unsigned long prim, unsigned long dinfo, void *data) dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE, dinfo, sizeof(RELEASE_COMPLETE_t), p_m_d_ntmode); release_complete = (RELEASE_COMPLETE_t *)(dmsg->data + headerlen); - l1l2l3_trace_header(CC_RELEASE_COMPLETE | REQUEST, DIRECTION_OUT); + l1l2l3_trace_header(p_m_mISDNport, this, CC_RELEASE_COMPLETE | REQUEST, DIRECTION_OUT); enc_ie_cause(&release_complete->CAUSE, dmsg, (p_m_d_ntmode)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, 16); end_trace(); msg_queue_tail(&p_m_mISDNport->downqueue, dmsg); @@ -1413,7 +1304,7 @@ void Pdss1::release_complete_ind(unsigned long prim, unsigned long dinfo, void * int location, cause; struct message *message; - l1l2l3_trace_header(prim, DIRECTION_IN); + l1l2l3_trace_header(p_m_mISDNport, this, prim, DIRECTION_IN); dec_ie_cause(release_complete->CAUSE, (Q931_info_t *)((unsigned long)data+headerlen), &location, &cause); end_trace(); @@ -1465,7 +1356,7 @@ void Pdss1::notify_ind(unsigned long prim, unsigned long dinfo, void *data) struct message *message; int notify, type, plan, present; - l1l2l3_trace_header(prim, DIRECTION_IN); + l1l2l3_trace_header(p_m_mISDNport, this, prim, DIRECTION_IN); dec_ie_notify(notifying->NOTIFY, (Q931_info_t *)((unsigned long)data+headerlen), ¬ify); dec_ie_redir_dn(notifying->REDIR_DN, (Q931_info_t *)((unsigned long)data+headerlen), &type, &plan, &present, (unsigned char *)message->param.notifyinfo.id, sizeof(message->param.notifyinfo.id)); end_trace(); @@ -1526,14 +1417,14 @@ void Pdss1::hold_ind(unsigned long prim, unsigned long dinfo, void *data) msg_t *dmsg; // class Endpoint *epoint; - l1l2l3_trace_header(prim, DIRECTION_IN); + l1l2l3_trace_header(p_m_mISDNport, this, prim, DIRECTION_IN); end_trace(); if (!ACTIVE_EPOINT(p_epointlist) || p_m_hold) { dmsg = create_l3msg(CC_HOLD_REJECT | REQUEST, MT_HOLD_REJECT, dinfo, sizeof(HOLD_REJECT_t), p_m_d_ntmode); hold_reject = (HOLD_REJECT_t *)(dmsg->data + headerlen); - l1l2l3_trace_header(CC_HOLD_REJECT | REQUEST, DIRECTION_OUT); + l1l2l3_trace_header(p_m_mISDNport, this, CC_HOLD_REJECT | REQUEST, DIRECTION_OUT); enc_ie_cause(&hold_reject->CAUSE, dmsg, (p_m_d_ntmode)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, p_m_hold?101:31); /* normal unspecified / incompatible state */ add_trace("reason", NULL, "no endpoint"); end_trace(); @@ -1549,11 +1440,10 @@ void Pdss1::hold_ind(unsigned long prim, unsigned long dinfo, void *data) message_put(message); /* deactivate bchannel */ - chan_trace_header("CHANNEL RELEASE (hold)"); + chan_trace_header(p_m_mISDNport, this, "CHANNEL RELEASE (hold)", DIRECTION_NONE); add_trace("disconnect", "channel", "%d", p_m_b_channel); end_trace(); - free_bchannel(); -prüfen, ob bei allen alloc_bchannel/free_bchannel ein trace erfolgt + drop_bchannel(); /* set hold state */ p_m_hold = 1; @@ -1569,7 +1459,7 @@ pr /* acknowledge hold */ dmsg = create_l3msg(CC_HOLD_ACKNOWLEDGE | REQUEST, MT_HOLD_ACKNOWLEDGE, dinfo, sizeof(HOLD_ACKNOWLEDGE_t), p_m_d_ntmode); hold_acknowledge = (HOLD_ACKNOWLEDGE_t *)(dmsg->data + headerlen); - l1l2l3_trace_header(CC_HOLD_ACKNOWLEDGE | REQUEST, DIRECTION_OUT); + l1l2l3_trace_header(p_m_mISDNport, this, CC_HOLD_ACKNOWLEDGE | REQUEST, DIRECTION_OUT); end_trace(); msg_queue_tail(&p_m_mISDNport->downqueue, dmsg); } @@ -1587,7 +1477,7 @@ void Pdss1::retrieve_ind(unsigned long prim, unsigned long dinfo, void *data) msg_t *dmsg; int ret; - l1l2l3_trace_header(prim, DIRECTION_IN); + l1l2l3_trace_header(p_m_mISDNport, this, prim, DIRECTION_IN); dec_ie_channel_id(retrieve->CHANNEL_ID, (Q931_info_t *)((unsigned long)data+headerlen), &exclusive, &channel); end_trace(); @@ -1598,7 +1488,7 @@ void Pdss1::retrieve_ind(unsigned long prim, unsigned long dinfo, void *data) dmsg = create_l3msg(CC_RETRIEVE_REJECT | REQUEST, MT_RETRIEVE_REJECT, dinfo, sizeof(RETRIEVE_REJECT_t), p_m_d_ntmode); retrieve_reject = (RETRIEVE_REJECT_t *)(dmsg->data + headerlen); - l1l2l3_trace_header(CC_RETRIEVE_REJECT | REQUEST, DIRECTION_OUT); + l1l2l3_trace_header(p_m_mISDNport, this, CC_RETRIEVE_REJECT | REQUEST, DIRECTION_OUT); enc_ie_cause(&retrieve_reject->CAUSE, dmsg, (p_m_d_ntmode)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, cause); end_trace(); msg_queue_tail(&p_m_mISDNport->downqueue, dmsg); @@ -1612,63 +1502,21 @@ void Pdss1::retrieve_ind(unsigned long prim, unsigned long dinfo, void *data) message->param.notifyinfo.local = 1; /* call is retrieved by supplementary service */ message_put(message); + /* hunt channel */ + ret = channel = hunt_bchannel(channel, exclusive); + if (ret < 0) + goto no_channel; - -mach den channel-kram, wie beim setup - - - - - - - - - - /* channel_id */ - chan_trace_header("CHANNEL RELEASE (retrieve)"); - if (exclusive<0) - exclusive = 0; -alle channels richtig convertieren - if (channel < 0) - channel = -1; /* any channel */ - if (channel == ANY_CHANNEL) - channel = -1; /* any channel */ - if (channel == CHANNEL_NO) - add_trace("channel", "request", "no-channel"); - else - add_trace("channel", "request", (channel>0)?"%d%s":"any", channel, exclusive?" (forced)":""); - /* debug */ - if (channel==CHANNEL_NO && (p_type==PORT_TYPE_DSS1_TE_IN||p_type==PORT_TYPE_DSS1_TE_OUT)) - { - add_trace("conclusion", NULL, "incoming call-waiting not supported for TE-mode"); - end_trace(); - cause = 6; - goto reject; - } /* open channel */ - ret = alloc_bchannel(channel, exclusive); + ret = seize_bchannel(channel, 1); if (ret < 0) { - PDEBUG(DEBUG_BCHANNEL, "- channel is not available (cause=%d), so we send a retrieve_reject.\n", -ret); + no_channel: cause = -ret; goto reject; } + bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_ACTIVATE); - - - - - - - - - - - - - - - /* set hold state */ p_m_hold = 0; p_m_timeout = 0; @@ -1676,7 +1524,7 @@ alle channels richtig convertieren /* acknowledge retrieve */ dmsg = create_l3msg(CC_RETRIEVE_ACKNOWLEDGE | REQUEST, MT_RETRIEVE_ACKNOWLEDGE, dinfo, sizeof(RETRIEVE_ACKNOWLEDGE_t), p_m_d_ntmode); retrieve_acknowledge = (RETRIEVE_ACKNOWLEDGE_t *)(dmsg->data + headerlen); - l1l2l3_trace_header(CC_RETRIEVE_ACKNOWLEDGE | REQUEST, DIRECTION_OUT); + l1l2l3_trace_header(p_m_mISDNport, this, CC_RETRIEVE_ACKNOWLEDGE | REQUEST, DIRECTION_OUT); enc_ie_channel_id(&retrieve_acknowledge->CHANNEL_ID, dmsg, 1, p_m_b_channel); end_trace(); msg_queue_tail(&p_m_mISDNport->downqueue, dmsg); @@ -1696,7 +1544,7 @@ void Pdss1::suspend_ind(unsigned long prim, unsigned long dinfo, void *data) msg_t *dmsg; int ret = -31; /* normal, unspecified */ - l1l2l3_trace_header(prim, DIRECTION_IN); + l1l2l3_trace_header(p_m_mISDNport, this, prim, DIRECTION_IN); dec_ie_call_id(suspend->CALL_ID, (Q931_info_t *)((unsigned long)data+headerlen), callid, &len); end_trace(); @@ -1705,7 +1553,7 @@ void Pdss1::suspend_ind(unsigned long prim, unsigned long dinfo, void *data) reject: dmsg = create_l3msg(CC_SUSPEND_REJECT | REQUEST, MT_SUSPEND_REJECT, dinfo, sizeof(SUSPEND_REJECT_t), p_m_d_ntmode); suspend_reject = (SUSPEND_REJECT_t *)(dmsg->data + headerlen); - l1l2l3_trace_header(CC_SUSPEND_REJECT | REQUEST, DIRECTION_OUT); + l1l2l3_trace_header(p_m_mISDNport, this, CC_SUSPEND_REJECT | REQUEST, DIRECTION_OUT); enc_ie_cause(&suspend_reject->CAUSE, dmsg, (p_m_d_ntmode)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, -ret); end_trace(); msg_queue_tail(&p_m_mISDNport->downqueue, dmsg); @@ -1739,10 +1587,10 @@ void Pdss1::suspend_ind(unsigned long prim, unsigned long dinfo, void *data) message_put(message); /* deactivate bchannel */ - chan_trace_header("CHANNEL RELEASE (suspend)"); + chan_trace_header(p_m_mISDNport, this, "CHANNEL RELEASE (suspend)", DIRECTION_NONE); add_trace("disconnect", "channel", "%d", p_m_b_channel); end_trace(); - free_bchannel(); + drop_bchannel(); /* sending suspend to endpoint */ while (p_epointlist) @@ -1758,7 +1606,7 @@ void Pdss1::suspend_ind(unsigned long prim, unsigned long dinfo, void *data) /* sending SUSPEND_ACKNOWLEDGE */ dmsg = create_l3msg(CC_SUSPEND_ACKNOWLEDGE | REQUEST, MT_SUSPEND_ACKNOWLEDGE, dinfo, sizeof(SUSPEND_ACKNOWLEDGE_t), p_m_d_ntmode); suspend_acknowledge = (SUSPEND_ACKNOWLEDGE_t *)(dmsg->data + headerlen); - l1l2l3_trace_header(CC_SUSPEND_ACKNOWLEDGE | REQUEST, DIRECTION_OUT); + l1l2l3_trace_header(p_m_mISDNport, this, CC_SUSPEND_ACKNOWLEDGE | REQUEST, DIRECTION_OUT); end_trace(); msg_queue_tail(&p_m_mISDNport->downqueue, dmsg); @@ -1790,7 +1638,7 @@ void Pdss1::resume_ind(unsigned long prim, unsigned long dinfo, void *data) PERROR("fatal software error: l3-stack gives us a process id 0xff00-0xffff\n"); exit(-1); } - l1l2l3_trace_header(CC_NEW_CR | INDICATION, DIRECTION_IN); + l1l2l3_trace_header(p_m_mISDNport, this, CC_NEW_CR | INDICATION, DIRECTION_IN); if (p_m_d_l3id) add_trace("callref", "old", "0x%x", p_m_d_l3id); add_trace("callref", "new", "0x%x", dinfo); @@ -1798,19 +1646,16 @@ void Pdss1::resume_ind(unsigned long prim, unsigned long dinfo, void *data) if (p_m_d_l3id&(~0xff) == 0xff00) p_m_mISDNport->procids[p_m_d_l3id&0xff] = 0; p_m_d_l3id = dinfo; - p_m_d_ces = setup->ces; + p_m_d_ces = resume->ces; } - l1l2l3_trace_header(prim, DIRECTION_IN); + l1l2l3_trace_header(p_m_mISDNport, this, prim, DIRECTION_IN); dec_ie_call_id(resume->CALL_ID, (Q931_info_t *)((unsigned long)data+headerlen), callid, &len); end_trace(); /* if blocked, release call */ if (p_m_mISDNport->ifport->block) { - RELEASE_COMPLETE_t *release_complete; - - printlog("--- port#%d is blocked.\n", mISDNport->ifport->portnum); ret = -27; goto reject; } @@ -1818,18 +1663,24 @@ void Pdss1::resume_ind(unsigned long prim, unsigned long dinfo, void *data) /* call id */ if (len<0) len = 0; - /* channel_id */ + /* channel_id (no channel is possible in message) */ exclusive = 0; channel = -1; /* any channel */ /* hunt channel */ - ret = hunt_bchannel(channel, exclusive); + ret = channel = hunt_bchannel(channel, exclusive); + if (ret < 0) + goto no_channel; + + /* open channel */ + ret = seize_bchannel(channel, 1); if (ret < 0) { + no_channel: reject: dmsg = create_l3msg(CC_RESUME_REJECT | REQUEST, MT_RESUME_REJECT, dinfo, sizeof(RESUME_REJECT_t), p_m_d_ntmode); resume_reject = (RESUME_REJECT_t *)(dmsg->data + headerlen); - l1l2l3_trace_header(CC_RESUME_REJECT | REQUEST, DIRECTION_OUT); + l1l2l3_trace_header(p_m_mISDNport, this, CC_RESUME_REJECT | REQUEST, DIRECTION_OUT); enc_ie_cause(&resume_reject->CAUSE, dmsg, (p_m_d_ntmode)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, -ret); if (ret == -27) add_trace("reason", NULL, "port blocked"); @@ -1839,6 +1690,7 @@ void Pdss1::resume_ind(unsigned long prim, unsigned long dinfo, void *data) p_m_delete = 1; return; } + bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_ACTIVATE); /* create endpoint */ if (p_epointlist) @@ -1884,7 +1736,7 @@ void Pdss1::resume_ind(unsigned long prim, unsigned long dinfo, void *data) /* sending RESUME_ACKNOWLEDGE */ dmsg = create_l3msg(CC_RESUME_ACKNOWLEDGE | REQUEST, MT_RESUME_ACKNOWLEDGE, dinfo, sizeof(RESUME_ACKNOWLEDGE_t), p_m_d_ntmode); resume_acknowledge = (RESUME_ACKNOWLEDGE_t *)(dmsg->data + headerlen); - l1l2l3_trace_header(CC_RESUME_ACKNOWLEDGE | REQUEST, DIRECTION_OUT); + l1l2l3_trace_header(p_m_mISDNport, this, CC_RESUME_ACKNOWLEDGE | REQUEST, DIRECTION_OUT); enc_ie_channel_id(&resume_acknowledge->CHANNEL_ID, dmsg, 1, p_m_b_channel); end_trace(); msg_queue_tail(&p_m_mISDNport->downqueue, dmsg); @@ -1902,7 +1754,7 @@ void Pdss1::facility_ind(unsigned long prim, unsigned long dinfo, void *data) int facil_len; struct message *message; - l1l2l3_trace_header(prim, DIRECTION_IN); + l1l2l3_trace_header(p_m_mISDNport, this, prim, DIRECTION_IN); dec_ie_facility(facility->FACILITY, (Q931_info_t *)((unsigned long)data+headerlen), facil, &facil_len); end_trace(); @@ -1923,14 +1775,13 @@ void Pdss1::facility_ind(unsigned long prim, unsigned long dinfo, void *data) */ void Pdss1::message_isdn(unsigned long prim, unsigned long dinfo, void *data) { - int i; int new_l3id; int timer_hex=0; switch (prim) { case CC_TIMEOUT | INDICATION: - l1l2l3_trace_header(prim, DIRECTION_IN); + l1l2l3_trace_header(p_m_mISDNport, this, prim, DIRECTION_IN); if (p_m_d_ntmode) { int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN; @@ -1952,7 +1803,7 @@ void Pdss1::message_isdn(unsigned long prim, unsigned long dinfo, void *data) case CC_SETUP | CONFIRM: if (p_m_d_ntmode) { - l1l2l3_trace_header(CC_NEW_CR | INDICATION, DIRECTION_IN); + l1l2l3_trace_header(p_m_mISDNport, this, CC_NEW_CR | INDICATION, DIRECTION_IN); add_trace("callref", "old", "0x%x", p_m_d_l3id); /* nt-library now gives us a new id via CC_SETUP_CONFIRM */ if ((p_m_d_l3id&0xff00) != 0xff00) @@ -1961,7 +1812,6 @@ void Pdss1::message_isdn(unsigned long prim, unsigned long dinfo, void *data) add_trace("callref", "new", "0x%x", p_m_d_l3id); end_trace(); } - end_trace; break; case CC_INFORMATION | INDICATION: @@ -2071,7 +1921,7 @@ void Pdss1::message_isdn(unsigned long prim, unsigned long dinfo, void *data) break; case CC_RELEASE_CR | INDICATION: - l1l2l3_trace_header(CC_RELEASE_CR | INDICATION, DIRECTION_IN); + l1l2l3_trace_header(p_m_mISDNport, this, CC_RELEASE_CR | INDICATION, DIRECTION_IN); add_trace("callref", NULL, "0x%x", p_m_d_l3id); end_trace(); if (p_m_d_ntmode) @@ -2100,7 +1950,7 @@ void Pdss1::message_isdn(unsigned long prim, unsigned long dinfo, void *data) break; case CC_NEW_CR | INDICATION: - l1l2l3_trace_header(prim, DIRECTION_IN); + l1l2l3_trace_header(p_m_mISDNport, this, prim, DIRECTION_IN); if (p_m_d_l3id) add_trace("callref", "old", "0x%x", p_m_d_l3id); if (p_m_d_ntmode) @@ -2118,7 +1968,7 @@ void Pdss1::message_isdn(unsigned long prim, unsigned long dinfo, void *data) break; default: - l1l2l3_trace_header(prim, DIRECTION_IN); + l1l2l3_trace_header(p_m_mISDNport, this, prim, DIRECTION_IN); add_trace("unhandled", "prim", "0x%x", prim); end_trace(); } @@ -2209,8 +2059,8 @@ void Pdss1::message_information(unsigned long epoint_id, int message_id, union p if (param->information.number[0]) /* only if we have something to dial */ { dmsg = create_l3msg(CC_INFORMATION | REQUEST, MT_INFORMATION, p_m_d_l3id, sizeof(INFORMATION_t), p_m_d_ntmode); - l1l2l3_trace_header(CC_INFORMATION | REQUEST, DIRECTION_OUT); information = (INFORMATION_t *)(dmsg->data + headerlen); + l1l2l3_trace_header(p_m_mISDNport, this, CC_INFORMATION | REQUEST, DIRECTION_OUT); enc_ie_called_pn(&information->CALLED_PN, dmsg, 0, 1, (unsigned char *)param->information.number); end_trace(); msg_queue_tail(&p_m_mISDNport->downqueue, dmsg); @@ -2237,6 +2087,8 @@ void Pdss1::message_setup(unsigned long epoint_id, int message_id, union paramet /* release if port is blocked */ if (p_m_mISDNport->ifport->block) { + struct message *message; + message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE); message->param.disconnectinfo.cause = 27; // temp. unavail. message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL; @@ -2264,7 +2116,7 @@ void Pdss1::message_setup(unsigned long epoint_id, int message_id, union paramet /* sending information */ dmsg = create_l3msg(CC_INFORMATION | REQUEST, MT_INFORMATION, p_m_d_l3id, sizeof(INFORMATION_t), p_m_d_ntmode); information = (INFORMATION_t *)(dmsg->data + headerlen); - l1l2l3_trace_header(CC_INFORMATION | REQUEST, DIRECTION_OUT); + l1l2l3_trace_header(p_m_mISDNport, this, CC_INFORMATION | REQUEST, DIRECTION_OUT); if (p_m_d_ntmode) enc_ie_display(&information->DISPLAY, dmsg, (unsigned char *)p_callerinfo.display); end_trace(); @@ -2303,7 +2155,7 @@ void Pdss1::message_setup(unsigned long epoint_id, int message_id, union paramet channel = CHANNEL_NO; /* creating l3id */ - l1l2l3_trace_header(CC_NEW_CR | REQUEST, DIRECTION_OUT); + l1l2l3_trace_header(p_m_mISDNport, this, CC_NEW_CR | REQUEST, DIRECTION_OUT); if (p_m_d_ntmode) { i = 0; @@ -2351,8 +2203,8 @@ void Pdss1::message_setup(unsigned long epoint_id, int message_id, union paramet /* preparing setup message */ dmsg = create_l3msg(CC_SETUP | REQUEST, MT_SETUP, p_m_d_l3id, sizeof(SETUP_t), p_m_d_ntmode); - l1l2l3_trace_header(CC_SETUP | REQUEST, DIRECTION_OUT); setup = (SETUP_t *)(dmsg->data + headerlen); + l1l2l3_trace_header(p_m_mISDNport, this, CC_SETUP | REQUEST, DIRECTION_OUT); /* channel information */ if (channel >= 0) /* it should */ { @@ -2539,7 +2391,7 @@ void Pdss1::message_facility(unsigned long epoint_id, int message_id, union para /* sending facility */ dmsg = create_l3msg(CC_FACILITY | REQUEST, MT_FACILITY, p_m_d_l3id, sizeof(FACILITY_t), p_m_d_ntmode); facility = (FACILITY_t *)(dmsg->data + headerlen); - l1l2l3_trace_header(CC_FACILITY | REQUEST, DIRECTION_OUT); + l1l2l3_trace_header(p_m_mISDNport, this, CC_FACILITY | REQUEST, DIRECTION_OUT); enc_ie_facility(&facility->FACILITY, dmsg, (unsigned char *)param->facilityinfo.data, param->facilityinfo.len); end_trace(); msg_queue_tail(&p_m_mISDNport->downqueue, dmsg); @@ -2621,7 +2473,7 @@ void Pdss1::message_notify(unsigned long epoint_id, int message_id, union parame /* sending notification */ dmsg = create_l3msg(CC_NOTIFY | REQUEST, MT_NOTIFY, p_m_d_l3id, sizeof(NOTIFY_t), p_m_d_ntmode); notification = (NOTIFY_t *)(dmsg->data + headerlen); - l1l2l3_trace_header(CC_NOTIFY | REQUEST, DIRECTION_OUT); + l1l2l3_trace_header(p_m_mISDNport, this, CC_NOTIFY | REQUEST, DIRECTION_OUT); enc_ie_notify(¬ification->NOTIFY, dmsg, notify); /* sending redirection number only in ntmode */ if (type >= 0 && p_m_d_ntmode) @@ -2636,7 +2488,7 @@ void Pdss1::message_notify(unsigned long epoint_id, int message_id, union parame /* sending information */ dmsg = create_l3msg(CC_INFORMATION | REQUEST, MT_INFORMATION, p_m_d_l3id, sizeof(INFORMATION_t), p_m_d_ntmode); information = (INFORMATION_t *)(dmsg->data + headerlen); - l1l2l3_trace_header(CC_INFORMATION | REQUEST, DIRECTION_OUT); + l1l2l3_trace_header(p_m_mISDNport, this, CC_INFORMATION | REQUEST, DIRECTION_OUT); enc_ie_display(&information->DISPLAY, dmsg, (unsigned char *)param->notifyinfo.display); end_trace(); msg_queue_tail(&p_m_mISDNport->downqueue, dmsg); @@ -2653,7 +2505,7 @@ void Pdss1::message_overlap(unsigned long epoint_id, int message_id, union param /* sending setup_acknowledge */ dmsg = create_l3msg(CC_SETUP_ACKNOWLEDGE | REQUEST, MT_SETUP_ACKNOWLEDGE, p_m_d_l3id, sizeof(SETUP_ACKNOWLEDGE_t), p_m_d_ntmode); setup_acknowledge = (SETUP_ACKNOWLEDGE_t *)(dmsg->data + headerlen); - l1l2l3_trace_header(CC_SETUP_ACKNOWLEDGE | REQUEST, DIRECTION_OUT); + l1l2l3_trace_header(p_m_mISDNport, this, CC_SETUP_ACKNOWLEDGE | REQUEST, DIRECTION_OUT); /* channel information */ if (p_state == PORT_STATE_IN_SETUP) enc_ie_channel_id(&setup_acknowledge->CHANNEL_ID, dmsg, 1, p_m_b_channel); @@ -2679,7 +2531,7 @@ void Pdss1::message_proceeding(unsigned long epoint_id, int message_id, union pa /* sending proceeding */ dmsg = create_l3msg(CC_PROCEEDING | REQUEST, MT_CALL_PROCEEDING, p_m_d_l3id, sizeof(CALL_PROCEEDING_t), p_m_d_ntmode); proceeding = (CALL_PROCEEDING_t *)(dmsg->data + headerlen); - l1l2l3_trace_header(CC_PROCEEDING | REQUEST, DIRECTION_OUT); + l1l2l3_trace_header(p_m_mISDNport, this, CC_PROCEEDING | REQUEST, DIRECTION_OUT); /* channel information */ if (p_state == PORT_STATE_IN_SETUP) enc_ie_channel_id(&proceeding->CHANNEL_ID, dmsg, 1, p_m_b_channel); @@ -2710,7 +2562,7 @@ void Pdss1::message_alerting(unsigned long epoint_id, int message_id, union para /* sending proceeding */ dmsg = create_l3msg(CC_PROCEEDING | REQUEST, MT_CALL_PROCEEDING, p_m_d_l3id, sizeof(CALL_PROCEEDING_t), p_m_d_ntmode); proceeding = (CALL_PROCEEDING_t *)(dmsg->data + headerlen); - l1l2l3_trace_header(CC_PROCEEDING | REQUEST, DIRECTION_OUT); + l1l2l3_trace_header(p_m_mISDNport, this, CC_PROCEEDING | REQUEST, DIRECTION_OUT); /* channel information */ enc_ie_channel_id(&proceeding->CHANNEL_ID, dmsg, 1, p_m_b_channel); /* progress information */ @@ -2726,7 +2578,7 @@ void Pdss1::message_alerting(unsigned long epoint_id, int message_id, union para /* sending alerting */ dmsg = create_l3msg(CC_ALERTING | REQUEST, MT_ALERTING, p_m_d_l3id, sizeof(ALERTING_t), p_m_d_ntmode); alerting = (ALERTING_t *)(dmsg->data + headerlen); - l1l2l3_trace_header(CC_ALERTING | REQUEST, DIRECTION_OUT); + l1l2l3_trace_header(p_m_mISDNport, this, CC_ALERTING | REQUEST, DIRECTION_OUT); /* channel information */ if (p_state == PORT_STATE_IN_SETUP) enc_ie_channel_id(&alerting->CHANNEL_ID, dmsg, 1, p_m_b_channel); @@ -2760,7 +2612,7 @@ void Pdss1::message_connect(unsigned long epoint_id, int message_id, union param /* sending proceeding */ dmsg = create_l3msg(CC_PROCEEDING | REQUEST, MT_CALL_PROCEEDING, p_m_d_l3id, sizeof(CALL_PROCEEDING_t), p_m_d_ntmode); proceeding = (CALL_PROCEEDING_t *)(dmsg->data + headerlen); - l1l2l3_trace_header(CC_PROCEEDING | REQUEST, DIRECTION_OUT); + l1l2l3_trace_header(p_m_mISDNport, this, CC_PROCEEDING | REQUEST, DIRECTION_OUT); /* channel information */ enc_ie_channel_id(&proceeding->CHANNEL_ID, dmsg, 1, p_m_b_channel); // /* progress information */ @@ -2783,7 +2635,7 @@ void Pdss1::message_connect(unsigned long epoint_id, int message_id, union param /* sending information */ dmsg = create_l3msg(CC_INFORMATION | REQUEST, MT_INFORMATION, p_m_d_l3id, sizeof(INFORMATION_t), p_m_d_ntmode); information = (INFORMATION_t *)(dmsg->data + headerlen); - l1l2l3_trace_header(CC_INFORMATION | REQUEST, DIRECTION_OUT); + l1l2l3_trace_header(p_m_mISDNport, this, CC_INFORMATION | REQUEST, DIRECTION_OUT); if (p_m_d_ntmode) enc_ie_display(&information->DISPLAY, dmsg, (unsigned char *)p_connectinfo.display); end_trace(); @@ -2800,7 +2652,7 @@ void Pdss1::message_connect(unsigned long epoint_id, int message_id, union param /* preparing connect message */ dmsg = create_l3msg(CC_CONNECT | REQUEST, MT_CONNECT, p_m_d_l3id, sizeof(CONNECT_t), p_m_d_ntmode); connect = (CONNECT_t *)(dmsg->data + headerlen); - l1l2l3_trace_header(CC_CONNECT | REQUEST, DIRECTION_OUT); + l1l2l3_trace_header(p_m_mISDNport, this, CC_CONNECT | REQUEST, DIRECTION_OUT); /* connect information */ plan = 1; switch (p_connectinfo.ntype) @@ -2899,7 +2751,7 @@ void Pdss1::message_disconnect(unsigned long epoint_id, int message_id, union pa /* sending release */ dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE, p_m_d_l3id, sizeof(RELEASE_COMPLETE_t), p_m_d_ntmode); release_complete = (RELEASE_COMPLETE_t *)(dmsg->data + headerlen); - l1l2l3_trace_header(CC_RELEASE_COMPLETE | REQUEST, DIRECTION_OUT); + l1l2l3_trace_header(p_m_mISDNport, this, CC_RELEASE_COMPLETE | REQUEST, DIRECTION_OUT); /* send cause */ enc_ie_cause(&release_complete->CAUSE, dmsg, (p_m_d_ntmode && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_LOCAL:param->disconnectinfo.location, param->disconnectinfo.cause); end_trace(); @@ -2917,7 +2769,7 @@ void Pdss1::message_disconnect(unsigned long epoint_id, int message_id, union pa /* sending proceeding */ dmsg = create_l3msg(CC_PROCEEDING | REQUEST, MT_CALL_PROCEEDING, p_m_d_l3id, sizeof(CALL_PROCEEDING_t), p_m_d_ntmode); proceeding = (CALL_PROCEEDING_t *)(dmsg->data + headerlen); - l1l2l3_trace_header(CC_PROCEEDING | REQUEST, DIRECTION_OUT); + l1l2l3_trace_header(p_m_mISDNport, this, CC_PROCEEDING | REQUEST, DIRECTION_OUT); /* channel information */ enc_ie_channel_id(&proceeding->CHANNEL_ID, dmsg, 1, p_m_b_channel); /* progress information */ @@ -2933,7 +2785,7 @@ void Pdss1::message_disconnect(unsigned long epoint_id, int message_id, union pa /* sending disconnect */ dmsg = create_l3msg(CC_DISCONNECT | REQUEST, MT_DISCONNECT, p_m_d_l3id, sizeof(DISCONNECT_t), p_m_d_ntmode); disconnect = (DISCONNECT_t *)(dmsg->data + headerlen); - l1l2l3_trace_header(CC_DISCONNECT | REQUEST, DIRECTION_OUT); + l1l2l3_trace_header(p_m_mISDNport, this, CC_DISCONNECT | REQUEST, DIRECTION_OUT); /* progress information */ if (p_capainfo.bearer_capa==INFO_BC_SPEECH || p_capainfo.bearer_capa==INFO_BC_AUDIO @@ -2970,7 +2822,7 @@ void Pdss1::message_release(unsigned long epoint_id, int message_id, union param /* sending release */ dmsg = create_l3msg(CC_RELEASE | REQUEST, MT_RELEASE, p_m_d_l3id, sizeof(RELEASE_t), p_m_d_ntmode); release = (RELEASE_t *)(dmsg->data + headerlen); - l1l2l3_trace_header(CC_RELEASE | REQUEST, DIRECTION_OUT); + l1l2l3_trace_header(p_m_mISDNport, this, CC_RELEASE | REQUEST, DIRECTION_OUT); /* send cause */ enc_ie_cause(&release->CAUSE, dmsg, (p_m_d_ntmode && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_LOCAL:param->disconnectinfo.location, param->disconnectinfo.cause); end_trace(); @@ -2979,7 +2831,7 @@ void Pdss1::message_release(unsigned long epoint_id, int message_id, union param /* remove epoint */ remove_endpoint: free_epointid(epoint_id); - l1l2l3_trace_header(CC_RELEASE_CR | REQUEST, DIRECTION_OUT); + l1l2l3_trace_header(p_m_mISDNport, this, CC_RELEASE_CR | REQUEST, DIRECTION_OUT); add_trace("callref", "new", "0x%x", p_m_d_l3id); end_trace(); if (p_m_d_ntmode) @@ -3000,7 +2852,7 @@ void Pdss1::message_release(unsigned long epoint_id, int message_id, union param /* sending release */ dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE, p_m_d_l3id, sizeof(RELEASE_COMPLETE_t), p_m_d_ntmode); release_complete = (RELEASE_COMPLETE_t *)(dmsg->data + headerlen); - l1l2l3_trace_header(CC_RELEASE | REQUEST, DIRECTION_OUT); + l1l2l3_trace_header(p_m_mISDNport, this, CC_RELEASE | REQUEST, DIRECTION_OUT); /* send cause */ enc_ie_cause(&release_complete->CAUSE, dmsg, (p_m_d_ntmode && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_LOCAL:param->disconnectinfo.location, param->disconnectinfo.cause); end_trace(); @@ -3017,7 +2869,7 @@ void Pdss1::message_release(unsigned long epoint_id, int message_id, union param /* sending proceeding */ dmsg = create_l3msg(CC_PROCEEDING | REQUEST, MT_CALL_PROCEEDING, p_m_d_l3id, sizeof(CALL_PROCEEDING_t), p_m_d_ntmode); proceeding = (CALL_PROCEEDING_t *)(dmsg->data + headerlen); - l1l2l3_trace_header(CC_PROCEEDING | REQUEST, DIRECTION_OUT); + l1l2l3_trace_header(p_m_mISDNport, this, CC_PROCEEDING | REQUEST, DIRECTION_OUT); /* channel information */ enc_ie_channel_id(&proceeding->CHANNEL_ID, dmsg, 1, p_m_b_channel); /* progress information */ @@ -3032,7 +2884,7 @@ void Pdss1::message_release(unsigned long epoint_id, int message_id, union param /* sending disconnect */ dmsg = create_l3msg(CC_DISCONNECT | REQUEST, MT_DISCONNECT, p_m_d_l3id, sizeof(DISCONNECT_t), p_m_d_ntmode); disconnect = (DISCONNECT_t *)(dmsg->data + headerlen); - l1l2l3_trace_header(CC_DISCONNECT | REQUEST, DIRECTION_OUT); + l1l2l3_trace_header(p_m_mISDNport, this, CC_DISCONNECT | REQUEST, DIRECTION_OUT); /* progress information */ if (p_capainfo.bearer_capa==INFO_BC_SPEECH || p_capainfo.bearer_capa==INFO_BC_AUDIO @@ -3135,7 +2987,7 @@ int Pdss1::message_epoint(unsigned long epoint_id, int message_id, union paramet act.dinfo = 0; act.len = 0; mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC); - l1l2l3_trace_header(act.prim, DIRECTION_OUT); + l1l2l3_trace_header(p_m_mISDNport, this, act.prim, DIRECTION_OUT); end_trace(); // /* set timeout */ // p_m_mISDNport->l1timeout = now+3; @@ -3300,7 +3152,7 @@ int stack2manager_nt(void *dat, void *arg) case DL_ESTABLISH | INDICATION: case DL_ESTABLISH | CONFIRM: ss_estab: - l1l2l3_trace_header(prim, DIRECTION_IN); + l1l2l3_trace_header(mISDNport, NULL, hh->prim, DIRECTION_IN); add_trace("tei", NULL, "%d", hh->dinfo); end_trace(); if (mISDNport->ptp && hh->dinfo == 0) @@ -3319,7 +3171,7 @@ int stack2manager_nt(void *dat, void *arg) case DL_RELEASE | INDICATION: case DL_RELEASE | CONFIRM: ss_rel: - l1l2l3_trace_header(prim, DIRECTION_IN); + l1l2l3_trace_header(mISDNport, NULL, hh->prim, DIRECTION_IN); add_trace("tei", NULL, "%d", hh->dinfo); end_trace(); if (mISDNport->ptp && hh->dinfo == 0) @@ -3341,7 +3193,9 @@ int stack2manager_nt(void *dat, void *arg) PERROR("FATAL ERROR: cannot create port object.\n"); dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE, hh->dinfo, sizeof(RELEASE_COMPLETE_t), mISDNport->ntmode); release_complete = (RELEASE_COMPLETE_t *)(dmsg->data + mISDN_HEADER_LEN); + l1l2l3_trace_header(mISDNport, NULL, CC_RELEASE_COMPLETE | REQUEST, DIRECTION_OUT); enc_ie_cause_standalone(mISDNport->ntmode?&release_complete->CAUSE:NULL, dmsg, (mISDNport->ntmode)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, 47); + end_trace(); msg_queue_tail(&mISDNport->downqueue, dmsg); break; } @@ -3351,7 +3205,7 @@ int stack2manager_nt(void *dat, void *arg) case CC_RESUME | INDICATION: /* creating port object */ SPRINT(name, "%s-%d-in", mISDNport->ifport->interface->name, mISDNport->portnum); - if (!(pdss1 = new Pdss1(PORT_TYPE_DSS1_NT_IN, mISDNport, name, NULL))) + if (!(pdss1 = new Pdss1(PORT_TYPE_DSS1_NT_IN, mISDNport, name, NULL, 0, 0))) { SUSPEND_REJECT_t *suspend_reject; msg_t *dmsg; @@ -3359,7 +3213,9 @@ int stack2manager_nt(void *dat, void *arg) PERROR("FATAL ERROR: cannot create port object.\n"); dmsg = create_l3msg(CC_SUSPEND_REJECT | REQUEST, MT_SUSPEND_REJECT, hh->dinfo, sizeof(SUSPEND_REJECT_t), mISDNport->ntmode); suspend_reject = (SUSPEND_REJECT_t *)(dmsg->data + mISDN_HEADER_LEN); + l1l2l3_trace_header(mISDNport, NULL, CC_SUSPEND_REJECT | REQUEST, DIRECTION_OUT); enc_ie_cause_standalone(mISDNport->ntmode?&suspend_reject->CAUSE:NULL, dmsg, (mISDNport->ntmode)?1:0, 47); + end_trace(); msg_queue_tail(&mISDNport->downqueue, dmsg); break; } @@ -3426,7 +3282,7 @@ int stack2manager_te(struct mISDNport *mISDNport, msg_t *msg) /* creating port object */ SPRINT(name, "%s-%d-in", mISDNport->ifport->interface->name, mISDNport->portnum); - if (!(pdss1 = new Pdss1(PORT_TYPE_DSS1_TE_IN, mISDNport, name, NULL))) + if (!(pdss1 = new Pdss1(PORT_TYPE_DSS1_NT_IN, mISDNport, name, NULL, 0, 0))) { RELEASE_COMPLETE_t *release_complete; msg_t *dmsg; @@ -3434,7 +3290,9 @@ int stack2manager_te(struct mISDNport *mISDNport, msg_t *msg) PERROR("FATAL ERROR: cannot create port object.\n"); dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE, frm->dinfo, sizeof(RELEASE_COMPLETE_t), mISDNport->ntmode); release_complete = (RELEASE_COMPLETE_t *)(dmsg->data + mISDN_HEADER_LEN); + l1l2l3_trace_header(mISDNport, NULL, CC_RELEASE_COMPLETE | REQUEST, DIRECTION_OUT); enc_ie_cause_standalone(mISDNport->ntmode?&release_complete->CAUSE:NULL, dmsg, (mISDNport->ntmode)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, 47); + end_trace(); msg_queue_tail(&mISDNport->downqueue, dmsg); free_msg(msg); return(0); diff --git a/dss1.h b/dss1.h index d8ffe49..93f0865 100644 --- a/dss1.h +++ b/dss1.h @@ -13,7 +13,7 @@ class Pdss1 : public PmISDN { public: - Pdss1(int type, struct mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel); + Pdss1(int type, struct mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive); ~Pdss1(); int p_m_d_l3id; /* current l3 process id */ int p_m_d_ces; /* ntmode: tei&sapi */ @@ -31,6 +31,7 @@ class Pdss1 : public PmISDN void new_state(int state); /* set new state */ void isdn_show_send_message(unsigned long prim, msg_t *msg); int received_first_reply_to_setup(unsigned long prim, int exclusive, int channel); + int hunt_bchannel(int exclusive, int channel); void information_ind(unsigned long prim, unsigned long dinfo, void *data); void setup_ind(unsigned long prim, unsigned long dinfo, void *data); void setup_acknowledge_ind(unsigned long prim, unsigned long dinfo, void *data); diff --git a/endpoint.cpp b/endpoint.cpp index 39cba95..1e66143 100644 --- a/endpoint.cpp +++ b/endpoint.cpp @@ -69,7 +69,7 @@ Endpoint::Endpoint(int port_id, int call_id) if (port) { if ((port->p_type&PORT_CLASS_mISDN_MASK) == PORT_CLASS_mISDN_DSS1) - earlyb = port->mISDNport->is_earlyb; + earlyb = ((class PmISDN *)port)->p_m_mISDNport->is_earlyb; if (!portlist_new(port_id, port->p_type, earlyb)) { PERROR("no mem for portlist, exitting...\n"); @@ -170,7 +170,7 @@ struct port_list *Endpoint::portlist_new(unsigned long port_id, int port_type, i /* link to call or port */ portlist->port_id = port_id; portlist->port_type = port_type; - portlist->earlyb = earlyb; + portlist->early_b = earlyb; return(portlist); } diff --git a/endpoint.h b/endpoint.h index e556bf3..744f3ea 100644 --- a/endpoint.h +++ b/endpoint.h @@ -33,7 +33,7 @@ class Endpoint /* port relation */ struct port_list *ep_portlist; /* link to list of ports */ - struct port_list *portlist_new(unsigned long port_id, int port_type); + struct port_list *portlist_new(unsigned long port_id, int port_type, int earlyb); void free_portlist(struct port_list *portlist); /* call relation */ diff --git a/ie.cpp b/ie.cpp index d0c3f49..0ac73a4 100644 --- a/ie.cpp +++ b/ie.cpp @@ -1096,7 +1096,7 @@ void Pdss1::enc_ie_progress(unsigned char **ntmode, msg_t *msg, int coding, int add_trace("progress", "codeing", "%d", coding); add_trace("progress", "location", "%d", location); - add_trace("progress", "indicator", "%d", indicator); + add_trace("progress", "indicator", "%d", progress); l = 2; p = msg_put(msg, l+2); @@ -1136,7 +1136,7 @@ void Pdss1::dec_ie_progress(unsigned char *p, Q931_info_t *qi, int *coding, int add_trace("progress", "codeing", "%d", *coding); add_trace("progress", "location", "%d", *location); - add_trace("progress", "indicator", "%d", *indicator); + add_trace("progress", "indicator", "%d", *progress); } @@ -1426,7 +1426,7 @@ void Pdss1::dec_ie_facility(unsigned char *p, Q931_info_t *qi, unsigned char *fa } debug[i*3] = '\0'; - add_trace("facility", NULL, "%s", buffer[0]?buffer+1:""); + add_trace("facility", NULL, "%s", debug[0]?debug+1:""); } diff --git a/interface.c b/interface.c index e522471..2fe7b2c 100644 --- a/interface.c +++ b/interface.c @@ -18,14 +18,31 @@ struct interface *interface_first = NULL; /* first interface is current list */ struct interface *interface_newlist = NULL; /* first interface in new list */ -/* set default selchannel */ -void default_selchannel(struct interface_port *ifport) +/* set default out_channel */ +void default_out_channel(struct interface_port *ifport) { struct select_channel *selchannel, **selchannelp; - /* channel selection for TE-ports */ - if (!ifport->mISDNport->ntmode) + selchannel = (struct select_channel *)malloc(sizeof(struct select_channel)); + if (!selchannel) + { + PERROR("No memory!"); + return; + } + memuse++; + memset(selchannel, 0, sizeof(struct select_channel)); + + if (ifport->mISDNport->ntmode) + selchannel->channel = CHANNEL_FREE; + else + selchannel->channel = CHANNEL_ANY; + + ifport->out_channel = selchannel; + + /* additional channel selection for multipoint NT ports */ + if (!ifport->mISDNport->ptp && ifport->mISDNport->ntmode) { + selchannelp = &(selchannel->next); selchannel = (struct select_channel *)malloc(sizeof(struct select_channel)); if (!selchannel) { @@ -33,16 +50,18 @@ void default_selchannel(struct interface_port *ifport) return; } memuse++; - memset(*selchannelp, 0, sizeof(struct select_channel)); - *selchannelp->channel = SEL_CHANNEL_ANY; - selchannelp = &ifport->selchannel; - while(*selchannelp) - selchannelp = &((*selchannelp)->next); + memset(selchannel, 0, sizeof(struct select_channel)); + selchannel->channel = CHANNEL_NO; // call waiting *selchannelp = selchannel; - return(0); } +} + + +/* set default in_channel */ +void default_in_channel(struct interface_port *ifport) +{ + struct select_channel *selchannel; - /* channel selection for NT-ports */ selchannel = (struct select_channel *)malloc(sizeof(struct select_channel)); if (!selchannel) { @@ -50,30 +69,11 @@ void default_selchannel(struct interface_port *ifport) return; } memuse++; - memset(*selchannelp, 0, sizeof(struct select_channel)); - *selchannelp->channel = SEL_CHANNEL_FREE; - selchannelp = &ifport->selchannel; - while(*selchannelp) - selchannelp = &((*selchannelp)->next); - *selchannelp = selchannel; - - /* additional channel selection for multipoint ports */ - if (!ifport->mISDNport->ptp) - { - selchannel = (struct select_channel *)malloc(sizeof(struct select_channel)); - if (!selchannel) - { - PERROR("No memory!"); - return; - } - memuse++; - memset(*selchannelp, 0, sizeof(struct select_channel)); - *selchannelp->channel = SEL_CHANNEL_NO; // call waiting - selchannelp = &ifport->selchannel; - while(*selchannelp) - selchannelp = &((*selchannelp)->next); - *selchannelp = selchannel; - } + memset(selchannel, 0, sizeof(struct select_channel)); + + selchannel->channel = CHANNEL_FREE; + + ifport->in_channel = selchannel; } @@ -325,7 +325,7 @@ static int inter_channel_out(struct interface *interface, char *filename, int li if (!strcasecmp(el, "force")) { ifport->channel_force = 1; - if (ifport->selchannel) + if (ifport->out_channel) { SPRINT(interface_error, "Error in %s (line %d): value 'force' may only appear as first element in list.\n", filename, line); return(-1); @@ -333,17 +333,17 @@ static int inter_channel_out(struct interface *interface, char *filename, int li } else if (!strcasecmp(el, "any")) { - val = SEL_CHANNEL_ANY; + val = CHANNEL_ANY; goto selchannel; } else if (!strcasecmp(el, "free")) { - val = SEL_CHANNEL_FREE; + val = CHANNEL_FREE; goto selchannel; } else if (!strcasecmp(el, "no")) { - val = SEL_CHANNEL_NO; + val = CHANNEL_NO; goto selchannel; } else { @@ -372,7 +372,7 @@ static int inter_channel_out(struct interface *interface, char *filename, int li /* set value */ selchannel->channel = val; /* tail port */ - selchannelp = &ifport->selchannel; + selchannelp = &ifport->out_channel; while(*selchannelp) selchannelp = &((*selchannelp)->next); *selchannelp = selchannel; @@ -402,14 +402,14 @@ static int inter_channel_in(struct interface *interface, char *filename, int lin { el = p; p = get_seperated(p); - if (ifport->in_select) if (ifport->in_select->channel == SEL_CHANNEL_FREE) + if (ifport->in_channel) if (ifport->in_channel->channel == CHANNEL_FREE) { SPRINT(interface_error, "Error in %s (line %d): parameter '%s' has values behind 'free' keyword. They has no effect.\n", filename, line, parameter); return(-1); } if (!strcasecmp(el, "free")) { - val = SEL_CHANNEL_FREE; + val = CHANNEL_FREE; goto selchannel; } else { @@ -438,7 +438,7 @@ static int inter_channel_in(struct interface *interface, char *filename, int lin /* set value */ selchannel->channel = val; /* tail port */ - selchannelp = &ifport->in_select; + selchannelp = &ifport->in_channel; while(*selchannelp) selchannelp = &((*selchannelp)->next); *selchannelp = selchannel; @@ -509,7 +509,6 @@ static int inter_screen(struct interface_screen **ifscreenp, struct interface *i } memuse++; memset(ifscreen, 0, sizeof(struct interface_screen)); -#warning handle unchanged as unchanged!! ifscreen->match_type = -1; /* unchecked */ ifscreen->match_present = -1; /* unchecked */ ifscreen->result_type = -1; /* unchanged */ @@ -571,7 +570,7 @@ static int inter_screen(struct interface_screen **ifscreenp, struct interface *i /* check for % at the end */ if (strchr(el, '%')) { - if (strchr(el, '%') != el+len(el)-1) + if (strchr(el, '%') != el+strlen(el)-1) { SPRINT(interface_error, "Error in %s (line %d): %% joker found, but must at the end.\n", filename, line, parameter); return(-1); @@ -630,7 +629,7 @@ static int inter_screen(struct interface_screen **ifscreenp, struct interface *i /* check for % at the end */ if (strchr(el, '%')) { - if (strchr(el, '%') != el+len(el)-1) + if (strchr(el, '%') != el+strlen(el)-1) { SPRINT(interface_error, "Error in %s (line %d): %% joker found, but must at the end.\n", filename, line, parameter); return(-1); @@ -660,11 +659,30 @@ static int inter_screen_out(struct interface *interface, char *filename, int lin { return(inter_screen(&interface->ifscreen_out, interface, filename, line, parameter, value)); } -static int inter_filter(struct interface *interface, char *filename, int line, char *parameter, char *value) +static int inter_nodtmf(struct interface *interface, char *filename, int line, char *parameter, char *value) { + struct interface_port *ifport; + + /* port in chain ? */ + if (!interface->ifport) + { + SPRINT(interface_error, "Error in %s (line %d): parameter '%s' expects previous 'port' definition.\n", filename, line, parameter); + return(-1); + } + /* goto end of chain */ + ifport = interface->ifport; + while(ifport->next) + ifport = ifport->next; + ifport->nodtmf = 1; + return(0); +} #warning filter to be done +#if 0 +static int inter_filter(struct interface *interface, char *filename, int line, char *parameter, char *value) +{ return(0); } +#endif /* @@ -715,7 +733,7 @@ struct interface_param interface_param[] = { "If no channel was requested, the first free channel found is selected.\n" "This parameter must follow a 'port' parameter.\n" " [,...] - List of channels to accept.\n" - " free - Accept any free channel\n" + " free - Accept any free channel"}, {"msn", &inter_msn, ",[[,...]]", "Incomming caller ID is checked against given MSN numbers.\n" @@ -736,6 +754,10 @@ struct interface_param interface_param[] = { "Adds an entry for outgoing calls to the caller ID screen list.\n" "See 'screen-in' for help."}, + {"nodtmf", &inter_nodtmf, "", + "Disables DTMF detection for this interface.\n" + "This parameter must follow a 'port' parameter."}, + #if 0 #warning todo: filter, also in the PmISDN object {"filter", &inter_filter, " [parameters]", @@ -1081,8 +1103,10 @@ void relink_interfaces(void) if (ifport->mISDNport) { /* default channel selection list */ - if (!ifport->selchannel) - default_selchannel(ifport); + if (!ifport->out_channel) + default_out_channel(ifport); + if (!ifport->in_channel) + default_in_channel(ifport); /* default is_tones */ if (ifport->interface->is_tones) ifport->mISDNport->is_tones = (ifport->interface->is_tones==IS_YES); diff --git a/interface.h b/interface.h index e1a18b5..ce15094 100644 --- a/interface.h +++ b/interface.h @@ -48,10 +48,12 @@ struct interface_port { struct interface *interface; /* link to interface */ struct mISDNport *mISDNport; /* link to port */ int portnum; /* port number */ - int ptp; /* load stack in PTP mode */ + int ptp; /* force load stack in PTP mode */ + int ptmp; /* force load stack in PTP mode */ int channel_force; /* forces channel by protocol */ - struct select_channel *out_select; /* list of channels to select */ - struct select_channel *in_select; /* the same for incoming channels */ + int nodtmf; /* disables DTMF */ + struct select_channel *out_channel; /* list of channels to select */ + struct select_channel *in_channel; /* the same for incoming channels */ int block; /* set if interface is blocked */ }; diff --git a/mISDN.cpp b/mISDN.cpp index 61eff9f..cf70697 100644 --- a/mISDN.cpp +++ b/mISDN.cpp @@ -53,26 +53,26 @@ PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_setti p_m_b_channel = 0; p_m_b_exclusive = 0; p_m_b_reserve = 0; - p_m_b_addr = 0; - p_m_b_stid = 0; p_m_jittercheck = 0; p_m_delete = 0; p_m_hold = 0; p_m_txvol = p_m_rxvol = 0; p_m_conf = 0; p_m_txdata = 0; -#warning set delay by routing parameter or interface config p_m_delay = 0; p_m_echo = 0; p_m_tone = 0; p_m_rxoff = 0; p_m_calldata = 0; - p_m_dtmf = !options.nodtmf; - sollen wir daraus eine interface-option machen?: + p_m_dtmf = !mISDNport->ifport->nodtmf; p_m_timeout = 0; p_m_timer = 0; -#warning denke auch an die andere seite. also das setup sollte dies weitertragen + /* audio from up */ + p_m_fromup_buffer_readp = 0; + p_m_fromup_buffer_writep = 0; + + /* crypt */ p_m_crypt = 0; p_m_crypt_listen = 0; p_m_crypt_msg_loops = 0; @@ -96,9 +96,8 @@ PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_setti mISDNport->b_reserved++; } - } else /* reserve channel */ - if (channel) // only if constructor was called with a channel resevation + if (channel > 0) // only if constructor was called with a channel resevation seize_bchannel(channel, exclusive); /* we increase the number of objects: */ @@ -115,7 +114,7 @@ PmISDN::~PmISDN() struct message *message; /* remove bchannel relation */ - free_bchannel(); + drop_bchannel(); /* release epoint */ while (p_epointlist) @@ -136,9 +135,128 @@ PmISDN::~PmISDN() /* + * trace + */ +void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, char *msgtext, int direction) +{ + /* init trace with given values */ + start_trace(mISDNport?mISDNport->portnum:0, + mISDNport?mISDNport->ifport->interface:NULL, + port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype):NULL, + port?port->p_dialinginfo.number:NULL, + direction, + CATEGORY_CH, + port?port->p_serial:0, + msgtext); +} + + +/* + * layer trace header + */ +static struct isdn_message { + char *name; + unsigned long value; +} isdn_message[] = { + {"TIMEOUT", CC_TIMEOUT}, + {"SETUP", CC_SETUP}, + {"SETUP_ACK", CC_SETUP_ACKNOWLEDGE}, + {"PROCEEDING", CC_PROCEEDING}, + {"ALERTING", CC_ALERTING}, + {"CONNECT", CC_CONNECT}, + {"CONNECT RES", CC_CONNECT}, + {"CONNECT_ACK", CC_CONNECT_ACKNOWLEDGE}, + {"DISCONNECT", CC_DISCONNECT}, + {"RELEASE", CC_RELEASE}, + {"RELEASE_COMP", CC_RELEASE_COMPLETE}, + {"INFORMATION", CC_INFORMATION}, + {"PROGRESS", CC_PROGRESS}, + {"NOTIFY", CC_NOTIFY}, + {"SUSPEND", CC_SUSPEND}, + {"SUSPEND_ACK", CC_SUSPEND_ACKNOWLEDGE}, + {"SUSPEND_REJ", CC_SUSPEND_REJECT}, + {"RESUME", CC_RESUME}, + {"RESUME_ACK", CC_RESUME_ACKNOWLEDGE}, + {"RESUME_REJ", CC_RESUME_REJECT}, + {"HOLD", CC_HOLD}, + {"HOLD_ACK", CC_HOLD_ACKNOWLEDGE}, + {"HOLD_REJ", CC_HOLD_REJECT}, + {"RETRIEVE", CC_RETRIEVE}, + {"RETRIEVE_ACK", CC_RETRIEVE_ACKNOWLEDGE}, + {"RETRIEVE_REJ", CC_RETRIEVE_REJECT}, + {"FACILITY", CC_FACILITY}, + {"STATUS", CC_STATUS}, + {"RESTART", CC_RESTART}, + {"RELEASE_CR", CC_RELEASE_CR}, + {"NEW_CR", CC_NEW_CR}, + {"DL_ESTABLISH", DL_ESTABLISH}, + {"DL_RELEASE", DL_RELEASE}, + {"PH_ACTIVATE", PH_ACTIVATE}, + {"PH_DEACTIVATE", PH_DEACTIVATE}, + + {NULL, 0}, +}; +static char *isdn_prim[4] = { + " REQUEST", + " CONFIRM", + " INDICATION", + " RESPONSE", +}; +void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned long prim, int direction) +{ + int i; + char msgtext[64] = "<>"; + + /* select message and primitive text */ + i = 0; + while(isdn_message[i].name) + { + if (isdn_message[i].value == (prim&0xffffff00)) + { + SCPY(msgtext, isdn_message[i].name); + break; + } + i++; + } + SCAT(msgtext, isdn_prim[prim&0x00000003]); + + /* add direction */ + if (direction && (prim&0xffffff00)!=CC_NEW_CR && (prim&0xffffff00)!=CC_RELEASE_CR) + { + if (mISDNport) + { + if (mISDNport->ntmode) + { + if (direction == DIRECTION_OUT) + SCAT(msgtext, " N->U"); + else + SCAT(msgtext, " N<-U"); + } else + { + if (direction == DIRECTION_OUT) + SCAT(msgtext, " U->N"); + else + SCAT(msgtext, " U<-N"); + } + } + } + + /* init trace with given values */ + start_trace(mISDNport?mISDNport->portnum:0, + mISDNport?mISDNport->ifport->interface:NULL, + port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype):NULL, + port?port->p_dialinginfo.number:NULL, + direction, + CATEGORY_CH, + port?port->p_serial:0, + msgtext); +} + + +/* * send control information to the channel (dsp-module) */ -void ph_control(unsigned long b_addr, int c1, int c2) +void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, unsigned long b_addr, int c1, int c2, char *trace_name, int trace_value) { unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+sizeof(int)]; iframe_t *ctrl = (iframe_t *)buffer; @@ -151,9 +269,12 @@ void ph_control(unsigned long b_addr, int c1, int c2) *d++ = c1; *d++ = c2; mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC); + chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT); + add_trace(trace_name, NULL, "%d", trace_value); + end_trace(); } -void ph_control_block(unsigned long b_addr, int c1, void *c2, int c2_len) +void ph_control_block(struct mISDNport *mISDNport, class PmISDN *isdnport, unsigned long b_addr, int c1, void *c2, int c2_len, char *trace_name, int trace_value) { unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+c2_len]; iframe_t *ctrl = (iframe_t *)buffer; @@ -166,194 +287,378 @@ void ph_control_block(unsigned long b_addr, int c1, void *c2, int c2_len) *d++ = c1; memcpy(d, c2, c2_len); mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC); + chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT); + add_trace(trace_name, NULL, "%d", trace_value); + end_trace(); } /* - * activate / deactivate bchannel + * subfunction for bchannel_event + * create stack */ -static void bchannel_activate(struct mISDNport *mISDNport, int i) +static int _bchannel_create(struct mISDNport *mISDNport, int i) { - iframe_t act; + unsigned char buff[1024]; + layer_info_t li; + mISDN_pid_t pid; + int ret; - /* we must activate if we are deactivated */ - if (mISDNport->b_state[i] == B_STATE_IDLE) + if (mISDNport->b_stid[i]) { - /* activate bchannel */ - PDEBUG(DEBUG_BCHANNEL, "activating bchannel (index %d), because currently idle (address 0x%x).\n", i, mISDNport->b_addr[i]); - act.prim = DL_ESTABLISH | REQUEST; - act.addr = mISDNport->b_addr[i] | FLG_MSG_DOWN; - act.dinfo = 0; - act.len = 0; - mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC); - mISDNport->b_state[i] = B_STATE_ACTIVATING; - return; + PERROR("Error: no stack for index"); + return(-1); + } + if (mISDNport->b_addr[i]) + { + PERROR("Error: stack already created"); + return(-1); } - /* if we are active, we configure our channel */ - if (mISDNport->b_state[i] == B_STATE_ACTIVE) + /* create new layer */ + PDEBUG(DEBUG_BCHANNEL, "creating new layer for bchannel %d (index %d).\n" , i+1+(i>=15), i); + memset(&li, 0, sizeof(li)); + memset(&pid, 0, sizeof(pid)); + li.object_id = -1; + li.extentions = 0; + li.st = mISDNport->b_stid[i]; + UCPY(li.name, "B L4"); + li.pid.layermask = ISDN_LAYER((4)); + li.pid.protocol[4] = ISDN_PID_L4_B_USER; + ret = mISDN_new_layer(mISDNdevice, &li); + if (ret) + { + failed_new_layer: + PERROR("mISDN_new_layer() failed to add bchannel %d (index %d)\n", i+1+(i>=15), i); + goto failed; + } + mISDNport->b_addr[i] = li.id; + if (!li.id) { - unsigned char buffer[mISDN_HEADER_LEN+(ISDN_PRELOAD<<3)]; - iframe_t *pre = (iframe_t *)buffer; /* preload data */ - unsigned char *p = (unsigned char *)&pre->data.p; + goto failed_new_layer; + } + PDEBUG(DEBUG_BCHANNEL, "new layer (b_addr=0x%x)\n", mISDNport->b_addr[i]); + + /* create new stack */ + pid.protocol[1] = ISDN_PID_L1_B_64TRANS; + pid.protocol[2] = ISDN_PID_L2_B_TRANS; + pid.protocol[3] = ISDN_PID_L3_B_DSP; + pid.protocol[4] = ISDN_PID_L4_B_USER; + pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) | ISDN_LAYER((4)); + ret = mISDN_set_stack(mISDNdevice, mISDNport->b_stid[i], &pid); + if (ret) + { + stack_error: + PERROR("mISDN_set_stack() failed (ret=%d) to add bchannel (index %d) stid=0x%x\n", ret, i, mISDNport->b_stid[i]); + mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i], MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC); + goto failed; + } + ret = mISDN_get_setstack_ind(mISDNdevice, mISDNport->b_addr[i]); + if (ret) + goto stack_error; + + /* get layer id */ + mISDNport->b_addr[i] = mISDN_get_layerid(mISDNdevice, mISDNport->b_stid[i], 4); + if (!mISDNport->b_addr[i]) + goto stack_error; + chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create stack", DIRECTION_OUT); + add_trace("channel", NULL, "%d", i+1+(i>=15)); + add_trace("stack", "id", "%d", mISDNport->b_stid[i]); + add_trace("stack", "address", "%d", mISDNport->b_addr[i]); + end_trace(); - /* it is an error if this channel is not associated with a port object */ - if (!mISDNport->b_port[i]) - { - PERROR("bchannel index i=%d not associated with a port object\n", i); - return; - } + return(0); - /* configure dsp features */ - if (mISDNport->b_port[i]->p_m_txdata) - { - PDEBUG(DEBUG_BCHANNEL, "during activation, we set txdata to txdata=%d.\n", mISDNport->b_port[i]->p_m_txdata); - ph_control(mISDNport->b_addr[i], (mISDNport->b_port[i]->p_m_txdata)?CMX_TXDATA_ON:CMX_TXDATA_OFF); - } - if (mISDNport->b_port[i]->p_m_delay) - { - PDEBUG(DEBUG_BCHANNEL, "during activation, we set delay to delay=%d.\n", mISDNport->b_port[i]->p_m_delay); - ph_control(mISDNport->b_addr[i], CMX_DELAY, mISDNport->b_port[i]->p_m_delay); - } - if (mISDNport->b_port[i]->p_m_txvol) - { - PDEBUG(DEBUG_BCHANNEL, "during activation, we change tx-volume to shift=%d.\n", mISDNport->b_port[i]->p_m_txvol); - ph_control(mISDNport->b_addr[i], VOL_CHANGE_TX, mISDNport->b_port[i]->p_m_txvol); - } - if (mISDNport->b_port[i]->p_m_rxvol) - { - PDEBUG(DEBUG_BCHANNEL, "during activation, we change rx-volume to shift=%d.\n", mISDNport->b_port[i]->p_m_rxvol); - ph_control(mISDNport->b_addr[i], VOL_CHANGE_RX, mISDNport->b_port[i]->p_m_rxvol); - } -//tone if (mISDNport->b_port[i]->p_m_conf && !mISDNport->b_port[i]->p_m_tone) - if (mISDNport->b_port[i]->p_m_conf) - { - PDEBUG(DEBUG_BCHANNEL, "during activation, we change conference to conf=%d.\n", mISDNport->b_port[i]->p_m_conf); - ph_control(mISDNport->b_addr[i], CMX_CONF_JOIN, mISDNport->b_port[i]->p_m_conf); - } - if (mISDNport->b_port[i]->p_m_echo) - { - PDEBUG(DEBUG_BCHANNEL, "during activation, we set echo to echo=%d.\n", mISDNport->b_port[i]->p_m_echo); - ph_control(mISDNport->b_addr[i], CMX_ECHO_ON, 0); - } - if (mISDNport->b_port[i]->p_m_tone) - { - PDEBUG(DEBUG_BCHANNEL, "during activation, we set tone to tone=%d.\n", mISDNport->b_port[i]->p_m_tone); - ph_control(mISDNport->b_addr[i], TONE_PATT_ON, mISDNport->b_port[i]->p_m_tone); - } - if (mISDNport->b_port[i]->p_m_rxoff) - { - PDEBUG(DEBUG_BCHANNEL, "during activation, we set rxoff to rxoff=%d.\n", mISDNport->b_port[i]->p_m_rxoff); - ph_control(mISDNport->b_addr[i], CMX_RECEIVE_OFF, 0); - } -#if 0 - if (mISDNport->b_port[i]->p_m_txmix) - { - PDEBUG(DEBUG_BCHANNEL, "during activation, we set txmix to txmix=%d.\n", mISDNport->b_port[i]->p_m_txmix); - ph_control(mISDNport->b_addr[i], CMX_MIX_ON, 0); - } -#endif - if (mISDNport->b_port[i]->p_m_dtmf) - { - PDEBUG(DEBUG_BCHANNEL, "during activation, we set dtmf to dtmf=%d.\n", mISDNport->b_port[i]->p_m_dtmf); - ph_control(mISDNport->b_addr[i], DTMF_TONE_START, 0); - } - if (mISDNport->b_port[i]->p_m_crypt) - { - PDEBUG(DEBUG_BCHANNEL, "during activation, we set crypt to crypt=%d.\n", mISDNport->b_port[i]->p_m_crypt); - ph_control_block(mISDNport->b_addr[i], BF_ENABLE_KEY, mISDNport->b_port[i]->p_m_crypt_key, mISDNport->b_port[i]->p_m_crypt_key_len); - } - todo: wer startet/stoppt eigentlich den audio-transmit +failed: + mISDNport->b_addr[i] = 0; + return(-1); +} + + +/* + * subfunction for bchannel_event + * activate request + */ +static void _bchannel_activate(struct mISDNport *mISDNport, int i) +{ + iframe_t act; + + /* activate bchannel */ + chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL activate", DIRECTION_OUT); + add_trace("channel", NULL, "%d", i+1+(i>=15)); + end_trace(); + act.prim = DL_ESTABLISH | REQUEST; + act.addr = mISDNport->b_addr[i] | FLG_MSG_DOWN; + act.dinfo = 0; + act.len = 0; + mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC); +} + + +/* + * subfunction for bchannel_event + * set features + */ +static void _bchannel_configure(struct mISDNport *mISDNport, int i) +{ + struct PmISDN *port; + int addr; + + port = mISDNport->b_port[i]; + addr = mISDNport->b_addr[i]; + if (!port) + { + PERROR("bchannel index i=%d not associated with a port object\n", i); + return; } + + /* set dsp features */ + if (port->p_m_txdata) + ph_control(mISDNport, port, addr, (port->p_m_txdata)?CMX_TXDATA_ON:CMX_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata); + if (port->p_m_delay) + ph_control(mISDNport, port, addr, CMX_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay); + if (port->p_m_txvol) + ph_control(mISDNport, port, addr, VOL_CHANGE_TX, port->p_m_txvol, "DSP-TXVOL", port->p_m_txvol); + if (port->p_m_rxvol) + ph_control(mISDNport, port, addr, VOL_CHANGE_RX, port->p_m_rxvol, "DSP-RXVOL", port->p_m_rxvol); + if (port->p_m_conf) + ph_control(mISDNport, port, addr, CMX_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf); + if (port->p_m_echo) + ph_control(mISDNport, port, addr, CMX_ECHO_ON, 0, "DSP-ECHO", 1); + if (port->p_m_tone) + ph_control(mISDNport, port, addr, TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone); + if (port->p_m_rxoff) + ph_control(mISDNport, port, addr, CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1); +// if (port->p_m_txmix) +// ph_control(mISDNport, port, addr, CMX_MIX_ON, 0, "DSP-MIX", 1); + if (port->p_m_dtmf) + ph_control(mISDNport, port, addr, DTMF_TONE_START, 0, "DSP-DTMF", 1); + if (port->p_m_crypt) + ph_control_block(mISDNport, port, addr, BF_ENABLE_KEY, port->p_m_crypt_key, port->p_m_crypt_key_len, "DSP-CRYPT", port->p_m_crypt_key_len); } -static void bchannel_deactivate(struct mISDNport *mISDNport, int i) +/* + * subfunction for bchannel_event + * deactivate + */ +static void _bchannel_deactivate(struct mISDNport *mISDNport, int i) { iframe_t dact; + int addr; + + chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL deactivate", DIRECTION_OUT); + add_trace("channel", NULL, "%d", i+1+(i>=15)); + end_trace(); + dact.prim = DL_RELEASE | REQUEST; + dact.addr = addr | FLG_MSG_DOWN; + dact.dinfo = 0; + dact.len = 0; + mISDN_write(mISDNdevice, &dact, mISDN_HEADER_LEN+dact.len, TIMEOUT_1SEC); +} + +/* + * subfunction for bchannel_event + * destroy stack + */ +static void _bchannel_destroy(struct mISDNport *mISDNport, int i) +{ + unsigned char buff[1024]; + + chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove stack", DIRECTION_OUT); + add_trace("channel", NULL, "%d", i+1+(i>=15)); + add_trace("stack", "id", "%d", mISDNport->b_stid[i]); + add_trace("stack", "address", "%d", mISDNport->b_addr[i]); + end_trace(); + /* remove our stack only if set */ + PDEBUG(DEBUG_BCHANNEL, "free stack (b_addr=0x%x)\n", mISDNport->b_addr[i]); + mISDN_clear_stack(mISDNdevice, mISDNport->b_stid[i]); + if (mISDNport->b_addr[i]) + mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i] | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC); + mISDNport->b_addr[i] = 0; +} + - if (mISDNport->b_state[i] == B_STATE_ACTIVE) +/* +bchannel procedure +------------------ + +A bchannel goes through the following states in this order: + +- B_STATE_IDLE +No one is using the bchannel. +It is available and not linked to Port class, nor reserved. + +- B_STATE_ACTIVATING +The bchannel stack is created and an activation request is sent. +It MAY be linked to Port class, but already unlinked due to Port class removal. + +- B_STATE_ACTIVE +The bchannel is active and cofigured to the Port class needs. +Also it is linked to a Port class, otherwhise it would be deactivated. + +- B_STATE_DEACTIVATING +The bchannel is in deactivating state, due to deactivation request. +It may be linked to a Port class, that likes to reactivate it. + +- B_STATE_IDLE +See above. +After deactivating bchannel, and if not used, the bchannel becomes idle again. + + +A bchannel can have the following events: + +- B_EVENT_ACTIVATE +A bchannel is required by a Port class. + +- B_EVENT_ACTIVATED +The bchannel beomes active. + +- B_EVENT_DEACTIVATE +The bchannel is not required by Port class anymore + +- B_EVENT_DEACTIVATED +The bchannel becomes inactive. + +All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class. + +*/ + +/* + * process bchannel events + * - mISDNport is a pointer to the port's structure + * - i is the index of the bchannel + * - event is the B_EVENT_* value + * - port is the PmISDN class pointer + */ +void bchannel_event(struct mISDNport *mISDNport, int i, int event) +{ + int state = mISDNport->b_state[i]; + + switch(event) { - /* reset dsp features */ + case B_EVENT_ACTIVATE: + /* port may not be used by any other bchannel */ if (mISDNport->b_port[i]) { - if (mISDNport->b_port[i]->p_m_txdata) - { - PDEBUG(DEBUG_BCHANNEL, "during deactivation, we reset txdata from txdata=%d.\n", mISDNport->b_port[i]->p_m_txdata); - ph_control(mISDNport->b_addr[i], CMX_TXDATA_OFF, 0); - } - if (mISDNport->b_port[i]->p_m_delay) - { - PDEBUG(DEBUG_BCHANNEL, "during deactivation, we reset delay from delay=%d.\n", mISDNport->b_port[i]->p_m_delay); - ph_control(mISDNport->b_addr[i], CMX_JITTER, 0); - } - if (mISDNport->b_port[i]->p_m_txvol) - { - PDEBUG(DEBUG_BCHANNEL, "during deactivation, we reset tx-volume from shift=%d.\n", mISDNport->b_port[i]->p_m_txvol); - ph_control(mISDNport->b_addr[i], VOL_CHANGE_TX, 0); - } - if (mISDNport->b_port[i]->p_m_rxvol) - { - PDEBUG(DEBUG_BCHANNEL, "during deactivation, we reset rx-volume from shift=%d.\n", mISDNport->b_port[i]->p_m_rxvol); - ph_control(mISDNport->b_addr[i], VOL_CHANGE_RX, 0); - } - if (mISDNport->b_port[i]->p_m_conf) - { - PDEBUG(DEBUG_BCHANNEL, "during deactivation, we release conference from conf=%d.\n", mISDNport->b_port[i]->p_m_conf); - ph_control(mISDNport->b_addr[i], CMX_CONF_SPLIT, 0); - } - if (mISDNport->b_port[i]->p_m_echo) - { - PDEBUG(DEBUG_BCHANNEL, "during deactivation, we reset echo from echo=%d.\n", mISDNport->b_port[i]->p_m_echo); - ph_control(mISDNport->b_addr[i], CMX_ECHO_OFF, 0); - } - if (mISDNport->b_port[i]->p_m_tone) - { - PDEBUG(DEBUG_BCHANNEL, "during deactivation, we reset tone from tone=%d.\n", mISDNport->b_port[i]->p_m_tone); - ph_control(mISDNport->b_addr[i], TONE_PATT_OFF, 0); - } - if (mISDNport->b_port[i]->p_m_rxoff) + PERROR("SOFTWARE ERROR: bchannel must not be linked to a Port class\n"); + exit(-1); + } + switch(state) + { + case B_STATE_IDLE: + /* create stack and send activation request */ + if (_bchannel_create(mISDNport, i)) { - PDEBUG(DEBUG_BCHANNEL, "during deactivation, we reset rxoff from rxoff=%d.\n", mISDNport->b_port[i]->p_m_rxoff); - ph_control(mISDNport->b_addr[i], CMX_RECEIVE_ON, 0); + _bchannel_activate(mISDNport, i); + state = B_STATE_ACTIVATING; } -#if 0 - if (mISDNport->b_port[i]->p_m_txmix) + break; + + case B_STATE_ACTIVATING: + /* do nothing, because it is already activating */ + break; + + case B_STATE_DEACTIVATING: + /* do nothing, because we must wait until we can reactivate */ + break; + + default: + PERROR("Illegal event %d at state %d, please correct.\n", event, state); + } + break; + + case B_EVENT_ACTIVATED: + switch(state) + { + case B_STATE_ACTIVATING: + if (mISDNport->b_port[i]) { - PDEBUG(DEBUG_BCHANNEL, "during deactivation, we reset txmix from txmix=%d.\n", mISDNport->b_port[i]->p_m_txmix); - ph_control(mISDNport->b_addr[i], CMX_MIX_OFF, 0); - } -#endif - if (mISDNport->b_port[i]->p_m_dtmf) + /* bchannel is active and used by Port class, so we configure bchannel */ + _bchannel_configure(mISDNport, i); + state = B_STATE_ACTIVE; + } else { - PDEBUG(DEBUG_BCHANNEL, "during deactivation, we reset dtmf from dtmf=%d.\n", mISDNport->b_port[i]->p_m_dtmf); - ph_control(mISDNport->b_addr[i], DTMF_TONE_STOP, 0); + /* bchannel is active, but not used anymore (or has wrong stack config), so we deactivate */ + _bchannel_deactivate(mISDNport, i); + state = B_STATE_DEACTIVATING; } - if (mISDNport->b_port[i]->p_m_crypt) + break; + + default: + PERROR("Illegal event %d at state %d, please correct.\n", event, state); + } + break; + + case B_EVENT_DEACTIVATE: + if (!mISDNport->b_port[i]) + { + PERROR("SOFTWARE ERROR: bchannel must be linked to a Port class\n"); + exit(-1); + } + switch(state) + { + case B_STATE_IDLE: + /* bchannel is idle due to an error, so we do nothing */ + break; + + case B_STATE_ACTIVATING: + /* do nothing because we must wait until bchanenl is active before deactivating */ + break; + + case B_STATE_ACTIVE: + /* bchannel is active, so we deactivate */ + _bchannel_deactivate(mISDNport, i); + state = B_STATE_DEACTIVATING; + break; + + case B_STATE_DEACTIVATING: + /* 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_DEACTIVATED: + _bchannel_destroy(mISDNport, i); + state = B_STATE_IDLE; + switch(state) + { + case B_STATE_DEACTIVATING: + if (mISDNport->b_port[i]) { - PDEBUG(DEBUG_BCHANNEL, "during deactivation, we reset crypt from crypt=%d.\n", mISDNport->b_port[i]->p_m_dtmf); - ph_control(mISDNport->b_addr[i], BF_DISABLE, 0); + /* bchannel is now deactivate, but is requied by Port class, so we reactivate */ + if (_bchannel_create(mISDNport, i)) + { + _bchannel_activate(mISDNport, i); + state = B_STATE_ACTIVATING; + } } + break; + + default: + PERROR("Illegal event %d at state %d, please correct.\n", event, state); } - /* deactivate bchannel */ - PDEBUG(DEBUG_BCHANNEL, "deactivating bchannel (index %d), because currently active.\n", i); - dact.prim = DL_RELEASE | REQUEST; - dact.addr = mISDNport->b_addr[i] | FLG_MSG_DOWN; - dact.dinfo = 0; - dact.len = 0; - mISDN_write(mISDNdevice, &dact, mISDN_HEADER_LEN+dact.len, TIMEOUT_1SEC); - mISDNport->b_state[i] = B_STATE_DEACTIVATING; - return; + break; + + default: + PERROR("Illegal event %d, please correct.\n", event); } + + mISDNport->b_state[i] = state; } + + /* * check for available channel and reserve+set it. * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO * give exclusiv flag * returns -(cause value) or x = channel x or 0 = no channel + * NOTE: no activation is done here */ -denke ans aktivieren und deaktivieren int PmISDN::seize_bchannel(int channel, int exclusive) { int i; @@ -407,32 +712,34 @@ int PmISDN::seize_bchannel(int channel, int exclusive) return(-34); /* no free channel */ seize: + PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i); + /* link Port */ p_m_mISDNport->b_port[i] = this; p_m_b_index = i; p_m_b_channel = channel; p_m_b_exclusive = exclusive; - p_m_b_stid = p_m_mISDNport->b_stid[i]; - p_m_b_addr = p_m_mISDNport->b_addr[i]; p_m_jittercheck = 0; /* reserve channel */ - if (p_m_b_reserve == 0) // already reserved + if (!p_m_b_reserve) { p_m_b_reserve = 1; - mISDNport->b_reserved++; + p_m_mISDNport->b_reserved++; } - PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i); - return(channel); } /* * drop reserved channel and unset it. + * deactivation is also done */ void PmISDN::drop_bchannel(void) { + if (p_m_b_index < 0) + return; + /* unreserve channel */ if (p_m_b_reserve) p_m_mISDNport->b_reserved--; @@ -444,62 +751,12 @@ void PmISDN::drop_bchannel(void) PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name); + if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE) + bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DEACTIVATE); p_m_mISDNport->b_port[p_m_b_index] = NULL; p_m_b_index = -1; p_m_b_channel = 0; p_m_b_exclusive = 0; - p_m_b_addr = 0; - p_m_b_stid = 0; -} - - -/* - * data is to be transmitted to the remote - */ -wech void Port::transmit(unsigned char *buffer, int length, int tonelength) -{ - /* send tone data to isdn device only if we have data, otherwhise we send nothing */ - if (tonelength>0 && (p_tone_fh>=0 || p_tone_fetched || p_m_crypt_msg_loops)) - { - unsigned char buf[mISDN_HEADER_LEN+tonelength]; - iframe_t *frm = (iframe_t *)buf; - - if (p_m_crypt_msg_loops) - { - /* send pending message */ - int tosend; - - tosend = p_m_crypt_msg_len - p_m_crypt_msg_current; - if (tosend > newlen) - tosend = newlen; - memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, tosend); - p_m_crypt_msg_current += tosend; - if (p_m_crypt_msg_current == p_m_crypt_msg_len) - { - p_m_crypt_msg_current = 0; - p_m_crypt_msg_loops--; - } - } - frm->prim = DL_DATA | REQUEST; - frm->addr = p_m_b_addr | FLG_MSG_DOWN; - frm->dinfo = 0; - frm->len = tonelength; - memcpy(&frm->data.p, buffer, tonelength); - mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC); - - if (p_debug_nothingtosend) - { - p_debug_nothingtosend = 0; - PDEBUG((DEBUG_PORT | DEBUG_BCHANNEL), "PmISDN(%s) start sending, because we have tones and/or remote audio.\n", p_name); - } - } else - { - if (!p_debug_nothingtosend) - { - p_debug_nothingtosend = 1; - PDEBUG((DEBUG_PORT | DEBUG_BCHANNEL), "PmISDN(%s) stop sending, because we have only silence.\n", p_name); - } - } } @@ -510,38 +767,40 @@ int PmISDN::handler(void) { struct message *message; int elapsed, length; + int ret; + int inbuffer; if ((ret = Port::handler())) return(ret); - inbuffer = (p_fromup_buffer_writep - p_fromup_buffer_readp) & FROMUP_BUFFER_MASK + inbuffer = (p_m_fromup_buffer_writep - p_m_fromup_buffer_readp) & FROMUP_BUFFER_MASK; /* send tone data to isdn device only if we have data */ if (p_tone_fh>=0 || p_tone_fetched || p_m_crypt_msg_loops || inbuffer) { /* calculate how much to transmit */ - if (!p_last_tv.sec) + if (!p_last_tv_sec) { - elapsed = ISDN_PRELOAD << 3; /* preload for the first time */ + elapsed = ISDN_PRELOAD; /* preload for the first time */ } else { - elapsed = 1000 * (now_tv.sec - p_last_tv_sec) - + (now_tv.usec/1000) - p_last_tv_msec; + elapsed = 8000 * (now_tv.tv_sec - p_last_tv_sec) + + 8 * (now_tv.tv_usec/1000 - p_last_tv_msec); /* gap was greater preload, so only fill up to preload level */ - if (elapsed > (ISDN_PRELOAD<<3)) + if (elapsed > ISDN_PRELOAD) { - elapsed = ISDN_PRELOAD << 3 + elapsed = ISDN_PRELOAD; } } if (elapsed >= ISDN_TRANSMIT) { - unsigned char buf[mISDN_HEADER_LEN+(ISDN_PRELOAD<<3)], *p = buf; + unsigned char buf[mISDN_HEADER_LEN+ISDN_PRELOAD], *p = buf; iframe_t *frm = (iframe_t *)buf; - p_last_tv_sec = now_tv.sec; - p_last_tv_msec = now_tv.usec/1000; + p_last_tv_sec = now_tv.tv_sec; + p_last_tv_msec = now_tv.tv_usec/1000; /* read tones */ - length = read_audio(buffer, elapsed); + length = read_audio(p, elapsed); /* * get data from up @@ -555,13 +814,14 @@ int PmISDN::handler(void) if (inbuffer <= length) { /* clear buffer */ - p_fromup_buffer_readp = p_fromup_buffer_writep; + p_m_fromup_buffer_readp = p_m_fromup_buffer_writep; inbuffer = 0; } else { /* skip what we already have with tones */ - p_fromup_buffer_readp = (p_fromup_buffer_readp + length) & FROMUP_BUFFER_MASK; + p_m_fromup_buffer_readp = (p_m_fromup_buffer_readp + length) & FROMUP_BUFFER_MASK; inbuffer -= length; + p += length; } /* if we have more in buffer, than we send this time */ if (inbuffer > (elapsed-length)) @@ -571,8 +831,8 @@ int PmISDN::handler(void) /* now fill up with fromup_buffer */ while (inbuffer) { - *p++ = p_fromup_buffer[p_fromup_buffer_readp]; - p_fromup_buffer_readp = (p_fromup_buffer_readp + 1) & FROMUP_BUFFER_MASK; + *p++ = p_m_fromup_buffer[p_m_fromup_buffer_readp]; + p_m_fromup_buffer_readp = (p_m_fromup_buffer_readp + 1) & FROMUP_BUFFER_MASK; inbuffer--; } } @@ -583,13 +843,17 @@ int PmISDN::handler(void) /* send pending message */ int tosend; - /* we need full length */ - length = elapsed; - check!! + /* how much do we have to send */ tosend = p_m_crypt_msg_len - p_m_crypt_msg_current; - if (tosend > length) - tosend = length; - memcpy(buffer, p_m_crypt_msg+p_m_crypt_msg_current, tosend); + if (tosend > elapsed) + tosend = elapsed; + + /* our length increases, if less */ + if (length < tosend) + length = tosend; + + /* copy message (part) to buffer */ + memcpy(buf, p_m_crypt_msg+p_m_crypt_msg_current, tosend); p_m_crypt_msg_current += tosend; if (p_m_crypt_msg_current == p_m_crypt_msg_len) { @@ -598,10 +862,10 @@ int PmISDN::handler(void) } } frm->prim = DL_DATA | REQUEST; - frm->addr = p_m_b_addr | FLG_MSG_DOWN; + frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN; frm->dinfo = 0; frm->len = length; - memcpy(&frm->data.p, buffer, length); + memcpy(&frm->data.p, buf, length); mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC); if (p_debug_nothingtosend) @@ -613,7 +877,7 @@ int PmISDN::handler(void) } } else { - if (!cwp_debug_nothingtosend) + if (!p_debug_nothingtosend) { p_debug_nothingtosend = 1; PDEBUG((DEBUG_PORT | DEBUG_BCHANNEL), "PmISDN(%s) stop sending, because we have only silence.\n", p_name); @@ -649,10 +913,6 @@ void PmISDN::bchannel_receive(iframe_t *frm) unsigned char *data_temp; unsigned long length_temp; struct message *message; - struct timeval tv; - struct timezone tz; - long long jitter_now; - int newlen; unsigned char *p; int l; unsigned long cont; @@ -690,6 +950,9 @@ void PmISDN::bchannel_receive(iframe_t *frm) // PDEBUG(DEBUG_PORT, "PmISDN(%s) received a PH_CONTROL INDICATION 0x%x\n", p_name, cont); if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL) { + chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN); + add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK); + end_trace(); message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF); message->param.dtmf = cont & DTMF_TONE_MASK; PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf); @@ -699,6 +962,9 @@ void PmISDN::bchannel_receive(iframe_t *frm) switch(cont) { case BF_REJECT: + chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN); + add_trace("DSP-CRYPT", NULL, "error"); + end_trace(); message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT); message->param.crypt.type = CC_ERROR_IND; PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name); @@ -706,6 +972,9 @@ void PmISDN::bchannel_receive(iframe_t *frm) break; case BF_ACCEPT: + chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN); + add_trace("DSP-CRYPT", NULL, "ok"); + end_trace(); message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT); message->param.crypt.type = CC_ACTBF_CONF; PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name); @@ -713,18 +982,20 @@ void PmISDN::bchannel_receive(iframe_t *frm) break; case CMX_TX_DATA: - if (!p_m_txdatad) + if (!p_m_txdata) { /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */ PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring rx data, because 'txdata' is turned off\n", p_name); return; } if (p_record) - record(&(cont+1), frm->len - 4, 1); // from up + record((unsigned char *)(cont+1), frm->len - 4, 1); // from up break; default: - PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION unknown 0x%x.\n", p_name, cont); + chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN); + add_trace("unknown", NULL, "0x%x", cont); + end_trace(); } return; } @@ -785,9 +1056,6 @@ void PmISDN::bchannel_receive(iframe_t *frm) message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA); message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp; memcpy(message->param.data.data, data_temp, message->param.data.len); - message->param.data.compressed = 1; - message->param.data.port_id = p_serial; - message->param.data.port_type = p_type; message_put(message); if (length_temp <= sizeof(message->param.data.data)) break; @@ -818,7 +1086,7 @@ void PmISDN::set_echotest(int echo) PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo); if (p_m_b_channel) if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE) - ph_control(p_m_b_addr, p_m_echo?CMX_ECHO_ON:CMX_ECHO_OFF, 0); + ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], p_m_echo?CMX_ECHO_ON:CMX_ECHO_OFF, 0, "DSP-ECHO", p_m_echo); } } @@ -846,7 +1114,7 @@ void PmISDN::set_tone(char *dir, char *tone) if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE) { PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone); - ph_control(p_m_b_addr, TONE_PATT_OFF, 0); + ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0); } p_m_tone = 0; Port::set_tone(dir, tone); @@ -928,7 +1196,7 @@ void PmISDN::set_tone(char *dir, char *tone) PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone); if (p_m_b_channel) if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE) - ph_control(p_m_b_addr, p_m_tone?TONE_PATT_ON:TONE_PATT_OFF, p_m_tone); + ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], p_m_tone?TONE_PATT_ON:TONE_PATT_OFF, p_m_tone, "DSP-TONE", p_m_tone); } /* turn user-space tones off in cases of no tone OR dsp tone */ Port::set_tone("",NULL); @@ -948,7 +1216,7 @@ void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_txvol); if (p_m_b_channel) if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE) - ph_control(p_m_b_addr, VOL_CHANGE_TX, p_m_txvol); + ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], VOL_CHANGE_TX, p_m_txvol, "DSP-TXVOL", p_m_txvol); } if (p_m_rxvol != param->mISDNsignal.rxvol) { @@ -956,7 +1224,7 @@ void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rxvol); if (p_m_b_channel) if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE) - ph_control(p_m_b_addr, VOL_CHANGE_RX, p_m_rxvol); + ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], VOL_CHANGE_RX, p_m_rxvol, "DSP-RXVOL", p_m_rxvol); } break; @@ -969,7 +1237,7 @@ void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf); if (p_m_b_channel) if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE) - ph_control(p_m_b_addr, (p_m_conf)?CMX_CONF_JOIN:CMX_CONF_SPLIT, p_m_conf); + ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], (p_m_conf)?CMX_CONF_JOIN:CMX_CONF_SPLIT, p_m_conf, "DSP-CONF", p_m_conf); } /* we must set, even if currently tone forbids conf */ p_m_conf = param->mISDNsignal.conf; @@ -981,48 +1249,20 @@ void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union { p_m_calldata = param->mISDNsignal.calldata; PDEBUG(DEBUG_BCHANNEL, "we change to calldata=%d.\n", p_m_calldata); - auch senden } break; -#if 0 - case mISDNSIGNAL_NODATA: - p_m_nodata = param->mISDNsignal.nodata; - if (p_m_txmix == p_m_nodata) /* txmix != !nodata */ - { - p_m_txmix = !p_m_nodata; - PDEBUG(DEBUG_BCHANNEL, "we change mix mode to txmix=%d (nodata=%d).\n", p_m_txmix, p_m_nodata); - if (p_m_b_channel) - if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE) - ph_control(p_m_b_addr, p_m_txmix?CMX_MIX_ON:CMX_MIX_OFF, 0); - } - break; -#endif - -#if 0 - case mISDNSIGNAL_RXOFF: - if (p_m_rxoff != param->mISDNsignal.rxoff) - { - p_m_rxoff = param->mISDNsignal.rxoff; - PDEBUG(DEBUG_BCHANNEL, "we change receive mode to rxoff=%d.\n", p_m_rxoff); - if (p_m_b_channel) - if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE) - ph_control(p_m_b_addr, p_m_rxoff?CMX_RECEIVE_OFF:CMX_RECEIVE_ON, 0); - } - break; - - case mISDNSIGNAL_DTMF: - if (p_m_dtmf != param->mISDNsignal.dtmf) + case mISDNSIGNAL_DELAY: + if (p_m_delay != param->mISDNsignal.delay) { - p_m_dtmf = param->mISDNsignal.dtmf; - PDEBUG(DEBUG_BCHANNEL, "we change dtmf mode to dtmf=%d.\n", p_m_dtmf); + p_m_delay = param->mISDNsignal.delay; + PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay); if (p_m_b_channel) if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE) - ph_control(p_m_b_addr, p_m_dtmf?DTMF_TONE_START:DTMF_TONE_STOP, 0); + ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], p_m_delay?CMX_DELAY:CMX_JITTER, p_m_delay, "DSP-DELAY", p_m_delay); } break; -#endif default: PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message); } @@ -1051,7 +1291,7 @@ void PmISDN::message_crypt(unsigned long epoint_id, int message_id, union parame PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt); if (p_m_b_channel) if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE) - ph_control_block(p_m_b_addr, p_m_crypt?BF_ENABLE_KEY:BF_DISABLE, p_m_crypt_key, p_m_crypt_key_len); + ph_control_block(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], p_m_crypt?BF_ENABLE_KEY:BF_DISABLE, p_m_crypt_key, p_m_crypt_key_len, "DSP-CRYPT", p_m_crypt_key_len); break; case CC_DACT_REQ: /* deactivate session encryption */ @@ -1082,7 +1322,7 @@ void PmISDN::message_crypt(unsigned long epoint_id, int message_id, union parame if (p_m_txmix) { PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix); - ph_control(p_m_b_addr, CMX_MIX_OFF, 0); + ph_control(p_m_mISDNport, this, p_mISDNport->b_addr[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0); } #endif break; @@ -1103,6 +1343,10 @@ int PmISDN::message_epoint(unsigned long epoint_id, int message_id, union parame switch(message_id) { + case MESSAGE_DATA: /* tx-data from upper layer */ + txfromup(param->data.data, param->data.len); + return(1); + case MESSAGE_mISDNSIGNAL: /* user command */ PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message); message_mISDNsignal(epoint_id, message_id, param); @@ -1119,14 +1363,6 @@ int PmISDN::message_epoint(unsigned long epoint_id, int message_id, union parame /* - * transmit function for data to mISDN b-channel - */ -void Port::transmit(unsigned char *buffer, int length) -{ -} - - -/* * main loop for processing messages from mISDN device */ int mISDN_handler(void) @@ -1151,57 +1387,61 @@ int mISDN_handler(void) while(i < mISDNport->b_num) { isdnport=mISDNport->b_port[i]; - /* call bridges in user space OR crypto OR recording */ - if (isdnport->p_m_calldata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record) + if (isdnport) { - /* rx IS required */ - if (isdnport->p_m_rxoff) + /* call bridges in user space OR crypto OR recording */ + if (isdnport->p_m_calldata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record) { - /* turn on RX */ - isdnport->p_m_rxoff = 0; - PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n"); - if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE) - ph_control(isdnport->p_m_b_addr, CMX_RECEIVE_ON, 0); - return(1); - } - } else - { - /* rx NOT required */ - if (!isdnport->p_m_rxoff) + /* rx IS required */ + if (isdnport->p_m_rxoff) + { + /* turn on RX */ + isdnport->p_m_rxoff = 0; + PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n"); + if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE) + ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_ON, 0, "DSP-RXOFF", 0); + return(1); + } + } else { - /* turn off RX */ - isdnport->p_m_rxoff = 1; - PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n"); - if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE) - ph_control(isdnport->p_m_b_addr, CMX_RECEIVE_OFF, 0); - return(1); + /* rx NOT required */ + if (!isdnport->p_m_rxoff) + { + /* turn off RX */ + isdnport->p_m_rxoff = 1; + PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n"); + if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE) + ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1); + return(1); + } } - } - /* recordin */ - if (isdnport->p_record) - { - /* txdata IS required */ - if (!isdnport->p_m_txdata) + /* recording */ + if (isdnport->p_record) { - /* turn on RX */ - isdnport->p_m_txdata = 1; - PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n"); - if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE) - ph_control(isdnport->p_m_b_addr, CMX_TXDATA_ON, 0); - return(1); - } - } else - { - /* txdata NOT required */ - if (isdnport->p_m_txdata) + /* txdata IS required */ + if (!isdnport->p_m_txdata) + { + /* turn on RX */ + isdnport->p_m_txdata = 1; + PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n"); + if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE) + ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1); + return(1); + } + } else { - /* turn off RX */ - isdnport->p_m_txdata = 0; - PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n"); - if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE) - ph_control(isdnport->p_m_b_addr, CMX_TXDATA_OFF, 0); - return(1); + /* txdata NOT required */ + if (isdnport->p_m_txdata) + { + /* turn off RX */ + isdnport->p_m_txdata = 0; + PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n"); + if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE) + ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_OFF, 0, "DSP-TXDATA", 0); + return(1); + } } + } i++; } #if 0 @@ -1234,6 +1474,8 @@ int mISDN_handler(void) act.len = 0; mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC); } + l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | REQUEST, DIRECTION_OUT); + end_trace(); return(1); } } @@ -1330,23 +1572,28 @@ int mISDN_handler(void) case MGR_SHORTSTATUS | CONFIRM: switch(frm->dinfo) { case SSTATUS_L1_ACTIVATED: - PDEBUG(DEBUG_ISDN, "Received SSTATUS_L1_ACTIVATED for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name); + l1l2l3_trace_header(mISDNport, NULL, PH_ACTIVATE | (frm->prim & 0x3), DIRECTION_IN); + end_trace(); goto ss_act; case SSTATUS_L1_DEACTIVATED: - PDEBUG(DEBUG_ISDN, "Received SSTATUS_L1_DEACTIVATED for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name); + l1l2l3_trace_header(mISDNport, NULL, PH_DEACTIVATE | (frm->prim & 0x3), DIRECTION_IN); + end_trace(); goto ss_deact; case SSTATUS_L2_ESTABLISHED: - PDEBUG(DEBUG_ISDN, "Received SSTATUS_L2_ESTABLISHED for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name); + l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | (frm->prim & 0x3), DIRECTION_IN); + end_trace(); goto ss_estab; case SSTATUS_L2_RELEASED: - PDEBUG(DEBUG_ISDN, "Received SSTATUS_L2_RELEASED for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name); + l1l2l3_trace_header(mISDNport, NULL, DL_RELEASE | (frm->prim & 0x3), DIRECTION_IN); + end_trace(); goto ss_rel; } break; case PH_ACTIVATE | CONFIRM: case PH_ACTIVATE | INDICATION: - PDEBUG(DEBUG_ISDN, "Received PH_ACTIVATED for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name); + l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN); + end_trace(); if (mISDNport->ntmode) { mISDNport->l1link = 1; @@ -1360,7 +1607,8 @@ int mISDN_handler(void) case PH_DEACTIVATE | CONFIRM: case PH_DEACTIVATE | INDICATION: - PDEBUG(DEBUG_ISDN, "Received PH_DEACTIVATED for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name); + l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN); + end_trace(); if (mISDNport->ntmode) { mISDNport->l1link = 0; @@ -1379,11 +1627,10 @@ int mISDN_handler(void) case DL_ESTABLISH | INDICATION: case DL_ESTABLISH | CONFIRM: -// PDEBUG(DEBUG_ISDN, "addr 0x%x established data link (DL) TE portnum=%d (DL_ESTABLISH)\n", frm->addr, mISDNport->portnum); + l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN); + end_trace(); if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */ ss_estab: -// if (mISDNport->ntmode) -// break; if (mISDNport->l2establish) { mISDNport->l2establish = 0; @@ -1394,11 +1641,10 @@ int mISDN_handler(void) case DL_RELEASE | INDICATION: case DL_RELEASE | CONFIRM: -// PDEBUG(DEBUG_ISDN, "addr 0x%x released data link (DL) TE portnum=%d (DL_RELEASE)\n", frm->addr, mISDNport->portnum); + l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN); + end_trace(); if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */ ss_rel: -// if (mISDNport->ntmode) -// break; mISDNport->l2link = 0; if (mISDNport->ptp) { @@ -1485,11 +1731,7 @@ int mISDN_handler(void) PERROR("unhandled b-establish (address 0x%x).\n", frm->addr); break; } - mISDNport->b_state[i] = B_STATE_ACTIVE; - if (!mISDNport->b_port[i]) - bchannel_deactivate(mISDNport, i); - else - bchannel_activate(mISDNport, i); + bchannel_event(mISDNport, i, B_EVENT_ACTIVATED); break; case PH_DEACTIVATE | INDICATION: @@ -1509,11 +1751,7 @@ int mISDN_handler(void) PERROR("unhandled b-release (address 0x%x).\n", frm->addr); break; } - mISDNport->b_state[i] = B_STATE_IDLE; - if (mISDNport->b_port[i]) - bchannel_activate(mISDNport, i); - else - bchannel_deactivate(mISDNport, i); + bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED); break; } break; @@ -1538,7 +1776,7 @@ int mISDN_handler(void) /* * global function to add a new card (port) */ -struct mISDNport *mISDN_port_open(int port, int ptp, int ptmp) +struct mISDNport *mISDNport_open(int port, int ptp, int ptmp) { int ret; unsigned char buff[1025]; @@ -1546,14 +1784,12 @@ struct mISDNport *mISDN_port_open(int port, int ptp, int ptmp) stack_info_t *stinf; struct mISDNport *mISDNport, **mISDNportp; int i, cnt; - layer_info_t li; // interface_info_t ii; net_stack_t *nst; manager_t *mgr; - mISDN_pid_t pid; + layer_info_t li; int pri = 0; int nt = 0; - iframe_t dact; /* open mISDNdevice if not already open */ if (mISDNdevice < 0) @@ -1710,6 +1946,7 @@ struct mISDNport *mISDN_port_open(int port, int ptp, int ptmp) while(i < stinf->childcnt) { mISDNport->b_stid[i] = stinf->child[i]; + mISDNport->b_state[i] = B_STATE_IDLE; PDEBUG(DEBUG_ISDN, "b_stid[%d] = 0x%x.\n", i, mISDNport->b_stid[i]); i++; } @@ -1837,70 +2074,16 @@ struct mISDNport *mISDN_port_open(int port, int ptp, int ptmp) PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n"); - /* add all bchannel layers */ - i = 0; - while(i < mISDNport->b_num) - { - /* create new layer */ - PDEBUG(DEBUG_BCHANNEL, "creating bchannel %d (index %d).\n" , i+1+(i>=15), i); - memset(&li, 0, sizeof(li)); - memset(&pid, 0, sizeof(pid)); - li.object_id = -1; - li.extentions = 0; - li.st = mISDNport->b_stid[i]; - UCPY(li.name, "B L4"); - li.pid.layermask = ISDN_LAYER((4)); - li.pid.protocol[4] = ISDN_PID_L4_B_USER; - ret = mISDN_new_layer(mISDNdevice, &li); - if (ret) - { - failed_new_layer: - PERROR("mISDN_new_layer() failed to add bchannel %d (index %d)\n", i+1+(i>=15), i); - goto closeport; - } - mISDNport->b_addr[i] = li.id; - if (!li.id) - { - goto failed_new_layer; - } - PDEBUG(DEBUG_BCHANNEL, "new layer (b_addr=0x%x)\n", mISDNport->b_addr[i]); - - /* create new stack */ - pid.protocol[1] = ISDN_PID_L1_B_64TRANS; - pid.protocol[2] = ISDN_PID_L2_B_TRANS; - pid.protocol[3] = ISDN_PID_L3_B_DSP; - pid.protocol[4] = ISDN_PID_L4_B_USER; - pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) | ISDN_LAYER((4)); - ret = mISDN_set_stack(mISDNdevice, mISDNport->b_stid[i], &pid); - if (ret) - { - stack_error: - PERROR("mISDN_set_stack() failed (ret=%d) to add bchannel (index %d) stid=0x%x\n", ret, i, mISDNport->b_stid[i]); - mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i], MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC); - mISDNport->b_addr[i] = 0; -// mISDNport->b_addr_low[i] = 0; - goto closeport; - } - ret = mISDN_get_setstack_ind(mISDNdevice, mISDNport->b_addr[i]); - if (ret) - goto stack_error; - - /* get layer id */ - mISDNport->b_addr[i] = mISDN_get_layerid(mISDNdevice, mISDNport->b_stid[i], 4); - if (!mISDNport->b_addr[i]) - goto stack_error; - /* deactivate bchannel if already enabled due to crash */ - PDEBUG(DEBUG_BCHANNEL, "deactivating bchannel (index %d) as a precaution.\n", i); - dact.prim = DL_RELEASE | REQUEST; - dact.addr = mISDNport->b_addr[i] | FLG_MSG_DOWN; - dact.dinfo = 0; - dact.len = 0; - mISDN_write(mISDNdevice, &dact, mISDN_HEADER_LEN+dact.len, TIMEOUT_1SEC); - - i++; - } - PDEBUG(DEBUG_ISDN, "- port %d %s (%s) %d b-channels\n", mISDNport->portnum, (mISDNport->ntmode)?"NT-mode":"TE-mode", (mISDNport->ptp)?"Point-To-Point":"Multipoint", mISDNport->b_num); - printlog("opening port %d %s (%s) %d b-channels\n", mISDNport->portnum, (mISDNport->ntmode)?"NT-mode":"TE-mode", (mISDNport->ptp)?"Point-To-Point":"Multipoint", mISDNport->b_num); + start_trace(mISDNport->portnum, + mISDNport->ifport->interface, + NULL, + NULL, + DIRECTION_NONE, + CATEGORY_CH, + 0, + "PORT (open)"); + add_trace("channels", NULL, "%d", mISDNport->b_num); + end_trace(); return(mISDNport); } @@ -1922,7 +2105,7 @@ void mISDNport_close(struct mISDNport *mISDNport) { struct mISDNport **mISDNportp; class Port *port; - classs PmISDN *pmISDN; + class PmISDN *isdnport; net_stack_t *nst; unsigned char buf[32]; int i; @@ -1933,29 +2116,34 @@ void mISDNport_close(struct mISDNport *mISDNport) { if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN) { - pmISDN = (class PmISDN)*port; - if (pmISDN->p_m_mISDNport) + isdnport = (class PmISDN *)port; + if (isdnport->p_m_mISDNport) { - PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", pnISDN->p_name, mISDNport->portnum); - delete pmISDN; + PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum); + delete isdnport; } } port = port->next; } - printlog("closing port %d\n", mISDNport->portnum); + start_trace(mISDNport->portnum, + mISDNport->ifport->interface, + NULL, + NULL, + DIRECTION_NONE, + CATEGORY_CH, + 0, + "PORT (close)"); + end_trace(); /* free bchannels */ i = 0; while(i < mISDNport->b_num) { - bchannel_deactivate(mISDNport, i); - PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i); if (mISDNport->b_stid[i]) { - mISDN_clear_stack(mISDNdevice, mISDNport->b_stid[i]); - if (mISDNport->b_addr[i]) - mISDN_write_frame(mISDNdevice, buf, mISDNport->b_addr[i] | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC); + _bchannel_destroy(mISDNport, i); + PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i); } i++; } @@ -2196,3 +2384,31 @@ void mISDN_port_info(void) } +/* + * enque data from upper buffer + */ +void PmISDN::txfromup(unsigned char *data, int length) +{ + int avail; + /* no data */ + if (!length) + return; + + /* get free samples in buffer */ + avail = ((p_m_fromup_buffer_readp - p_m_fromup_buffer_writep - 1) & FROMUP_BUFFER_MASK); + if (avail < length) + { + PDEBUG(DEBUG_PORT, "Port(%d): fromup_buffer overflows, this shall not happen under normal conditions\n", p_serial); + return; + } + + /* write data to buffer and return */ + while(length) + { + p_m_fromup_buffer[p_m_fromup_buffer_writep] = *data++; + p_m_fromup_buffer_writep = (p_m_fromup_buffer_writep + 1) & FROMUP_BUFFER_MASK; + length--; + } + return; // must return, because length is 0 +} + diff --git a/mISDN.h b/mISDN.h index 49ff539..1798b88 100644 --- a/mISDN.h +++ b/mISDN.h @@ -9,12 +9,22 @@ ** ** \*****************************************************************************/ +enum { + B_STATE_IDLE, + B_STATE_ACTIVATING, + B_STATE_ACTIVE, + B_STATE_DEACTIVATING, +}; -#define B_STATE_IDLE 0 -#define B_STATE_ACTIVATING 1 -#define B_STATE_ACTIVE 2 -#define B_STATE_DEACTIVATING 3 +enum { + B_EVENT_ACTIVATE, + B_EVENT_ACTIVATED, + B_EVENT_DEACTIVATE, + B_EVENT_DEACTIVATED, +}; +#define FROMUP_BUFFER_SIZE 1024 +#define FROMUP_BUFFER_MASK 1023 extern int entity; extern int mISDNdevice; @@ -69,25 +79,28 @@ calls with no bchannel (call waiting, call on hold). /* mISDN none-object functions */ void mISDN_port_info(void); -struct mISDNport *mISDNport_open(int port, int ptp); +struct mISDNport *mISDNport_open(int port, int ptp, int ptmp); void mISDNport_close_all(void); void mISDNport_close(struct mISDNport *mISDNport); void mISDN_port_reorder(void); int mISDN_handler(void); void enc_ie_cause_standalone(unsigned char **ntmode, msg_t *msg, int location, int cause); -void ph_control(unsigned long b_addr, int c1, int c2); -void ph_control_block(unsigned long b_addr, int c1, void *c2, int c2_len); +void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, unsigned long b_addr, int c1, int c2, char *trace_name, int trace_value); +void ph_control_block(struct mISDNport *mISDNport, unsigned long b_addr, int c1, void *c2, int c2_len, char *trace_name, int trace_value); msg_t *create_l2msg(int prim, int dinfo, int size); void setup_queue(struct mISDNport *mISDNport, int link); int stack2manager_nt(void *dat, void *arg); int stack2manager_te(struct mISDNport *mISDNport, msg_t *msg); +void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, char *msgtext, int direction); +void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned long prim, int direction); +void bchannel_event(struct mISDNport *mISDNport, int i, int event); /* mISDN port classes */ class PmISDN : public Port { public: - PmISDN(int type, struct mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel); + PmISDN(int type, struct mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive); ~PmISDN(); void bchannel_receive(iframe_t *frm); int handler(void); @@ -101,10 +114,15 @@ class PmISDN : public Port int p_m_echo, p_m_conf; /* remote echo, conference number */ int p_m_tone; /* current kernel space tone */ int p_m_rxoff; /* rx from driver is disabled */ - int p_m_nodata; /* all parties within a conf are isdn ports, so pure bridging is possible */ -// int p_m_txmix; /* mix tx with conference */ -// int p_m_txmix_on; /* delay for turning back on after sending a binary message, must be signed */ +// int p_m_nodata; /* all parties within a conf are isdn ports, so pure bridging is possible */ + int p_m_txdata; /* get what we transmit */ int p_m_dtmf; /* dtmf decoding is enabled */ + int p_m_calldata; /* the call requires data due to no briging capability */ + + int p_m_fromup_buffer_readp; /* buffer for audio from remote endpoint */ + int p_m_fromup_buffer_writep; + unsigned char p_m_fromup_buffer[FROMUP_BUFFER_SIZE]; + void txfromup(unsigned char *data, int length); int p_m_crypt; /* encryption is enabled */ int p_m_crypt_msg_loops; /* sending a message */ @@ -127,9 +145,7 @@ class PmISDN : public Port int p_m_b_index; /* index 0,1 0..29 */ int p_m_b_channel; /* number 1,2 1..15,17... */ int p_m_b_exclusive; /* if bchannel is exclusive */ -// int p_m_b_reserved; /* set if channel is reserved */ - int p_m_b_stid; /* current stack id */ - int p_m_b_addr; /* current layer address */ + int p_m_b_reserve; /* set if channel is reserved */ long long p_m_jittercheck; /* time of audio data */ long long p_m_jitterdropped; /* number of bytes dropped */ int p_m_delete; /* true if obj. must del. */ @@ -137,8 +153,8 @@ class PmISDN : public Port unsigned long p_m_timeout; /* timeout of timers */ time_t p_m_timer; /* start of timer */ - int alloc_bchannel(int channel, int exclusive); - void free_bchannel(void); + int seize_bchannel(int channel, int exclusive); /* requests / reserves / links bchannels, but does not open it! */ + void drop_bchannel(void); }; extern unsigned char mISDN_rand[256]; /* noisy randomizer */ diff --git a/main.c b/main.c index 9bf22e8..c97e69d 100644 --- a/main.c +++ b/main.c @@ -46,7 +46,7 @@ int global_debug = 0; int quit=0; pthread_mutex_t mutexd; // debug output mutex -pthread_mutex_t mutexl; // log output mutex +//pthread_mutex_t mutext; // trace output mutex pthread_mutex_t mutexe; // error output mutex int memuse = 0; @@ -105,36 +105,6 @@ static void debug(const char *function, int line, char *prefix, char *buffer) debug_newline = 1; } -muss ins trace -void printlog(const char *fmt, ...) -{ - char buffer[4096]; - va_list args; - FILE *fp; - - pthread_mutex_lock(&mutexl); - - va_start(args,fmt); - VUNPRINT(buffer,sizeof(buffer)-1,fmt,args); - buffer[sizeof(buffer)-1]=0; - va_end(args); - - if (options.log[0]) - { - if (options.deb & DEBUG_LOG) - debug(NULL, 0, "LOG ->", buffer); - - if ((fp = fopen(options.log, "a"))) - { - fduse++; - fprintf(fp, "%04d.%02d.%02d %02d:%02d:%02d %s", now_tm->tm_year+1900, now_tm->tm_mon+1, now_tm->tm_mday, now_tm->tm_hour, now_tm->tm_min, now_tm->tm_sec, buffer); - fclose(fp); - fduse--; - } - } - - pthread_mutex_unlock(&mutexl); -} void _printdebug(const char *function, int line, unsigned long mask, const char *fmt, ...) { @@ -231,7 +201,7 @@ int main(int argc, char *argv[]) char prefix_string[64]; struct sched_param schedp; char *debug_prefix = "alloc"; - int created_mutexd = 0, created_mutexl = 0, created_mutexe = 0, + int created_mutexd = 0,/* created_mutext = 0,*/ created_mutexe = 0, created_lock = 0, created_signal = 0, created_debug = 0; #ifdef DEBUG_DURATION time_t durationupdate; @@ -282,12 +252,12 @@ int main(int argc, char *argv[]) goto free; } created_mutexd = 1; - if (pthread_mutex_init(&mutexl, NULL)) - { - fprintf(stderr, "cannot create 'printlog' mutex\n"); - goto free; - } - created_mutexl = 1; +// if (pthread_mutex_init(&mutext, NULL)) +// { +// fprintf(stderr, "cannot create 'trace' mutex\n"); +// goto free; +// } +// created_mutext = 1; if (pthread_mutex_init(&mutexe, NULL)) { fprintf(stderr, "cannot create 'PERROR' mutex\n"); @@ -500,7 +470,6 @@ int main(int argc, char *argv[]) /*** main loop ***/ printf("%s %s started, waiting for calls...\n", NAME, VERSION_STRING); - printlog("%s %s started, waiting for calls...\n", NAME, VERSION_STRING); GET_NOW(); #ifdef DEBUG_DURATION start_d = now_d; @@ -724,7 +693,7 @@ BUDETECT idletime += 4000; } } - printlog("PBX terminated\n"); + printf("PBX terminated\n"); ret=0; /* free all */ @@ -808,9 +777,9 @@ free: if (created_mutexe) if (pthread_mutex_destroy(&mutexe)) fprintf(stderr, "cannot destroy 'PERROR' mutex\n"); - if (created_mutexl) - if (pthread_mutex_destroy(&mutexl)) - fprintf(stderr, "cannot destroy 'printlog' mutex\n"); +// if (created_mutext) +// if (pthread_mutex_destroy(&mutext)) +// fprintf(stderr, "cannot destroy 'trace' mutex\n"); if (created_mutexd) if (pthread_mutex_destroy(&mutexd)) fprintf(stderr, "cannot destroy 'PDEBUG' mutex\n"); diff --git a/main.h b/main.h index 3398cdf..62241fb 100644 --- a/main.h +++ b/main.h @@ -31,7 +31,6 @@ extern int fhuse; #define PDEBUG_RUNTIME(mask, fmt, arg...) _printdebug(NULL, 0, mask, fmt, ## arg) #define PERROR_RUNTIME(fmt, arg...) _printerror(NULL, 0, fmt, ## arg) void _printdebug(const char *function, int line, unsigned long mask, const char *fmt, ...); -void printlog(const char *fmt, ...); void _printerror(const char *function, int line, const char *fmt, ...); #define DEBUG_CONFIG 0x0001 @@ -62,12 +61,12 @@ void _printerror(const char *function, int line, const char *fmt, ...); * preload transmit buffer to avoid gaps at the beginning due to jitter * this is also the maximum load that will be kept in tx-buffer */ -#define ISDN_PRELOAD 128 // 1024 samples +#define ISDN_PRELOAD 1024 // samples /* * interval for refreshing transmit buffer */ -#define ISDN_TRANSMIT 32 // 256 samples +#define ISDN_TRANSMIT 256 // samples /* give sendmail program. if not inside $PATH, give absolute path here (e.g. "/usr/sbin/sendmail") */ diff --git a/message.h b/message.h index 1c2df57..e34e2f3 100644 --- a/message.h +++ b/message.h @@ -118,10 +118,11 @@ enum { /* diversion types */ #define INFO_HLC_AUDIOVISUAL 0xe0 enum { /* isdnsignal */ - mISDNSIGNAL_VOLUME, - mISDNSIGNAL_CONF, + mISDNSIGNAL_VOLUME, /* change volume */ + mISDNSIGNAL_CONF, /* joint/split conference */ mISDNSIGNAL_CALLDATA, /* data required by call instance */ - mISDNSIGNAL_ECHO, + mISDNSIGNAL_ECHO, /* enable/disable echoe */ + mISDNSIGNAL_DELAY, /* use delay or adaptive jitter */ }; /* call-info structure CALLER */ @@ -241,8 +242,6 @@ struct park_info { struct param_data { unsigned char data[512]; /* audio/hdlc data */ int len; /* audio/hdlc data */ -// unsigned long port_id; /* to identify the source of this data */ -// int port_type; /* type of the source's port */ }; struct param_play { @@ -268,6 +267,7 @@ struct param_mISDNsignal { int calldata; int tone; int echo; + int delay; }; /* encryption control structure CRYPT */ diff --git a/options.c b/options.c index e788183..3e5dda8 100644 --- a/options.c +++ b/options.c @@ -31,7 +31,6 @@ struct options options = { "tones_american", /* directory of tones */ "", /* directories of tones to fetch */ "extensions", /* directory of extensions */ - 0, /* dtmf detection on */ "", /* dummy caller id */ 0, /* use tones by dsp.o */ 0, /* by default use priority 0 */ @@ -231,12 +230,6 @@ int read_options(void) PDEBUG(DEBUG_CONFIG, "inernational dial prefix: %s\n", param); } else - if (!strcmp(option,"nodtmf")) - { - options.nodtmf = 1; - - PDEBUG(DEBUG_CONFIG, "disable dtmf detection\n"); - } else if (!strcmp(option,"dummyid")) { SCPY(options.dummyid, param); diff --git a/options.h b/options.h index ecf7e3c..571ba8e 100644 --- a/options.h +++ b/options.h @@ -22,7 +22,6 @@ struct options { char tones_dir[64]; /* directory of all tones/patterns */ char fetch_tones[256]; /* directories of tones to fetch */ char extensions_dir[64]; /* directory of extensions */ - int nodtmf; /* use dtmf detection */ char dummyid[32]; /* caller id for external calls if not available */ int dsptones; /* tones will be generated via dsp.o 1=american 2=ger */ int schedule; /* run process in realtime @ given priority */ diff --git a/port.cpp b/port.cpp index 017ba69..1c0f63e 100644 --- a/port.cpp +++ b/port.cpp @@ -9,6 +9,44 @@ ** ** \*****************************************************************************/ +/* HOW TO audio? + +Audio flow has two ways: + +* from channel to the upper layer + -> sound from mISDN channel + -> announcement from vbox channel + +* from the upper layer to the channel + -> sound from remote channel + -> sound from asterisk + +Audio is required: + + -> if local or remote channel is not mISDN + -> if endpoint is linked to asterisk + -> if call is recorded (vbox) + + +Functions: + +* PmISDN::txfromup + -> audio from upper layer is buffered for later transmission to channel +* PmISDN::handler + -> buffered audio from upper layer or tones are transmitted via system clock +* mISDN_handler + -> rx-data from port to record() and upper layer + -> tx-data from port (dsp) to record() +* VboxPort::handler + -> streaming announcement to upper layer + -> recording announcement +* VboxPort::message_epoint + -> recording audio message from upper layer + + + +*/ + #include #include #include @@ -19,10 +57,6 @@ #include #include "main.h" -#define BETTERDELAY - -//#define MIXER_DEBUG /* debug mixer buffer overflow and underrun */ - class Port *port_first = NULL; unsigned long port_serial = 1; /* must be 1, because 0== no port */ @@ -149,8 +183,6 @@ Port::Port(int type, char *portname, struct port_settings *settings) p_tone_fh = -1; p_tone_fetched = NULL; p_tone_name[0] = '\0'; -// p_knock_fh = -1; -// p_knock_fetched = NULL; p_state = PORT_STATE_IDLE; p_epointlist = NULL; memset(&p_callerinfo, 0, sizeof(p_callerinfo)); @@ -158,19 +190,20 @@ Port::Port(int type, char *portname, struct port_settings *settings) memset(&p_connectinfo, 0, sizeof(p_connectinfo)); memset(&p_redirinfo, 0, sizeof(p_redirinfo)); memset(&p_capainfo, 0, sizeof(p_capainfo)); - memset(p_mixer_buffer, 0, sizeof(p_mixer_buffer)); - memset(p_record_buffer, 0, sizeof(p_record_buffer)); - memset(p_stereo_buffer, 0, sizeof(p_stereo_buffer)); - p_mixer_rel = NULL; - p_mixer_readp = 0; p_echotest = 0; - next = NULL; + + /* call recording */ p_record = NULL; p_record_type = 0; p_record_length = 0; + p_record_skip = 0; p_record_filename[0] = '\0'; + p_record_buffer_readp = 0; + p_record_buffer_writep = 0; + p_record_buffer_dir = 0; /* append port to chain */ + next = NULL; temp = port_first; tempp = &port_first; while(temp) @@ -189,7 +222,6 @@ Port::Port(int type, char *portname, struct port_settings *settings) */ Port::~Port(void) { - struct mixer_relation *relation, *rtemp; class Port *temp, **tempp; struct message *message; @@ -200,18 +232,6 @@ Port::~Port(void) PDEBUG(DEBUG_PORT, "removing port of type %d, name '%s'\n", p_type, p_name); - /* free mixer relation chain */ - relation = p_mixer_rel; - while(relation) - { - rtemp = relation; - relation = relation->next; - memset(rtemp, 0, sizeof(struct mixer_relation)); - free(rtemp); - pmemuse--; - } - p_mixer_rel = NULL; /* beeing paranoid */ - /* disconnect port from endpoint */ while(p_epointlist) { @@ -480,7 +500,6 @@ void Port::set_vbox_speed(int speed) int Port::read_audio(unsigned char *buffer, int length) { int l,len; - int readp; int nodata=0; /* to detect 0-length files and avoid endless reopen */ char filename[128]; int tone_left_before; /* temp variable to determine the change in p_tone_left */ @@ -490,7 +509,6 @@ int Port::read_audio(unsigned char *buffer, int length) return(0); len = length; - codec_in = p_tone_codec; /* if there is no tone set, use silence */ if (p_tone_name[0] == 0) @@ -612,7 +630,6 @@ try_loop: PDEBUG(DEBUG_PORT, "PORT(%s) no tone loop: %s\n",p_name, filename); p_tone_dir[0] = '\0'; p_tone_name[0] = '\0'; - // codec_in = CODEC_LAW; goto rest_is_silence; } fhuse++; @@ -626,7 +643,6 @@ try_loop: PDEBUG(DEBUG_PORT, "PORT(%s) no tone loop: %s\n",p_name, filename); p_tone_dir[0] = '\0'; p_tone_name[0] = '\0'; - // codec_in = CODEC_LAW; goto rest_is_silence; } fhuse++; @@ -642,14 +658,6 @@ done: } -/* - * dummy for transmit function, since this must be inherited - */ -void Port::transmit(unsigned char *buffer, int length, int tonelength) -{ -} - - /* port handler: * process transmission clock */ int Port::handler(void) @@ -672,10 +680,6 @@ int Port::message_epoint(unsigned long epoint_id, int message_id, union paramete set_tone(param->tone.dir,param->tone.name); return(1); - case MESSAGE_DATA: /* tx-data from upper layer */ - fromup(param->data.data, param->data.len); - return(1); - case MESSAGE_VBOX_TONE: /* play tone of answering machine */ PDEBUG(DEBUG_PORT, "PORT(%s) set answering machine tone '%s' '%s'\n", p_name, param->tone.dir, param->tone.name); set_vbox_tone(param->tone.dir, param->tone.name); @@ -818,9 +822,10 @@ void Port::close_record(int beep) if (!p_record) return; + PDEBUG(DEBUG_PORT, "data still in record buffer: %d (dir %d)\n", (p_record_buffer_writep - p_record_buffer_readp) & RECORD_BUFFER_MASK, p_record_buffer_dir); memcpy(&callerinfo, &p_callerinfo, sizeof(struct caller_info)); - apply_callerid_restriction(p_record_anon_ignore, -1, callerinfo.id, &callerinfo.ntype, &callerinfo.present, &callerinfo.screen, callerinfo.voip, callerinfo.intern, callerinfo.name); + apply_callerid_restriction(p_record_anon_ignore, -1, callerinfo.id, &callerinfo.ntype, &callerinfo.present, &callerinfo.screen, NULL/*callerinfo.voip*/, callerinfo.extension, callerinfo.name); SCPY(number, p_dialinginfo.number); SCPY(callerid, numberrize_callerinfo(callerinfo.id, callerinfo.ntype)); @@ -1011,7 +1016,7 @@ void Port::close_record(int beep) /* send email with sample*/ if (p_record_vbox_email[0]) { - send_mail(p_record_vbox_email_file?filename:(char *)"", callerid, callerinfo.intern, callerinfo.name, p_record_vbox_email, p_record_vbox_year, p_record_vbox_mon, p_record_vbox_mday, p_record_vbox_hour, p_record_vbox_min, p_record_extension); + send_mail(p_record_vbox_email_file?filename:(char *)"", callerid, callerinfo.extension, callerinfo.name, p_record_vbox_email, p_record_vbox_year, p_record_vbox_mon, p_record_vbox_mday, p_record_vbox_hour, p_record_vbox_min, p_record_extension); } } } @@ -1025,26 +1030,36 @@ void Port::close_record(int beep) * * If one stream (dir) received packets, they are stored to a * buffer to wait for the other stream (dir), so both streams can - * be combined. If the buffer is full, it's read pointer is written - * without mixing stream. + * be combined. If the buffer is full, it's content is written + * without mixing stream. (assuming only one stram (dir) exists.) * A flag is used to indicate what stream is currently in buffer. * * NOTE: First stereo sample (odd) is from down, second is from up. */ -alle buffer initialisieren -record nur aufrufen, wenn recorded wird. -restlicher buffer wegschreiben beim schliessen -void Port::record(char *data, int length, int dir_fromup) +void Port::record(unsigned char *data, int length, int dir_fromup) { unsigned char write_buffer[1024], *d; signed short *s; - int r, w; + int free, i, ii; signed long sample; /* no recording */ if (!p_record || !length) return; + /* skip */ + if (dir_fromup) + { + /* more than we have */ + if (p_record_skip > length) + { + p_record_skip -= length; + return; + } + data += p_record_skip; + length -= p_record_skip; + } + free = ((p_record_buffer_readp - p_record_buffer_writep - 1) & RECORD_BUFFER_MASK); /* the buffer stores the same data stream */ @@ -1055,7 +1070,7 @@ void Port::record(char *data, int length, int dir_fromup) /* first write what we can to the buffer */ while(free && length) { - p_record_buffer[p_record_buffer_writep] = audio_law_to_s32(*data++); + p_record_buffer[p_record_buffer_writep] = audio_law_to_s32[*data++]; p_record_buffer_writep = (p_record_buffer_writep + 1) & RECORD_BUFFER_MASK; free--; length--; @@ -1132,9 +1147,7 @@ void Port::record(char *data, int length, int dir_fromup) free += sizeof(write_buffer); goto same_again; } - - /* the buffer store the other stream */ - different_again: + /* the buffer stores the other stream */ /* if buffer empty, change it */ if (p_record_buffer_readp == p_record_buffer_writep) @@ -1155,7 +1168,7 @@ void Port::record(char *data, int length, int dir_fromup) while(i < ii) { sample = p_record_buffer[p_record_buffer_readp] - + audio_law_to_s32(*data++); + + audio_law_to_s32[*data++]; p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK; if (sample < 32767) sample = -32767; @@ -1174,7 +1187,7 @@ void Port::record(char *data, int length, int dir_fromup) i = 0; while(i < ii) { - *s++ = audio_law_to_s32(*data++); + *s++ = audio_law_to_s32[*data++]; *s++ = p_record_buffer[p_record_buffer_readp]; p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK; i++; @@ -1185,7 +1198,7 @@ void Port::record(char *data, int length, int dir_fromup) while(i < ii) { *s++ = p_record_buffer[p_record_buffer_readp]; - *s++ = audio_law_to_s32(*data++); + *s++ = audio_law_to_s32[*data++]; i++; } } @@ -1198,7 +1211,7 @@ void Port::record(char *data, int length, int dir_fromup) while(i < ii) { sample = p_record_buffer[p_record_buffer_readp] - + audio_law_to_s32(*data++); + + audio_law_to_s32[*data++]; p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK; if (sample < 32767) sample = -32767; @@ -1216,7 +1229,7 @@ void Port::record(char *data, int length, int dir_fromup) while(i < ii) { sample = p_record_buffer[p_record_buffer_readp] - + audio_law_to_s32(*data++); + + audio_law_to_s32[*data++]; p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK; if (sample < 32767) sample = -32767; @@ -1241,32 +1254,3 @@ void Port::record(char *data, int length, int dir_fromup) } -/* - * enque data from upper buffer - */ -iniialisieren der werte -void Port::txfromup(unsigned char *data, int length) -{ - - /* no recording */ - if (!length) - return; - - /* get free samples in buffer */ - free = ((p_fromup_buffer_readp - p_fromup_buffer_writep - 1) & FROMUP_BUFFER_MASK); - if (free < length) - { - PDEBUG(DEBUG_PORT, "Port(%d): fromup_buffer overflows, this shall not happen under normal conditions\n", p_serial); - return; - } - - /* write data to buffer and return */ - while(length) - { - p_fromup_buffer[p_fromup_buffer_writep] = *data++; - p_fromup_buffer_writep = (p_fromup_buffer_writep + 1) & FROMUP_BUFFER_MASK; - length--; - } - return; // must return, because length is 0 -} - diff --git a/port.h b/port.h index 0ee91e7..3a7bdb1 100644 --- a/port.h +++ b/port.h @@ -80,6 +80,9 @@ enum { /* event list from listening to tty */ TTYI_EVENT_BUSY, /* channel unavailable */ }; +#define RECORD_BUFFER_LENGTH 1024 +#define RECORD_BUFFER_MASK 1023 + /* structure of epoint_list */ struct epoint_list { struct epoint_list *next; @@ -110,13 +113,6 @@ inline unsigned long INACTIVE_EPOINT(struct epoint_list *epointlist) } -/* a linked list of soft-mixer relations */ -struct mixer_relation { - struct mixer_relation *next; /* next in list */ - unsigned long port_id; /* port related to */ - int mixer_writep; /* write pointer in buffer */ - }; - /* structure of port settings */ struct port_settings { char tones_dir[256]; /* directory of current tone */ @@ -144,11 +140,12 @@ class Port virtual void set_echotest(int echotest); virtual void set_tone(char *dir, char *name); virtual int read_audio(unsigned char *buffer, int length); - virtual void transmit(unsigned char *buffer, int length); struct port_settings p_settings; /* tone */ + unsigned long p_last_tv_sec; /* time stamp of last handler call, (to sync audio data */ + unsigned long p_last_tv_msec; int p_debug_nothingtosend; /* used for debugging the, if we have currently nothing to send (used for ISDN) */ char p_tone_dir[256]; /* name of current directory */ char p_tone_name[256]; /* name of current tone */ @@ -187,10 +184,17 @@ class Port /* recording */ int open_record(int type, int mode, int skip, char *terminal, int anon_ignore, char *vbox_email, int vbox_email_file); void close_record(int beep); + void record(unsigned char *data, int length, int dir_fromup); FILE *p_record; /* recording fp: if not NULL, recording is enabled */ int p_record_type; /* codec to use: RECORD_MONO, RECORD_STEREO, ... */ int p_record_skip; /* skip bytes before writing the sample */ unsigned long p_record_length; /* size of what's written so far */ + + unsigned char p_record_buffer[RECORD_BUFFER_LENGTH]; + unsigned long p_record_buffer_readp; + unsigned long p_record_buffer_writep; + int p_record_buffer_dir; /* current direction in buffer */ + char p_record_filename[256]; /* record filename */ int p_record_vbox; /* 0= normal recording, 1= announcement, 2= record to vbox dir */ int p_record_vbox_year; /* time when vbox recording started */ diff --git a/route.c b/route.c index c950587..c992686 100644 --- a/route.c +++ b/route.c @@ -364,7 +364,7 @@ struct action_defs action_defs[] = { { ACTION_EFI, "efi", &EndpointAppPBX::action_init_efi, NULL, NULL, PARAM_PROCEEDING | PARAM_ALERTING | PARAM_CONNECT, - "Elektronische Fernsprecher Identifikation."}, + "Elektronische Fernsprecher Identifikation - announces caller ID."}, { -1, NULL, NULL, NULL, NULL, 0, NULL} }; diff --git a/route.h b/route.h index e89fb89..97a2429 100644 --- a/route.h +++ b/route.h @@ -131,7 +131,7 @@ enum { /* how to parse text file during startup */ #define PARAM_ROOM (1LL<<39) #define PARAM_TIMEOUT (1LL<<40) #define PARAM_NOPASSWORD (1LL<<41) -#define PARAM_STRIP (1LL<<42) +#define PARAM_STRIP (1LL<<42) /* action index diff --git a/tones.c b/tones.c index 5d64125..0cd4684 100644 --- a/tones.c +++ b/tones.c @@ -278,10 +278,15 @@ int open_tone(char *file, int *codec, signed long *length, signed long *left) * the len must be the number of samples, NOT for the bytes to read!! * the data returned is law-code */ -int read_tone(int fh, void *buffer, int codec, int len, signed long size, signed long *left, int speed) +int read_tone(int fh, unsigned char *buffer, int codec, int len, signed long size, signed long *left, int speed) { int l; int offset; + signed short buffer16[len], *buf16 = buffer16; + signed short buffer32[len<<1], *buf32 = buffer32; + unsigned char buffer8[len], *buf8 = buffer8; + signed long sample; + int i = 0; //printf("left=%ld\n",*left); /* if no *left is given (law has unknown length) */ @@ -320,9 +325,6 @@ int read_tone(int fh, void *buffer, int codec, int len, signed long size, signed break; case CODEC_MONO: - signed short buffer16[len], *buf16 = buffer16; - signed long sample; - int i = 0; l = read(fh, buf16, len<<1); if (l>0) { @@ -342,9 +344,6 @@ int read_tone(int fh, void *buffer, int codec, int len, signed long size, signed case CODEC_STEREO: { - signed short buffer32[len<<1], *buf32 = buffer32; - signed long sample; - int i = 0; l = read(fh, buf32, len<<2); if (l>0) { @@ -365,8 +364,6 @@ int read_tone(int fh, void *buffer, int codec, int len, signed long size, signed case CODEC_8BIT: { - unsigned char buffer8[len], *buf8 = buffer8; - int i = 0; l = read(fh, buf8, len); if (l>0) { diff --git a/tones.h b/tones.h index 9901dc5..3cfaf77 100644 --- a/tones.h +++ b/tones.h @@ -10,11 +10,11 @@ \*****************************************************************************/ int open_tone(char *file, int *codec, signed long *length, signed long *left); -int read_tone(int fh, void *buffer, int codec, int len, signed long size, signed long *left, int speed); +int read_tone(int fh, unsigned char *buffer, int codec, int len, signed long size, signed long *left, int speed); int fetch_tones(void); void free_tones(void); void *open_tone_fetched(char *dir, char *file, int *codec, signed long *length, signed long *left); -int read_tone_fetched(void **fetched, void *buffer, int codec, int len, signed long size, signed long *left, int speed); +int read_tone_fetched(void **fetched, void *buffer, int len, signed long size, signed long *left, int speed); /* tone sets */ struct tonesettone { diff --git a/trace.c b/trace.c index 999a6fe..ebe117d 100644 --- a/trace.c +++ b/trace.c @@ -11,6 +11,7 @@ #include "main.h" +trace auch ein printdebug struct trace trace; char trace_string[MX_TRACE_ELEMENTS * 100 + 400]; @@ -32,7 +33,7 @@ static char *spaces[11] = { * initializes a new trace * all values will be reset */ -void start_trace(int port, char *interface, char *caller, char *dialing, int direction, int category, int serial, char *name); +void start_trace(int port, struct interface *interface, char *caller, char *dialing, int direction, int category, int serial, char *name) { if (trace.name[0]) PERROR("trace already started (name=%s)\n", trace.name); @@ -106,6 +107,8 @@ void end_trace(void); { string = print_trace(1, 0, NULL, NULL, NULL, -1, "AP", CATEGORY_EP); fwrite(string, strlen(string), 1, fp); + if (options.deb) + debug(NULL, 0, "trace", string); } memset(trace, 0, sizeof(struct trace)); @@ -211,7 +214,10 @@ static char *print_trace(int detail, int port, char *interface, char *caller, ch default: SCAT(trace_string, "--"); } - SPRINT(buffer, "(%d): %s", trace.serial, trace.name[0]?trace.name:""); + if (trace.serial) + SPRINT(buffer, "(%d): %s", trace.serial, trace.name[0]?trace.name:""); + else + SPRINT(buffer, ": %s", trace.name[0]?trace.name:""); SCAT(trace_string, buffer); /* elements */ diff --git a/trace.h b/trace.h index e7012e0..816f660 100644 --- a/trace.h +++ b/trace.h @@ -41,7 +41,9 @@ struct trace { #define CATEGORY_EP 0x02 -void start_trace(int port, char *interface, char *caller, char *dialing, int direction, char *category, char *name); -void add_trace(char *name, char *sub, char *value); +void start_trace(int port, struct interface *interface, char *caller, char *dialing, int direction, int category, int serial, char *name); +void add_trace(char *name, char *sub, const char *fmt, ...); void end_trace(void); //char *print_trace(int port, char *interface, char *caller, char *dialing, int direction, char *category, char *name); + + diff --git a/vbox.cpp b/vbox.cpp index d0f124d..bbd0c50 100644 --- a/vbox.cpp +++ b/vbox.cpp @@ -62,7 +62,7 @@ int VBoxPort::handler(void) { struct message *message; unsigned long tosend; - unsigned char buffer[ISDN_TRANSMIT<<3]; + unsigned char buffer[ISDN_TRANSMIT]; time_t currenttime; class Endpoint *epoint; int ret; @@ -160,8 +160,6 @@ int VBoxPort::handler(void) if (p_record) record(buffer, tosend, 0); // from down message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA); - message->param.data.port_type = p_type; - message->param.data.port_id = p_serial; message->param.data.len = tosend; memcpy(message->param.data.data, buffer, tosend); message_put(message); @@ -180,7 +178,6 @@ int VBoxPort::message_epoint(unsigned long epoint_id, int message_id, union para struct message *message; class Endpoint *epoint; char filename[256], *c; - class EndpointAppPBX *eapp; if (Port::message_epoint(epoint_id, message_id, param)) return(1); @@ -194,6 +191,10 @@ int VBoxPort::message_epoint(unsigned long epoint_id, int message_id, union para switch(message_id) { + case MESSAGE_DATA: + record(param->data.data, param->data.len, 1); // from up + return(1); + case MESSAGE_DISCONNECT: /* call has been disconnected */ PDEBUG(DEBUG_VBOX, "PORT(%s) vbox port with (caller id %s) received disconnect cause=%d\n", p_name, p_callerinfo.id, param->disconnectinfo.cause); @@ -224,7 +225,7 @@ int VBoxPort::message_epoint(unsigned long epoint_id, int message_id, union para case MESSAGE_SETUP: /* dial-out command received from epoint, answer with connect */ /* get apppbx */ - memcpy(&p_vbox_ext, ((class EndpointAppPBX *)(epoint->ep_app))->e_ext, sizeof(p_vbox_ext)); + memcpy(&p_vbox_ext, &((class EndpointAppPBX *)(epoint->ep_app))->e_ext, sizeof(p_vbox_ext)); /* extract optional announcement file */ if ((c = strchr(param->setup.dialinginfo.number, ','))) { diff --git a/vbox.h b/vbox.h index e9f8168..3a7dc3a 100644 --- a/vbox.h +++ b/vbox.h @@ -33,5 +33,7 @@ class VBoxPort : public Port unsigned long p_vbox_audio_transferred; /* number of samples sent to endpoint */ signed long p_vbox_record_start; /* start for recording */ signed long p_vbox_record_limit; /* limit for recording */ + + struct extension p_vbox_ext; /* save settings of extension */ };