QSIG:
- added support for rerouting informations on incoming calls
This commit is contained in:
parent
3b730f1042
commit
6bba2bbfc6
11
README.qsig
11
README.qsig
|
@ -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:
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,7 +556,56 @@ 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;
|
||||||
|
@ -564,8 +614,14 @@ unsigned int cc_qsig_add_call_setup_data(unsigned char *data, struct capi_pvt *i
|
||||||
|
|
||||||
/*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) {
|
||||||
|
case 1: /* HACK: Test only */
|
||||||
|
cc_qsig_encode_ecma_name_invoke(data, &dataidx, &invoke, i, 1);
|
||||||
cc_qsig_add_invoke(data, &dataidx, &invoke);
|
cc_qsig_add_invoke(data, &dataidx, &invoke);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
/* }*/
|
/* }*/
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue