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
MelwareDE 6 years ago
parent 955b02d460
commit ea23483041
  1. 2
      CHANGES
  2. 6
      README
  3. 86
      chan_capi.c
  4. 1
      chan_capi.h

@ -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

@ -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)
======================================

@ -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…
Cancel
Save