- code cleanup
  - some minor bugfixes
  - bugfix in LEG_INFO2 code - caused a asterisk crash
  - adapted some macros from libpri, to make code more readable
  - started code for outbound CCNR requests
This commit is contained in:
MelwareDE 2007-12-06 19:07:28 +00:00
parent a8c926e858
commit 84550afacf
8 changed files with 373 additions and 95 deletions

View File

@ -65,7 +65,7 @@ The QSIG support includes:
- Call Transfer (outgoing)
You can do an outbound call transfer.
First you need the PLCI (logical channel id) of your first channel. You'll get it with capicommand(getplci). This
First you need the PLCI (logical channel id) of your first channel. You'll get it with capicommand(qsig_getplci). This
command returns the channel id in the variable QSIG_PLCI. Now you can enable the call transfer feature.
Simply add "Ct<PLCI>" to QSIG_SETUP (i.e. QSIG_SETUP="X/Ct${QSIG_PLCI}" ). On the next dial command the call will
be automatically transferred. The transfer occurs after the CONNECT. If you want an transfer early on ringing you
@ -104,6 +104,12 @@ Future Targets:
How to use:
===========
You will find more documentation at the chan_capi wiki.
Please visit: http://www.melware.org/ChanCapiConf
simply enable Q.SIG with following line in your capi.conf interface:
Here we go with new configuration

View File

@ -5529,6 +5529,34 @@ static int pbxcli_capi_no_debug(int fd, int argc, char *argv[])
return RESULT_SUCCESS;
}
/*
* enable QSIG debugging
*/
static int pbxcli_capi_qsig_do_debug(int fd, int argc, char *argv[])
{
if (argc != 3)
return RESULT_SHOWUSAGE;
capiqsigdebug = 1;
ast_cli(fd, "CAPI QSIG Debugging Enabled\n");
return RESULT_SUCCESS;
}
/*
* disable QSIG debugging
*/
static int pbxcli_capi_qsig_no_debug(int fd, int argc, char *argv[])
{
if (argc != 4)
return RESULT_SHOWUSAGE;
capiqsigdebug = 0;
ast_cli(fd, "CAPI QSIG Debugging Disabled\n");
return RESULT_SUCCESS;
}
/*
* usages
*/
@ -5548,6 +5576,14 @@ static char no_debug_usage[] =
"Usage: capi no debug\n"
" Disables dumping of CAPI packets for debugging purposes\n";
static char qsig_debug_usage[] =
"Usage: capi qsig debug\n"
" Enables dumping of CAPI QSIG facilities for debugging purposes\n";
static char qsig_no_debug_usage[] =
"Usage: capi qsig no debug\n"
" Disables dumping of CAPI QSIG facilities for debugging purposes\n";
static char chatinfo_usage[] =
"Usage: capi chatinfo\n"
" Show info about chat status.\n";
@ -5563,6 +5599,10 @@ static struct ast_cli_entry cli_debug =
{ { "capi", "debug", NULL }, pbxcli_capi_do_debug, "Enable CAPI debugging", debug_usage };
static struct ast_cli_entry cli_no_debug =
{ { "capi", "no", "debug", NULL }, pbxcli_capi_no_debug, "Disable CAPI debugging", no_debug_usage };
static struct ast_cli_entry cli_qsig_debug =
{ { "capi", "qsig", "debug", NULL }, pbxcli_capi_qsig_do_debug, "Enable CAPI QSIG debugging", qsig_debug_usage };
static struct ast_cli_entry cli_qsig_no_debug =
{ { "capi", "qsig", "no", "debug", NULL }, pbxcli_capi_qsig_no_debug, "Disable CAPI QSIG debugging", qsig_no_debug_usage };
static struct ast_cli_entry cli_chatinfo =
{ { "capi", "chatinfo", NULL }, pbxcli_capi_chatinfo, "Show CAPI chat info", chatinfo_usage };
@ -6091,6 +6131,8 @@ int unload_module(void)
ast_cli_unregister(&cli_show_channels);
ast_cli_unregister(&cli_debug);
ast_cli_unregister(&cli_no_debug);
ast_cli_unregister(&cli_qsig_debug);
ast_cli_unregister(&cli_qsig_no_debug);
ast_cli_unregister(&cli_chatinfo);
#ifdef CC_AST_HAS_VERSION_1_4
@ -6198,6 +6240,8 @@ int load_module(void)
ast_cli_register(&cli_show_channels);
ast_cli_register(&cli_debug);
ast_cli_register(&cli_no_debug);
ast_cli_register(&cli_qsig_debug);
ast_cli_register(&cli_qsig_no_debug);
ast_cli_register(&cli_chatinfo);
ast_register_application(commandapp, pbx_capicommand_exec, commandsynopsis, commandtdesc);

View File

