CAPI specs (5th edition diagrams in section A.5) say that early B3 should
trigger on progress indication ("Progress tones available") and this is how chan_capi actually worked before revision 101 (2005-09-04). Q.931 (05.98) sections 5.1.2 and 5.4 also specify similar handling on lower level (they also add "Call is not end-to-end ISDN; further call progress information may be available in-band" as possible triggering indication). This patch adds 't' option to dial string that allows switching chan_capi to such mode of operation. Without this option set chan_capi works as it did previously. While we are at it also let's clean up handling of 'DISCONNECT' message received via INFO_IND - 'case 2' had unnecessary dependency on 'doB3' variable (only one value is possible by this point in code with i->outgoing being set), 'case 4' had unreachable branch and unnecessary predicates (which were always true). These changes should not cause any differences in operation. Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>master
parent
955b02d460
commit
ea23483041
2
CHANGES
2
CHANGES
|
@ -6,6 +6,8 @@ HEAD
|
|||
- refuse to reload on active channels
|
||||
- ast_devstate_changed() changes with new cache argument
|
||||
- check for bchannel information element on incoming call
|
||||
- added 't' option to select in-band tones available indication as Q.931
|
||||
(thanks to Maciej S. Szmigiero <mail@maciej.szmigiero.name>)
|
||||
|
||||
|
||||
chan_capi-1.1.6
|
||||
|
|
6
README
6
README
|
@ -93,6 +93,9 @@ The Dial string
|
|||
The string consists of a list of characters with the following meaning:
|
||||
'b' : early B3 always.
|
||||
'B' : early B3 on successful calls only.
|
||||
't' : enable B3 only on in-band tones available indication as Q.931 (05/98)
|
||||
recommends (without this option it will be enabled on "PROGRESS" or
|
||||
"ALERTING" messages, any "Progress" indication or channel identification).
|
||||
'd' : use the default caller ID that is set by defaultcid= in capi.conf
|
||||
'o' : use overlap sending of number.
|
||||
(Useful if additional digits should be send afterwards or together
|
||||
|
@ -371,7 +374,8 @@ you:
|
|||
indications)
|
||||
|
||||
For normal PBX usage, you would use the "b" option, always Early B3.
|
||||
|
||||
You can also add "t" option so B3 will be enabled only on in-band tones available
|
||||
indication as Q.931 (05/98) recommends.
|
||||
|
||||
Overlap sending (a.k.a. real dialtone)
|
||||
======================================
|
||||
|
|
86
chan_capi.c
86
chan_capi.c
|
@ -1295,17 +1295,6 @@ void cc_start_b3(struct capi_pvt *i)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* start early B3
|
||||
*/
|
||||
static void start_early_b3(struct capi_pvt *i)
|
||||
{
|
||||
if (i->doB3 != CAPI_B3_DONT) {
|
||||
/* we do early B3 Connect */
|
||||
cc_start_b3(i);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* signal 'progress' to PBX
|
||||
*/
|
||||
|
@ -1313,7 +1302,11 @@ static void send_progress(struct capi_pvt *i)
|
|||
{
|
||||
struct ast_frame fr = { AST_FRAME_CONTROL, };
|
||||
|
||||
start_early_b3(i);
|
||||
if (i->doB3 != CAPI_B3_DONT &&
|
||||
!(i->fsetting & CAPI_FSETTING_EARLYB3_ONLY_WHEN_TONES_AVAIL)) {
|
||||
/* we do early B3 Connect */
|
||||
cc_start_b3(i);
|
||||
}
|
||||
|
||||
if (!(i->isdnstate & CAPI_ISDN_STATE_PROGRESS)) {
|
||||
i->isdnstate |= CAPI_ISDN_STATE_PROGRESS;
|
||||
|
@ -1608,6 +1601,13 @@ static int pbx_capi_call(struct ast_channel *c, void *idest, int timeout)
|
|||
cc_log(LOG_WARNING, "B3 already set in '%s'\n", idest);
|
||||
i->doB3 = CAPI_B3_ON_SUCCESS;
|
||||
break;
|
||||
case 't': /* enable B3 only on in-band tones available indication */
|
||||
if ((i->fsetting & CAPI_FSETTING_EARLYB3_ONLY_WHEN_TONES_AVAIL))
|
||||
cc_log(LOG_WARNING,
|
||||
"B3 on in-band tones avail only already set in '%s'\n",
|
||||
idest);
|
||||
i->fsetting |= CAPI_FSETTING_EARLYB3_ONLY_WHEN_TONES_AVAIL;
|
||||
break;
|
||||
case 'o': /* overlap sending of digits */
|
||||
if (i->doOverlap)
|
||||
cc_log(LOG_WARNING, "Overlap already set in '%s'\n", idest);
|
||||
|
@ -1649,6 +1649,18 @@ static int pbx_capi_call(struct ast_channel *c, void *idest, int timeout)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (((!dest) || (!dest[0])) &&
|
||||
i->fsetting & CAPI_FSETTING_EARLYB3_ONLY_WHEN_TONES_AVAIL)
|
||||
cc_log(LOG_WARNING,
|
||||
"dialtone request with B3 on in-band tones avail setting might not work on all exchanges in '%s'\n",
|
||||
idest);
|
||||
|
||||
if (i->doB3 == CAPI_B3_DONT &&
|
||||
i->fsetting & CAPI_FSETTING_EARLYB3_ONLY_WHEN_TONES_AVAIL)
|
||||
cc_log(LOG_WARNING,
|
||||
"B3 on in-band tones avail setting ignored when early B3 is disabled in '%s'\n",
|
||||
idest);
|
||||
|
||||
i->peer = cc_get_peer_link_id(pbx_builtin_getvar_helper(c, "CAPIPEERLINKID"));
|
||||
i->outgoing = 1;
|
||||
|
||||
|
@ -3901,16 +3913,26 @@ static int search_did(struct ast_channel *c)
|
|||
*/
|
||||
static void handle_progress_indicator(_cmsg *CMSG, unsigned int PLCI, struct capi_pvt *i)
|
||||
{
|
||||
int inband_info = 0;
|
||||
|
||||
if (INFO_IND_INFOELEMENT(CMSG)[0] < 2) {
|
||||
cc_verbose(3, 1, VERBOSE_PREFIX_4 "%s: Progress description missing\n",
|
||||
i->vname);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((INFO_IND_INFOELEMENT(CMSG)[2] & 0x60) != 0x00) {
|
||||
cc_verbose(3, 1,
|
||||
VERBOSE_PREFIX_4 "%s: Progress description has unsupported coding\n",
|
||||
i->vname);
|
||||
return;
|
||||
}
|
||||
|
||||
switch(INFO_IND_INFOELEMENT(CMSG)[2] & 0x7f) {
|
||||
case 0x01:
|
||||
cc_verbose(4, 1, VERBOSE_PREFIX_4 "%s: Not end-to-end ISDN\n",
|
||||
i->vname);
|
||||
inband_info = 1;
|
||||
break;
|
||||
case 0x02:
|
||||
cc_verbose(4, 1, VERBOSE_PREFIX_4 "%s: Destination is non ISDN\n",
|
||||
|
@ -3932,12 +3954,19 @@ static void handle_progress_indicator(_cmsg *CMSG, unsigned int PLCI, struct cap
|
|||
case 0x08:
|
||||
cc_verbose(4, 1, VERBOSE_PREFIX_4 "%s: In-band information available\n",
|
||||
i->vname);
|
||||
inband_info = 1;
|
||||
break;
|
||||
default:
|
||||
cc_verbose(3, 1, VERBOSE_PREFIX_4 "%s: Unknown progress description %02x\n",
|
||||
i->vname, INFO_IND_INFOELEMENT(CMSG)[2]);
|
||||
}
|
||||
|
||||
if (inband_info && i->doB3 != CAPI_B3_DONT &&
|
||||
i->fsetting & CAPI_FSETTING_EARLYB3_ONLY_WHEN_TONES_AVAIL)
|
||||
cc_start_b3(i);
|
||||
|
||||
send_progress(i);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4139,12 +4168,17 @@ static void capidev_handle_info_disconnect(_cmsg *CMSG, unsigned int PLCI, unsig
|
|||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* at this point the call is either incoming or we are always doing B3 */
|
||||
|
||||
/* case 2: we are doing B3, and receive the 0x8045 after a successful call */
|
||||
if ((i->doB3 != CAPI_B3_DONT) &&
|
||||
(i->state == CAPI_STATE_CONNECTED) && (i->outgoing == 1)) {
|
||||
if ((i->state == CAPI_STATE_CONNECTED) && (i->outgoing == 1)) {
|
||||
cc_verbose(4, 1, VERBOSE_PREFIX_3 "%s: Disconnect case 2\n",
|
||||
i->vname);
|
||||
/*
|
||||
* FIXME: is this right? if this is just a normal hangup of
|
||||
* a successful call shouldn't it be the same as case 1?
|
||||
*/
|
||||
capi_queue_cause_control(i, 1);
|
||||
return;
|
||||
}
|
||||
|
@ -4165,22 +4199,11 @@ static void capidev_handle_info_disconnect(_cmsg *CMSG, unsigned int PLCI, unsig
|
|||
capi_queue_cause_control(i, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* case 4 (a.k.a. the italian case): B3 always. call is unsuccessful */
|
||||
if ((i->doB3 == CAPI_B3_ALWAYS) && (i->outgoing == 1)) {
|
||||
cc_verbose(4, 1, VERBOSE_PREFIX_3 "%s: Disconnect case 4\n",
|
||||
i->vname);
|
||||
if ((i->state == CAPI_STATE_CONNECTED) &&
|
||||
(i->isdnstate & CAPI_ISDN_STATE_B3_UP)) {
|
||||
capi_queue_cause_control(i, 1);
|
||||
return;
|
||||
}
|
||||
/* wait for the 0x001e (PROGRESS), play audio and wait for a timeout from the network */
|
||||
return;
|
||||
}
|
||||
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: Other case DISCONNECT INFO_IND\n",
|
||||
|
||||
/* case 4 (a.k.a. the italian case): always doing B3 and call is unsuccessful */
|
||||
cc_verbose(4, 1, VERBOSE_PREFIX_3 "%s: Disconnect case 4\n",
|
||||
i->vname);
|
||||
return;
|
||||
/* play audio and wait for a timeout from the network */
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -4285,7 +4308,8 @@ static void capidev_handle_info_indication(_cmsg *CMSG, unsigned int PLCI, unsig
|
|||
case 0x0018: /* Channel Identification */
|
||||
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element CHANNEL IDENTIFICATION %02x\n",
|
||||
i->vname, INFO_IND_INFOELEMENT(CMSG)[1]);
|
||||
if (i->doB3 == CAPI_B3_ON_SUCCESS) {
|
||||
if (i->doB3 != CAPI_B3_DONT &&
|
||||
!(i->fsetting & CAPI_FSETTING_EARLYB3_ONLY_WHEN_TONES_AVAIL)) {
|
||||
/* try early B3 Connect */
|
||||
cc_start_b3(i);
|
||||
}
|
||||
|
|
|
@ -348,6 +348,7 @@ struct cc_capi_gains {
|
|||
/* Features and settings of current connection */
|
||||
#define CAPI_FSETTING_STAYONLINE 0x00000001
|
||||
#define CAPI_FSETTING_EARLY_BRIDGE 0x00000002
|
||||
#define CAPI_FSETTING_EARLYB3_ONLY_WHEN_TONES_AVAIL 0x00000004
|
||||
|
||||
/* Private qsig data for capi device */
|
||||
struct cc_qsig_data {
|
||||
|
|
Loading…
Reference in New Issue