Add display ie text handling options.
The display ie handling can be controlled independently in the send and receive directions with the following options: * Block display text data. * Use display text in SETUP/CONNECT messages for name. * Use display text for COLP name updates (FACILITY/NOTIFY as appropriate). * Pass arbitrary display text during a call. Sent in INFORMATION messages. Received from any message that the display text was not used as a name. If the display options are not set then the options default to legacy behavior. git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@2190 2fbb986a-6c06-0410-b554-c9c1f0a7f128
This commit is contained in:
parent
d0dbd5b3f2
commit
ed0d76d538
80
libpri.h
80
libpri.h
@ -547,6 +547,7 @@ struct pri_rerouting_data {
|
||||
#define PRI_SUBCMD_AOC_CHARGING_REQ_RSP 22 /*!< Advice Of Charge Request Response information */
|
||||
#define PRI_SUBCMD_MCID_REQ 23 /*!< Malicious Call ID Request */
|
||||
#define PRI_SUBCMD_MCID_RSP 24 /*!< Malicious Call ID Request response */
|
||||
#define PRI_SUBCMD_DISPLAY_TEXT 25 /*!< Received display ie text */
|
||||
|
||||
#if defined(STATUS_REQUEST_PLACE_HOLDER)
|
||||
struct pri_subcmd_status_request {
|
||||
@ -967,6 +968,35 @@ struct pri_subcmd_mcid_rsp {
|
||||
int fail_code;
|
||||
};
|
||||
|
||||
struct pri_subcmd_display_txt {
|
||||
/*!
|
||||
* \brief Character set the text is using.
|
||||
* \details
|
||||
* unknown(0),
|
||||
* iso8859-1(1),
|
||||
* enum-value-withdrawn-by-ITU-T(2)
|
||||
* iso8859-2(3),
|
||||
* iso8859-3(4),
|
||||
* iso8859-4(5),
|
||||
* iso8859-5(6),
|
||||
* iso8859-7(7),
|
||||
* iso10646-BmpString(8),
|
||||
* iso10646-utf-8String(9)
|
||||
*/
|
||||
int char_set;
|
||||
/*!
|
||||
* \brief Number of octets in the display message.
|
||||
* \note Not including any added null terminator.
|
||||
*/
|
||||
int length;
|
||||
/*!
|
||||
* \brief Display text data.
|
||||
* \note Null terminated on receive.
|
||||
* \note Does not need to be null terminated on send.
|
||||
*/
|
||||
char text[128];
|
||||
};
|
||||
|
||||
struct pri_subcommand {
|
||||
/*! PRI_SUBCMD_xxx defined values */
|
||||
int cmd;
|
||||
@ -999,6 +1029,7 @@ struct pri_subcommand {
|
||||
struct pri_subcmd_aoc_e aoc_e;
|
||||
struct pri_subcmd_mcid_req mcid_req;
|
||||
struct pri_subcmd_mcid_rsp mcid_rsp;
|
||||
struct pri_subcmd_display_txt display;
|
||||
} u;
|
||||
};
|
||||
|
||||
@ -1840,6 +1871,55 @@ int pri_transfer_rsp(struct pri *ctrl, q931_call *call, int invoke_id, int is_su
|
||||
*/
|
||||
void pri_aoc_events_enable(struct pri *ctrl, int enable);
|
||||
|
||||
#define PRI_DISPLAY_OPTION_BLOCK (1 << 0) /*!< Do not pass display text. */
|
||||
#define PRI_DISPLAY_OPTION_NAME_INITIAL (1 << 1) /*!< Use display in SETUP/CONNECT for name. */
|
||||
#define PRI_DISPLAY_OPTION_NAME_UPDATE (1 << 2) /*!< Use display in FACILITY/NOTIFY for COLP name if appropriate. */
|
||||
#define PRI_DISPLAY_OPTION_TEXT (1 << 3) /*!< Pass arbitrary display text in INFORMATION messages during call. */
|
||||
|
||||
/*!
|
||||
* \brief Set the display ie send policy options.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param flags Option flags to apply.
|
||||
*
|
||||
* \note
|
||||
* If no flags set then legacy default behaviour.
|
||||
*
|
||||
* \note
|
||||
* Not all options are supported by all switches.
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
void pri_display_options_send(struct pri *ctrl, unsigned long flags);
|
||||
|
||||
/*!
|
||||
* \brief Set the display ie receive policy options.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param flags Option flags to apply.
|
||||
*
|
||||
* \note
|
||||
* If no flags set then legacy default behaviour.
|
||||
*
|
||||
* \note
|
||||
* Not all options are supported by all switches.
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
void pri_display_options_receive(struct pri *ctrl, unsigned long flags);
|
||||
|
||||
/*!
|
||||
* \brief Send display text during a call.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param call Q.931 call leg
|
||||
* \param display Display text to send.
|
||||
*
|
||||
* \retval 0 on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int pri_display_text(struct pri *ctrl, q931_call *call, const struct pri_subcmd_display_txt *display);
|
||||
|
||||
/*!
|
||||
* \brief Set the call hold feature enable flag.
|
||||
*
|
||||
|
96
pri.c
96
pri.c
@ -288,6 +288,60 @@ static int __pri_write(struct pri *pri, void *buf, int buflen)
|
||||
return res;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Determine the default display text send options.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
*
|
||||
* \return Default display text send options. (legacy behaviour defaults)
|
||||
*/
|
||||
static unsigned long pri_display_options_send_default(struct pri *ctrl)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
switch (ctrl->switchtype) {
|
||||
case PRI_SWITCH_QSIG:
|
||||
flags = PRI_DISPLAY_OPTION_BLOCK;
|
||||
break;
|
||||
case PRI_SWITCH_EUROISDN_E1:
|
||||
case PRI_SWITCH_EUROISDN_T1:
|
||||
if (ctrl->localtype == PRI_CPE) {
|
||||
flags = PRI_DISPLAY_OPTION_BLOCK;
|
||||
break;
|
||||
}
|
||||
flags = PRI_DISPLAY_OPTION_NAME_INITIAL;
|
||||
break;
|
||||
default:
|
||||
flags = PRI_DISPLAY_OPTION_NAME_INITIAL;
|
||||
break;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Determine the default display text receive options.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
*
|
||||
* \return Default display text receive options. (legacy behaviour defaults)
|
||||
*/
|
||||
static unsigned long pri_display_options_receive_default(struct pri *ctrl)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
switch (ctrl->switchtype) {
|
||||
case PRI_SWITCH_QSIG:
|
||||
flags = PRI_DISPLAY_OPTION_BLOCK;
|
||||
break;
|
||||
default:
|
||||
flags = PRI_DISPLAY_OPTION_NAME_INITIAL;
|
||||
break;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Destroy the given link.
|
||||
*
|
||||
@ -481,6 +535,8 @@ static struct pri *pri_ctrl_new(int fd, int node, int switchtype, pri_io_cb rd,
|
||||
ctrl->q931_rxcount = 0;
|
||||
ctrl->q931_txcount = 0;
|
||||
|
||||
ctrl->display_flags.send = pri_display_options_send_default(ctrl);
|
||||
ctrl->display_flags.receive = pri_display_options_receive_default(ctrl);
|
||||
switch (switchtype) {
|
||||
case PRI_SWITCH_GR303_EOC:
|
||||
ctrl->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
|
||||
@ -999,7 +1055,7 @@ int pri_connected_line_update(struct pri *ctrl, q931_call *call, const struct pr
|
||||
*/
|
||||
if (new_number) {
|
||||
q931_notify_redirection(ctrl, call, PRI_NOTIFY_TRANSFER_ACTIVE,
|
||||
&party_id.number);
|
||||
&party_id.name, &party_id.number);
|
||||
}
|
||||
if (new_subaddress || (party_id.subaddress.valid && new_number)) {
|
||||
q931_subaddress_transfer(ctrl, call);
|
||||
@ -1050,10 +1106,10 @@ int pri_connected_line_update(struct pri *ctrl, q931_call *call, const struct pr
|
||||
* connected yet.
|
||||
*/
|
||||
q931_notify_redirection(ctrl, call, PRI_NOTIFY_TRANSFER_ACTIVE,
|
||||
&party_id.number);
|
||||
&party_id.name, &party_id.number);
|
||||
#else
|
||||
q931_request_subaddress(ctrl, call, PRI_NOTIFY_TRANSFER_ACTIVE,
|
||||
&party_id.number);
|
||||
&party_id.name, &party_id.number);
|
||||
#endif /* defined(USE_NOTIFY_FOR_ECT) */
|
||||
}
|
||||
if (new_subaddress || (party_id.subaddress.valid && new_number)) {
|
||||
@ -1167,7 +1223,7 @@ int pri_redirecting_update(struct pri *ctrl, q931_call *call, const struct pri_p
|
||||
* themselves. Well... If you consider someone else picking up
|
||||
* the handset a redirection then how is the network to know?
|
||||
*/
|
||||
q931_notify_redirection(ctrl, call, PRI_NOTIFY_CALL_DIVERTING,
|
||||
q931_notify_redirection(ctrl, call, PRI_NOTIFY_CALL_DIVERTING, NULL,
|
||||
&call->redirecting.to.number);
|
||||
}
|
||||
break;
|
||||
@ -2050,3 +2106,35 @@ void pri_cc_retain_signaling_rsp(struct pri *ctrl, int signaling_retention)
|
||||
ctrl->cc.option.signaling_retention_rsp = signaling_retention ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
void pri_display_options_send(struct pri *ctrl, unsigned long flags)
|
||||
{
|
||||
if (!ctrl) {
|
||||
return;
|
||||
}
|
||||
if (!flags) {
|
||||
flags = pri_display_options_send_default(ctrl);
|
||||
}
|
||||
ctrl->display_flags.send = flags;
|
||||
}
|
||||
|
||||
void pri_display_options_receive(struct pri *ctrl, unsigned long flags)
|
||||
{
|
||||
if (!ctrl) {
|
||||
return;
|
||||
}
|
||||
if (!flags) {
|
||||
flags = pri_display_options_receive_default(ctrl);
|
||||
}
|
||||
ctrl->display_flags.receive = flags;
|
||||
}
|
||||
|
||||
int pri_display_text(struct pri *ctrl, q931_call *call, const struct pri_subcmd_display_txt *display)
|
||||
{
|
||||
if (!ctrl || !display || display->length <= 0
|
||||
|| sizeof(display->text) < display->length || !pri_is_call_valid(ctrl, call)) {
|
||||
/* Parameter sanity checks failed. */
|
||||
return -1;
|
||||
}
|
||||
return q931_display_text(ctrl, call, display);
|
||||
}
|
||||
|
@ -3355,8 +3355,18 @@ int pri_call_add_standard_apdus(struct pri *ctrl, q931_call *call)
|
||||
*/
|
||||
int send_call_transfer_complete(struct pri *ctrl, q931_call *call, int call_status)
|
||||
{
|
||||
if (rose_call_transfer_complete_encode(ctrl, call, call_status)
|
||||
|| q931_facility(ctrl, call)) {
|
||||
int status;
|
||||
|
||||
status = rose_call_transfer_complete_encode(ctrl, call, call_status);
|
||||
if (!status) {
|
||||
if (!call_status && call->local_id.number.valid
|
||||
&& (ctrl->display_flags.send & PRI_DISPLAY_OPTION_NAME_UPDATE)) {
|
||||
status = q931_facility_display_name(ctrl, call, &call->local_id.name);
|
||||
} else {
|
||||
status = q931_facility(ctrl, call);
|
||||
}
|
||||
}
|
||||
if (status) {
|
||||
pri_message(ctrl,
|
||||
"Could not schedule facility message for call transfer completed.\n");
|
||||
return -1;
|
||||
@ -3574,6 +3584,7 @@ int send_subaddress_transfer(struct pri *ctrl, struct q931_call *call)
|
||||
*/
|
||||
static void etsi_request_subaddress(struct pri *ctrl, struct q931_call *call)
|
||||
{
|
||||
struct q931_party_name name;
|
||||
int changed = 0;
|
||||
|
||||
switch (call->notify) {
|
||||
@ -3585,6 +3596,15 @@ static void etsi_request_subaddress(struct pri *ctrl, struct q931_call *call)
|
||||
}
|
||||
/* Fall through */
|
||||
case PRI_NOTIFY_TRANSFER_ALERTING:
|
||||
if (ctrl->display_flags.receive & PRI_DISPLAY_OPTION_NAME_UPDATE) {
|
||||
if (q931_display_name_get(call, &name)) {
|
||||
if (q931_party_name_cmp(&call->remote_id.name, &name)) {
|
||||
/* The remote party name information changed. */
|
||||
call->remote_id.name = name;
|
||||
changed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (call->redirection_number.valid
|
||||
&& q931_party_number_cmp(&call->remote_id.number, &call->redirection_number)) {
|
||||
/* The remote party number information changed. */
|
||||
@ -3626,6 +3646,7 @@ static void etsi_request_subaddress(struct pri *ctrl, struct q931_call *call)
|
||||
static void handle_subaddress_transfer(struct pri *ctrl, struct q931_call *call, const struct rosePartySubaddress *subaddr)
|
||||
{
|
||||
int changed = 0;
|
||||
struct q931_party_name name;
|
||||
struct q931_party_subaddress q931_subaddress;
|
||||
|
||||
q931_party_subaddress_init(&q931_subaddress);
|
||||
@ -3640,6 +3661,15 @@ static void handle_subaddress_transfer(struct pri *ctrl, struct q931_call *call,
|
||||
call->remote_id.number = call->redirection_number;
|
||||
changed = 1;
|
||||
}
|
||||
if (ctrl->display_flags.receive & PRI_DISPLAY_OPTION_NAME_UPDATE) {
|
||||
if (q931_display_name_get(call, &name)) {
|
||||
if (q931_party_name_cmp(&call->remote_id.name, &name)) {
|
||||
/* The remote party name information changed. */
|
||||
call->remote_id.name = name;
|
||||
changed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
call->incoming_ct_state = INCOMING_CT_STATE_POST_CONNECTED_LINE;
|
||||
}
|
||||
@ -4684,6 +4714,10 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
send_ect_link_id_rsp(ctrl, call, invoke->invoke_id);
|
||||
break;
|
||||
case ROSE_ETSI_EctInform:
|
||||
if (ctrl->display_flags.receive & PRI_DISPLAY_OPTION_NAME_UPDATE) {
|
||||
q931_display_name_get(call, &call->remote_id.name);
|
||||
}
|
||||
|
||||
/* redirectionNumber is put in remote_id.number */
|
||||
if (invoke->args.etsi.EctInform.redirection_present) {
|
||||
rose_copy_presented_number_unscreened_to_q931(ctrl,
|
||||
@ -5002,6 +5036,10 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
break;
|
||||
#endif /* Not handled yet */
|
||||
case ROSE_QSIG_CallingName:
|
||||
if (ctrl->display_flags.receive & PRI_DISPLAY_OPTION_NAME_UPDATE) {
|
||||
q931_display_name_get(call, &call->remote_id.name);
|
||||
}
|
||||
|
||||
/* CallingName is put in remote_id.name */
|
||||
rose_copy_name_to_q931(ctrl, &call->remote_id.name,
|
||||
&invoke->args.qsig.CallingName.name);
|
||||
@ -5023,6 +5061,10 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
}
|
||||
break;
|
||||
case ROSE_QSIG_CalledName:
|
||||
if (ctrl->display_flags.receive & PRI_DISPLAY_OPTION_NAME_UPDATE) {
|
||||
q931_display_name_get(call, &call->remote_id.name);
|
||||
}
|
||||
|
||||
/* CalledName is put in remote_id.name */
|
||||
rose_copy_name_to_q931(ctrl, &call->remote_id.name,
|
||||
&invoke->args.qsig.CalledName.name);
|
||||
@ -5044,6 +5086,10 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
}
|
||||
break;
|
||||
case ROSE_QSIG_ConnectedName:
|
||||
if (ctrl->display_flags.receive & PRI_DISPLAY_OPTION_NAME_UPDATE) {
|
||||
q931_display_name_get(call, &call->remote_id.name);
|
||||
}
|
||||
|
||||
/* ConnectedName is put in remote_id.name */
|
||||
rose_copy_name_to_q931(ctrl, &call->remote_id.name,
|
||||
&invoke->args.qsig.ConnectedName.name);
|
||||
@ -5095,6 +5141,10 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
break;
|
||||
#endif /* Not handled yet */
|
||||
case ROSE_QSIG_CallTransferActive:
|
||||
if (ctrl->display_flags.receive & PRI_DISPLAY_OPTION_NAME_UPDATE) {
|
||||
q931_display_name_get(call, &call->remote_id.name);
|
||||
}
|
||||
|
||||
call->incoming_ct_state = INCOMING_CT_STATE_POST_CONNECTED_LINE;
|
||||
|
||||
/* connectedAddress is put in remote_id */
|
||||
@ -5108,6 +5158,10 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
}
|
||||
break;
|
||||
case ROSE_QSIG_CallTransferComplete:
|
||||
if (ctrl->display_flags.receive & PRI_DISPLAY_OPTION_NAME_UPDATE) {
|
||||
q931_display_name_get(call, &call->remote_id.name);
|
||||
}
|
||||
|
||||
/* redirectionNumber is put in remote_id.number */
|
||||
rose_copy_presented_number_screened_to_q931(ctrl, &call->remote_id.number,
|
||||
&invoke->args.qsig.CallTransferComplete.redirection);
|
||||
@ -5139,6 +5193,10 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
case ROSE_QSIG_CallTransferUpdate:
|
||||
party_id = call->remote_id;
|
||||
|
||||
if (ctrl->display_flags.receive & PRI_DISPLAY_OPTION_NAME_UPDATE) {
|
||||
q931_display_name_get(call, &party_id.name);
|
||||
}
|
||||
|
||||
/* redirectionNumber is put in party_id.number */
|
||||
rose_copy_presented_number_screened_to_q931(ctrl, &party_id.number,
|
||||
&invoke->args.qsig.CallTransferUpdate.redirection);
|
||||
|
@ -60,6 +60,9 @@ struct pri_sched {
|
||||
/*! Maximum number of facility ie's to handle per incoming message. */
|
||||
#define MAX_FACILITY_IES 8
|
||||
|
||||
/*! Maximum length of sent display text string. (No null terminator.) */
|
||||
#define MAX_DISPLAY_TEXT 80
|
||||
|
||||
/*! Accumulated pri_message() line until a '\n' is seen on the end. */
|
||||
struct pri_msg_line {
|
||||
/*! Accumulated buffer used. */
|
||||
@ -177,6 +180,13 @@ struct pri {
|
||||
/*! Number of facility ie's in the array from the current received message. */
|
||||
unsigned char count;
|
||||
} facility;
|
||||
/*! Display text policy handling options. */
|
||||
struct {
|
||||
/*! Send display text policy option flags. */
|
||||
unsigned long send;
|
||||
/*! Receive display text policy option flags. */
|
||||
unsigned long receive;
|
||||
} display_flags;
|
||||
};
|
||||
|
||||
/*! \brief Maximum name length plus null terminator (From ECMA-164) */
|
||||
@ -603,6 +613,29 @@ struct q931_call {
|
||||
unsigned char initially_redirected;
|
||||
} cc;
|
||||
|
||||
/*! Display text ie contents. */
|
||||
struct {
|
||||
/*! Display ie text. NULL if not present or consumed as remote name. */
|
||||
const char *text;
|
||||
/*! Length of display text. */
|
||||
unsigned char length;
|
||||
/*!
|
||||
* \brief Character set the text is using.
|
||||
* \details
|
||||
* unknown(0),
|
||||
* iso8859-1(1),
|
||||
* enum-value-withdrawn-by-ITU-T(2)
|
||||
* iso8859-2(3),
|
||||
* iso8859-3(4),
|
||||
* iso8859-4(5),
|
||||
* iso8859-5(6),
|
||||
* iso8859-7(7),
|
||||
* iso10646-BmpString(8),
|
||||
* iso10646-utf-8String(9)
|
||||
*/
|
||||
unsigned char char_set;
|
||||
} display;
|
||||
|
||||
/* AOC charge requesting on Setup */
|
||||
int aoc_charging_request;
|
||||
};
|
||||
@ -938,6 +971,11 @@ void pri_copy_party_id_to_q931(struct q931_party_id *q931_id, const struct pri_p
|
||||
void q931_party_id_fixup(const struct pri *ctrl, struct q931_party_id *id);
|
||||
int q931_party_id_presentation(const struct q931_party_id *id);
|
||||
|
||||
int q931_display_name_get(struct q931_call *call, struct q931_party_name *name);
|
||||
int q931_display_text(struct pri *ctrl, struct q931_call *call, const struct pri_subcmd_display_txt *display);
|
||||
|
||||
int q931_facility_display_name(struct pri *ctrl, struct q931_call *call, const struct q931_party_name *name);
|
||||
|
||||
const char *q931_call_state_str(enum Q931_CALL_STATE callstate);
|
||||
const char *msg2str(int msg);
|
||||
|
||||
@ -948,9 +986,9 @@ struct pri_subcommand *q931_alloc_subcommand(struct pri *ctrl);
|
||||
struct q931_call *q931_find_link_id_call(struct pri *ctrl, int link_id);
|
||||
struct q931_call *q931_find_held_active_call(struct pri *ctrl, struct q931_call *held_call);
|
||||
|
||||
int q931_request_subaddress(struct pri *ctrl, struct q931_call *call, int notify, const struct q931_party_number *number);
|
||||
int q931_request_subaddress(struct pri *ctrl, struct q931_call *call, int notify, const struct q931_party_name *name, const struct q931_party_number *number);
|
||||
int q931_subaddress_transfer(struct pri *ctrl, struct q931_call *call);
|
||||
int q931_notify_redirection(struct pri *ctrl, q931_call *call, int notify, const struct q931_party_number *number);
|
||||
int q931_notify_redirection(struct pri *ctrl, struct q931_call *call, int notify, const struct q931_party_name *name, const struct q931_party_number *number);
|
||||
|
||||
struct pri_cc_record *pri_cc_find_by_reference(struct pri *ctrl, unsigned reference_id);
|
||||
struct pri_cc_record *pri_cc_find_by_linkage(struct pri *ctrl, unsigned linkage_id);
|
||||
|
396
q931.c
396
q931.c
@ -936,6 +936,125 @@ int q931_party_id_presentation(const struct q931_party_id *id)
|
||||
return number_value | number_screening;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Clear the display text.
|
||||
*
|
||||
* \param call Q.931 call to clear display text.
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
static void q931_display_clear(struct q931_call *call)
|
||||
{
|
||||
call->display.text = NULL;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Set the display text for the party name.
|
||||
*
|
||||
* \param call Q.931 call to set display text to the party name.
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
static void q931_display_name_send(struct q931_call *call, const struct q931_party_name *name)
|
||||
{
|
||||
if (name->valid) {
|
||||
switch (name->presentation & PRI_PRES_RESTRICTION) {
|
||||
case PRI_PRES_ALLOWED:
|
||||
call->display.text = (char *) name->str;
|
||||
call->display.length = strlen(name->str);
|
||||
call->display.char_set = name->char_set;
|
||||
break;
|
||||
default:
|
||||
call->display.text = NULL;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
call->display.text = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Get the display text into the party name.
|
||||
*
|
||||
* \param call Q.931 call to get the display text into the party name.
|
||||
* \param name Party name to fill if there is display text.
|
||||
*
|
||||
* \note
|
||||
* The party name is not touched if there is no display text.
|
||||
*
|
||||
* \note
|
||||
* The display text is consumed.
|
||||
*
|
||||
* \return TRUE if party name filled.
|
||||
*/
|
||||
int q931_display_name_get(struct q931_call *call, struct q931_party_name *name)
|
||||
{
|
||||
if (!call->display.text) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
name->valid = 1;
|
||||
name->char_set = call->display.char_set;
|
||||
if (call->display.length < sizeof(name->str)) {
|
||||
memcpy(name->str, call->display.text, call->display.length);
|
||||
name->str[call->display.length] = '\0';
|
||||
} else {
|
||||
name->str[0] = '\0';
|
||||
}
|
||||
if (name->str[0]) {
|
||||
name->presentation = PRI_PRES_ALLOWED;
|
||||
} else {
|
||||
name->presentation = PRI_PRES_RESTRICTED;
|
||||
}
|
||||
|
||||
/* Mark the display text as consumed. */
|
||||
call->display.text = NULL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Fill a subcmd with any display text.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param call Q.931 call leg.
|
||||
*
|
||||
* \note
|
||||
* The display text is consumed.
|
||||
*
|
||||
* \return Nothing
|
||||
*/
|
||||
static void q931_display_subcmd(struct pri *ctrl, struct q931_call *call)
|
||||
{
|
||||
struct pri_subcommand *subcmd;
|
||||
|
||||
if (call->display.text && call->display.length
|
||||
&& (ctrl->display_flags.receive & PRI_DISPLAY_OPTION_TEXT)) {
|
||||
subcmd = q931_alloc_subcommand(ctrl);
|
||||
if (subcmd) {
|
||||
/* Setup display text subcommand */
|
||||
subcmd->cmd = PRI_SUBCMD_DISPLAY_TEXT;
|
||||
subcmd->u.display.char_set = call->display.char_set;
|
||||
if (call->display.length < sizeof(subcmd->u.display.text)) {
|
||||
subcmd->u.display.length = call->display.length;
|
||||
} else {
|
||||
/* Truncate display text and leave room for a null terminator. */
|
||||
subcmd->u.display.length = sizeof(subcmd->u.display.text) - 1;
|
||||
}
|
||||
memcpy(subcmd->u.display.text, call->display.text, subcmd->u.display.length);
|
||||
|
||||
/* Make sure display text is null terminated. */
|
||||
subcmd->u.display.text[subcmd->u.display.length] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/* Mark the display text as consumed. */
|
||||
call->display.text = NULL;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Find the winning subcall if it exists or current call if not outboundbroadcast.
|
||||
*
|
||||
@ -2435,36 +2554,22 @@ static void dump_progress_indicator(int full_ie, struct pri *ctrl, q931_ie *ie,
|
||||
|
||||
static int receive_display(int full_ie, struct pri *ctrl, q931_call *call, int msgtype, q931_ie *ie, int len)
|
||||
{
|
||||
unsigned char *data;
|
||||
u_int8_t *data;
|
||||
|
||||
switch (msgtype) {
|
||||
case Q931_SETUP:
|
||||
case Q931_CONNECT:
|
||||
/*
|
||||
* Only keep the display message on SETUP and CONNECT messages
|
||||
* as the remote name.
|
||||
*/
|
||||
break;
|
||||
default:
|
||||
if (ctrl->display_flags.receive & PRI_DISPLAY_OPTION_BLOCK) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
call->remote_id.name.valid = 1;
|
||||
|
||||
data = ie->data;
|
||||
if (data[0] & 0x80) {
|
||||
/* Skip over character set */
|
||||
data++;
|
||||
len--;
|
||||
}
|
||||
call->remote_id.name.char_set = PRI_CHAR_SET_ISO8859_1;
|
||||
|
||||
q931_get_number((unsigned char *) call->remote_id.name.str, sizeof(call->remote_id.name.str), data, len - 2);
|
||||
if (call->remote_id.name.str[0]) {
|
||||
call->remote_id.name.presentation = PRI_PRES_ALLOWED;
|
||||
} else {
|
||||
call->remote_id.name.presentation = PRI_PRES_RESTRICTED;
|
||||
}
|
||||
call->display.text = (char *) data;
|
||||
call->display.length = len - 2;
|
||||
call->display.char_set = PRI_CHAR_SET_ISO8859_1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2473,30 +2578,31 @@ static int transmit_display(int full_ie, struct pri *ctrl, q931_call *call, int
|
||||
size_t datalen;
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
|
||||
if (!call->local_id.name.valid || !call->local_id.name.str[0]) {
|
||||
if (!call->display.text || !call->display.length) {
|
||||
return 0;
|
||||
}
|
||||
if (ctrl->display_flags.send & PRI_DISPLAY_OPTION_BLOCK) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
switch (ctrl->switchtype) {
|
||||
case PRI_SWITCH_QSIG:
|
||||
/* Q.SIG supports names */
|
||||
return 0;
|
||||
case PRI_SWITCH_EUROISDN_E1:
|
||||
case PRI_SWITCH_EUROISDN_T1:
|
||||
if (ctrl->localtype == PRI_CPE) {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* Prefix name with character set indicator. */
|
||||
/* Prefix text with character set indicator. */
|
||||
ie->data[0] = 0xb1;
|
||||
++i;
|
||||
break;
|
||||
}
|
||||
|
||||
datalen = strlen(call->local_id.name.str);
|
||||
memcpy(ie->data + i, call->local_id.name.str, datalen);
|
||||
datalen = call->display.length;
|
||||
if (MAX_DISPLAY_TEXT < datalen + i) {
|
||||
datalen = MAX_DISPLAY_TEXT - i;
|
||||
}
|
||||
memcpy(ie->data + i, call->display.text, datalen);
|
||||
return 2 + i + datalen;
|
||||
}
|
||||
|
||||
@ -4742,20 +4848,27 @@ int maintenance_service(struct pri *ctrl, int span, int channel, int changestatu
|
||||
return send_message(ctrl, c, (pd << 8) | mt, maintenance_service_ies);
|
||||
}
|
||||
|
||||
static int status_ies[] = { Q931_CAUSE, Q931_IE_CALL_STATE, -1 };
|
||||
|
||||
static int q931_status(struct pri *ctrl, q931_call *call, int cause)
|
||||
{
|
||||
static int status_ies[] = {
|
||||
Q931_CAUSE,
|
||||
Q931_IE_CALL_STATE,
|
||||
-1
|
||||
};
|
||||
|
||||
call->cause = cause;
|
||||
call->causecode = CODE_CCITT;
|
||||
call->causeloc = LOC_USER;
|
||||
return send_message(ctrl, call, Q931_STATUS, status_ies);
|
||||
}
|
||||
|
||||
static int information_ies[] = { Q931_CALLED_PARTY_NUMBER, -1 };
|
||||
|
||||
int q931_information(struct pri *ctrl, q931_call *c, char digit)
|
||||
{
|
||||
static int information_ies[] = {
|
||||
Q931_CALLED_PARTY_NUMBER,
|
||||
-1
|
||||
};
|
||||
|
||||
c->overlap_digits[0] = digit;
|
||||
c->overlap_digits[1] = '\0';
|
||||
|
||||
@ -4772,6 +4885,84 @@ int q931_information(struct pri *ctrl, q931_call *c, char digit)
|
||||
return send_message(ctrl, c, Q931_INFORMATION, information_ies);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Actually send display text if in the right call state.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param call Q.931 call leg
|
||||
* \param display Display text to send.
|
||||
*
|
||||
* \retval 0 on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
static int q931_display_text_helper(struct pri *ctrl, struct q931_call *call, const struct pri_subcmd_display_txt *display)
|
||||
{
|
||||
int status;
|
||||
static int information_display_ies[] = {
|
||||
Q931_DISPLAY,
|
||||
-1
|
||||
};
|
||||
|
||||
switch (call->ourcallstate) {
|
||||
case Q931_CALL_STATE_OVERLAP_SENDING:
|
||||
case Q931_CALL_STATE_OUTGOING_CALL_PROCEEDING:
|
||||
case Q931_CALL_STATE_CALL_DELIVERED:
|
||||
case Q931_CALL_STATE_CALL_RECEIVED:
|
||||
case Q931_CALL_STATE_CONNECT_REQUEST:
|
||||
case Q931_CALL_STATE_INCOMING_CALL_PROCEEDING:
|
||||
case Q931_CALL_STATE_ACTIVE:
|
||||
case Q931_CALL_STATE_OVERLAP_RECEIVING:
|
||||
call->display.text = display->text;
|
||||
call->display.length = display->length;
|
||||
call->display.char_set = display->char_set;
|
||||
status = send_message(ctrl, call, Q931_INFORMATION, information_display_ies);
|
||||
q931_display_clear(call);
|
||||
break;
|
||||
default:
|
||||
status = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Send display text during a call.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param call Q.931 call leg
|
||||
* \param display Display text to send.
|
||||
*
|
||||
* \retval 0 on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int q931_display_text(struct pri *ctrl, struct q931_call *call, const struct pri_subcmd_display_txt *display)
|
||||
{
|
||||
int status;
|
||||
unsigned idx;
|
||||
struct q931_call *subcall;
|
||||
|
||||
if ((ctrl->display_flags.send & (PRI_DISPLAY_OPTION_BLOCK | PRI_DISPLAY_OPTION_TEXT))
|
||||
!= PRI_DISPLAY_OPTION_TEXT) {
|
||||
/* Not enabled */
|
||||
return 0;
|
||||
}
|
||||
if (call->outboundbroadcast && call->master_call == call) {
|
||||
status = 0;
|
||||
for (idx = 0; idx < ARRAY_LEN(call->subcalls); ++idx) {
|
||||
subcall = call->subcalls[idx];
|
||||
if (subcall && q931_display_text_helper(ctrl, subcall, display)) {
|
||||
status = -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
status = q931_display_text_helper(ctrl, call, display);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
static int keypad_facility_ies[] = { Q931_IE_KEYPAD_FACILITY, -1 };
|
||||
|
||||
int q931_keypad_facility(struct pri *ctrl, q931_call *call, const char *digits)
|
||||
@ -4789,41 +4980,66 @@ static int restart_ack(struct pri *ctrl, q931_call *c)
|
||||
return send_message(ctrl, c, Q931_RESTART_ACKNOWLEDGE, restart_ack_ies);
|
||||
}
|
||||
|
||||
static int facility_ies[] = { Q931_IE_FACILITY, -1 };
|
||||
|
||||
int q931_facility(struct pri*ctrl, q931_call *c)
|
||||
int q931_facility(struct pri *ctrl, struct q931_call *call)
|
||||
{
|
||||
return send_message(ctrl, c, Q931_FACILITY, facility_ies);
|
||||
static int facility_ies[] = {
|
||||
Q931_IE_FACILITY,
|
||||
-1
|
||||
};
|
||||
|
||||
return send_message(ctrl, call, Q931_FACILITY, facility_ies);
|
||||
}
|
||||
|
||||
static int facility_notify_ies[] = {
|
||||
Q931_IE_FACILITY,
|
||||
Q931_IE_NOTIFY_IND,
|
||||
Q931_IE_REDIRECTION_NUMBER,
|
||||
-1
|
||||
};
|
||||
int q931_facility_display_name(struct pri *ctrl, struct q931_call *call, const struct q931_party_name *name)
|
||||
{
|
||||
int status;
|
||||
static int facility_display_ies[] = {
|
||||
Q931_IE_FACILITY,
|
||||
Q931_DISPLAY,
|
||||
-1
|
||||
};
|
||||
|
||||
q931_display_name_send(call, name);
|
||||
status = send_message(ctrl, call, Q931_FACILITY, facility_display_ies);
|
||||
q931_display_clear(call);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Send a FACILITY RequestSubaddress with optional redirection number.
|
||||
* \brief Send a FACILITY RequestSubaddress with optional redirection name and number.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param call Q.931 call leg
|
||||
* \param notify Notification indicator
|
||||
* \param name Redirection name to send if not NULL.
|
||||
* \param number Redirection number to send if not NULL.
|
||||
*
|
||||
* \retval 0 on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int q931_request_subaddress(struct pri *ctrl, struct q931_call *call, int notify, const struct q931_party_number *number)
|
||||
int q931_request_subaddress(struct pri *ctrl, struct q931_call *call, int notify, const struct q931_party_name *name, const struct q931_party_number *number)
|
||||
{
|
||||
int status;
|
||||
struct q931_call *winner;
|
||||
static int facility_notify_ies[] = {
|
||||
Q931_IE_FACILITY,
|
||||
Q931_IE_NOTIFY_IND,
|
||||
Q931_DISPLAY,
|
||||
Q931_IE_REDIRECTION_NUMBER,
|
||||
-1
|
||||
};
|
||||
|
||||
winner = q931_find_winning_call(call);
|
||||
if (!winner) {
|
||||
return -1;
|
||||
}
|
||||
q931_display_clear(winner);
|
||||
if (number) {
|
||||
winner->redirection_number = *number;
|
||||
if (number->valid && name
|
||||
&& (ctrl->display_flags.send & PRI_DISPLAY_OPTION_NAME_UPDATE)) {
|
||||
q931_display_name_send(winner, name);
|
||||
}
|
||||
} else {
|
||||
q931_party_number_init(&winner->redirection_number);
|
||||
}
|
||||
@ -4832,10 +5048,13 @@ int q931_request_subaddress(struct pri *ctrl, struct q931_call *call, int notify
|
||||
|| send_message(ctrl, winner, Q931_FACILITY, facility_notify_ies)) {
|
||||
pri_message(ctrl,
|
||||
"Could not schedule facility message for request subaddress.\n");
|
||||
return -1;
|
||||
status = -1;
|
||||
} else {
|
||||
status = 0;
|
||||
}
|
||||
q931_display_clear(winner);
|
||||
|
||||
return 0;
|
||||
return status;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -4878,43 +5097,58 @@ int q931_subaddress_transfer(struct pri *ctrl, struct q931_call *call)
|
||||
return status;
|
||||
}
|
||||
|
||||
static int notify_ies[] = { Q931_IE_NOTIFY_IND, Q931_IE_REDIRECTION_NUMBER, -1 };
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Actually send a NOTIFY message with optional redirection number.
|
||||
* \brief Actually send a NOTIFY message with optional redirection name and number.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param call Q.931 call leg
|
||||
* \param notify Notification indicator
|
||||
* \param name Redirection display name to send if not NULL.
|
||||
* \param number Redirection number to send if not NULL.
|
||||
*
|
||||
* \retval 0 on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
static int q931_notify_redirection_helper(struct pri *ctrl, q931_call *call, int notify, const struct q931_party_number *number)
|
||||
static int q931_notify_redirection_helper(struct pri *ctrl, struct q931_call *call, int notify, const struct q931_party_name *name, const struct q931_party_number *number)
|
||||
{
|
||||
int status;
|
||||
static int notify_ies[] = {
|
||||
Q931_IE_NOTIFY_IND,
|
||||
Q931_DISPLAY,
|
||||
Q931_IE_REDIRECTION_NUMBER,
|
||||
-1
|
||||
};
|
||||
|
||||
q931_display_clear(call);
|
||||
if (number) {
|
||||
call->redirection_number = *number;
|
||||
if (number->valid && name
|
||||
&& (ctrl->display_flags.send & PRI_DISPLAY_OPTION_NAME_UPDATE)) {
|
||||
q931_display_name_send(call, name);
|
||||
}
|
||||
} else {
|
||||
q931_party_number_init(&call->redirection_number);
|
||||
}
|
||||
call->notify = notify;
|
||||
return send_message(ctrl, call, Q931_NOTIFY, notify_ies);
|
||||
status = send_message(ctrl, call, Q931_NOTIFY, notify_ies);
|
||||
q931_display_clear(call);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Send a NOTIFY message with optional redirection number.
|
||||
* \brief Send a NOTIFY message with optional redirection name and number.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param call Q.931 call leg
|
||||
* \param notify Notification indicator
|
||||
* \param name Redirection display name to send if not NULL.
|
||||
* \param number Redirection number to send if not NULL.
|
||||
*
|
||||
* \retval 0 on success.
|
||||
* \retval -1 on error.
|
||||
*/
|
||||
int q931_notify_redirection(struct pri *ctrl, q931_call *call, int notify, const struct q931_party_number *number)
|
||||
int q931_notify_redirection(struct pri *ctrl, struct q931_call *call, int notify, const struct q931_party_name *name, const struct q931_party_number *number)
|
||||
{
|
||||
int status;
|
||||
unsigned idx;
|
||||
@ -4930,7 +5164,7 @@ int q931_notify_redirection(struct pri *ctrl, q931_call *call, int notify, const
|
||||
case Q931_CALL_STATE_OUTGOING_CALL_PROCEEDING:
|
||||
case Q931_CALL_STATE_CALL_DELIVERED:
|
||||
case Q931_CALL_STATE_ACTIVE:
|
||||
if (q931_notify_redirection_helper(ctrl, subcall, notify, number)) {
|
||||
if (q931_notify_redirection_helper(ctrl, subcall, notify, name, number)) {
|
||||
status = -1;
|
||||
}
|
||||
break;
|
||||
@ -4940,7 +5174,7 @@ int q931_notify_redirection(struct pri *ctrl, q931_call *call, int notify, const
|
||||
}
|
||||
}
|
||||
} else {
|
||||
status = q931_notify_redirection_helper(ctrl, call, notify, number);
|
||||
status = q931_notify_redirection_helper(ctrl, call, notify, name, number);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
@ -4964,7 +5198,7 @@ int q931_notify(struct pri *ctrl, q931_call *c, int channel, int info)
|
||||
/* Cannot send NOTIFY message if the mandatory ie is not going to be present. */
|
||||
return -1;
|
||||
}
|
||||
return q931_notify_redirection(ctrl, c, info, NULL);
|
||||
return q931_notify_redirection(ctrl, c, info, NULL, NULL);
|
||||
}
|
||||
|
||||
#ifdef ALERTING_NO_PROGRESS
|
||||
@ -5278,6 +5512,11 @@ int q931_connect(struct pri *ctrl, q931_call *c, int channel, int nonisdn)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (ctrl->display_flags.send & PRI_DISPLAY_OPTION_NAME_INITIAL) {
|
||||
q931_display_name_send(c, &c->local_id.name);
|
||||
} else {
|
||||
q931_display_clear(c);
|
||||
}
|
||||
if (ctrl->localtype == PRI_NETWORK) {
|
||||
/* networks may send date/time */
|
||||
return send_message(ctrl, c, Q931_CONNECT, connect_net_ies);
|
||||
@ -5473,6 +5712,11 @@ static void t303_expiry(void *data)
|
||||
* retransmits will lose the facility ies.
|
||||
*/
|
||||
pri_call_add_standard_apdus(ctrl, c);
|
||||
if (ctrl->display_flags.send & PRI_DISPLAY_OPTION_NAME_INITIAL) {
|
||||
q931_display_name_send(c, &c->local_id.name);
|
||||
} else {
|
||||
q931_display_clear(c);
|
||||
}
|
||||
c->cc.saved_ie_contents.length = 0;
|
||||
c->cc.saved_ie_flags = 0;
|
||||
if (ctrl->link.next && !ctrl->bri)
|
||||
@ -5567,6 +5811,11 @@ int q931_setup(struct pri *ctrl, q931_call *c, struct pri_sr *req)
|
||||
c->aoc_charging_request = req->aoc_charging_request;
|
||||
|
||||
pri_call_add_standard_apdus(ctrl, c);
|
||||
if (ctrl->display_flags.send & PRI_DISPLAY_OPTION_NAME_INITIAL) {
|
||||
q931_display_name_send(c, &c->local_id.name);
|
||||
} else {
|
||||
q931_display_clear(c);
|
||||
}
|
||||
|
||||
/* Save the initial cc-parties. */
|
||||
c->cc.party_a = c->local_id;
|
||||
@ -6808,7 +7057,8 @@ int q931_receive(struct q921_link *link, q931_h *h, int len)
|
||||
break;
|
||||
}
|
||||
q931_clr_subcommands(ctrl);
|
||||
|
||||
q931_display_clear(c);
|
||||
|
||||
/* Handle IEs */
|
||||
memset(mandies, 0, sizeof(mandies));
|
||||
for (x = 0; x < ARRAY_LEN(msgs); ++x) {
|
||||
@ -6830,6 +7080,7 @@ int q931_receive(struct q921_link *link, q931_h *h, int len)
|
||||
/* Allow the message anyway. We have already processed an ie. */
|
||||
break;
|
||||
}
|
||||
q931_display_clear(c);
|
||||
return -1;
|
||||
}
|
||||
for (y = 0; y < ARRAY_LEN(mandies); ++y) {
|
||||
@ -6907,6 +7158,17 @@ int q931_receive(struct q921_link *link, q931_h *h, int len)
|
||||
}
|
||||
|
||||
if (!missingmand) {
|
||||
switch (mh->msg) {
|
||||
case Q931_SETUP:
|
||||
case Q931_CONNECT:
|
||||
if (ctrl->display_flags.receive & PRI_DISPLAY_OPTION_NAME_INITIAL) {
|
||||
q931_display_name_get(c, &c->remote_id.name);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Now handle the facility ie's after all the other ie's were processed. */
|
||||
q931_handle_facilities(ctrl, c, mh->msg);
|
||||
}
|
||||
@ -6939,6 +7201,8 @@ int q931_receive(struct q921_link *link, q931_h *h, int len)
|
||||
}
|
||||
break;
|
||||
}
|
||||
q931_display_subcmd(ctrl, c);
|
||||
q931_display_clear(c);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -7888,6 +8152,7 @@ static int post_handle_q931_message(struct pri *ctrl, struct q931_mh *mh, struct
|
||||
default:
|
||||
break;
|
||||
}
|
||||
q931_display_subcmd(ctrl, c);
|
||||
if (ctrl->subcmds.counter_subcmd) {
|
||||
q931_fill_facility_event(ctrl, c);
|
||||
return Q931_RES_HAVEEVENT;
|
||||
@ -8294,6 +8559,7 @@ static int post_handle_q931_message(struct pri *ctrl, struct q931_mh *mh, struct
|
||||
}
|
||||
}
|
||||
|
||||
q931_display_subcmd(ctrl, c);
|
||||
if (ctrl->subcmds.counter_subcmd) {
|
||||
q931_fill_facility_event(ctrl, c);
|
||||
res = Q931_RES_HAVEEVENT;
|
||||
@ -8307,6 +8573,17 @@ static int post_handle_q931_message(struct pri *ctrl, struct q931_mh *mh, struct
|
||||
}
|
||||
/* Fall through */
|
||||
case PRI_NOTIFY_TRANSFER_ALERTING:
|
||||
if (ctrl->display_flags.receive & PRI_DISPLAY_OPTION_NAME_UPDATE) {
|
||||
struct q931_party_name name;
|
||||
|
||||
if (q931_display_name_get(c, &name)) {
|
||||
if (q931_party_name_cmp(&c->remote_id.name, &name)) {
|
||||
/* The remote party name information changed. */
|
||||
c->remote_id.name = name;
|
||||
changed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (c->redirection_number.valid
|
||||
&& q931_party_number_cmp(&c->remote_id.number, &c->redirection_number)) {
|
||||
/* The remote party number information changed. */
|
||||
@ -8331,6 +8608,7 @@ static int post_handle_q931_message(struct pri *ctrl, struct q931_mh *mh, struct
|
||||
}
|
||||
}
|
||||
|
||||
q931_display_subcmd(ctrl, c);
|
||||
if (ctrl->subcmds.counter_subcmd) {
|
||||
q931_fill_facility_event(ctrl, c);
|
||||
res = Q931_RES_HAVEEVENT;
|
||||
|
Loading…
Reference in New Issue
Block a user