diff --git a/chan_capi.c b/chan_capi.c index d1dd434..eed81a7 100644 --- a/chan_capi.c +++ b/chan_capi.c @@ -142,7 +142,8 @@ static int capi_capability = AST_FORMAT_ALAW; static pthread_t monitor_thread = (pthread_t)(0-1); -static struct capi_pvt *iflist = NULL; +struct capi_pvt *iflist = NULL; + static struct cc_capi_controller *capi_controllers[CAPI_MAX_CONTROLLERS + 1]; static int capi_num_controllers = 0; static unsigned int capi_counter = 0; @@ -4067,6 +4068,9 @@ static int pbx_capi_peer_link(struct ast_channel *c, char *param) pbx_builtin_setvar_helper(c, "_CAPIPEERLINKID", buffer); } + cc_verbose(2, 1, VERBOSE_PREFIX_3 "Added %s as CAPI peer link.\n", + c->name); + return 0; } @@ -4520,119 +4524,6 @@ static int pbx_capi_3pty_begin(struct ast_channel *c, char *param) return 0; } -/* - * Initiate a QSIG Single Step Call Transfer - */ -static int pbx_capi_qsig_ssct(struct ast_channel *c, char *param) -{ - unsigned char fac[CAPI_MAX_FACILITYDATAARRAY_SIZE]; - _cmsg CMSG; - struct capi_pvt *i = CC_CHANNEL_PVT(c); - - if (!param) { /* no data implies no Calling Number and Destination Number */ - cc_log(LOG_WARNING, "capi qsig_ssct requires source number and destination number\n"); - return -1; - } - - cc_qsig_do_facility(fac, c, param, 99, 0); - - INFO_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(),0); - INFO_REQ_PLCI(&CMSG) = i->PLCI; - INFO_REQ_FACILITYDATAARRAY(&CMSG) = fac; - - _capi_put_cmsg(&CMSG); - - - return 0; -} - -/* - * Initiate a QSIG Call Transfer - */ -static int pbx_capi_qsig_ct(struct ast_channel *c, char *param) -{ - unsigned char fac[CAPI_MAX_FACILITYDATAARRAY_SIZE]; - _cmsg CMSG; - struct capi_pvt *i = CC_CHANNEL_PVT(c); - struct capi_pvt *ii = NULL; - unsigned int callmark; - char *marker; - - if (!param) { /* no data implies no Calling Number and Destination Number */ - cc_log(LOG_WARNING, "capi qsig_ct requires call marker, source number, destination number and await_connect info\n"); - return -1; - } - - marker = strsep(¶m, "|"); - - callmark = atoi(marker); - cc_verbose(1, 1, VERBOSE_PREFIX_4 " * QSIG_CT: using call marker %i(%s)\n", callmark, marker); - - cc_mutex_lock(&iflock); - for (ii = iflist; ii; ii = ii->next) { - if (ii->qsig_data.callmark == callmark) - break; - } - cc_mutex_unlock(&iflock); - - if (!ii) { - cc_log(LOG_WARNING, "capi qsig_ct call marker not found!\n"); - return -1; - } - - cc_qsig_do_facility(fac, c, param, 12, 0); - - INFO_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(),0); - INFO_REQ_PLCI(&CMSG) = ii->PLCI; - INFO_REQ_FACILITYDATAARRAY(&CMSG) = fac; - - _capi_put_cmsg(&CMSG); - - cc_qsig_do_facility(fac, c, param, 12, 1); - - INFO_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(),0); - INFO_REQ_PLCI(&CMSG) = i->PLCI; - INFO_REQ_FACILITYDATAARRAY(&CMSG) = fac; - - _capi_put_cmsg(&CMSG); - - - - return 0; -} - -/* - * Initiate a QSIG Call Transfer - */ -static int pbx_capi_qsig_callmark(struct ast_channel *c, char *param) -{ - struct capi_pvt *i = CC_CHANNEL_PVT(c); - - if (!param) { /* no data implies no Calling Number and Destination Number */ - cc_log(LOG_WARNING, "capi qsig_callmark requires an call identifier\n"); - return -1; - } - - i->qsig_data.callmark = atoi(param); - - return 0; -} - -/* - * Initiate a QSIG Call Transfer - */ -static int pbx_capi_qsig_getplci(struct ast_channel *c, char *param) -{ - struct capi_pvt *i = CC_CHANNEL_PVT(c); - char buffer[10]; - - snprintf(buffer, sizeof(buffer)-1, "%d", i->PLCI); - cc_verbose(4, 1, VERBOSE_PREFIX_4 "QSIG_GETPLCI: %s\n", buffer); - pbx_builtin_setvar_helper(c, "QSIG_PLCI", buffer); - - return 0; -} - /* * struct of capi commands */ @@ -4653,7 +4544,8 @@ static struct capicommands_s { { "holdtype", pbx_capi_holdtype, 1 }, { "retrieve", pbx_capi_retrieve, 0 }, { "ect", pbx_capi_ect, 1 }, - { "3pty_begin", pbx_capi_3pty_begin, 1 }, + { "3pty_begin", pbx_capi_3pty_begin, 1 }, + { "ccbs", pbx_capi_ccbs, 0 }, { "qsig_ssct", pbx_capi_qsig_ssct, 1 }, { "qsig_ct", pbx_capi_qsig_ct, 1 }, { "qsig_callmark",pbx_capi_qsig_callmark, 1 }, diff --git a/chan_capi.h b/chan_capi.h index 9a753c5..05d3861 100644 --- a/chan_capi.h +++ b/chan_capi.h @@ -561,6 +561,7 @@ struct cc_capi_controller { * prototypes */ extern unsigned capi_ApplID; +extern struct capi_pvt *iflist; extern void cc_start_b3(struct capi_pvt *i); #endif diff --git a/chan_capi_qsig.h b/chan_capi_qsig.h index 95c2ff0..e8ec550 100644 --- a/chan_capi_qsig.h +++ b/chan_capi_qsig.h @@ -163,6 +163,11 @@ extern unsigned int cc_qsig_handle_invokeoperation(int invokeident, struct cc_qs extern unsigned int cc_qsig_do_facility(unsigned char *fac, struct ast_channel *c, char *param, unsigned int factype, int info1); +extern int pbx_capi_qsig_getplci(struct ast_channel *c, char *param); +extern int pbx_capi_qsig_ssct(struct ast_channel *c, char *param); +extern int pbx_capi_qsig_ct(struct ast_channel *c, char *param); +extern int pbx_capi_qsig_callmark(struct ast_channel *c, char *param); + /* *** ECMA QSIG Functions */ diff --git a/chan_capi_qsig_core.c b/chan_capi_qsig_core.c index b804e57..a533a17 100644 --- a/chan_capi_qsig_core.c +++ b/chan_capi_qsig_core.c @@ -809,3 +809,113 @@ unsigned int cc_qsig_do_facility(unsigned char *fac, struct ast_channel *c, cha return 0; } + +/* + * Initiate a QSIG Call Transfer + */ +int pbx_capi_qsig_getplci(struct ast_channel *c, char *param) +{ + struct capi_pvt *i = CC_CHANNEL_PVT(c); + char buffer[10]; + + snprintf(buffer, sizeof(buffer)-1, "%d", i->PLCI); + cc_verbose(4, 1, VERBOSE_PREFIX_4 "QSIG_GETPLCI: %s\n", buffer); + pbx_builtin_setvar_helper(c, "QSIG_PLCI", buffer); + + return 0; +} + +/* + * Initiate a QSIG Single Step Call Transfer + */ +int pbx_capi_qsig_ssct(struct ast_channel *c, char *param) +{ + unsigned char fac[CAPI_MAX_FACILITYDATAARRAY_SIZE]; + _cmsg CMSG; + struct capi_pvt *i = CC_CHANNEL_PVT(c); + + if (!param) { /* no data implies no Calling Number and Destination Number */ + cc_log(LOG_WARNING, "capi qsig_ssct requires source number and destination number\n"); + return -1; + } + + cc_qsig_do_facility(fac, c, param, 99, 0); + + INFO_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(),0); + INFO_REQ_PLCI(&CMSG) = i->PLCI; + INFO_REQ_FACILITYDATAARRAY(&CMSG) = fac; + + _capi_put_cmsg(&CMSG); + + return 0; +} + +/* + * Initiate a QSIG Call Transfer + */ +int pbx_capi_qsig_ct(struct ast_channel *c, char *param) +{ + unsigned char fac[CAPI_MAX_FACILITYDATAARRAY_SIZE]; + _cmsg CMSG; + struct capi_pvt *i = CC_CHANNEL_PVT(c); + struct capi_pvt *ii = NULL; + unsigned int callmark; + char *marker; + + if (!param) { /* no data implies no Calling Number and Destination Number */ + cc_log(LOG_WARNING, "capi qsig_ct requires call marker, source number, destination number and await_connect info\n"); + return -1; + } + + marker = strsep(¶m, "|"); + + callmark = atoi(marker); + cc_verbose(1, 1, VERBOSE_PREFIX_4 " * QSIG_CT: using call marker %i(%s)\n", callmark, marker); + + for (ii = iflist; ii; ii = ii->next) { + if (ii->qsig_data.callmark == callmark) + break; + } + + if (!ii) { + cc_log(LOG_WARNING, "capi qsig_ct call marker not found!\n"); + return -1; + } + + cc_qsig_do_facility(fac, c, param, 12, 0); + + INFO_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(),0); + INFO_REQ_PLCI(&CMSG) = ii->PLCI; + INFO_REQ_FACILITYDATAARRAY(&CMSG) = fac; + + _capi_put_cmsg(&CMSG); + + cc_qsig_do_facility(fac, c, param, 12, 1); + + INFO_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(),0); + INFO_REQ_PLCI(&CMSG) = i->PLCI; + INFO_REQ_FACILITYDATAARRAY(&CMSG) = fac; + + _capi_put_cmsg(&CMSG); + + return 0; +} + +/* + * Initiate a QSIG Call Transfer + */ +int pbx_capi_qsig_callmark(struct ast_channel *c, char *param) +{ + struct capi_pvt *i = CC_CHANNEL_PVT(c); + + if (!param) { /* no data implies no Calling Number and Destination Number */ + cc_log(LOG_WARNING, "capi qsig_callmark requires an call identifier\n"); + return -1; + } + + i->qsig_data.callmark = atoi(param); + + return 0; +} + + diff --git a/chan_capi_supplementary.c b/chan_capi_supplementary.c index ab0c507..bb70798 100644 --- a/chan_capi_supplementary.c +++ b/chan_capi_supplementary.c @@ -198,3 +198,34 @@ void handle_facility_indication_supplementary( } } +/* + * capicommand 'ccbs' + */ +int pbx_capi_ccbs(struct ast_channel *c, char *data) +{ + char *slinkageid, *context, *exten, *priority; + unsigned int linkid = 0; + char *result = "ERROR"; + + slinkageid = strsep(&data, "|"); + context = strsep(&data, "|"); + exten = strsep(&data, "|"); + priority = data; + + if (slinkageid) { + linkid = (unsigned int)strtoul(slinkageid, NULL, 0); + } + + if ((!context) || (!exten) || (!priority)) { + cc_log(LOG_WARNING, "capi ccbs requires ||\n"); + return -1; + } + + cc_verbose(3, 1, VERBOSE_PREFIX_3 "capi ccbs: '%d' '%s' '%s' '%s'\n", + linkid, context, exten, priority); + + pbx_builtin_setvar_helper(c, "CCBSSTATUS", result); + + return 0; +} + diff --git a/chan_capi_supplementary.h b/chan_capi_supplementary.h index 7e98273..ff407f3 100644 --- a/chan_capi_supplementary.h +++ b/chan_capi_supplementary.h @@ -14,12 +14,6 @@ #ifndef _PBX_CAPI_SUPP_H #define _PBX_CAPI_SUPP_H -/* - * prototypes - */ -extern void ListenOnSupplementary(unsigned controller); -extern void handle_facility_indication_supplementary(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i); - typedef enum { CCBSNR_TYPE_NULL = 0, CCBSNR_TYPE_CCBS, @@ -38,4 +32,11 @@ struct ccbsnr_s { int priority; }; +/* + * prototypes + */ +extern void ListenOnSupplementary(unsigned controller); +extern void handle_facility_indication_supplementary(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i); +extern int pbx_capi_ccbs(struct ast_channel *c, char *data); + #endif diff --git a/chan_capi_utils.c b/chan_capi_utils.c index c813843..6145c6e 100644 --- a/chan_capi_utils.c +++ b/chan_capi_utils.c @@ -649,7 +649,7 @@ struct ast_channel *cc_get_peer_link_id(const char *p) struct ast_channel *chan = NULL; if (p) { - id = (int)strtoul(p, NULL, 0); + id = (int)strtol(p, NULL, 0); } if ((id >= 0) && (id < CAPI_MAX_PEERLINKCHANNELS)) {