@ -14,6 +14,8 @@
#ifndef PBX_QSIG_H
#define PBX_QSIG_H
int capiqsigdebug;
#define QSIG_DISABLED 0x00
#define QSIG_ENABLED 0x01 /* shouldn't be used anymore */
@ -102,6 +104,91 @@
#define CCQSIG_TIMER_WAIT_PRPROPOSE 1 /* Wait x seconds */
struct rose_component {
u_int8_t type;
u_int8_t len;
u_int8_t data[0];
};
#define GET_COMPONENT(component, idx, ptr, length) \
if ((idx)+2 > (length)) \
break; \
(component) = (struct rose_component*)&((ptr)[idx]); \
if ((idx)+(component)->len+2 > (length)) { \
if ((component)->len != ASN1_LEN_INDEF) \
pri_message(pri, "Length (%d) of 0x%X component is too long\n", (component)->len, (component)->type); \
}
#define NEXT_COMPONENT(component, idx) \
(idx) += (component)->len + 2
#define SUB_COMPONENT(component, idx) \
(idx) += 2
#define CHECK_COMPONENT(component, comptype, message) \
if ((component)->type && ((component)->type & ASN1_TYPE_MASK) != (comptype)) { \
pri_message(pri, (message), (component)->type); \
asn1_dump(pri, (component), (component)->len+2); \
break; \
}
#define ASN1_GET_INTEGER(component, variable) \
do { \
int comp_idx; \
(variable) = 0; \
for (comp_idx = 0; comp_idx < (component)->len; ++comp_idx) \
(variable) = ((variable) << 8) | (component)->data[comp_idx]; \
} while (0)
#define ASN1_FIXUP_LEN(component, size) \
do { \
if ((component)->len == ASN1_LEN_INDEF) \
size += 2; \
} while (0)
#define ASN1_ADD_SIMPLE(component, comptype, ptr, idx) \
do { \
(component) = (struct rose_component *)&((ptr)[(idx)]); \
(component)->type = (comptype); \
(component)->len = 0; \
(idx) += 2; \
} while (0)
#define ASN1_ADD_BYTECOMP(component, comptype, ptr, idx, value) \
do { \
(component) = (struct rose_component *)&((ptr)[(idx)]); \
(component)->type = (comptype); \
(component)->len = 1; \
(component)->data[0] = (value); \
(idx) += 3; \
} while (0)
#define ASN1_ADD_WORDCOMP(component, comptype, ptr, idx, value) \
do { \
int __val = (value); \
int __i = 0; \
(component) = (struct rose_component *)&((ptr)[(idx)]); \
(component)->type = (comptype); \
if ((__val >> 24)) \
(component)->data[__i++] = (__val >> 24) & 0xff; \
if ((__val >> 16)) \
(component)->data[__i++] = (__val >> 16) & 0xff; \
if ((__val >> 8)) \
(component)->data[__i++] = (__val >> 8) & 0xff; \
(component)->data[__i++] = __val & 0xff; \
(component)->len = __i; \
(idx) += 2 + __i; \
} while (0)
#define ASN1_PUSH(stack, stackpointer, component) \
(stack)[(stackpointer)++] = (component)
#define ASN1_FIXUP(stack, stackpointer, data, idx) \
do { \
--(stackpointer); \
(stack)[(stackpointer)]->len = (unsigned char *)&((data)[(idx)]) - (unsigned char *)(stack)[(stackpointer)] - 2; \
} while (0)
#define free_null(x) { free(x); x = NULL; }
@ -150,6 +237,7 @@ struct cc_qsig_nfe {
/*
*** QSIG Core Functions
*/
extern void cc_qsig_verbose(int c_d, char *text, ...);
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);
@ -157,6 +245,7 @@ extern int cc_qsig_add_invoke(unsigned char * buf, unsigned int *idx, struct cc_
extern unsigned int cc_qsig_asn1_get_string(unsigned char *buf, int buflen, unsigned char *data);
extern unsigned int cc_qsig_asn1_get_integer(unsigned char *data, int *idx);
extern unsigned char *cc_qsig_asn1_oid2str(unsigned char *data, int size);
extern int cc_qsig_asn1_add_string2(unsigned char asn1_type, void *data, int len, int max_len, void *src, int src_len);
extern unsigned int cc_qsig_asn1_add_string(unsigned char *buf, int *idx, char *data, int datalen);
extern unsigned int cc_qsig_asn1_add_integer(unsigned char *buf, int *idx, int value);

View File

@ -50,7 +50,7 @@ unsigned int cc_qsig_asn197ade_get_partynumber(char *buf, int buflen, int *idx,
numtype = (data[myidx++] & 0x0F); /* defines type of Number: numDigits, publicPartyNum, nsapEncNum, dataNumDigits */
/* cc_verbose(1, 1, VERBOSE_PREFIX_4 " * num type %i,%i\n", numtype, myidx); */
/* cc_qsig_verbose( 1, VERBOSE_PREFIX_4 " * num type %i,%i\n", numtype, myidx); */
switch (numtype){
case 0:
if (data[myidx] > 0) { /* length of this context data */
@ -79,7 +79,7 @@ unsigned int cc_qsig_asn197ade_get_partynumber(char *buf, int buflen, int *idx,
}
break;
};
/* cc_verbose(1, 1, VERBOSE_PREFIX_4 " * num type %i,%i\n", numtype, myidx); */
/* cc_qsig_verbose( 1, VERBOSE_PREFIX_4 " * num type %i,%i\n", numtype, myidx); */
return myidx - *idx;
}
@ -97,7 +97,7 @@ unsigned int cc_qsig_asn197ade_get_numdigits(char *buf, int buflen, int *idx, un
memcpy(buf, &data[myidx], strsize);
buf[strsize] = 0;
/* cc_verbose(1, 1, VERBOSE_PREFIX_4 " * string length %i,%i\n", strsize, *idx); */
/* cc_qsig_verbose( 1, VERBOSE_PREFIX_4 " * string length %i,%i\n", strsize, *idx); */
return strsize;
}
@ -138,12 +138,12 @@ unsigned int cc_qsig_asn197ade_get_pns(unsigned char *data, int *idx, struct asn
numtype = (data[myidx++] & 0x0F); /* defines type of Number */
/* cc_verbose(1, 1, VERBOSE_PREFIX_4 " * num type %i,%i\n", numtype, myidx); */
/* cc_qsig_verbose( 1, VERBOSE_PREFIX_4 " * num type %i,%i\n", numtype, myidx); */
switch (numtype){
case 0:
/* myidx points now to length */
res = cc_qsig_asn197ade_get_partynumber(buf, buflen, &myidx, data);
/* cc_verbose(1, 1, VERBOSE_PREFIX_4 " * res %i\n", numtype); */
/* cc_qsig_verbose( 1, VERBOSE_PREFIX_4 " * res %i\n", numtype); */
if (!res)
return 0;

View File

@ -54,7 +54,7 @@ unsigned int cc_qsig_asn197no_get_name(char *buf, int buflen, unsigned int *bufd
/* This facility is encoded as SEQUENCE */
seqlength = data[++myidx];
myidx++;
cc_verbose(1, 1, VERBOSE_PREFIX_4 " Got name sequence (Length= %i)\n", seqlength);
cc_qsig_verbose( 1, VERBOSE_PREFIX_4 " Got name sequence (Length= %i)\n", seqlength);
}
if (nametag < 0x80) { /* Tag shows an simple String */
@ -76,13 +76,13 @@ unsigned int cc_qsig_asn197no_get_name(char *buf, int buflen, unsigned int *bufd
namelength = cc_qsig_asn1_get_string((unsigned char *)buf, buflen, &data[myidx]);
myidx += namelength + 1;
} else {
cc_verbose(1, 1, VERBOSE_PREFIX_4 " Namestruct not ECMA conform (String expected)\n");
cc_qsig_verbose( 1, VERBOSE_PREFIX_4 " Namestruct not ECMA conform (String expected)\n");
break;
}
if (data[myidx++] == ASN1_INTEGER) {
charset = cc_qsig_asn1_get_integer(data, &myidx);
} else {
cc_verbose(1, 1, VERBOSE_PREFIX_4 " Namestruct not ECMA conform (Integer expected)\n");
cc_qsig_verbose( 1, VERBOSE_PREFIX_4 " Namestruct not ECMA conform (Integer expected)\n");
}
break;
case 4: /* Name not available */

View File

@ -28,6 +28,69 @@
#include "chan_capi_qsig_asn197ade.h"
#include "chan_capi_qsig_asn197no.h"
AST_MUTEX_DEFINE_STATIC(qsig_verbose_lock);
/*
* helper for <pbx>_verbose with different verbose settings
*/
void cc_qsig_verbose(int c_d, char *text, ...)
{
char line[4096];
va_list ap;
va_start(ap, text);
vsnprintf(line, sizeof(line), text, ap);
va_end(ap);
#if 0
{
FILE *fp;
if ((fp = fopen("/tmp/cclog", "a")) != NULL) {
fprintf(fp, "%s", line);
fclose(fp);
}
}
#endif
if (option_verbose > 4) {
if ((!c_d) || ((c_d) && (capiqsigdebug))) {
cc_mutex_lock(&qsig_verbose_lock);
cc_pbx_verbose(line);
cc_mutex_unlock(&qsig_verbose_lock);
}
}
}
/*!
* \brief Encodes an ASN.1 string with type of string
*
* \param asn1_type type of string like ASN1_OCTETSTRING
* \param data pointer to target buffer
* \param len size of target buffer
* \param max_len of the string data
* \param src source pointer for string
* \param src_len string length
* \return data length
*/
int cc_qsig_asn1_add_string2(unsigned char asn1_type, void *data, int len, int max_len, void *src, int src_len)
{
struct rose_component *comp = NULL;
if (len < 2 + src_len)
return -1;
if (max_len && (src_len > max_len))
src_len = max_len;
comp = (struct rose_component *)data;
comp->type = asn1_type;
comp->len = src_len;
memcpy(comp->data, src, src_len);
return 2 + src_len;
}
/*!
* \brief Encodes an ASN.1 string
*
@ -110,7 +173,7 @@ unsigned int cc_qsig_asn1_get_integer(unsigned char *data, int *idx)
intlen = data[myidx++];
if ((intlen < 1) || (intlen > 2)) { /* i don't know if there's a bigger Integer as 16bit -> read specs */
cc_verbose(1, 1, VERBOSE_PREFIX_3 "ASN1Decode: Size of ASN.1 Integer not supported: %i\n", intlen);
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "ASN1Decode: Size of ASN.1 Integer not supported: %i\n", intlen);
*idx = myidx + intlen;
return 0;
}
@ -137,7 +200,7 @@ unsigned char *cc_qsig_asn1_oid2str(unsigned char *data, int size)
s = buf;
if (size < 3) {
cc_verbose(1, 1, VERBOSE_PREFIX_3 "OID2STR: Object identifier too small (%i).\n", size);
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "OID2STR: Object identifier too small (%i).\n", size);
return NULL;
}
@ -279,7 +342,7 @@ int cc_qsig_add_invoke(unsigned char * buf, unsigned int *idx, struct cc_qsig_in
myidx += invoke->oid_len;
break;
default:
cc_verbose(1, 1, VERBOSE_PREFIX_3 "QSIG: Unknown Invoke Type, not encoded (%i)\n", invoke->descr_type);
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "QSIG: Unknown Invoke Type, not encoded (%i)\n", invoke->descr_type);
return -1;
break;
}
@ -308,18 +371,18 @@ unsigned int cc_qsig_check_facility(unsigned char *data, int *idx, int *apduval,
/* First byte after Facility Length */
if (data[myidx] != (unsigned char)(0x80 | protocol)) {
cc_verbose(1, 1, VERBOSE_PREFIX_3 "QSIG: received protocol 0x%#x not configured!\n", (data[myidx] ^= 0x80));
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "QSIG: received protocol 0x%#x not configured!\n", (data[myidx] ^= 0x80));
return 0;
}
myidx++;
cc_verbose(1, 1, VERBOSE_PREFIX_3 "QSIG: Supplementary Services\n");
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "QSIG: Supplementary Services\n");
if (data[myidx] == (unsigned char)COMP_TYPE_NFE) {
myidx++;
/* TODO: Check Entities? */
myidx += data[myidx] + 1;
*idx = myidx;
cc_verbose(1, 1, VERBOSE_PREFIX_3 "QSIG: Facility has NFE struct\n");
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "QSIG: Facility has NFE struct\n");
}
if ((data[myidx] == (unsigned char)COMP_TYPE_APDU_INTERP)) {
myidx++;
@ -327,7 +390,7 @@ unsigned int cc_qsig_check_facility(unsigned char *data, int *idx, int *apduval,
*apduval = data[myidx++];
/* TODO: implement real reject or clear call ? */
*idx = myidx;
cc_verbose(1, 1, VERBOSE_PREFIX_3 "QSIG: Facility has APDU - What to do if INVOKE is unknown: %s\n", APDU_STR[*apduval]);
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "QSIG: Facility has APDU - What to do if INVOKE is unknown: %s\n", APDU_STR[*apduval]);
}
return 1;
}
@ -375,7 +438,7 @@ signed int cc_qsig_get_invokeid(unsigned char *data, int *idx, struct cc_qsig_in
invoke->offset = invoffset; /* offset in Facility Array, where the Invoke Data starts */
invidtype = data[myidx++]; /* Get INVOKE Id Type */
if (invidtype != ASN1_INTEGER) {
cc_verbose(1, 1, VERBOSE_PREFIX_3 "QSIG: Unknown Invoke Identifier Type 0x%#x\n", invidtype);
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "QSIG: Unknown Invoke Identifier Type 0x%#x\n", invidtype);
return -1;
}
temp = cc_qsig_asn1_get_integer(data, &myidx);
@ -408,7 +471,7 @@ signed int cc_qsig_fill_invokestruct(unsigned char *data, int *idx, struct cc_qs
datalen = temp2 - myidx;
if (datalen > 255) {
cc_verbose(1, 1, VERBOSE_PREFIX_3 "QSIG: Unsupported INVOKE Operation Size (max 255 Bytes): %i\n", datalen);
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "QSIG: Unsupported INVOKE Operation Size (max 255 Bytes): %i\n", datalen);
datalen = 255;
}
@ -424,7 +487,7 @@ signed int cc_qsig_fill_invokestruct(unsigned char *data, int *idx, struct cc_qs
invoke->descr_type = ASN1_OBJECTIDENTIFIER;
temp = data[myidx++]; /* Length of OID */
if (temp > 20) {
cc_verbose(1, 1, VERBOSE_PREFIX_3 "QSIG: Unsupported INVOKE Operation OID Size (max 20 Bytes): %i\n", temp);
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "QSIG: Unsupported INVOKE Operation OID Size (max 20 Bytes): %i\n", temp);
temp = 20;
}
@ -444,7 +507,7 @@ signed int cc_qsig_fill_invokestruct(unsigned char *data, int *idx, struct cc_qs
datalen = temp2 - myidx;
if (datalen > 255) {
cc_verbose(1, 1, VERBOSE_PREFIX_3 "QSIG: Unsupported INVOKE Operation Size (max 255 Bytes): %i\n", datalen);
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "QSIG: Unsupported INVOKE Operation Size (max 255 Bytes): %i\n", datalen);
datalen = 255;
}
@ -456,13 +519,13 @@ signed int cc_qsig_fill_invokestruct(unsigned char *data, int *idx, struct cc_qs
break;
default:
cc_verbose(1, 1, VERBOSE_PREFIX_3 "QSIG: Unknown INVOKE Operation Type: %i\n", invoptyp);
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "QSIG: Unknown INVOKE Operation Type: %i\n", invoptyp);
temp2 = (invoke->len) + (invoke->offset) + 1; /* Array End = Invoke Length + Invoke Offset +1 */
datalen = temp2 - myidx;
if (datalen > 255) {
cc_verbose(1, 1, VERBOSE_PREFIX_3 "QSIG: Unsupported INVOKE Operation Size (max 255 Bytes): %i\n", datalen);
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "QSIG: Unsupported INVOKE Operation Size (max 255 Bytes): %i\n", datalen);
datalen = 255;
}
@ -489,7 +552,7 @@ static int ident_qsig_invoke(int invoketype)
case 21:
return CCQSIG__ECMA__LEGINFO2;
default:
cc_verbose(1, 1, VERBOSE_PREFIX_4 "QSIG: Unhandled QSIG INVOKE (%i)\n", invoketype);
cc_qsig_verbose( 1, VERBOSE_PREFIX_4 "QSIG: Unhandled QSIG INVOKE (%i)\n", invoketype);
return -1;
}
}
@ -502,14 +565,14 @@ signed int cc_qsig_identifyinvoke(struct cc_qsig_invokedata *invoke, int protoco
int invokedescrtype = 0;
int datalen;
/* cc_verbose(1, 1, VERBOSE_PREFIX_4 "CONNECT_IND (Ident Invoke %i)\n", invoke->descr_type); */
/* cc_qsig_verbose( 1, VERBOSE_PREFIX_4 "CONNECT_IND (Ident Invoke %i)\n", invoke->descr_type); */
switch (protocol) {
case QSIG_TYPE_ALCATEL_ECMA:
switch (invoke->descr_type) {
case ASN1_INTEGER:
invokedescrtype = 1;
cc_verbose(1, 1, VERBOSE_PREFIX_3 "QSIG: INVOKE OP (%i)\n", invoke->type);
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "QSIG: INVOKE OP (%i)\n", invoke->type);
return ident_qsig_invoke(invoke->type);
break;
case ASN1_OBJECTIDENTIFIER:
@ -519,10 +582,10 @@ signed int cc_qsig_identifyinvoke(struct cc_qsig_invokedata *invoke, int protoco
unsigned char *oidstr = NULL;
oidstr = cc_qsig_asn1_oid2str(invoke->oid_bin, invoke->oid_len);
if (oidstr) {
cc_verbose(1, 1, VERBOSE_PREFIX_3 "QSIG: INVOKE OP (%s)\n", oidstr);
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "QSIG: INVOKE OP (%s)\n", oidstr);
free(oidstr);
} else {
cc_verbose(1, 1, VERBOSE_PREFIX_3 "QSIG: INVOKE OP (unknown - OID not displayable)\n");
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "QSIG: INVOKE OP (unknown - OID not displayable)\n");
}
if ((datalen) == 4) {
@ -533,7 +596,7 @@ signed int cc_qsig_identifyinvoke(struct cc_qsig_invokedata *invoke, int protoco
return -1;
break;
default:
cc_verbose(1, 1, VERBOSE_PREFIX_3 "QSIG: Unidentified INVOKE OP\n");
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "QSIG: Unidentified INVOKE OP\n");
break;
}
break;
@ -541,7 +604,7 @@ signed int cc_qsig_identifyinvoke(struct cc_qsig_invokedata *invoke, int protoco
switch (invoke->descr_type) {
case ASN1_INTEGER:
invokedescrtype = 1;
cc_verbose(1, 1, VERBOSE_PREFIX_3 "QSIG: INVOKE OP (%i)\n", invoke->type);
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "QSIG: INVOKE OP (%i)\n", invoke->type);
return ident_qsig_invoke(invoke->type);
break;
case ASN1_OBJECTIDENTIFIER:
@ -551,10 +614,10 @@ signed int cc_qsig_identifyinvoke(struct cc_qsig_invokedata *invoke, int protoco
unsigned char *oidstr = NULL;
oidstr = cc_qsig_asn1_oid2str(invoke->oid_bin, invoke->oid_len);
if (oidstr) {
cc_verbose(1, 1, VERBOSE_PREFIX_3 "QSIG: INVOKE OP (%s)\n", oidstr);
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "QSIG: INVOKE OP (%s)\n", oidstr);
free(oidstr);
} else {
cc_verbose(1, 1, VERBOSE_PREFIX_3 "QSIG: INVOKE OP (unknown - OID not displayable)\n");
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "QSIG: INVOKE OP (unknown - OID not displayable)\n");
}
if ((datalen) == 4) {
@ -564,7 +627,7 @@ signed int cc_qsig_identifyinvoke(struct cc_qsig_invokedata *invoke, int protoco
}
break;
default:
cc_verbose(1, 1, VERBOSE_PREFIX_3 "QSIG: Unidentified INVOKE OP\n");
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "QSIG: Unidentified INVOKE OP\n");
break;
}
break;
@ -623,18 +686,18 @@ static void pbx_capi_qsig_handle_ctc(struct cc_qsig_invokedata *invoke, struct c
ii = capi_find_interface_bynumber(ctc.redirectionNumber.partyNumber);
if (ii) {
char *prpn = i->qsig_data.if_pr_propose_pn;
cc_verbose(1, 1, VERBOSE_PREFIX_3 "QSIG: Call Transfer partner channel for %s found at channel %s, bridging possible.\n", ctc.redirectionNumber.partyNumber, ii->vname);
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "QSIG: Call Transfer partner channel for %s found at channel %s, bridging possible.\n", ctc.redirectionNumber.partyNumber, ii->vname);
if (!(strlen(prpn))) {
cc_verbose(1, 1, VERBOSE_PREFIX_3 "QSIG: Path Replacement not configured, bridging not available!\n");
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "QSIG: Path Replacement not configured, bridging not available!\n");
} else {
unsigned char fac[CAPI_MAX_FACILITYDATAARRAY_SIZE];
cc_verbose(1, 1, VERBOSE_PREFIX_3 "QSIG: Trying to bridge with Path Replacement number %s...\n", prpn);
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "QSIG: Trying to bridge with Path Replacement number %s...\n", prpn);
switch (ii->state) {
case CAPI_STATE_ALERTING:
cc_verbose(1, 1, VERBOSE_PREFIX_3 "QSIG: peer is in state ALERTING, PATH REPLACE follows after CONNECT...\n");
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "QSIG: peer is in state ALERTING, PATH REPLACE follows after CONNECT...\n");
ii->qsig_data.pr_propose_cid = strdup("123"); /* HACK: need an dynamic ID */
ii->qsig_data.pr_propose_pn = strdup(i->qsig_data.if_pr_propose_pn);
ii->qsig_data.pr_propose_doinboundbridge = 1;
@ -642,7 +705,7 @@ static void pbx_capi_qsig_handle_ctc(struct cc_qsig_invokedata *invoke, struct c
i->qsig_data.partner_plci = ii->PLCI;
break;
case CAPI_STATE_CONNECTED:
cc_verbose(1, 1, VERBOSE_PREFIX_3 "QSIG: peer is CONNECTED...\n");
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "QSIG: peer is CONNECTED...\n");
i->qsig_data.pr_propose_cid = strdup("123"); /* HACK: need an dynamic ID */
i->qsig_data.pr_propose_pn = strdup(i->qsig_data.if_pr_propose_pn);
ii->qsig_data.pr_propose_doinboundbridge = 1;
@ -657,7 +720,7 @@ static void pbx_capi_qsig_handle_ctc(struct cc_qsig_invokedata *invoke, struct c
i->qsig_data.pr_propose_pn = NULL;
break;
default:
cc_verbose(1, 1, VERBOSE_PREFIX_3 "QSIG: peer's state is %i, which is not handled yet...\n", ii->state);
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "QSIG: peer's state is %i, which is not handled yet...\n", ii->state);
break;
}
@ -719,14 +782,14 @@ static int qsig_handle_q932facility(unsigned char *data, struct capi_pvt *i, int
if (cc_qsig_check_facility(data, &facidx, &action_unkn_apdu, protocoltype)) {
while ((facidx) < faclen) {
cc_verbose(1, 1, VERBOSE_PREFIX_3 "Checking INVOKE at index %i (of %i)\n", facidx, faclen);
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "Checking INVOKE at index %i (of %i)\n", facidx, faclen);
invoke_len = cc_qsig_check_invoke(data, &facidx);
if (invoke_len > 0) {
if (cc_qsig_get_invokeid(data, &facidx, &invoke) == 0) {
invoketmp1 = cc_qsig_fill_invokestruct(data, &facidx, &invoke, action_unkn_apdu);
invoke_op = cc_qsig_identifyinvoke(&invoke, i->qsigfeat);
if (invoke_op < 0) {
cc_verbose(1, 1, VERBOSE_PREFIX_3 "Invoke not identified!\n");
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "Invoke not identified!\n");
}
cc_qsig_handle_invokeoperation(invoke_op, &invoke, i);
}
@ -761,7 +824,7 @@ unsigned int cc_qsig_handle_capiind(unsigned char *data, struct capi_pvt *i)
faclen = data[facidx++];
faclen += facidx;
while (facidx < faclen0) {
cc_verbose(1, 1, VERBOSE_PREFIX_3 "Checking Facility at index %i\n", facidx);
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "Checking Facility at index %i\n", facidx);
switch (i->qsigfeat) {
case QSIG_TYPE_ALCATEL_ECMA:
qsig_handle_q932facility(data, i, &facidx, faclen, Q932_PROTOCOL_ROSE);
@ -770,23 +833,23 @@ unsigned int cc_qsig_handle_capiind(unsigned char *data, struct capi_pvt *i)
qsig_handle_q932facility(data, i, &facidx, faclen, Q932_PROTOCOL_EXTENSIONS);
break;
default:
cc_verbose(1, 1, VERBOSE_PREFIX_3 "Unknown QSIG protocol configured (%i)\n", i->qsigfeat);
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "Unknown QSIG protocol configured (%i)\n", i->qsigfeat);
break;
}
if (facidx < faclen0) { /* there may follow a new facility */
if (data[facidx] == 0x1c) {
cc_verbose(1, 1, VERBOSE_PREFIX_3 "Found another facility at index %i\n", facidx);
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "Found another facility at index %i\n", facidx);
facidx++;
faclen = data[facidx++];
faclen += facidx;
} else {
cc_verbose(1, 1, VERBOSE_PREFIX_3 "More data found in facility at index %i, but this is not an facility (%#x)\n", facidx, data[facidx]);
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "More data found in facility at index %i, but this is not an facility (%#x)\n", facidx, data[facidx]);
facidx++; /* don't start an endlessloop */
}
}
}
cc_verbose(1, 1, VERBOSE_PREFIX_3 "Facility done at index %i from %i\n", facidx, faclen);
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "Facility done at index %i from %i\n", facidx, faclen);
return 1;
}
@ -802,9 +865,9 @@ unsigned int cc_qsig_handle_capi_facilityind(unsigned char *data, struct capi_pv
return 0;
}
faclen = data[facidx++];
/* cc_verbose(1, 1, VERBOSE_PREFIX_3 "CONNECT_IND (Got Facility IE, Length=%#x)\n", faclen); */
/* cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "CONNECT_IND (Got Facility IE, Length=%#x)\n", faclen); */
while (facidx < faclen) {
cc_verbose(1, 1, VERBOSE_PREFIX_3 "Checking Facility at index %i\n", facidx);
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "Checking Facility at index %i\n", facidx);
switch (i->qsigfeat) {
case QSIG_TYPE_ALCATEL_ECMA:
qsig_handle_q932facility(data, i, &facidx, faclen, Q932_PROTOCOL_ROSE);
@ -813,13 +876,13 @@ unsigned int cc_qsig_handle_capi_facilityind(unsigned char *data, struct capi_pv
qsig_handle_q932facility(data, i, &facidx, faclen, Q932_PROTOCOL_EXTENSIONS);
break;
default:
cc_verbose(1, 1, VERBOSE_PREFIX_3 "Unknown QSIG protocol configured (%i)\n", i->qsigfeat);
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "Unknown QSIG protocol configured (%i)\n", i->qsigfeat);
/* kill endlessloop */
facidx += faclen;
break;
}
}
cc_verbose(1, 1, VERBOSE_PREFIX_3 "Facility done at index %i from %i\n", facidx, faclen);
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "Facility done at index %i from %i\n", facidx, faclen);
return 1;
}
@ -828,16 +891,16 @@ static int identify_qsig_setup_callfeature(char *param)
char *p = param;
switch (*p) {
case 't':
cc_verbose(1, 1, "Call Transfer");
cc_qsig_verbose( 1, "Call Transfer");
p++;
if (*p == 'r') {
cc_verbose(1, 1, " on ALERT");
cc_qsig_verbose( 1, " on ALERT");
return 2;
} else {
return 1;
}
default:
cc_verbose(1, 1, "unknown (%c)\n", *p);
cc_qsig_verbose( 1, "unknown (%c)\n", *p);
break;
}
@ -868,13 +931,13 @@ unsigned int cc_qsig_add_call_setup_data(unsigned char *data, struct capi_pvt *i
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");
cc_qsig_verbose( 1, VERBOSE_PREFIX_4 "Sending QSIG external PROGRESS IE.\n");
add_externalinfo = 1;
pp = strsep (&p, "/");
pp = NULL;
break;
case 'C':
cc_verbose(1, 1, VERBOSE_PREFIX_4 "QSIG Call Feature requested: ");
cc_qsig_verbose( 1, VERBOSE_PREFIX_4 "QSIG Call Feature requested: ");
p++;
switch(identify_qsig_setup_callfeature(p)) {
case 1: /* Call transfer */
@ -890,7 +953,7 @@ unsigned int cc_qsig_add_call_setup_data(unsigned char *data, struct capi_pvt *i
if (ii)
ii->qsig_data.partner_plci = i->PLCI;
cc_verbose(1, 1, " for plci %#x\n", i->qsig_data.partner_plci);
cc_qsig_verbose( 1, " for plci %#x\n", i->qsig_data.partner_plci);
}
break;
case 2: /* Call transfer on ring */
@ -906,7 +969,7 @@ unsigned int cc_qsig_add_call_setup_data(unsigned char *data, struct capi_pvt *i
if (ii)
ii->qsig_data.partner_plci = i->PLCI;
cc_verbose(1, 1, " for plci %#x\n", i->qsig_data.partner_plci);
cc_qsig_verbose( 1, " for plci %#x\n", i->qsig_data.partner_plci);
}
break;
default:
@ -1091,7 +1154,7 @@ int pbx_capi_qsig_getplci(struct ast_channel *c, char *param)
char buffer[10];
snprintf(buffer, sizeof(buffer)-1, "%d", i->PLCI);
cc_verbose(4, 1, VERBOSE_PREFIX_4 "QSIG_GETPLCI: %s\n", buffer);
cc_qsig_verbose( 1, VERBOSE_PREFIX_4 "QSIG_GETPLCI: %s\n", buffer);
pbx_builtin_setvar_helper(c, "QSIG_PLCI", buffer);
return 0;
@ -1139,7 +1202,7 @@ int pbx_capi_qsig_ct(struct ast_channel *c, char *param)
marker = strsep(&param, "|");
callmark = atoi(marker);
cc_verbose(1, 1, VERBOSE_PREFIX_4 " * QSIG_CT: using call marker %i(%s)\n", callmark, marker);
cc_qsig_verbose( 1, VERBOSE_PREFIX_4 " * QSIG_CT: using call marker %i(%s)\n", callmark, marker);
for (ii = capi_iflist; ii; ii = ii->next) {
if (ii->qsig_data.callmark == callmark)
@ -1304,7 +1367,7 @@ static void qsig_cleanup_channel(struct capi_pvt *i)
void interface_cleanup_qsig(struct capi_pvt *i)
{
if (i->qsigfeat) {
cc_verbose(1, 1, VERBOSE_PREFIX_4 "QSIG: cleanup channel\n");
cc_qsig_verbose( 1, VERBOSE_PREFIX_4 "QSIG: cleanup channel\n");
qsig_cleanup_channel(i);
}
}
@ -1332,14 +1395,14 @@ int pbx_capi_qsig_wait_for_prpropose(struct capi_pvt *i)
i->qsig_data.waitevent = CAPI_QSIG_WAITEVENT_PRPROPOSE;
abstime.tv_sec = time(NULL) + CCQSIG_TIMER_WAIT_PRPROPOSE; /* PR PROPOSE TIMER */
abstime.tv_nsec = 0;
cc_verbose(4, 1, "%s: wait for PATH REPLACEMENT.\n",
cc_qsig_verbose( 1, "%s: wait for PATH REPLACEMENT.\n",
i->vname);
if (ast_cond_timedwait(&i->qsig_data.event_trigger, &i->lock, &abstime) != 0) {
cc_log(LOG_WARNING, "%s: timed out waiting for PATH REPLACEMENT.\n",
i->vname);
ret = 0;
} else {
cc_verbose(4, 1, "%s: cond signal received for PATH REPLACEMENT.\n",
cc_qsig_verbose( 1, "%s: cond signal received for PATH REPLACEMENT.\n",
i->vname);
}
}
@ -1358,7 +1421,7 @@ static void pbx_capi_qsig_post_handling(struct capi_pvt *i)
(i->qsig_data.pr_propose_sentback == 1)) {
i->qsig_data.waitevent = 0;
ast_cond_signal(&i->qsig_data.event_trigger);
cc_verbose(4, 1, "%s: found and signal for PATH REPLACEMENT state.\n",
cc_qsig_verbose( 1, "%s: found and signal for PATH REPLACEMENT state.\n",
i->vname);
return;
}
@ -1466,7 +1529,7 @@ void pbx_capi_qsig_handle_info_indication(_cmsg *CMSG, unsigned int PLCI, unsign
ii->qsig_data.pr_propose_active = 1;
}
} else
cc_verbose(1, 1, VERBOSE_PREFIX_4 " * QSIG_PATHREPLACEMENT_PROPOSE: no partner channel found (%#x)\n", i->qsig_data.partner_plci);
cc_qsig_verbose( 1, VERBOSE_PREFIX_4 " * QSIG_PATHREPLACEMENT_PROPOSE: no partner channel found (%#x)\n", i->qsig_data.partner_plci);
@ -1481,7 +1544,7 @@ void pbx_capi_qsig_handle_info_indication(_cmsg *CMSG, unsigned int PLCI, unsign
struct capi_pvt *ii = capi_find_interface_by_plci(i->qsig_data.partner_plci);
if (ii) {
cc_verbose(1, 1, VERBOSE_PREFIX_4 " * QSIG_PATHREPLACEMENT_PROPOSE: trying to complete bridge...\n");
cc_qsig_verbose( 1, VERBOSE_PREFIX_4 " * QSIG_PATHREPLACEMENT_PROPOSE: trying to complete bridge...\n");
chanx = ast_bridged_channel(i->owner);
ast_channel_masquerade(ii->owner, chanx);
}

View File

@ -49,7 +49,7 @@ void cc_qsig_op_ecma_isdn_namepres(struct cc_qsig_invokedata *invoke, struct cap
int myidx = 0;
char *nametype = NULL;
cc_verbose(1, 1, VERBOSE_PREFIX_4 "Handling Name Operation (id# %#x)\n", invoke->id);
cc_qsig_verbose( 1, VERBOSE_PREFIX_4 "Handling Name Operation (id# %#x)\n", invoke->id);
callername[0] = 0;
datalength = invoke->datalen;
@ -85,7 +85,7 @@ void cc_qsig_op_ecma_isdn_namepres(struct cc_qsig_invokedata *invoke, struct cap
case 2: /* Connected Name */
case 3: /* Busy Name */
if (i->qsig_data.dnameid) { /* this facility may come more than once - if so, then update this value */
cc_verbose(1, 1, VERBOSE_PREFIX_4 " * deleting previously received name.\n", nametype, namelength, callername);
cc_qsig_verbose( 1, VERBOSE_PREFIX_4 " * deleting previously received name.\n", nametype, namelength, callername);
free(i->qsig_data.dnameid);
}
i->qsig_data.dnameid = strdup(callername); /* save name as destination in qsig specific fields */
@ -95,7 +95,7 @@ void cc_qsig_op_ecma_isdn_namepres(struct cc_qsig_invokedata *invoke, struct cap
break;
}
cc_verbose(1, 1, VERBOSE_PREFIX_4 " * Got %s: \"%s\" (%i byte(s))\n", nametype, callername, namelength);
cc_qsig_verbose( 0, VERBOSE_PREFIX_4 " * Got %s: \"%s\" (%i byte(s))\n", nametype, callername, namelength);
/* if there was an sequence tag, we have more informations here, but we will ignore it at the moment */
@ -140,6 +140,7 @@ int cc_qsig_encode_ecma_name_invoke(unsigned char * buf, unsigned int *idx, stru
namelen = 50;
memcpy(namebuf, name, namelen);
}
namebuf[namelen] = 0;
invoke->id = 1;
invoke->descr_type = -1; /* Let others do the work: qsig_add_invoke */
@ -158,7 +159,7 @@ int cc_qsig_encode_ecma_name_invoke(unsigned char * buf, unsigned int *idx, stru
invoke->datalen = dataidx;
memcpy(invoke->data, data, dataidx);
cc_verbose(1, 1, VERBOSE_PREFIX_4 " * Sending \"%s\": (%i byte(s))\n", namebuf, namelen);
cc_qsig_verbose( 0, VERBOSE_PREFIX_4 " * Sending \"%s\": (%i byte(s))\n", namebuf, namelen);
return 0;
}
@ -228,7 +229,7 @@ int cc_qsig_encode_ecma_isdn_leginfo3_invoke(unsigned char * buf, unsigned int *
invoke->datalen = dataidx;
memcpy(invoke->data, data, dataidx);
cc_verbose(1, 1, VERBOSE_PREFIX_4 " * Sending QSIG_LEG_INFO3 \"%s\": (%i byte(s))\n", namebuf, namelen);
cc_qsig_verbose( 0, VERBOSE_PREFIX_4 " * Sending QSIG_LEG_INFO3 \"%s\": (%i byte(s))\n", namebuf, namelen);
return 0;
}
@ -272,11 +273,14 @@ void cc_qsig_op_ecma_isdn_leginfo2(struct cc_qsig_invokedata *invoke, struct cap
divertName[0] = 0;
origCalledName[0] = 0;
cc_verbose(1, 1, VERBOSE_PREFIX_4 "Handling QSIG LEG INFO2 (id# %#x)\n", invoke->id);
cc_qsig_verbose( 1, VERBOSE_PREFIX_4 "Handling QSIG LEG INFO2 (id# %#x)\n", invoke->id);
origPNS.partyNumber = NULL;
divertPNS.partyNumber = NULL;
if (invoke->data[myidx++] != (ASN1_SEQUENCE | ASN1_TC_UNIVERSAL | ASN1_TF_CONSTRUCTED)) { /* 0x30 */
/* We do not handle this, because it should start with an sequence tag */
cc_verbose(1, 1, VERBOSE_PREFIX_4 " * not Handling QSIG LEG INFO2 - not a sequence\n");
cc_qsig_verbose( 1, VERBOSE_PREFIX_4 " * not Handling QSIG LEG INFO2 - not a sequence\n");
return;
}
@ -284,7 +288,7 @@ void cc_qsig_op_ecma_isdn_leginfo2(struct cc_qsig_invokedata *invoke, struct cap
seqlength = invoke->data[myidx++];
datalength = invoke->datalen;
if (datalength < (seqlength+1)) {
cc_verbose(1, 1, VERBOSE_PREFIX_4 " * not Handling QSIG LEG INFO2 - buffer error\n");
cc_qsig_verbose( 1, VERBOSE_PREFIX_4 " * not Handling QSIG LEG INFO2 - buffer error\n");
return;
}
@ -296,7 +300,7 @@ void cc_qsig_op_ecma_isdn_leginfo2(struct cc_qsig_invokedata *invoke, struct cap
while (myidx < datalength) {
parameter = (invoke->data[myidx++] & 0x0f);
cc_verbose(1, 1, VERBOSE_PREFIX_4 " * Found parameter %i\n", parameter);
cc_qsig_verbose( 1, VERBOSE_PREFIX_4 " * Found parameter %i\n", parameter);
switch (parameter) {
case 0:
myidx++; /* Ignore Length of enumeration tag*/
@ -317,16 +321,16 @@ void cc_qsig_op_ecma_isdn_leginfo2(struct cc_qsig_invokedata *invoke, struct cap
/* Redirecting Name */
temp = invoke->data[myidx++]; /* keep the length of this info - maybe we don't get all data now */
cc_qsig_asn197no_get_name(divertName, ASN197NO_NAME_STRSIZE, &temp2, &myidx, invoke->data);
myidx += temp;
myidx += temp + 1;
break;
case 4:
/* origCalled Name */
temp = invoke->data[myidx++]; /* keep the length of this info - maybe we don't get all data now */
cc_qsig_asn197no_get_name(origCalledName, ASN197NO_NAME_STRSIZE, &temp2, &myidx, invoke->data);
myidx += temp;
myidx += temp + 1;
break;
default:
cc_verbose(1, 1, VERBOSE_PREFIX_4 " * unknown parameter %i\n", parameter);
cc_qsig_verbose( 1, VERBOSE_PREFIX_4 " * unknown parameter %i\n", parameter);
break;
}
}
@ -338,12 +342,14 @@ void cc_qsig_op_ecma_isdn_leginfo2(struct cc_qsig_invokedata *invoke, struct cap
snprintf(tempstr, 5, "%i", divCount);
pbx_builtin_setvar_helper(i->owner, "_QSIG_LI2_DIVCOUNT", tempstr);
if (divertPNS.partyNumber)
pbx_builtin_setvar_helper(i->owner, "_QSIG_LI2_DIVNUM", divertPNS.partyNumber);
if (origPNS.partyNumber)
pbx_builtin_setvar_helper(i->owner, "_QSIG_LI2_ODIVNUM", origPNS.partyNumber);
pbx_builtin_setvar_helper(i->owner, "_QSIG_LI2_DIVNAME", divertName);
pbx_builtin_setvar_helper(i->owner, "_QSIG_LI2_ODIVNAME", origCalledName);
cc_verbose(1, 1, VERBOSE_PREFIX_4 " * Got QSIG_LEG_INFO2: %i(%i), %ix %s->%s, %s->%s\n", divReason, orgDivReason, divCount, origPNS.partyNumber, divertPNS.partyNumber, origCalledName, divertName);
cc_qsig_verbose( 0, VERBOSE_PREFIX_4 " * Got QSIG_LEG_INFO2: %i(%i), %ix %s->%s, %s->%s\n", divReason, orgDivReason, divCount, origPNS.partyNumber, divertPNS.partyNumber, origCalledName, divertName);
return;
@ -474,7 +480,7 @@ void cc_qsig_encode_ecma_calltransfer(unsigned char * buf, unsigned int *idx, st
invoke->datalen = ix;
memcpy(invoke->data, c, ix);
cc_verbose(1, 1, VERBOSE_PREFIX_4 " * Sending QSIG_CT: %i->%s\n", info, cid);
cc_qsig_verbose( 0, VERBOSE_PREFIX_4 " * Sending QSIG_CT: %i->%s\n", info, cid);
if (cid)
free(cid);
@ -517,9 +523,9 @@ unsigned int cc_qsig_decode_ecma_calltransfer(struct cc_qsig_invokedata *invoke,
ctc->callStatus = answered;
ctc->argumentExtension = NULL; /* unhandled yet */
#define ct_err(x...) { cc_verbose(1, 1, VERBOSE_PREFIX_4 " * not Handling QSIG CALL TRANSFER - "x); return 0; }
#define ct_err(x...) { cc_qsig_verbose( 1, VERBOSE_PREFIX_4 " * not Handling QSIG CALL TRANSFER - "x); return 0; }
cc_verbose(1, 1, VERBOSE_PREFIX_4 "Handling QSIG CALL TRANSFER (id# %#x)\n", invoke->id);
cc_qsig_verbose( 1, VERBOSE_PREFIX_4 "Handling QSIG CALL TRANSFER (id# %#x)\n", invoke->id);
if (data[myidx++] != (ASN1_SEQUENCE | ASN1_TC_UNIVERSAL | ASN1_TF_CONSTRUCTED)) { /* 0x30 */
/* We do not handle this, because it should start with an sequence tag */
@ -554,7 +560,7 @@ unsigned int cc_qsig_decode_ecma_calltransfer(struct cc_qsig_invokedata *invoke,
if (ctc->basicCallInfoElements) {
memcpy(ctc->basicCallInfoElements, &data[myidx+1], data[myidx] );
} else {
cc_verbose(1, 1, VERBOSE_PREFIX_4 " * QSIG CALL TRANSFER - couldn't allocate memory for basicCallInfoElements.\n", (int)data[myidx]);
cc_qsig_verbose( 1, VERBOSE_PREFIX_4 " * QSIG CALL TRANSFER - couldn't allocate memory for basicCallInfoElements.\n", (int)data[myidx]);
}
myidx += data[myidx] + 1;
}
@ -574,7 +580,7 @@ unsigned int cc_qsig_decode_ecma_calltransfer(struct cc_qsig_invokedata *invoke,
}
}
cc_verbose(1, 1, VERBOSE_PREFIX_4 " * Got QSIG CALL TRANSFER endDesignation: %i partyNumber: %s (ScreeningInd: %i), partyName: \"%s\", Call state: %s\n",
cc_qsig_verbose( 0, VERBOSE_PREFIX_4 " * Got QSIG CALL TRANSFER endDesignation: %i partyNumber: %s (ScreeningInd: %i), partyName: \"%s\", Call state: %s\n",
ctc->endDesignation, ctc->redirectionNumber.partyNumber, ctc->redirectionNumber.screeningInd, ctc->redirectionName, ct_status_txt[ctc->callStatus]);
return 1;
@ -649,7 +655,7 @@ void cc_qsig_encode_ecma_sscalltransfer(unsigned char * buf, unsigned int *idx,
invoke->datalen = ix;
memcpy(invoke->data, c, ix);
cc_verbose(1, 1, VERBOSE_PREFIX_4 " * Sending QSIG_SSCT: %s->%s\n", cidsrc, ciddst);
cc_qsig_verbose( 0, VERBOSE_PREFIX_4 " * Sending QSIG_SSCT: %s->%s\n", cidsrc, ciddst);
}
@ -680,11 +686,11 @@ void cc_qsig_op_ecma_isdn_prpropose(struct cc_qsig_invokedata *invoke, struct ca
callid[0] = 0;
reroutingnr[0] = 0;
cc_verbose(1, 1, VERBOSE_PREFIX_4 "Handling QSIG PATH REPLACEMENT PROPOSE (id# %#x)\n", invoke->id);
cc_qsig_verbose( 1, VERBOSE_PREFIX_4 "Handling QSIG PATH REPLACEMENT PROPOSE (id# %#x)\n", invoke->id);
if (invoke->data[myidx++] != (ASN1_SEQUENCE | ASN1_TC_UNIVERSAL | ASN1_TF_CONSTRUCTED)) { /* 0x30 */
/* We do not handle this, because it should start with an sequence tag */
cc_verbose(1, 1, VERBOSE_PREFIX_4 " * not Handling QSIG REPLACEMENT PROPOSE - not a sequence\n");
cc_qsig_verbose( 1, VERBOSE_PREFIX_4 " * not Handling QSIG REPLACEMENT PROPOSE - not a sequence\n");
return;
}
@ -692,7 +698,7 @@ void cc_qsig_op_ecma_isdn_prpropose(struct cc_qsig_invokedata *invoke, struct ca
seqlength = invoke->data[myidx++];
datalength = invoke->datalen;
if (datalength < (seqlength+1)) {
cc_verbose(1, 1, VERBOSE_PREFIX_4 " * not Handling QSIG REPLACEMENT PROPOSE - buffer error\n");
cc_qsig_verbose( 1, VERBOSE_PREFIX_4 " * not Handling QSIG REPLACEMENT PROPOSE - buffer error\n");
return;
}
@ -701,7 +707,7 @@ void cc_qsig_op_ecma_isdn_prpropose(struct cc_qsig_invokedata *invoke, struct ca
strsize = cc_qsig_asn1_get_string((unsigned char*)&callid, sizeof(callid), &invoke->data[myidx]);
myidx += strsize +1;
} else {
cc_verbose(1, 1, VERBOSE_PREFIX_4 " * not Handling QSIG REPLACEMENT PROPOSE - NUMERICSTRING expected\n");
cc_qsig_verbose( 1, VERBOSE_PREFIX_4 " * not Handling QSIG REPLACEMENT PROPOSE - NUMERICSTRING expected\n");
return;
}
@ -711,7 +717,7 @@ void cc_qsig_op_ecma_isdn_prpropose(struct cc_qsig_invokedata *invoke, struct ca
if (temp) {
myidx += temp;
} else {
cc_verbose(1, 1, VERBOSE_PREFIX_4 " * not Handling QSIG REPLACEMENT PROPOSE - partyNumber expected (%i)\n", myidx);
cc_qsig_verbose( 1, VERBOSE_PREFIX_4 " * not Handling QSIG REPLACEMENT PROPOSE - partyNumber expected (%i)\n", myidx);
return;
}
@ -719,7 +725,7 @@ void cc_qsig_op_ecma_isdn_prpropose(struct cc_qsig_invokedata *invoke, struct ca
i->qsig_data.pr_propose_cid = strdup(callid);
i->qsig_data.pr_propose_pn = strdup(reroutingnr);
cc_verbose(1, 1, VERBOSE_PREFIX_4 " * Got QSIG_PATHREPLACEMENT_PROPOSE Call identity: %s, Party number: %s (%i)\n", callid, reroutingnr, temp);
cc_qsig_verbose( 0, VERBOSE_PREFIX_4 " * Got QSIG_PATHREPLACEMENT_PROPOSE Call identity: %s, Party number: %s (%i)\n", callid, reroutingnr, temp);
return;
}
@ -742,7 +748,6 @@ 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 = 4;
char *callid, *reroutingnr;
@ -751,6 +756,11 @@ void cc_qsig_encode_ecma_prpropose(unsigned char * buf, unsigned int *idx, struc
char c[255];
int ix = 0;
int res = 0;
int ii = 0;
struct rose_component *comp = NULL, *compstk[10];
int compsp = 0;
if (!i->qsig_data.pr_propose_cid)
return ;
@ -765,6 +775,7 @@ void cc_qsig_encode_ecma_prpropose(unsigned char * buf, unsigned int *idx, struc
seqlen += cidlen + rrnlen;
#if 0
c[ix++] = ASN1_SEQUENCE | ASN1_TF_CONSTRUCTED; /* start of SEQUENCE */
c[ix++] = seqlen;
@ -777,6 +788,23 @@ void cc_qsig_encode_ecma_prpropose(unsigned char * buf, unsigned int *idx, struc
c[ix++] = rrnlen;
memcpy(&c[ix], reroutingnr, rrnlen);
ix += rrnlen;
#else
ASN1_ADD_SIMPLE(comp, (ASN1_SEQUENCE | ASN1_TF_CONSTRUCTED), c, ii);
ASN1_PUSH(compstk, compsp, comp);
res = cc_qsig_asn1_add_string2(ASN1_NUMERICSTRING, &c[ii], sizeof(c) - ii, 20, callid, cidlen);
if (res < 0)
return;
ii += res;
res = cc_qsig_asn1_add_string2(ASN1_TC_CONTEXTSPEC, &c[ii], sizeof(c) - ii, 20, reroutingnr, rrnlen);
if (res < 0)
return;
ii += res;
ASN1_FIXUP(compstk, compsp, c, ii);
ix = ii;
#endif
/* end of SEQUENCE */
/* there are optional data possible here */
@ -787,8 +815,44 @@ void cc_qsig_encode_ecma_prpropose(unsigned char * buf, unsigned int *idx, struc
invoke->datalen = ix;
memcpy(invoke->data, c, ix);
cc_verbose(1, 1, VERBOSE_PREFIX_4 " * Sending QSIG_PATHREPLACEMENT_PROPOSE: Call identity: %s, Party number: %s\n", callid, reroutingnr);
cc_qsig_verbose( 0, VERBOSE_PREFIX_4 " * Sending QSIG_PATHREPLACEMENT_PROPOSE: Call identity: %s, Party number: %s\n", callid, reroutingnr);
return;
}
void cc_qsig_encode_ecma_ccnr_req(unsigned char * buf, unsigned int *idx, struct cc_qsig_invokedata *invoke, struct capi_pvt *i, char *param)
{
int invokeop = 27;
int ii = 0;
unsigned char c[256];
struct rose_component *comp = NULL, *compstk[10];
int compsp = 0;
int ix = 0;
ASN1_ADD_SIMPLE(comp, (ASN1_TF_CONSTRUCTED | ASN1_SEQUENCE), c, ii);
ASN1_PUSH(compstk, compsp, comp);
#if 0 /* Constructed data - ECMAv1 HICOM/HIPATH */
ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1), buffer, i);
ASN1_PUSH(compstk, compsp, comp);
res = asn1_string_encode(ASN1_OCTETSTRING, &buffer[i], sizeof(buffer)-i, 50, c->callername, namelen);
if (res < 0)
return -1;
i += res;
ASN1_FIXUP(compstk, compsp, buffer, i);
#endif
invoke->id = invokeop;
invoke->descr_type = -1;
invoke->type = invokeop;
invoke->datalen = ix;
memcpy(invoke->data, c, ix);
cc_qsig_verbose( 1, VERBOSE_PREFIX_4 " * Sending QSIG_CCNR_REQ\n");
return ;
}

View File

@ -18,6 +18,7 @@
/* ECMA Features structs */
/* Call Transfer Complete struct */
struct cc_qsig_ctcomplete {
enum {
@ -35,6 +36,17 @@ struct cc_qsig_ctcomplete {
char *argumentExtension; /* OPTIONAL: ASN1_SEQUENCE - manufacturer specific extension */
};
/* CCBS struct */
struct cc_qsig_ccbsreq {
char *numberA; /* Simplified numbers*/
char *numberB;
char *PSS1InfoElement; /* Bearer caps, LLC, HLC */
char *subaddrA;
char *subaddrB;
int can_retain_service;
int retain_sig_connection;
char *extension;
};
/*
*** ECMA QSIG Functions