diff --git a/README.qsig b/README.qsig index 3c64444..915e975 100644 --- a/README.qsig +++ b/README.qsig @@ -48,10 +48,17 @@ The QSIG support includes: QSIG_LI2_ODIVNAME original diverting name at the moment only incoming handling is supported +- Possibility to inform QSIG switch about call from public network + If you set variable QSIG_SETUP=X then the QSIG switch on the other side will know, + this call source is public network - you will get different ring tone, etc. + In dialplan use: Set(__QSIG_SETUP=X) command. + The leading "__" tells asterisk, to export this variable to the outgoing channel and + its subchannels Future Targets: =============== - check code for buffer overflows +- Call Transfer - Path Replacement - CCBS - AOC @@ -79,8 +86,8 @@ Here we go with new configuration Set qsig to one of the following values, which corresponds to your configuration. 0 QSIG turned off -1 Alcatel (4400 & Enterprise - Maybe OXO/4200) ECMA variant -2 Siemens HiPath 4000 ECMAV2 +1 Alcatel (4400 & Enterprise - Maybe OXO/4200) ECMA (wrongly named ECMA - it is ETSI) variant +2 Siemens HiPath 4000 ECMAV2 & Alcatel 4400/Enterprise in ISO mode ToDo List: diff --git a/chan_capi.c b/chan_capi.c index 2baf50f..4202c2b 100644 --- a/chan_capi.c +++ b/chan_capi.c @@ -130,6 +130,7 @@ static char *commandtdesc = "CAPI command interface.\n" "\"params\" can be:\n" "early B3:\"b\"=always, \"B\"=on successful calls only\n" "\"d\":use callerID from capi.conf, \"o\":overlap sending number\n" +"\n\"q\":disable QSIG functions on outgoing call\n" "\n" "capicommand() where () can be:\n" "\"progress\" send progress (for NT mode)\n" @@ -1589,7 +1590,7 @@ static int pbx_capi_call(struct ast_channel *c, char *idest, int timeout) if (doqsig) { unsigned char *facilityarray = alloca(CAPI_MAX_FACILITYDATAARRAY_SIZE); - cc_qsig_add_call_setup_data(facilityarray, i); + cc_qsig_add_call_setup_data(facilityarray, i, c); CONNECT_REQ_FACILITYDATAARRAY(&CMSG) = facilityarray; } diff --git a/chan_capi_qsig.h b/chan_capi_qsig.h index d329d20..432bd46 100644 --- a/chan_capi_qsig.h +++ b/chan_capi_qsig.h @@ -145,7 +145,9 @@ extern signed int cc_qsig_check_invoke(unsigned char *data, int *idx); extern signed int cc_qsig_get_invokeid(unsigned char *data, int *idx, struct cc_qsig_invokedata *invoke); extern signed int cc_qsig_fill_invokestruct(unsigned char *data, int *idx, struct cc_qsig_invokedata *invoke, int apduval); extern unsigned int cc_qsig_handle_capiind(unsigned char *data, struct capi_pvt *i); -extern unsigned int cc_qsig_add_call_setup_data(unsigned char *data, struct capi_pvt *i); +extern unsigned int cc_qsig_add_call_setup_data(unsigned char *data, struct capi_pvt *i, struct ast_channel *c); +extern unsigned int cc_qsig_add_call_facility_data(unsigned char *data, struct capi_pvt *i, int facility); + extern signed int cc_qsig_identifyinvoke(struct cc_qsig_invokedata *invoke, int protocol); extern unsigned int cc_qsig_handle_invokeoperation(int invokeident, struct cc_qsig_invokedata *invoke, struct capi_pvt *i); @@ -154,7 +156,7 @@ extern unsigned int cc_qsig_handle_invokeoperation(int invokeident, struct cc_qs */ extern void cc_qsig_op_ecma_isdn_namepres(struct cc_qsig_invokedata *invoke, struct capi_pvt *i); -extern int cc_qsig_encode_ecma_name_invoke(unsigned char * buf, unsigned int *idx, struct cc_qsig_invokedata *invoke, struct capi_pvt *i); +extern int cc_qsig_encode_ecma_name_invoke(unsigned char * buf, unsigned int *idx, struct cc_qsig_invokedata *invoke, struct capi_pvt *i, int nametype); extern void cc_qsig_op_ecma_isdn_leginfo2(struct cc_qsig_invokedata *invoke, struct capi_pvt *i); #endif diff --git a/chan_capi_qsig_core.c b/chan_capi_qsig_core.c index ab727ff..0ed5bc4 100644 --- a/chan_capi_qsig_core.c +++ b/chan_capi_qsig_core.c @@ -20,6 +20,7 @@ #include #include +#include #include "chan_capi20.h" #include "chan_capi.h" #include "chan_capi_qsig.h" @@ -555,18 +556,73 @@ unsigned int cc_qsig_handle_capiind(unsigned char *data, struct capi_pvt *i) /* * Handles outgoing Facilies on Call SETUP */ -unsigned int cc_qsig_add_call_setup_data(unsigned char *data, struct capi_pvt *i) +unsigned int cc_qsig_add_call_setup_data(unsigned char *data, struct capi_pvt *i, struct ast_channel *c) +{ + /* TODO: Check buffers */ + struct cc_qsig_invokedata invoke; + struct cc_qsig_nfe nfe; + unsigned int dataidx = 0; + + const unsigned char xprogress[] = {0x1e,0x02,0xa0,0x90}; + char *p = NULL; + int add_externalinfo = 0; + + if ((p = pbx_builtin_getvar_helper(c, "QSIG_SETUP"))) { + /* some special dial parameters */ + /* parse the parameters */ + while ((p) && (*p)) { + switch (*p) { + case 'X': /* add PROGRESS INDICATOR for external calls*/ + cc_verbose(1, 1, VERBOSE_PREFIX_4, "Sending QSIG external PROGRESS IE.\n"); + add_externalinfo = 1; + while (((char)*p!=',')&&(*p)) /* Remove next values until separator (,), stop if zero */ + p++; + break; + default: + cc_log(LOG_WARNING, "Unknown parameter '%c' in QSIG_SETUP, ignoring.\n", *p); + while (((char)*p!=',')&&(*p)) + p++; + } + if (*p) /* this is not the end */ + p++; + } + } + +/*mg:remember me switch (i->doqsig) {*/ + cc_qsig_build_facility_struct(data, &dataidx, APDUINTERPRETATION_IGNORE, &nfe); + cc_qsig_encode_ecma_name_invoke(data, &dataidx, &invoke, i, 0); + cc_qsig_add_invoke(data, &dataidx, &invoke); + + if (add_externalinfo) { + /* add PROGRESS INDICATOR for external calls*/ + memcpy(&data[dataidx], xprogress, sizeof(xprogress)); + data[0] += data[0] + sizeof(xprogress); + } +/* }*/ + return 0; +} + +/* + * Handles outgoing Facilies on Call + */ +unsigned int cc_qsig_add_call_facility_data(unsigned char *data, struct capi_pvt *i, int facility) { /* TODO: Check buffers */ struct cc_qsig_invokedata invoke; struct cc_qsig_nfe nfe; unsigned int dataidx; -/*mg:remember me switch (i->doqsig) {*/ + /*mg:remember me switch (i->doqsig) {*/ cc_qsig_build_facility_struct(data, &dataidx, APDUINTERPRETATION_IGNORE, &nfe); - cc_qsig_encode_ecma_name_invoke(data, &dataidx, &invoke, i); - cc_qsig_add_invoke(data, &dataidx, &invoke); -/* }*/ + switch(facility) { + case 1: /* HACK: Test only */ + cc_qsig_encode_ecma_name_invoke(data, &dataidx, &invoke, i, 1); + cc_qsig_add_invoke(data, &dataidx, &invoke); + break; + default: + break; + } + /* }*/ return 0; } diff --git a/chan_capi_qsig_ecma.c b/chan_capi_qsig_ecma.c index e83242c..6cc3335 100644 --- a/chan_capi_qsig_ecma.c +++ b/chan_capi_qsig_ecma.c @@ -78,7 +78,7 @@ void cc_qsig_op_ecma_isdn_namepres(struct cc_qsig_invokedata *invoke, struct cap * returns * always 0 */ -int cc_qsig_encode_ecma_name_invoke(unsigned char * buf, unsigned int *idx, struct cc_qsig_invokedata *invoke, struct capi_pvt *i) +int cc_qsig_encode_ecma_name_invoke(unsigned char * buf, unsigned int *idx, struct cc_qsig_invokedata *invoke, struct capi_pvt *i, int nametype) { const unsigned char oid[] = {0x2b,0x0c,0x09,0x00}; /* 1.3.12.9.0 */ int oid_len = sizeof(oid); @@ -86,7 +86,6 @@ int cc_qsig_encode_ecma_name_invoke(unsigned char * buf, unsigned int *idx, stru unsigned char data[255]; int dataidx = 0; int namelen = 0; - /*TODO: write something */ if (i->owner->cid.cid_name) namelen = strlen(i->owner->cid.cid_name); @@ -111,6 +110,10 @@ int cc_qsig_encode_ecma_name_invoke(unsigned char * buf, unsigned int *idx, stru invoke->oid_len = oid_len; memcpy(invoke->oid_bin, oid, oid_len); + /* HACK: */ + if (nametype) + invoke->oid_bin[3] = 2; + if (namelen>0) { data[dataidx++] = 0x80; /* We send only simple Name, Namepresentation allowed */ data[dataidx++] = namelen; @@ -133,8 +136,8 @@ int cc_qsig_encode_ecma_name_invoke(unsigned char * buf, unsigned int *idx, stru /* * Handle Operation: 1.3.12.9.21 ECMA/ISDN/LEG_INFORMATION2 * - * This function decodes the namepresentation facility - * The name will be copied in the cid.cid_name field of the asterisk channel struct + * This function decodes the LEG INFORMATION2 facility + * The datas will be copied in the some Asterisk channel variables -> see README.qsig * * parameters * invoke struct, which contains encoded data from facility