Common subdirectories: libpri.org/build_tools and libpri/build_tools diff -uN libpri.org/libpri.h libpri/libpri.h --- libpri.org/libpri.h 2009-03-26 12:01:45.000000000 -0400 +++ libpri/libpri.h 2010-01-12 11:09:18.000000000 -0500 @@ -450,6 +450,18 @@ struct pri; struct pri_sr; +#define MAX_SPID_SIZE 16 +#define MAX_BRI_SERVICES 2 + +struct bri_service_element { + char spid[MAX_SPID_SIZE]; + int channel_id; +}; + +struct bri_services { + struct bri_service_element lines[MAX_BRI_SERVICES]; +}; + #define PRI_IO_FUNCS /* Type declaration for callbacks to read or write a HDLC frame as below */ typedef int (*pri_io_cb)(struct pri *pri, void *buf, int buflen); @@ -461,6 +473,8 @@ struct pri *pri_new(int fd, int nodetype, int switchtype); struct pri *pri_new_bri(int fd, int ptpmode, int nodetype, int switchtype); +struct pri *pri_new_bri_ex(int fd, int ptpmode, int nodetype, int switchtype, struct bri_services * services); + /* Create D-channel just as above with user defined I/O callbacks and data */ struct pri *pri_new_cb(int fd, int nodetype, int switchtype, pri_io_cb io_read, pri_io_cb io_write, void *userdata); diff -uN libpri.org/pri.c libpri/pri.c --- libpri.org/pri.c 2009-09-29 11:32:23.000000000 -0400 +++ libpri/pri.c 2010-01-12 11:09:47.000000000 -0500 @@ -198,7 +198,7 @@ free (p); } -struct pri *__pri_new_tei(int fd, int node, int switchtype, struct pri *master, pri_io_cb rd, pri_io_cb wr, void *userdata, int tei, int bri) +struct pri *__pri_new_tei(int fd, int node, int switchtype, struct pri *master, pri_io_cb rd, pri_io_cb wr, void *userdata, int tei, int bri, struct bri_services *services) { struct pri *p; @@ -219,6 +219,11 @@ p->protodisc = Q931_PROTOCOL_DISCRIMINATOR; p->master = master; p->callpool = &p->localpool; + p->line_service.channel_id = 0; + if(services && bri) + p->bri_services = *services; + else + memset(&(p->bri_services),0,sizeof(p->bri_services)); pri_default_timers(p, switchtype); if (master) { pri_set_debug(p, master->debug); @@ -235,7 +240,7 @@ p->protodisc = GR303_PROTOCOL_DISCRIMINATOR; p->sapi = Q921_SAPI_GR303_EOC; p->tei = Q921_TEI_GR303_EOC_OPS; - p->subchannel = __pri_new_tei(-1, node, PRI_SWITCH_GR303_EOC_PATH, p, NULL, NULL, NULL, Q921_TEI_GR303_EOC_PATH, 0); + p->subchannel = __pri_new_tei(-1, node, PRI_SWITCH_GR303_EOC_PATH, p, NULL, NULL, NULL, Q921_TEI_GR303_EOC_PATH, 0, NULL); if (!p->subchannel) { free(p); p = NULL; @@ -244,7 +249,7 @@ p->protodisc = GR303_PROTOCOL_DISCRIMINATOR; p->sapi = Q921_SAPI_GR303_TMC_CALLPROC; p->tei = Q921_TEI_GR303_TMC_CALLPROC; - p->subchannel = __pri_new_tei(-1, node, PRI_SWITCH_GR303_TMC_SWITCHING, p, NULL, NULL, NULL, Q921_TEI_GR303_TMC_SWITCHING, 0); + p->subchannel = __pri_new_tei(-1, node, PRI_SWITCH_GR303_TMC_SWITCHING, p, NULL, NULL, NULL, Q921_TEI_GR303_TMC_SWITCHING, 0, NULL); if (!p->subchannel) { free(p); p = NULL; @@ -288,15 +293,23 @@ struct pri *pri_new(int fd, int nodetype, int switchtype) { - return __pri_new_tei(fd, nodetype, switchtype, NULL, __pri_read, __pri_write, NULL, Q921_TEI_PRI, 0); + return __pri_new_tei(fd, nodetype, switchtype, NULL, __pri_read, __pri_write, NULL, Q921_TEI_PRI, 0, NULL); } struct pri *pri_new_bri(int fd, int ptpmode, int nodetype, int switchtype) { if (ptpmode) - return __pri_new_tei(fd, nodetype, switchtype, NULL, __pri_read, __pri_write, NULL, Q921_TEI_PRI, 1); + return __pri_new_tei(fd, nodetype, switchtype, NULL, __pri_read, __pri_write, NULL, Q921_TEI_PRI, 1, NULL); + else + return __pri_new_tei(fd, nodetype, switchtype, NULL, __pri_read, __pri_write, NULL, Q921_TEI_GROUP, 1, NULL); +} + +struct pri *pri_new_bri_ex(int fd, int ptpmode, int nodetype, int switchtype, struct bri_services * services) +{ + if (ptpmode) + return __pri_new_tei(fd, nodetype, switchtype, NULL, __pri_read, __pri_write, NULL, Q921_TEI_PRI, 1, services); else - return __pri_new_tei(fd, nodetype, switchtype, NULL, __pri_read, __pri_write, NULL, Q921_TEI_GROUP, 1); + return __pri_new_tei(fd, nodetype, switchtype, NULL, __pri_read, __pri_write, NULL, Q921_TEI_GROUP, 1, services); } struct pri *pri_new_cb(int fd, int nodetype, int switchtype, pri_io_cb io_read, pri_io_cb io_write, void *userdata) @@ -305,7 +318,7 @@ io_read = __pri_read; if (!io_write) io_write = __pri_write; - return __pri_new_tei(fd, nodetype, switchtype, NULL, io_read, io_write, userdata, Q921_TEI_PRI, 0); + return __pri_new_tei(fd, nodetype, switchtype, NULL, io_read, io_write, userdata, Q921_TEI_PRI, 0, NULL); } void *pri_get_userdata(struct pri *pri) diff -uN libpri.org/pri_internal.h libpri/pri_internal.h --- libpri.org/pri_internal.h 2008-10-17 12:13:42.000000000 -0400 +++ libpri/pri_internal.h 2010-01-11 14:20:45.000000000 -0500 @@ -51,6 +51,9 @@ #define MAX_TIMERS 32 +#define GET_MASTER_PRI(master,pri) for(master=pri;master->master;master=master->master) + + struct pri { int fd; /* File descriptor for D-Channel */ pri_io_cb read_func; /* Read data callback */ @@ -127,6 +130,9 @@ unsigned char last_invoke; /* Last ROSE invoke ID */ unsigned char sendfacility; + + struct bri_services bri_services; + struct bri_service_element line_service; }; struct pri_sr { @@ -264,6 +270,9 @@ /* Bridged call info */ q931_call *bridged_call; /* Pointer to other leg of bridged call */ + + char spid[MAX_SPID_SIZE]; + char eid[MAX_SPID_SIZE]; }; extern int pri_schedule_event(struct pri *pri, int ms, void (*function)(void *data), void *data); @@ -280,7 +289,7 @@ void libpri_copy_string(char *dst, const char *src, size_t size); -struct pri *__pri_new_tei(int fd, int node, int switchtype, struct pri *master, pri_io_cb rd, pri_io_cb wr, void *userdata, int tei, int bri); +struct pri *__pri_new_tei(int fd, int node, int switchtype, struct pri *master, pri_io_cb rd, pri_io_cb wr, void *userdata, int tei, int bri, struct bri_services * services); void __pri_free_tei(struct pri *p); diff -uN libpri.org/pri_q931.h libpri/pri_q931.h --- libpri.org/pri_q931.h 2008-10-17 12:13:42.000000000 -0400 +++ libpri/pri_q931.h 2010-01-09 16:14:15.000000000 -0500 @@ -216,6 +216,8 @@ #define Q931_IE_GENERIC_DIGITS (0x37 | Q931_CODESET(6)) #define Q931_IE_FEATURE_ACTIVATE 0x38 #define Q931_IE_FEATURE_IND 0x39 +#define Q931_IE_SPID 0x3A +#define Q931_IE_EID 0x3B #define Q931_IE_ORIGINAL_CALLED_NUMBER 0x73 #define Q931_IE_REDIRECTION_NUMBER 0x76 #define Q931_IE_REDIRECTION_SUBADDR 0x77 diff -uN libpri.org/q921.c libpri/q921.c --- libpri.org/q921.c 2009-09-29 11:32:23.000000000 -0400 +++ libpri/q921.c 2010-01-12 12:04:03.000000000 -0500 @@ -58,7 +58,8 @@ static void reschedule_t203(struct pri *pri); static void reschedule_t200(struct pri *pri); static void q921_restart(struct pri *pri, int now); -static void q921_tei_release_and_reacquire(struct pri *master); +static void q921_all_tei_release_and_reacquire(struct pri *master); +static void q921_one_tei_release_and_reacquire(struct pri *pri); static void q921_discard_retransmissions(struct pri *pri) { @@ -195,11 +196,11 @@ pri_error(pri, "Don't know how to U/A on a type %d node\n", pri->localtype); return; } - if (pri->bri && (pri->state == Q921_AWAITING_ESTABLISH)) { + if (pri->bri && (pri->q921_state == Q921_AWAITING_ESTABLISH) && (pri->sapi == Q921_SAPI_CALL_CTRL)) { if (pri->sabme_count >= pri->timers[PRI_TIMER_N200]) { pri_schedule_del(pri, pri->sabme_timer); pri->sabme_timer = 0; - q921_tei_release_and_reacquire(pri->master); + q921_one_tei_release_and_reacquire(pri); } else { pri->sabme_count++; } @@ -445,7 +446,7 @@ pri->q921_state = Q921_LINK_CONNECTION_RELEASED; pri->t200_timer = 0; if (pri->bri && pri->master) { - q921_tei_release_and_reacquire(pri->master); + q921_one_tei_release_and_reacquire(pri); return; } else { q921_dchannel_down(pri); @@ -469,7 +470,7 @@ pri->q921_state = Q921_LINK_CONNECTION_RELEASED; pri->t200_timer = 0; if (pri->bri && pri->master) { - q921_tei_release_and_reacquire(pri->master); + q921_one_tei_release_and_reacquire(pri); return; } else { q921_dchannel_down(pri); @@ -865,21 +866,67 @@ q921_discard_retransmissions(pri); } -static void q921_tei_release_and_reacquire(struct pri *master) +static void q921_all_tei_release_and_reacquire(struct pri *master) { /* Make sure the master is passed into this function */ - q921_dchannel_down(master->subchannel); - __pri_free_tei(master->subchannel); + pri_message(master, "Release all TEI and Reacquire\n"); + struct pri * sub = master->subchannel; + + while(sub) + { + struct pri *next = sub->subchannel; + sub->subchannel = NULL; + q921_dchannel_down(sub); + __pri_free_tei(sub); + sub = next; + } + master->subchannel = NULL; master->ev.gen.e = PRI_EVENT_DCHAN_DOWN; master->schedev = 1; q921_start(master, master->localtype == PRI_CPE); } +static void q921_one_tei_release_and_reacquire(struct pri *pri) +{ + struct pri *master = pri->master; + /* Make sure the master is passed into this function */ + pri_message(pri, "Release TEI %d\n",pri->tei); + q921_dchannel_down(pri); + if (master) + { + struct pri *prev = master; + /* Remove pri from subchannels chain */ + while(prev) + { + if (prev->subchannel == pri) + { + prev->subchannel = pri->subchannel; + break; + } + prev = prev->subchannel; + } + } + __pri_free_tei(pri); + + if (master) + { + /* If no subchannels then restart the master channel*/ + if(!master->subchannel) + { + pri_message(master, "Restart Master Channel\n"); + master->ev.gen.e = PRI_EVENT_DCHAN_DOWN; + master->schedev = 1; + q921_start(master, master->localtype == PRI_CPE); + } + } +} + static pri_event *q921_receive_MDL(struct pri *pri, q921_u *h, int len) { int ri; struct pri *sub; + struct pri *next; int tei; if (pri->debug & PRI_DEBUG_Q921_STATE) pri_message(pri, "Received MDL message\n"); @@ -901,16 +948,32 @@ } /* Go to master */ for (sub = pri; sub->master; sub = sub->master); - tei = 64; - while(sub->subchannel) { - if(sub->subchannel->tei == tei) - ++tei; - } - sub->subchannel = __pri_new_tei(-1, pri->localtype, pri->switchtype, pri, NULL, NULL, NULL, tei, 1); + + tei = 64; + while(sub->subchannel) { + if (sub->subchannel->tei >= tei) + { + if (sub->subchannel->tei == tei) + ++tei; + else + break; + } + sub = sub->subchannel; + } + + next = sub->subchannel; + sub->subchannel = __pri_new_tei(-1, pri->localtype, pri->switchtype, pri, NULL, NULL, NULL, tei, 1, NULL); if (!sub->subchannel) { pri_error(pri, "Unable to allocate D-channel for new TEI %d\n", tei); return NULL; } + sub->subchannel->subchannel = next; + /* Stop any SABME retransmissions */ + if (pri->sabme_timer) { + pri_schedule_del(pri, pri->sabme_timer); + pri->sabme_timer = 0; + } + q921_send_tei(pri, Q921_TEI_IDENTITY_ASSIGNED, ri, tei, 1); break; case Q921_TEI_IDENTITY_ASSIGNED: @@ -924,12 +987,12 @@ } if (pri->subchannel && (pri->subchannel->tei == tei)) { pri_error(pri, "TEI already assigned (new is %d, current is %d)\n", tei, pri->subchannel->tei); - q921_tei_release_and_reacquire(pri); + q921_all_tei_release_and_reacquire(pri); return NULL; } pri_message(pri, "TEI assiged to %d\n", tei); - pri->subchannel = __pri_new_tei(-1, pri->localtype, pri->switchtype, pri, NULL, NULL, NULL, tei, 1); + pri->subchannel = __pri_new_tei(-1, pri->localtype, pri->switchtype, pri, NULL, NULL, NULL, tei, 1, NULL); if (!pri->subchannel) { pri_error(pri, "Unable to allocate D-channel for new TEI %d\n", tei); return NULL; @@ -942,10 +1005,18 @@ /* If no subchannel (TEI) ignore */ if (!pri->subchannel) return NULL; - - /* If it's addressed to the group TEI or to our TEI specifically, we respond */ - if ((tei == Q921_TEI_GROUP) || (tei == pri->subchannel->tei)) - q921_send_tei(pri, Q921_TEI_IDENTITY_CHECK_RESPONSE, random() % 65535, pri->subchannel->tei, 1); + + sub = pri->subchannel; + while(sub) + { + /* If it's addressed to the group TEI or to our TEI specifically, we respond */ + if ((tei == Q921_TEI_GROUP) || (tei == sub->tei)) + { + q921_send_tei(pri, Q921_TEI_IDENTITY_CHECK_RESPONSE, random() % 65535, sub->tei, 1); + break; + } + sub = sub->subchannel; + } break; case Q921_TEI_IDENTITY_REMOVE: @@ -953,8 +1024,21 @@ if (!pri->subchannel) return NULL; - if ((tei == Q921_TEI_GROUP) || (tei == pri->subchannel->tei)) { - q921_tei_release_and_reacquire(pri); + if (tei == Q921_TEI_GROUP) + q921_all_tei_release_and_reacquire(pri); + else + { + sub = pri->subchannel; + while(sub) + { + /* If it's addressed to the group TEI or to our TEI specifically, we respond */ + if (tei == sub->tei) + { + q921_one_tei_release_and_reacquire(sub); + break; + } + sub = sub->subchannel; + } } } return NULL; /* Do we need to return something??? */ @@ -1186,7 +1270,7 @@ } else if ((pri->q921_state >= Q921_TEI_ASSIGNED) && pri->bri) { /* Possible duplicate TEI assignment */ if (pri->master) - q921_tei_release_and_reacquire(pri->master); + q921_all_tei_release_and_reacquire(pri->master); else pri_error(pri, "Huh!? no master found\n"); } else { @@ -1237,6 +1321,47 @@ if (pri->subchannel) return q921_receive(pri->subchannel, h, len + 2); else { + if ( (h->h.sapi == Q921_SAPI_CALL_CTRL) && (h->h.tei != Q921_TEI_GROUP)) + { + struct pri *master; + /* Go to master */ + GET_MASTER_PRI(master,pri); + + if ( master->bri && (master->localtype == PRI_NETWORK) && (master->sapi == Q921_SAPI_LAYER2_MANAGEMENT)) + { + if (h->h.tei >= 64) + q921_send_tei(master, Q921_TEI_IDENTITY_REMOVE, 0, h->h.tei, 1); + else + { + struct pri *sub; + if (pri->debug & PRI_DEBUG_Q921_DUMP) + pri_message(pri, "Create static TEI for SAPI/TEI=%d/%d\n", h->h.sapi, h->h.tei); + + sub = __pri_new_tei(-1, master->localtype, master->switchtype, master, NULL, NULL, NULL, h->h.tei, 1, NULL); + + if(!sub) + return NULL; + + while(master->subchannel) + { + if (master->subchannel->tei > h->h.tei) + break; + master = master->subchannel; + } + sub->subchannel = master->subchannel; + master->subchannel = sub; + + /* Stop any SABME retransmissions */ + if (master->sabme_timer) { + pri_schedule_del(master, master->sabme_timer); + master->sabme_timer = 0; + } + + return q921_receive(sub, h, len + 2); + } + } + + } return NULL; } @@ -1277,6 +1402,10 @@ pri->q921_state = Q921_DOWN; if (isCPE) q921_tei_request(pri); + else + { + q921_send_sabme(pri, isCPE); + } } else { q921_send_sabme(pri, isCPE); } diff -uN libpri.org/q931.c libpri/q931.c --- libpri.org/q931.c 2009-03-04 15:31:20.000000000 -0500 +++ libpri/q931.c 2010-01-12 10:08:44.000000000 -0500 @@ -42,6 +42,9 @@ #include #define MAX_MAND_IES 10 +#define EMPTY_STR_CHR 1 + +#define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) struct msgtype { int msgnum; @@ -1494,6 +1497,49 @@ return 0; } +static void q931_get_string(char *dst, int maxlen, unsigned char *src, int len) +{ + if ((len < 0) || (len > maxlen - 1)) { + dst[0] = 0; + return; + } + memcpy(dst, src, len); + dst[len] = 0; +} + + +static FUNC_SEND(transmit_spid) +{ + int l = strlen(call->spid); + if(l>32) + l = 32; + if(l) + memcpy(ie->data,call->spid,l); + return l+2; +} + +static FUNC_SEND(transmit_eid) +{ + int l = strlen(call->eid); + if(l>32) + l = 32; + if(l) + memcpy(ie->data,call->eid,l); + return l+2; +} + +static FUNC_RECV(receive_spid) +{ + q931_get_string(call->spid,sizeof(call->spid),ie->data,ie->len); + return 0; +} + +static FUNC_RECV(receive_eid) +{ + q931_get_string(call->eid,sizeof(call->eid),ie->data,ie->len); + return 0; +} + static char *callstate2str(int callstate) { static struct msgtype callstates[] = { @@ -1681,6 +1727,21 @@ } +static FUNC_DUMP(dump_spid) +{ + char tmp[256] = ""; + q931_get_string(tmp,sizeof(tmp),ie->data,ie->len); + + pri_message(pri, "SPID %s\n", tmp); +} + +static FUNC_DUMP(dump_eid) +{ + char tmp[256] = ""; + q931_get_string(tmp,sizeof(tmp),ie->data,ie->len); + pri_message(pri, "EID %s\n", tmp); +} + static FUNC_DUMP(dump_network_spec_fac) { pri_message(pri, "%c Network-Specific Facilities (len=%2d) [ ", prefix, ie->len); @@ -2170,6 +2231,8 @@ { 0, Q931_HIGH_LAYER_COMPAT, "High-layer Compatibility" }, { 1, Q931_PACKET_SIZE, "Packet Size" }, { 0, Q931_IE_FACILITY, "Facility" , dump_facility, receive_facility, transmit_facility }, + { 1, Q931_IE_SPID, "SPID" , dump_spid, receive_spid, transmit_spid }, + { 1, Q931_IE_EID, "EID" , dump_eid, receive_eid, transmit_eid }, { 1, Q931_IE_REDIRECTION_NUMBER, "Redirection Number" }, { 1, Q931_IE_REDIRECTION_SUBADDR, "Redirection Subaddress" }, { 1, Q931_IE_FEATURE_ACTIVATE, "Feature Activation" }, @@ -2295,6 +2358,11 @@ cr |= 0x8000; } break; + + case 0: + cr = 0; + break; + default: pri_error(NULL, "Call Reference Length not supported: %d\n", h->crlen); } @@ -2342,10 +2410,7 @@ struct pri *master; /* Find the master - He has the call pool */ - if (pri->master) - master = pri->master; - else - master = pri; + GET_MASTER_PRI(master,pri); cur = *master->callpool; prev = NULL; @@ -2366,11 +2431,11 @@ /* Call reference */ cur->cr = cr; /* PRI is set to whoever called us */ - if (pri->bri && (pri->localtype == PRI_CPE) && pri->subchannel && outboundnew) - cur->pri = pri->subchannel; - else - cur->pri = pri; - + if (pri->bri && (pri->localtype == PRI_CPE) && pri->subchannel && outboundnew) + cur->pri = pri->subchannel; + else + cur->pri = pri; + /* Append to end of list */ if (prev) prev->next = cur; @@ -2380,6 +2445,7 @@ return cur; } + q931_call *q931_new_call(struct pri *pri) { q931_call *cur; @@ -2407,18 +2473,21 @@ static void q931_destroy(struct pri *pri, int cr, q931_call *c) { q931_call *cur, *prev; - /* For destroying, make sure we are using the master span, since it maintains the call pool */ - for (;pri->master; pri = pri->master); + struct pri *master; + + /* Find the master - He has the call pool */ + GET_MASTER_PRI(master,pri); prev = NULL; - cur = *pri->callpool; + cur = *master->callpool; while(cur) { if ((c && (cur == c)) || (!c && (cur->cr == cr))) { if (prev) prev->next = cur->next; else - *pri->callpool = cur->next; + *master->callpool = cur->next; + if (pri->debug & PRI_DEBUG_Q931_STATE) pri_message(pri, "NEW_HANGUP DEBUG: Destroying the call, ourstate %s, peerstate %s\n",callstate2str(cur->ourcallstate),callstate2str(cur->peercallstate)); if (cur->retranstimer) @@ -2593,12 +2662,20 @@ h->crv[0] &= 0x7f; } } else { - h->crlen = 1; - if (call->cr || call->forceinvert) { - h->crv[0] = (((call->cr ^ 0x8000) & 0x8000) >> 8) | (call->cr & 0x7f); - } else { - /* Unless of course this has no call reference */ + if (call->cr == 0) + { h->crv[0] = 0; + h->crlen = 0; + } + else + { + h->crlen = 1; + if (call->cr || call->forceinvert) { + h->crv[0] = (((call->cr ^ 0x8000) & 0x8000) >> 8) | (call->cr & 0x7f); + } else { + /* Unless of course this has no call reference */ + h->crv[0] = 0; + } } } mh = (q931_mh *)(h->contents + h->crlen); @@ -2608,6 +2685,9 @@ if (h->crlen == 2) *len -= 5; else + if (h->crlen == 0) + *len -= 3; + else *len -= 4; } @@ -2707,6 +2787,15 @@ return send_message(pri, call, Q931_INFORMATION, keypad_facility_ies); } + +static int eid_ies[] = { Q931_IE_EID, -1 }; + +static int q931_eid_info(struct pri *pri, q931_call *call, char *eid) +{ + libpri_copy_string(call->eid, eid, sizeof(call->eid)); + return send_message(pri, call, Q931_INFORMATION, eid_ies); +} + static int restart_ack_ies[] = { Q931_CHANNEL_IDENT, Q931_RESTART_INDICATOR, -1 }; static int restart_ack(struct pri *pri, q931_call *c) @@ -3040,6 +3129,27 @@ { int res; + + if (pri->bri && (pri->localtype != PRI_CPE) && pri->subchannel && (c->pri == pri) && (pri->sapi == Q921_SAPI_LAYER2_MANAGEMENT)) + { + struct pri *sub = pri->subchannel; + while (sub) + { + if(sub->line_service.channel_id == req->channel) + { + pri_message(pri, "Override PRI for channel:%d\n",req->channel); + c->pri = sub; + break; + } + sub = sub->subchannel; + } + + if (c->pri == pri) + { + pri_error(pri, "Can't find PRI subchannel:%d\n",req->channel); + return -1; + } + } c->transcapability = req->transmode; c->transmoderate = TRANS_MODE_64_CIRCUIT; @@ -3280,6 +3390,7 @@ int codeset, cur_codeset; int last_ie[8]; struct apdu_event *cur = NULL; + struct pri *master; memset(last_ie, 0, sizeof(last_ie)); if (pri->debug & PRI_DEBUG_Q931_DUMP) @@ -3402,6 +3513,8 @@ break; case Q931_INFORMATION: c->callednum[0] = '\0'; + c->spid[0] = EMPTY_STR_CHR; + c->eid[0] = EMPTY_STR_CHR; break; case Q931_STATUS_ENQUIRY: break; @@ -3556,6 +3669,16 @@ q931_release_complete(pri, c, PRI_CAUSE_BEARERCAPABILITY_NOTIMPL); break; } + if(pri->bri && (c->channelno == 3)) + { + c->channelno = pri->line_service.channel_id; + pri_message(pri, "Override BRI Any Channel to %d\n", c->channelno); + if (c->channelno == 0) + { + q931_release_complete(pri, c, PRI_CAUSE_CHANNEL_UNACCEPTABLE); + break; + } + } pri->ev.e = PRI_EVENT_RING; pri->ev.ring.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16); pri->ev.ring.callingpres = c->callerpres; @@ -3858,8 +3981,30 @@ + the "Complete" msg which is basically an EOF on further digits XXX */ if (c->newcall) { + if(c->cr == 0) + { + if(c->spid[0] != EMPTY_STR_CHR) + { + int i; + pri->line_service.channel_id = 0; + + GET_MASTER_PRI(master,pri); + for(i=0; ispid,master->bri_services.lines[i].spid,sizeof(c->spid))==0) + { + pri_message(pri,"Set Line Service Channel ID:%d\n",master->bri_services.lines[i].channel_id); + pri->line_service = master->bri_services.lines[i]; + q931_eid_info(pri,c,c->spid); + break; + } + } + } + q931_destroycall(pri, c->cr); + } + else q931_release_complete(pri,c,PRI_CAUSE_INVALID_CALL_REFERENCE); - break; + break; } if (c->ourcallstate != Q931_CALL_STATE_OVERLAP_RECEIVING) { pri->ev.e = PRI_EVENT_KEYPAD_DIGIT;