Added command to deactivate CCBS.
parent
1b95f0ca10
commit
246e5b21cb
4
README
4
README
|
@ -233,6 +233,10 @@ Call completion on subscriber busy (CCBS):
|
|||
sent to the provided context/exten/priority. Of course, this only happens if your local
|
||||
phone is set to 'free' with capicommand(ccpartybusy), which is the default.
|
||||
|
||||
Deactivate CCBS:
|
||||
To deactivate a previously activated CCBS, use following command:
|
||||
Example:
|
||||
exten => s,1,capicommand(ccbsstop|${CCLINKAGEID})
|
||||
|
||||
Using CLIR
|
||||
==========
|
||||
|
|
|
@ -4390,6 +4390,7 @@ static struct capicommands_s {
|
|||
{ "ect", pbx_capi_ect, 1 },
|
||||
{ "3pty_begin", pbx_capi_3pty_begin, 1 },
|
||||
{ "ccbs", pbx_capi_ccbs, 0 },
|
||||
{ "ccbsstop", pbx_capi_ccbsstop, 0 },
|
||||
{ "ccpartybusy", pbx_capi_ccpartybusy, 0 },
|
||||
{ "qsig_ssct", pbx_capi_qsig_ssct, 1 },
|
||||
{ "qsig_ct", pbx_capi_qsig_ct, 1 },
|
||||
|
|
|
@ -210,6 +210,14 @@ static void del_ccbsnr_id(unsigned int plci, _cword id)
|
|||
cc_mutex_unlock(&ccbsnr_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* on an activated CCBS, the remote party is now free
|
||||
*/
|
||||
static void ccbsnr_remote_user_free(_cmsg *CMSG, char type, unsigned int PLCI, _cword rbref)
|
||||
{
|
||||
/* XXX start alerting , when answered use CCBS call */
|
||||
}
|
||||
|
||||
/*
|
||||
* send Listen for supplementary to specified controller
|
||||
*/
|
||||
|
@ -273,6 +281,7 @@ int handle_facility_indication_supplementary(
|
|||
cc_verbose(1, 1, VERBOSE_PREFIX_3 "contr%d: PLCI=%#x CCBS request reason=0x%04x "
|
||||
"handle=%d mode=0x%x rbref=0x%x\n",
|
||||
PLCI & 0xff, PLCI, infoword, handle, mode, rbref);
|
||||
show_capi_info(NULL, infoword);
|
||||
if ((ccbsnrlink = get_ccbsnr_link(0, 0, handle, 0xffff, NULL, NULL)) == NULL) {
|
||||
cc_log(LOG_WARNING, "capi ccbs request indication without request!\n");
|
||||
break;
|
||||
|
@ -286,8 +295,20 @@ int handle_facility_indication_supplementary(
|
|||
/* error */
|
||||
ccbsnrlink->state = CCBSNR_AVAILABLE;
|
||||
}
|
||||
show_capi_info(NULL, infoword);
|
||||
break;
|
||||
case 0x0010: /* CCBS deactivate */
|
||||
handle = read_capi_dword(&FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[6]);
|
||||
cc_verbose(1, 1, VERBOSE_PREFIX_3 "contr%d: PLCI=%#x CCBS deactivate handle=0x%x reason=0x%x\n",
|
||||
PLCI & 0xff, PLCI, handle, infoword);
|
||||
show_capi_info(NULL, infoword);
|
||||
if ((ccbsnrlink = get_ccbsnr_link(0, 0, handle, 0xffff, NULL, NULL)) == NULL) {
|
||||
cc_log(LOG_WARNING, "capi ccbs deactivate indication without request!\n");
|
||||
break;
|
||||
}
|
||||
if (infoword == 0) {
|
||||
/* success */
|
||||
ccbsnrlink->state = CCBSNR_AVAILABLE;
|
||||
}
|
||||
case 0x800d: /* CCBS erase call linkage ID */
|
||||
cc_verbose(1, 1, VERBOSE_PREFIX_3 "contr%d: PLCI=%#x CCBS/CCNR erase id=0x%04x\n",
|
||||
PLCI & 0xff, PLCI, infoword);
|
||||
|
@ -312,7 +333,7 @@ int handle_facility_indication_supplementary(
|
|||
rbref = read_capi_word(&FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[6]);
|
||||
cc_verbose(1, 1, VERBOSE_PREFIX_3 "contr%d: PLCI=%#x CCBS status ref=0x%04x mode=0x%x\n",
|
||||
PLCI & 0xff, PLCI, rbref, infoword);
|
||||
/* XXX start alerting */
|
||||
ccbsnr_remote_user_free(CMSG, CCBSNR_TYPE_CCBS, PLCI, rbref);
|
||||
break;
|
||||
case 0x8010: /* CCBS B-free */
|
||||
rbref = read_capi_word(&FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[6]);
|
||||
|
@ -483,6 +504,59 @@ int pbx_capi_ccpartybusy(struct ast_channel *c, char *data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* capicommand 'ccbsstop'
|
||||
*/
|
||||
int pbx_capi_ccbsstop(struct ast_channel *c, char *data)
|
||||
{
|
||||
char *slinkageid;
|
||||
unsigned int linkid = 0;
|
||||
unsigned int handle = 0;
|
||||
MESSAGE_EXCHANGE_ERROR error;
|
||||
_cword ref = 0xdead;
|
||||
struct ccbsnr_s *ccbsnr;
|
||||
|
||||
slinkageid = data;
|
||||
|
||||
if (slinkageid) {
|
||||
linkid = (unsigned int)strtoul(slinkageid, NULL, 0);
|
||||
}
|
||||
|
||||
cc_verbose(3, 1, VERBOSE_PREFIX_3 "capi ccbsstop: '%d'\n",
|
||||
linkid);
|
||||
|
||||
cc_mutex_lock(&ccbsnr_lock);
|
||||
ccbsnr = ccbsnr_list;
|
||||
while (ccbsnr) {
|
||||
if (((ccbsnr->plci & 0xff) == ((linkid >> 16) & 0xff)) &&
|
||||
(ccbsnr->id == (linkid & 0xffff)) &&
|
||||
(ccbsnr->type == CCBSNR_TYPE_CCBS) &&
|
||||
(ccbsnr->state == CCBSNR_ACTIVATED)) {
|
||||
ref = ccbsnr->rbref;
|
||||
handle = ccbsnr->handle;
|
||||
break;
|
||||
}
|
||||
ccbsnr = ccbsnr->next;
|
||||
}
|
||||
cc_mutex_unlock(&ccbsnr_lock);
|
||||
|
||||
if (ref != 0xdead) {
|
||||
error = capi_sendf(NULL, 0, CAPI_FACILITY_REQ, (linkid >> 16) & 0xff,
|
||||
get_capi_MessageNumber(),
|
||||
"w(w(dw))",
|
||||
FACILITYSELECTOR_SUPPLEMENTARY,
|
||||
0x0010, /* CCBS deactivate */
|
||||
handle, /* handle */
|
||||
ref /* CCBS reference */
|
||||
);
|
||||
} else {
|
||||
cc_verbose(3, 1, VERBOSE_PREFIX_3, "capi ccbsstop: linkid %d not found in table.\n",
|
||||
linkid);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* capicommand 'ccbs'
|
||||
*/
|
||||
|
|
|
@ -45,6 +45,7 @@ extern int handle_facility_indication_supplementary(
|
|||
extern void handle_facility_confirmation_supplementary(
|
||||
_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i);
|
||||
extern int pbx_capi_ccbs(struct ast_channel *c, char *data);
|
||||
extern int pbx_capi_ccbsstop(struct ast_channel *c, char *data);
|
||||
extern int pbx_capi_ccpartybusy(struct ast_channel *c, char *data);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue