- added support for rerouting informations on incoming calls
This commit is contained in:
MelwareDE 2007-03-25 17:03:19 +00:00
parent 3b730f1042
commit 6bba2bbfc6
5 changed files with 83 additions and 14 deletions

View File

@ -48,10 +48,17 @@ The QSIG support includes:
QSIG_LI2_ODIVNAME original diverting name QSIG_LI2_ODIVNAME original diverting name
at the moment only incoming handling is supported 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: Future Targets:
=============== ===============
- check code for buffer overflows - check code for buffer overflows
- Call Transfer
- Path Replacement - Path Replacement
- CCBS - CCBS
- AOC - AOC
@ -79,8 +86,8 @@ Here we go with new configuration
Set qsig to one of the following values, which corresponds to your configuration. Set qsig to one of the following values, which corresponds to your configuration.
0 QSIG turned off 0 QSIG turned off
1 Alcatel (4400 & Enterprise - Maybe OXO/4200) ECMA variant 1 Alcatel (4400 & Enterprise - Maybe OXO/4200) ECMA (wrongly named ECMA - it is ETSI) variant
2 Siemens HiPath 4000 ECMAV2 2 Siemens HiPath 4000 ECMAV2 & Alcatel 4400/Enterprise in ISO mode
ToDo List: ToDo List:

View File

@ -130,6 +130,7 @@ static char *commandtdesc = "CAPI command interface.\n"
"\"params\" can be:\n" "\"params\" can be:\n"
"early B3:\"b\"=always, \"B\"=on successful calls only\n" "early B3:\"b\"=always, \"B\"=on successful calls only\n"
"\"d\":use callerID from capi.conf, \"o\":overlap sending number\n" "\"d\":use callerID from capi.conf, \"o\":overlap sending number\n"
"\n\"q\":disable QSIG functions on outgoing call\n"
"\n" "\n"
"capicommand() where () can be:\n" "capicommand() where () can be:\n"
"\"progress\" send progress (for NT mode)\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) { if (doqsig) {
unsigned char *facilityarray = alloca(CAPI_MAX_FACILITYDATAARRAY_SIZE); 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; CONNECT_REQ_FACILITYDATAARRAY(&CMSG) = facilityarray;
} }

View File

@ -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_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 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_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 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); 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 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); extern void cc_qsig_op_ecma_isdn_leginfo2(struct cc_qsig_invokedata *invoke, struct capi_pvt *i);
#endif #endif

View File

@ -20,6 +20,7 @@
#include <asterisk/channel.h> #include <asterisk/channel.h>
#include <asterisk/options.h> #include <asterisk/options.h>
#include <asterisk/pbx.h>
#include "chan_capi20.h" #include "chan_capi20.h"
#include "chan_capi.h" #include "chan_capi.h"
#include "chan_capi_qsig.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 * 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 */ /* TODO: Check buffers */
struct cc_qsig_invokedata invoke; struct cc_qsig_invokedata invoke;
struct cc_qsig_nfe nfe; struct cc_qsig_nfe nfe;
unsigned int dataidx; 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_build_facility_struct(data, &dataidx, APDUINTERPRETATION_IGNORE, &nfe);
cc_qsig_encode_ecma_name_invoke(data, &dataidx, &invoke, i); switch(facility) {
cc_qsig_add_invoke(data, &dataidx, &invoke); 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; return 0;
} }

View File

@ -78,7 +78,7 @@ void cc_qsig_op_ecma_isdn_namepres(struct cc_qsig_invokedata *invoke, struct cap
* returns * returns
* always 0 * 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 */ const unsigned char oid[] = {0x2b,0x0c,0x09,0x00}; /* 1.3.12.9.0 */
int oid_len = sizeof(oid); 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]; unsigned char data[255];
int dataidx = 0; int dataidx = 0;
int namelen = 0; int namelen = 0;
/*TODO: write something */
if (i->owner->cid.cid_name) if (i->owner->cid.cid_name)
namelen = strlen(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; invoke->oid_len = oid_len;
memcpy(invoke->oid_bin, oid, oid_len); memcpy(invoke->oid_bin, oid, oid_len);
/* HACK: */
if (nametype)
invoke->oid_bin[3] = 2;
if (namelen>0) { if (namelen>0) {
data[dataidx++] = 0x80; /* We send only simple Name, Namepresentation allowed */ data[dataidx++] = 0x80; /* We send only simple Name, Namepresentation allowed */
data[dataidx++] = namelen; 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 * Handle Operation: 1.3.12.9.21 ECMA/ISDN/LEG_INFORMATION2
* *
* This function decodes the namepresentation facility * This function decodes the LEG INFORMATION2 facility
* The name will be copied in the cid.cid_name field of the asterisk channel struct * The datas will be copied in the some Asterisk channel variables -> see README.qsig
* *
* parameters * parameters
* invoke struct, which contains encoded data from facility * invoke struct, which contains encoded data from facility