libpri: Add control of inband audio progress indication ie to the SETUP_ACKNOWLEDGE message.
Added support to the libpri API to control the inband audio available progress indication ie on the SETUP_ACKNOWLEDGE message. * Added the progress indication ie progressmask value to the struct pri_event_setup_ack so the PRI_EVENT_SETUP_ACK event can indicate when a SETUP_ACKNOWLEDGE comes in with inband audio (ie dialtone). * Added pri_setup_ack() so when the SETUP_ACKNOWLEDGE message is sent it can indicate if inband audio is present (ie dialtone). This patch and a corresponding change in Asterisk work together to allow Asterisk to control the inband audio available progress indication ie on the SETUP_ACKNOWLEDGE message when dialtone is present. AST-1338 #close Reported by: Tyler Stewart Review: https://reviewboard.asterisk.org/r/3520/ git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@2320 2fbb986a-6c06-0410-b554-c9c1f0a7f128
This commit is contained in:
parent
13beaacc80
commit
cfac266390
66
libpri.h
66
libpri.h
@ -1213,6 +1213,7 @@ typedef struct pri_event_setup_ack {
|
|||||||
int channel;
|
int channel;
|
||||||
q931_call *call;
|
q931_call *call;
|
||||||
struct pri_subcommands *subcmds;
|
struct pri_subcommands *subcmds;
|
||||||
|
int progressmask;
|
||||||
} pri_event_setup_ack;
|
} pri_event_setup_ack;
|
||||||
|
|
||||||
typedef struct pri_event_notify {
|
typedef struct pri_event_notify {
|
||||||
@ -1408,8 +1409,17 @@ const char *pri_facility_error2str(int facility_error_code);
|
|||||||
*/
|
*/
|
||||||
const char *pri_facility_reject2str(int facility_reject_code);
|
const char *pri_facility_reject2str(int facility_reject_code);
|
||||||
|
|
||||||
/* Acknowledge a call and place it on the given channel. Set info to non-zero if there
|
/*!
|
||||||
is in-band data available on the channel */
|
* \brief Send the ALERTING message.
|
||||||
|
*
|
||||||
|
* \param pri D channel controller.
|
||||||
|
* \param call Q.931 call leg.
|
||||||
|
* \param channel Encoded channel id to use. If zero do not change channel id.
|
||||||
|
* \param info Nonzero to include a progress ie indicating inband audio available (ie ringback).
|
||||||
|
*
|
||||||
|
* \retval 0 on success.
|
||||||
|
* \retval -1 on error.
|
||||||
|
*/
|
||||||
int pri_acknowledge(struct pri *pri, q931_call *call, int channel, int info);
|
int pri_acknowledge(struct pri *pri, q931_call *call, int channel, int info);
|
||||||
|
|
||||||
/* Send a digit in overlap mode */
|
/* Send a digit in overlap mode */
|
||||||
@ -1419,12 +1429,44 @@ int pri_information(struct pri *pri, q931_call *call, char digit);
|
|||||||
/* Send a keypad facility string of digits */
|
/* Send a keypad facility string of digits */
|
||||||
int pri_keypad_facility(struct pri *pri, q931_call *call, const char *digits);
|
int pri_keypad_facility(struct pri *pri, q931_call *call, const char *digits);
|
||||||
|
|
||||||
/* Answer the incomplete(call without called number) call on the given channel.
|
/*!
|
||||||
Set non-isdn to non-zero if you are not connecting to ISDN equipment */
|
* \brief Send the SETUP_ACKNOWLEDGE message.
|
||||||
|
*
|
||||||
|
* \param pri D channel controller.
|
||||||
|
* \param call Q.931 call leg.
|
||||||
|
* \param channel Encoded channel id to use. If zero do not change channel id.
|
||||||
|
* \param nonisdn Nonzero to include a progress ie indicating non-end-to-end-ISDN.
|
||||||
|
*
|
||||||
|
* \retval 0 on success.
|
||||||
|
* \retval -1 on error.
|
||||||
|
*/
|
||||||
int pri_need_more_info(struct pri *pri, q931_call *call, int channel, int nonisdn);
|
int pri_need_more_info(struct pri *pri, q931_call *call, int channel, int nonisdn);
|
||||||
|
|
||||||
/* Answer(CONNECT) the call on the given channel.
|
/*!
|
||||||
Set non-isdn to non-zero if you are not connecting to ISDN equipment */
|
* \brief Send the SETUP_ACKNOWLEDGE message.
|
||||||
|
*
|
||||||
|
* \param ctrl D channel controller.
|
||||||
|
* \param call Q.931 call leg.
|
||||||
|
* \param channel Encoded channel id to use. If zero do not change channel id.
|
||||||
|
* \param nonisdn Nonzero to include a progress ie indicating non-end-to-end-ISDN.
|
||||||
|
* \param inband Nonzero to include a progress ie indicating inband audio available (ie dialtone).
|
||||||
|
*
|
||||||
|
* \retval 0 on success.
|
||||||
|
* \retval -1 on error.
|
||||||
|
*/
|
||||||
|
int pri_setup_ack(struct pri *ctrl, q931_call *call, int channel, int nonisdn, int inband);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Send the CONNECT message.
|
||||||
|
*
|
||||||
|
* \param pri D channel controller.
|
||||||
|
* \param call Q.931 call leg.
|
||||||
|
* \param channel Encoded channel id to use. If zero do not change channel id.
|
||||||
|
* \param nonisdn Nonzero to include a progress ie indicating non-end-to-end-ISDN.
|
||||||
|
*
|
||||||
|
* \retval 0 on success.
|
||||||
|
* \retval -1 on error.
|
||||||
|
*/
|
||||||
int pri_answer(struct pri *pri, q931_call *call, int channel, int nonisdn);
|
int pri_answer(struct pri *pri, q931_call *call, int channel, int nonisdn);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -1692,7 +1734,17 @@ int pri_progress(struct pri *pri, q931_call *c, int channel, int info);
|
|||||||
int pri_progress_with_cause(struct pri *pri, q931_call *c, int channel, int info, int cause);
|
int pri_progress_with_cause(struct pri *pri, q931_call *c, int channel, int info, int cause);
|
||||||
|
|
||||||
#define PRI_PROCEEDING_FULL
|
#define PRI_PROCEEDING_FULL
|
||||||
/* Send call proceeding */
|
/*!
|
||||||
|
* \brief Send the PROCEEDING message.
|
||||||
|
*
|
||||||
|
* \param pri D channel controller.
|
||||||
|
* \param c Q.931 call leg.
|
||||||
|
* \param channel Encoded channel id to use. If zero do not change channel id.
|
||||||
|
* \param info Nonzero to include a progress ie indicating inband audio available.
|
||||||
|
*
|
||||||
|
* \retval 0 on success.
|
||||||
|
* \retval -1 on error.
|
||||||
|
*/
|
||||||
int pri_proceeding(struct pri *pri, q931_call *c, int channel, int info);
|
int pri_proceeding(struct pri *pri, q931_call *c, int channel, int info);
|
||||||
|
|
||||||
/* Enable inband progress when a DISCONNECT is received */
|
/* Enable inband progress when a DISCONNECT is received */
|
||||||
|
10
pri.c
10
pri.c
@ -939,7 +939,15 @@ int pri_need_more_info(struct pri *pri, q931_call *call, int channel, int nonisd
|
|||||||
if (!pri || !pri_is_call_valid(pri, call)) {
|
if (!pri || !pri_is_call_valid(pri, call)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return q931_setup_ack(pri, call, channel, nonisdn);
|
return q931_setup_ack(pri, call, channel, nonisdn, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int pri_setup_ack(struct pri *ctrl, q931_call *call, int channel, int nonisdn, int inband)
|
||||||
|
{
|
||||||
|
if (!ctrl || !pri_is_call_valid(ctrl, call)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return q931_setup_ack(ctrl, call, channel, nonisdn, inband);
|
||||||
}
|
}
|
||||||
|
|
||||||
int pri_answer(struct pri *pri, q931_call *call, int channel, int nonisdn)
|
int pri_answer(struct pri *pri, q931_call *call, int channel, int nonisdn)
|
||||||
|
@ -468,7 +468,7 @@ extern int q931_notify(struct pri *pri, q931_call *call, int channel, int info);
|
|||||||
|
|
||||||
extern int q931_call_proceeding(struct pri *pri, q931_call *call, int channel, int info);
|
extern int q931_call_proceeding(struct pri *pri, q931_call *call, int channel, int info);
|
||||||
|
|
||||||
extern int q931_setup_ack(struct pri *pri, q931_call *call, int channel, int nonisdn);
|
extern int q931_setup_ack(struct pri *ctrl, q931_call *c, int channel, int nonisdn, int inband);
|
||||||
|
|
||||||
extern int q931_information(struct pri *pri, q931_call *call, char digit);
|
extern int q931_information(struct pri *pri, q931_call *call, char digit);
|
||||||
|
|
||||||
|
38
q931.c
38
q931.c
@ -2807,7 +2807,8 @@ static int receive_progress_indicator(int full_ie, struct pri *ctrl, q931_call *
|
|||||||
{
|
{
|
||||||
call->progloc = ie->data[0] & 0xf;
|
call->progloc = ie->data[0] & 0xf;
|
||||||
call->progcode = (ie->data[0] & 0x60) >> 5;
|
call->progcode = (ie->data[0] & 0x60) >> 5;
|
||||||
switch (call->progress = (ie->data[1] & 0x7f)) {
|
call->progress = (ie->data[1] & 0x7f);
|
||||||
|
switch (call->progress) {
|
||||||
case Q931_PROG_CALL_NOT_E2E_ISDN:
|
case Q931_PROG_CALL_NOT_E2E_ISDN:
|
||||||
call->progressmask |= PRI_PROG_CALL_NOT_E2E_ISDN;
|
call->progressmask |= PRI_PROG_CALL_NOT_E2E_ISDN;
|
||||||
break;
|
break;
|
||||||
@ -3084,7 +3085,9 @@ static void q931_apdu_msg_expire(struct pri *ctrl, struct q931_call *call, int m
|
|||||||
|
|
||||||
static int transmit_progress_indicator(int full_ie, struct pri *ctrl, q931_call *call, int msgtype, q931_ie *ie, int len, int order)
|
static int transmit_progress_indicator(int full_ie, struct pri *ctrl, q931_call *call, int msgtype, q931_ie *ie, int len, int order)
|
||||||
{
|
{
|
||||||
int code, mask;
|
int code;
|
||||||
|
int mask;
|
||||||
|
|
||||||
/* Can't send progress indicator on GR-303 -- EVER! */
|
/* Can't send progress indicator on GR-303 -- EVER! */
|
||||||
if (ctrl->link.next && !ctrl->bri)
|
if (ctrl->link.next && !ctrl->bri)
|
||||||
return 0;
|
return 0;
|
||||||
@ -5755,9 +5758,14 @@ int q931_alerting(struct pri *ctrl, q931_call *c, int channel, int info)
|
|||||||
return send_message(ctrl, c, Q931_ALERTING, alerting_ies);
|
return send_message(ctrl, c, Q931_ALERTING, alerting_ies);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int setup_ack_ies[] = { Q931_CHANNEL_IDENT, Q931_IE_FACILITY, Q931_PROGRESS_INDICATOR, -1 };
|
static int setup_ack_ies[] = {
|
||||||
|
Q931_CHANNEL_IDENT,
|
||||||
|
Q931_IE_FACILITY,
|
||||||
|
Q931_PROGRESS_INDICATOR,
|
||||||
|
-1
|
||||||
|
};
|
||||||
|
|
||||||
int q931_setup_ack(struct pri *ctrl, q931_call *c, int channel, int nonisdn)
|
int q931_setup_ack(struct pri *ctrl, q931_call *c, int channel, int nonisdn, int inband)
|
||||||
{
|
{
|
||||||
if (c->ourcallstate == Q931_CALL_STATE_CALL_INDEPENDENT_SERVICE) {
|
if (c->ourcallstate == Q931_CALL_STATE_CALL_INDEPENDENT_SERVICE) {
|
||||||
/* Cannot send this message when in this state */
|
/* Cannot send this message when in this state */
|
||||||
@ -5770,12 +5778,20 @@ int q931_setup_ack(struct pri *ctrl, q931_call *c, int channel, int nonisdn)
|
|||||||
}
|
}
|
||||||
c->chanflags &= ~FLAG_PREFERRED;
|
c->chanflags &= ~FLAG_PREFERRED;
|
||||||
c->chanflags |= FLAG_EXCLUSIVE;
|
c->chanflags |= FLAG_EXCLUSIVE;
|
||||||
|
|
||||||
|
c->progressmask = 0;
|
||||||
if (nonisdn && (ctrl->switchtype != PRI_SWITCH_DMS100)) {
|
if (nonisdn && (ctrl->switchtype != PRI_SWITCH_DMS100)) {
|
||||||
c->progloc = LOC_PRIV_NET_LOCAL_USER;
|
c->progloc = LOC_PRIV_NET_LOCAL_USER;
|
||||||
c->progcode = CODE_CCITT;
|
c->progcode = CODE_CCITT;
|
||||||
c->progressmask = PRI_PROG_CALLED_NOT_ISDN;
|
c->progressmask |= PRI_PROG_CALLED_NOT_ISDN;
|
||||||
} else
|
}
|
||||||
c->progressmask = 0;
|
if (inband) {
|
||||||
|
/* Inband audio is present (i.e. dialtone) */
|
||||||
|
c->progloc = LOC_PRIV_NET_LOCAL_USER;
|
||||||
|
c->progcode = CODE_CCITT;
|
||||||
|
c->progressmask |= PRI_PROG_INBAND_AVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
UPDATE_OURCALLSTATE(ctrl, c, Q931_CALL_STATE_OVERLAP_RECEIVING);
|
UPDATE_OURCALLSTATE(ctrl, c, Q931_CALL_STATE_OVERLAP_RECEIVING);
|
||||||
c->peercallstate = Q931_CALL_STATE_OVERLAP_SENDING;
|
c->peercallstate = Q931_CALL_STATE_OVERLAP_SENDING;
|
||||||
c->alive = 1;
|
c->alive = 1;
|
||||||
@ -5876,7 +5892,7 @@ int q931_connect(struct pri *ctrl, q931_call *c, int channel, int nonisdn)
|
|||||||
c->chanflags &= ~FLAG_PREFERRED;
|
c->chanflags &= ~FLAG_PREFERRED;
|
||||||
c->chanflags |= FLAG_EXCLUSIVE;
|
c->chanflags |= FLAG_EXCLUSIVE;
|
||||||
if (nonisdn && (ctrl->switchtype != PRI_SWITCH_DMS100)) {
|
if (nonisdn && (ctrl->switchtype != PRI_SWITCH_DMS100)) {
|
||||||
c->progloc = LOC_PRIV_NET_LOCAL_USER;
|
c->progloc = LOC_PRIV_NET_LOCAL_USER;
|
||||||
c->progcode = CODE_CCITT;
|
c->progcode = CODE_CCITT;
|
||||||
c->progressmask = PRI_PROG_CALLED_NOT_ISDN;
|
c->progressmask = PRI_PROG_CALLED_NOT_ISDN;
|
||||||
} else
|
} else
|
||||||
@ -7243,6 +7259,7 @@ static int prepare_to_handle_q931_message(struct pri *ctrl, q931_mh *mh, q931_ca
|
|||||||
c->useruserinfo[0] = '\0';
|
c->useruserinfo[0] = '\0';
|
||||||
c->cause = -1;
|
c->cause = -1;
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
|
case Q931_SETUP_ACKNOWLEDGE:
|
||||||
case Q931_CALL_PROCEEDING:
|
case Q931_CALL_PROCEEDING:
|
||||||
c->progress = -1;
|
c->progress = -1;
|
||||||
c->progressmask = 0;
|
c->progressmask = 0;
|
||||||
@ -7289,8 +7306,6 @@ static int prepare_to_handle_q931_message(struct pri *ctrl, q931_mh *mh, q931_ca
|
|||||||
break;
|
break;
|
||||||
case Q931_STATUS_ENQUIRY:
|
case Q931_STATUS_ENQUIRY:
|
||||||
break;
|
break;
|
||||||
case Q931_SETUP_ACKNOWLEDGE:
|
|
||||||
break;
|
|
||||||
case Q931_NOTIFY:
|
case Q931_NOTIFY:
|
||||||
c->notify = -1;
|
c->notify = -1;
|
||||||
q931_party_number_init(&c->redirection_number);
|
q931_party_number_init(&c->redirection_number);
|
||||||
@ -9199,6 +9214,7 @@ static int post_handle_q931_message(struct pri *ctrl, struct q931_mh *mh, struct
|
|||||||
ctrl->ev.setup_ack.subcmds = &ctrl->subcmds;
|
ctrl->ev.setup_ack.subcmds = &ctrl->subcmds;
|
||||||
ctrl->ev.setup_ack.channel = q931_encode_channel(c);
|
ctrl->ev.setup_ack.channel = q931_encode_channel(c);
|
||||||
ctrl->ev.setup_ack.call = c->master_call;
|
ctrl->ev.setup_ack.call = c->master_call;
|
||||||
|
ctrl->ev.setup_ack.progressmask = c->progressmask;
|
||||||
|
|
||||||
for (cur = c->apdus; cur; cur = cur->next) {
|
for (cur = c->apdus; cur; cur = cur->next) {
|
||||||
if (!cur->sent && cur->message == Q931_FACILITY) {
|
if (!cur->sent && cur->message == Q931_FACILITY) {
|
||||||
|
Loading…
Reference in New Issue
Block a user