QSIG:
- outbound call transfer - outbound path replacement after propose from switch - correct handling of outbound QSIG variants
This commit is contained in:
parent
e120f854f0
commit
a25c5ee55c
34
README.qsig
34
README.qsig
|
@ -57,13 +57,25 @@ The QSIG support includes:
|
|||
With capicommand(qsig_ct|src-id|dst-id) you can transfer an inbound call back to the qsig switch.
|
||||
The B-Channel of this call will be relased, so that the line is free for a next call.
|
||||
Unfortunately the call will be completely released by the switch, if the target is busy.
|
||||
I have to read the ECMA-300 standard, if there's a chance, to refuse the transfer in such a case.
|
||||
If you want need to know, if your target is busy, you can use the call transfer feature below.
|
||||
- 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
|
||||
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
|
||||
can use "Ctr<PLCI>". Then the target user will get the infos about the originating user, while his phone is ringing.
|
||||
|
||||
If the external switch offers an path replacement propose, it will be taken automatically in account.
|
||||
The B-Channels will be cleared by the switch after call connection. Your channels stay free.
|
||||
|
||||
|
||||
Future Targets:
|
||||
===============
|
||||
- check code for buffer overflows
|
||||
- Call Transfer
|
||||
- Path Replacement
|
||||
- Call Transfer inbound
|
||||
- Path Replacement inbound
|
||||
- Call Rerouting feature [ECMA-174]
|
||||
- CCBS
|
||||
- AOC
|
||||
- ...
|
||||
|
@ -73,18 +85,6 @@ How to use:
|
|||
|
||||
simply enable Q.SIG with following line in your capi.conf interface:
|
||||
|
||||
================================================================================
|
||||
********** deprecated **********************************************************
|
||||
#### qsig=on
|
||||
|
||||
#### Take care that you enable this only for interfaces, where the other end
|
||||
#### understands the Q.SIG protocoll. If not, then these switches may reject the
|
||||
#### entire call, because of wrong facility contents.
|
||||
|
||||
#### Later this will change to qsig=off or qsig=1..x where we can support some
|
||||
#### pbx manufacturer specific operations.
|
||||
================================================================================
|
||||
|
||||
Here we go with new configuration
|
||||
|
||||
Set qsig to one of the following values, which corresponds to your configuration.
|
||||
|
@ -97,6 +97,4 @@ Set qsig to one of the following values, which corresponds to your configuration
|
|||
ToDo List:
|
||||
==========
|
||||
|
||||
- Invoke Identifier handling - currently i use invoke id #1, will be corrected by capi (outgoing)
|
||||
- Handle later facilities - i don't know what to do with most informations now, maybe they are useless in asterisk
|
||||
- Outgoing calls support only qsig type 1 (Alcatel) - add support for others on outgoing
|
||||
- Support for inbound routing
|
|
@ -263,6 +263,7 @@ struct cc_qsig_data {
|
|||
unsigned int callmark;
|
||||
|
||||
/* Path Replacement */
|
||||
int pr_propose_sendback; /* send back an prior received PR PROPOSE on Connect */
|
||||
char *pr_propose_cid; /* Call identity */
|
||||
char *pr_propose_pn; /* Party Number */
|
||||
|
||||
|
|
|
@ -1002,10 +1002,10 @@ void interface_cleanup_qsig(struct capi_pvt *i)
|
|||
i->qsig_data.partner_ch = NULL;
|
||||
i->qsig_data.calltransfer_active = 0;
|
||||
i->qsig_data.calltransfer_onring = 0;
|
||||
if (i->qsig_data.pr_propose_cid)
|
||||
free(i->qsig_data.pr_propose_cid);
|
||||
if (i->qsig_data.pr_propose_pn)
|
||||
free(i->qsig_data.pr_propose_pn);
|
||||
if (i->qsig_data.pr_propose_cid)
|
||||
free(i->qsig_data.pr_propose_cid);
|
||||
if (i->qsig_data.pr_propose_pn)
|
||||
free(i->qsig_data.pr_propose_pn);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1029,27 +1029,37 @@ 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) {
|
||||
|
||||
/* got an Path Replacement */
|
||||
if ((i->qsig_data.pr_propose_cid && i->qsig_data.pr_propose_pn) &! i->qsig_data.pr_propose_sendback) {
|
||||
struct capi_pvt *ii = capi_find_interface_by_plci(i->qsig_data.partner_plci);
|
||||
|
||||
if (ii) {
|
||||
unsigned char fac[CAPI_MAX_FACILITYDATAARRAY_SIZE];
|
||||
|
||||
cc_qsig_do_facility(fac, i->owner, NULL, 4, 0);
|
||||
if (ii) {
|
||||
if (ii->state == CAPI_STATE_CONNECTED) { /* second line is connected, we can proceed */
|
||||
unsigned char fac[CAPI_MAX_FACILITYDATAARRAY_SIZE];
|
||||
|
||||
cc_qsig_do_facility(fac, i->owner, NULL, 4, 0);
|
||||
|
||||
capi_sendf(NULL, 0, CAPI_INFO_REQ, ii->PLCI, get_capi_MessageNumber(),
|
||||
"()(()()()s)",
|
||||
fac
|
||||
);
|
||||
} else {
|
||||
capi_sendf(NULL, 0, CAPI_INFO_REQ, ii->PLCI, get_capi_MessageNumber(),
|
||||
"()(()()()s)",
|
||||
fac
|
||||
);
|
||||
} else { /* Path Replacement has to be sent back after Connect on second line */
|
||||
ii->qsig_data.pr_propose_sendback = 1;
|
||||
ii->qsig_data.pr_propose_cid = strdup(i->qsig_data.pr_propose_cid);
|
||||
ii->qsig_data.pr_propose_pn = strdup(i->qsig_data.pr_propose_pn);
|
||||
}
|
||||
} 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);
|
||||
i->qsig_data.pr_propose_cid = NULL;
|
||||
free(i->qsig_data.pr_propose_pn);
|
||||
i->qsig_data.pr_propose_pn = NULL;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
break;
|
||||
|
@ -1110,27 +1120,53 @@ 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 = capi_find_interface_by_plci(i->qsig_data.partner_plci);
|
||||
|
||||
if (ii) {
|
||||
unsigned char fac[CAPI_MAX_FACILITYDATAARRAY_SIZE];
|
||||
|
||||
cc_qsig_do_facility(fac, i->owner, NULL, 4, 0);
|
||||
|
||||
capi_sendf(NULL, 0, CAPI_INFO_REQ, ii->PLCI, get_capi_MessageNumber(),
|
||||
if (i->qsig_data.calltransfer) {
|
||||
unsigned char fac[CAPI_MAX_FACILITYDATAARRAY_SIZE];
|
||||
struct capi_pvt *ii = capi_find_interface_by_plci(i->qsig_data.partner_plci);
|
||||
|
||||
/* needed for Path Replacement */
|
||||
ii->qsig_data.partner_plci = i->PLCI;
|
||||
|
||||
i->qsig_data.calltransfer = 0;
|
||||
|
||||
if (ii) {
|
||||
cc_qsig_do_facility(fac, ii->owner, NULL, 12, 0);
|
||||
|
||||
capi_sendf(NULL, 0, CAPI_INFO_REQ, ii->PLCI, get_capi_MessageNumber(),
|
||||
"()(()()()s)",
|
||||
fac
|
||||
);
|
||||
|
||||
cc_qsig_do_facility(fac, i->owner, NULL, 12, 1);
|
||||
|
||||
capi_sendf(NULL, 0, CAPI_INFO_REQ, i->PLCI, get_capi_MessageNumber(),
|
||||
"()(()()()s)",
|
||||
fac
|
||||
);
|
||||
} 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);
|
||||
);
|
||||
} else {
|
||||
cc_log(LOG_WARNING, "Call Transfer failed - second channel not found (PLCI %#x)!\n", i->qsig_data.partner_plci);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
{
|
||||
/* handle prior received Path Replacement */
|
||||
if ((i->qsig_data.pr_propose_cid && i->qsig_data.pr_propose_pn) && i->qsig_data.pr_propose_sendback) {
|
||||
unsigned char fac[CAPI_MAX_FACILITYDATAARRAY_SIZE];
|
||||
|
||||
cc_qsig_do_facility(fac, i->owner, NULL, 4, 0);
|
||||
|
||||
capi_sendf(NULL, 0, CAPI_INFO_REQ, i->PLCI, get_capi_MessageNumber(),
|
||||
"()(()()()s)",
|
||||
fac
|
||||
);
|
||||
|
||||
i->qsig_data.pr_propose_sendback = 0;
|
||||
free(i->qsig_data.pr_propose_cid);
|
||||
i->qsig_data.pr_propose_cid = NULL;
|
||||
free(i->qsig_data.pr_propose_pn);
|
||||
i->qsig_data.pr_propose_pn = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case 0x800d: /* SETUP ACK */
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue