- starting support of Path Replacement
 - removed an possible endless loop
 - bug fix on sending facilities in ISO (HICOM-ECMAV2) variant
This commit is contained in:
MelwareDE 2007-04-24 18:43:38 +00:00
parent 1756447915
commit ecf0c248af
3 changed files with 143 additions and 8 deletions

View File

@ -139,7 +139,7 @@ struct cc_qsig_nfe {
*** QSIG Core Functions
*/
extern int cc_qsig_build_facility_struct(unsigned char * buf, unsigned int *idx, int apdu_interpr, struct cc_qsig_nfe *nfe);
extern int cc_qsig_build_facility_struct(unsigned char * buf, unsigned int *idx, int protocolvar, int apdu_interpr, struct cc_qsig_nfe *nfe);
extern int cc_qsig_add_invoke(unsigned char * buf, unsigned int *idx, struct cc_qsig_invokedata *invoke, struct capi_pvt *i);
extern unsigned int cc_qsig_asn1_get_string(unsigned char *buf, int buflen, unsigned char *data);

View File

@ -152,7 +152,7 @@ void cc_qsig_update_facility_length(unsigned char * buf, unsigned int idx)
/*
* Create Invoke Struct
*/
int cc_qsig_build_facility_struct(unsigned char * buf, unsigned int *idx, int apdu_interpr, struct cc_qsig_nfe *nfe)
int cc_qsig_build_facility_struct(unsigned char * buf, unsigned int *idx, int protocolvar, int apdu_interpr, struct cc_qsig_nfe *nfe)
{
int myidx = *idx; /* we start with Index 1 - Byte 0 is Length of Facilitydataarray */
if (!myidx)
@ -160,7 +160,7 @@ int cc_qsig_build_facility_struct(unsigned char * buf, unsigned int *idx, int ap
buf[myidx++] = 0x1c;
buf[myidx++] = 0; /* Byte 2 length of Facilitydataarray */
buf[myidx++] = COMP_TYPE_DISCR_SS; /* QSIG Facility */
buf[myidx++] = 0x80 | protocolvar; /* QSIG Facility */
/* TODO: Outsource following struct to an separate function */
buf[myidx++] = COMP_TYPE_NFE; /* Network Facility Extension */
buf[myidx++] = 6; /* NFE Size hardcoded - not good */
@ -747,6 +747,7 @@ unsigned int cc_qsig_add_call_setup_data(unsigned char *data, struct capi_pvt *i
struct cc_qsig_invokedata invoke;
struct cc_qsig_nfe nfe;
unsigned int dataidx = 0;
int protocolvar = 0;
const unsigned char xprogress[] = {0x1e,0x02,0xa0,0x90};
char *p = NULL;
@ -776,6 +777,11 @@ unsigned int cc_qsig_add_call_setup_data(unsigned char *data, struct capi_pvt *i
} else {
i->qsig_data.calltransfer = 1;
i->qsig_data.partner_plci = atoi(pp);
/* set the other channel as partner to me */
struct capi_pvt *ii = find_interface_by_plci(i->qsig_data.partner_plci);
if (ii)
ii->qsig_data.partner_plci = i->PLCI;
cc_verbose(1, 1, " for plci %#x\n", i->qsig_data.partner_plci);
}
break;
@ -787,6 +793,11 @@ unsigned int cc_qsig_add_call_setup_data(unsigned char *data, struct capi_pvt *i
} else {
i->qsig_data.calltransfer_onring = 1;
i->qsig_data.partner_plci = atoi(pp);
/* set the other channel as partner to me */
struct capi_pvt *ii = find_interface_by_plci(i->qsig_data.partner_plci);
if (ii)
ii->qsig_data.partner_plci = i->PLCI;
cc_verbose(1, 1, " for plci %#x\n", i->qsig_data.partner_plci);
}
break;
@ -803,8 +814,20 @@ unsigned int cc_qsig_add_call_setup_data(unsigned char *data, struct capi_pvt *i
}
}
/*mg:remember me switch (i->doqsig) {*/
cc_qsig_build_facility_struct(data, &dataidx, APDUINTERPRETATION_IGNORE, &nfe);
switch (i->qsigfeat) {
case QSIG_TYPE_ALCATEL_ECMA:
protocolvar = Q932_PROTOCOL_ROSE;
break;
case QSIG_TYPE_HICOM_ECMAV2:
protocolvar = Q932_PROTOCOL_EXTENSIONS;
break;
default:
cc_log(LOG_WARNING, " Unknown QSIG variant configured.\n");
return 0;
break;
}
cc_qsig_build_facility_struct(data, &dataidx, protocolvar, APDUINTERPRETATION_IGNORE, &nfe);
cc_qsig_encode_ecma_name_invoke(data, &dataidx, &invoke, i, 0);
cc_qsig_add_invoke(data, &dataidx, &invoke, i);
@ -828,9 +851,28 @@ unsigned int cc_qsig_do_facility(unsigned char *fac, struct ast_channel *c, cha
struct capi_pvt *i = CC_CHANNEL_PVT(c);
/* struct capi_pvt *ii = NULL; */
unsigned int facidx = 0;
int protocolvar = 0;
cc_qsig_build_facility_struct(fac, &facidx, APDUINTERPRETATION_REJECT, &nfe);
switch (i->qsigfeat) {
case QSIG_TYPE_ALCATEL_ECMA:
protocolvar = Q932_PROTOCOL_ROSE;
break;
case QSIG_TYPE_HICOM_ECMAV2:
protocolvar = Q932_PROTOCOL_EXTENSIONS;
break;
default:
cc_log(LOG_WARNING, " Unknown QSIG variant configured.\n");
return 0;
break;
}
cc_qsig_build_facility_struct(fac, &facidx, protocolvar, APDUINTERPRETATION_REJECT, &nfe);
switch (factype) {
case 4: /* ECMA-xxx pathReplacementPropose */
cc_qsig_encode_ecma_prpropose(fac, &facidx, &invoke, i, param);
cc_qsig_add_invoke(fac, &facidx, &invoke, i);
break;
case 12: /* ECMA-178 callTransfer */
cc_qsig_encode_ecma_calltransfer(fac, &facidx, &invoke, i, param, info1);
cc_qsig_add_invoke(fac, &facidx, &invoke, i);
@ -848,7 +890,7 @@ unsigned int cc_qsig_do_facility(unsigned char *fac, struct ast_channel *c, cha
}
/*
* Initiate a QSIG Call Transfer
* capicommand getplci - needed for Call Transfer
*/
int pbx_capi_qsig_getplci(struct ast_channel *c, char *param)
{
@ -992,6 +1034,29 @@ void pbx_capi_qsig_handle_info_indication(_cmsg *CMSG, unsigned int PLCI, unsign
{
unsigned int qsiginvoke;
qsiginvoke = cc_qsig_handle_capi_facilityind( (unsigned char*) INFO_IND_INFOELEMENT(CMSG), i);
/*
if (i->qsig_data.pr_propose_cid && i->qsig_data.pr_propose_pn) {
struct capi_pvt *ii = find_interface_by_plci(i->qsig_data.partner_plci);
if (ii) {
unsigned char fac[CAPI_MAX_FACILITYDATAARRAY_SIZE];
_cmsg CMSG3;
cc_qsig_do_facility(fac, i->owner, NULL, 4, 0);
INFO_REQ_HEADER(&CMSG3, capi_ApplID, get_capi_MessageNumber(),0);
INFO_REQ_PLCI(&CMSG3) = ii->PLCI;
INFO_REQ_FACILITYDATAARRAY(&CMSG3) = fac;
_capi_put_cmsg(&CMSG3);
} else {
cc_verbose(1, 1, VERBOSE_PREFIX_4 " * QSIG_PATHREPLACEMENT_PROPOSE: no partner channel found (%#x)\n", i->qsig_data.partner_plci);
}
free(i->qsig_data.pr_propose_cid);
free(i->qsig_data.pr_propose_pn);
}
*/
}
break;
case 0x001e: /* Progress Indicator */
@ -1020,6 +1085,9 @@ void pbx_capi_qsig_handle_info_indication(_cmsg *CMSG, unsigned int PLCI, unsign
unsigned char fac[CAPI_MAX_FACILITYDATAARRAY_SIZE];
struct capi_pvt *ii = find_interface_by_plci(i->qsig_data.partner_plci);
/* needed for Path Replacement */
ii->qsig_data.partner_plci = i->PLCI;
_cmsg CMSG3;
i->qsig_data.calltransfer_onring = 0;
@ -1050,6 +1118,28 @@ void pbx_capi_qsig_handle_info_indication(_cmsg *CMSG, unsigned int PLCI, unsign
case 0x8005: /* SETUP */
break;
case 0x8007: /* CONNECT */
/* {
if (i->qsig_data.pr_propose_cid && i->qsig_data.pr_propose_pn) {
struct capi_pvt *ii = find_interface_by_plci(i->qsig_data.partner_plci);
if (ii) {
unsigned char fac[CAPI_MAX_FACILITYDATAARRAY_SIZE];
_cmsg CMSG3;
cc_qsig_do_facility(fac, i->owner, NULL, 4, 0);
INFO_REQ_HEADER(&CMSG3, capi_ApplID, get_capi_MessageNumber(),0);
INFO_REQ_PLCI(&CMSG3) = ii->PLCI;
INFO_REQ_FACILITYDATAARRAY(&CMSG3) = fac;
_capi_put_cmsg(&CMSG3);
} else {
cc_verbose(1, 1, VERBOSE_PREFIX_4 " * QSIG_PATHREPLACEMENT_PROPOSE: no partner channel found (%#x)\n", i->qsig_data.partner_plci);
}
free(i->qsig_data.pr_propose_cid);
free(i->qsig_data.pr_propose_pn);
}
}*/
break;
case 0x800d: /* SETUP ACK */
break;

View File

@ -502,7 +502,52 @@ void cc_qsig_op_ecma_isdn_prpropose(struct cc_qsig_invokedata *invoke, struct ca
void cc_qsig_encode_ecma_prpropose(unsigned char * buf, unsigned int *idx, struct cc_qsig_invokedata *invoke, struct capi_pvt *i, char *param)
{
/* TODO: write code */
// int invokeop = 19;
int invokeop = 4;
char *callid, *reroutingnr;
int cidlen, rrnlen;
int seqlen = 4;
char c[255];
int ix = 0;
if (!i->qsig_data.pr_propose_cid)
return ;
if (!i->qsig_data.pr_propose_pn)
return ;
callid = i->qsig_data.pr_propose_cid;
reroutingnr = i->qsig_data.pr_propose_pn;
cidlen = strlen(callid);
rrnlen = strlen(reroutingnr);
seqlen += cidlen + rrnlen;
c[ix++] = ASN1_SEQUENCE | ASN1_TF_CONSTRUCTED; /* start of SEQUENCE */
c[ix++] = seqlen;
c[ix++] = ASN1_NUMERICSTRING; /* val 1 - CallID */
c[ix++] = cidlen;
memcpy(&c[ix], callid, cidlen);
ix += cidlen;
c[ix++] = ASN1_TC_CONTEXTSPEC; /* val 2 - Rerouting number*/
c[ix++] = rrnlen;
memcpy(&c[ix], reroutingnr, rrnlen);
ix += rrnlen;
/* end of SEQUENCE */
/* there are optional data possible here */
invoke->id = invokeop;
invoke->descr_type = -1;
invoke->type = invokeop;
invoke->datalen = ix;
memcpy(invoke->data, c, ix);
cc_verbose(1, 1, VERBOSE_PREFIX_4 " * QSIG_PATHREPLACEMENT_PROPOSE: %s,%s\n", callid, reroutingnr);
return;
}