Commit 239f8186 authored by Richard Mudgett's avatar Richard Mudgett

Problems with ISDN MWI to phones.

1) The "controlling user number" is always the number of the voice mail box
which is identical with the subscriber number itself.  This number which
is listed in the ISDN phone MWI menu cannot be called back to contact the
voice mail box.  The controlling user number should be made configurable.

2) The MWI indication is not restricted to a user (broadcast facility with
dummy call reference).  A called party IE should be added to address only
the relevant MSN.  (ETSI 300-196 Section 8.3.2.4)

JIRA ABE-2738
JIRA SWP-2846


git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@2262 2fbb986a-6c06-0410-b554-c9c1f0a7f128
parent c794af65
......@@ -1621,11 +1621,11 @@ int pri_mwi_deactivate(struct pri *pri, q931_call *c, char *caller, int callerpl
* \brief Send a MWI indication on the specified D channel.
*
* \param ctrl D channel controller.
* \param mailbox Controlling party number (NULL if not present).
* \param mailbox Party receiving notification.
* \param basic_service Basic service enum (-1 if not present).
* \param num_messages NumberOfMessages (-1 if not present).
* \param caller_id Controlling party privided number (NULL if not present).
* \param timestamp Generalized Time format (NULL if not present).
* \param caller_id Party leaving message (NULL if not present).
* \param timestamp When message left. (Generalized Time format, NULL if not present)
* \param message_reference Message reference number (-1 if not present).
* \param message_status Message status: added(0), removed(1).
*
......@@ -1636,6 +1636,27 @@ int pri_mwi_indicate(struct pri *ctrl, const struct pri_party_id *mailbox,
int basic_service, int num_messages, const struct pri_party_id *caller_id,
const char *timestamp, int message_reference, int message_status);
/*!
* \brief Send a MWI indication on the specified D channel. (Take two)
*
* \param ctrl D channel controller.
* \param mailbox Party receiving notification.
* \param vm_id Voicemail system number (NULL if not present).
* \param basic_service Basic service enum (-1 if not present).
* \param num_messages NumberOfMessages (-1 if not present).
* \param caller_id Party leaving message (NULL if not present).
* \param timestamp When message left. (Generalized Time format, NULL if not present)
* \param message_reference Message reference number (-1 if not present).
* \param message_status Message status: added(0), removed(1).
*
* \retval 0 on success.
* \retval -1 on error.
*/
int pri_mwi_indicate_v2(struct pri *ctrl, const struct pri_party_id *mailbox,
const struct pri_party_id *vm_id, int basic_service, int num_messages,
const struct pri_party_id *caller_id, const char *timestamp, int message_reference,
int message_status);
/* Set service message support flag */
int pri_set_service_message_support(struct pri *pri, int supportflag);
......
......@@ -1746,11 +1746,11 @@ int mwi_message_send(struct pri *ctrl, q931_call *call, struct pri_sr *req, int
* \param ctrl D channel controller for diagnostic messages or global options.
* \param pos Starting position to encode the facility ie contents.
* \param end End of facility ie contents encoding data buffer.
* \param mailbox Controlling party number (NULL if not present).
* \param vm_id Controlling party number (NULL if not present).
* \param basic_service Basic service enum (-1 if not present).
* \param num_messages NumberOfMessages (-1 if not present).
* \param caller_id Controlling party privided number (NULL if not present).
* \param timestamp Generalized Time format (NULL if not present).
* \param timestamp When message left. (Generalized Time format, NULL if not present)
* \param message_reference Message reference number (-1 if not present).
* \param message_status Message status: added(0), removed(1).
*
......@@ -1758,7 +1758,7 @@ int mwi_message_send(struct pri *ctrl, q931_call *call, struct pri_sr *req, int
* \retval NULL on error.
*/
static unsigned char *enc_etsi_mwi_indicate_message(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const struct pri_party_id *mailbox, int basic_service,
unsigned char *end, const struct pri_party_id *vm_id, int basic_service,
int num_messages, const struct pri_party_id *caller_id, const char *timestamp,
int message_reference, int message_status)
{
......@@ -1774,8 +1774,8 @@ static unsigned char *enc_etsi_mwi_indicate_message(struct pri *ctrl, unsigned c
msg.operation = ROSE_ETSI_MWIIndicate;
msg.invoke_id = get_invokeid(ctrl);
if (mailbox && mailbox->number.valid) {
pri_copy_party_number_to_q931(&number, &mailbox->number);
if (vm_id && vm_id->number.valid) {
pri_copy_party_number_to_q931(&number, &vm_id->number);
q931_copy_number_to_rose(ctrl, &msg.args.etsi.MWIIndicate.controlling_user_number,
&number);
}
......@@ -1814,11 +1814,11 @@ static unsigned char *enc_etsi_mwi_indicate_message(struct pri *ctrl, unsigned c
*
* \param ctrl D channel controller.
* \param call Call leg to queue message.
* \param mailbox Controlling party number (NULL if not present).
* \param vm_id Voicemail system number (NULL if not present).
* \param basic_service Basic service enum (-1 if not present).
* \param num_messages NumberOfMessages (-1 if not present).
* \param caller_id Controlling party privided number (NULL if not present).
* \param timestamp Generalized Time format (NULL if not present).
* \param caller_id Party leaving message (NULL if not present).
* \param timestamp When message left. (Generalized Time format, NULL if not present)
* \param message_reference Message reference number (-1 if not present).
* \param message_status Message status: added(0), removed(1).
*
......@@ -1826,14 +1826,14 @@ static unsigned char *enc_etsi_mwi_indicate_message(struct pri *ctrl, unsigned c
* \retval -1 on error.
*/
static int rose_mwi_indicate_encode(struct pri *ctrl, struct q931_call *call,
const struct pri_party_id *mailbox, int basic_service, int num_messages,
const struct pri_party_id *vm_id, int basic_service, int num_messages,
const struct pri_party_id *caller_id, const char *timestamp, int message_reference,
int message_status)
{
unsigned char buffer[255];
unsigned char *end;
end = enc_etsi_mwi_indicate_message(ctrl, buffer, buffer + sizeof(buffer), mailbox,
end = enc_etsi_mwi_indicate_message(ctrl, buffer, buffer + sizeof(buffer), vm_id,
basic_service, num_messages, caller_id, timestamp, message_reference,
message_status);
if (!end) {
......@@ -1843,11 +1843,13 @@ static int rose_mwi_indicate_encode(struct pri *ctrl, struct q931_call *call,
return pri_call_apdu_queue(call, Q931_FACILITY, buffer, end - buffer, NULL);
}
int pri_mwi_indicate(struct pri *ctrl, const struct pri_party_id *mailbox,
int basic_service, int num_messages, const struct pri_party_id *caller_id,
const char *timestamp, int message_reference, int message_status)
int pri_mwi_indicate_v2(struct pri *ctrl, const struct pri_party_id *mailbox,
const struct pri_party_id *vm_id, int basic_service, int num_messages,
const struct pri_party_id *caller_id, const char *timestamp, int message_reference,
int message_status)
{
struct q931_call *call;
struct q931_party_id called;
if (!ctrl) {
return -1;
......@@ -1868,9 +1870,10 @@ int pri_mwi_indicate(struct pri *ctrl, const struct pri_party_id *mailbox,
return -1;
}
if (rose_mwi_indicate_encode(ctrl, call, mailbox, basic_service, num_messages,
pri_copy_party_id_to_q931(&called, mailbox);
if (rose_mwi_indicate_encode(ctrl, call, vm_id, basic_service, num_messages,
caller_id, timestamp, message_reference, message_status)
|| q931_facility(ctrl, call)) {
|| q931_facility_called(ctrl, call, &called)) {
pri_message(ctrl,
"Could not schedule facility message for MWI indicate message.\n");
return -1;
......@@ -1878,6 +1881,14 @@ int pri_mwi_indicate(struct pri *ctrl, const struct pri_party_id *mailbox,
return 0;
}
int pri_mwi_indicate(struct pri *ctrl, const struct pri_party_id *mailbox,
int basic_service, int num_messages, const struct pri_party_id *caller_id,
const char *timestamp, int message_reference, int message_status)
{
return pri_mwi_indicate_v2(ctrl, mailbox, mailbox, basic_service, num_messages,
caller_id, timestamp, message_reference, message_status);
}
/* End MWI */
/* EECT functions */
......
......@@ -980,6 +980,7 @@ 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);
int q931_facility_called(struct pri *ctrl, struct q931_call *call, const struct q931_party_id *called);
const char *q931_call_state_str(enum Q931_CALL_STATE callstate);
const char *msg2str(int msg);
......
......@@ -2342,12 +2342,21 @@ static int receive_called_party_number(int full_ie, struct pri *ctrl, q931_call
return -1;
}
call->called.number.valid = 1;
call->called.number.plan = ie->data[0] & 0x7f;
if (msgtype == Q931_SETUP) {
switch (msgtype) {
case Q931_FACILITY:
if (!q931_is_dummy_call(call)) {
/* Discard the number. */
return 0;
}
/* Fall through */
case Q931_REGISTER:
/* Accept the number for REGISTER only because it is so similar to SETUP. */
case Q931_SETUP:
q931_get_number((unsigned char *) call->called.number.str,
sizeof(call->called.number.str), ie->data + 1, len - 3);
} else if (call->ourcallstate == Q931_CALL_STATE_OVERLAP_RECEIVING) {
break;
case Q931_INFORMATION:
if (call->ourcallstate == Q931_CALL_STATE_OVERLAP_RECEIVING) {
/*
* Since we are receiving overlap digits now, we need to append
* them to any previously received digits in call->called.number.str.
......@@ -2362,6 +2371,13 @@ static int receive_called_party_number(int full_ie, struct pri *ctrl, q931_call
}
strncat(called_end, (char *) ie->data + 1, called_len);
}
break;
default:
/* Discard the number. */
return 0;
}
call->called.number.valid = 1;
call->called.number.plan = ie->data[0] & 0x7f;
q931_get_number((unsigned char *) call->overlap_digits, sizeof(call->overlap_digits),
ie->data + 1, len - 3);
......@@ -5103,6 +5119,35 @@ int q931_facility(struct pri *ctrl, struct q931_call *call)
return send_message(ctrl, call, Q931_FACILITY, facility_ies);
}
/*!
* \brief Send a FACILITY message with the called party number and subaddress ies.
*
* \param ctrl D channel controller.
* \param call Call leg to send message over.
* \param called Called party information to send.
*
* \note
* This function can only be used by the dummy call because the call's called
* structure is used by normal calls to contain persistent information.
*
* \retval 0 on success.
* \retval -1 on error.
*/
int q931_facility_called(struct pri *ctrl, struct q931_call *call, const struct q931_party_id *called)
{
static int facility_called_ies[] = {
Q931_IE_FACILITY,
Q931_CALLED_PARTY_NUMBER,
Q931_CALLED_PARTY_SUBADDR,
-1
};
q931_party_id_copy_to_address(&call->called, called);
libpri_copy_string(call->overlap_digits, call->called.number.str,
sizeof(call->overlap_digits));
return send_message(ctrl, call, Q931_FACILITY, facility_called_ies);
}
int q931_facility_display_name(struct pri *ctrl, struct q931_call *call, const struct q931_party_name *name)
{
int status;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment