Make number not available presentation also set screening to network provided.

Q.951 indicates that when the presentation indicator is "Number not
available due to interworking" for a number then the screening indicator
field should be "Network provided".

Released versions of Asterisk starting with v1.8 relesed before this patch
only recognized the PRES_NUMBER_NOT_AVAILABLE value as an unavailable
number.  This patch improves compatibility as a result.

* Made mask the presentation value for names and numbers from the upper
layer.

* Made pri_mwi_indicate_v2() also call q931_party_id_fixup() for
completeness even though it is a noop in this case.

* Made pri_pres2str() deceoode better.


git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@2284 2fbb986a-6c06-0410-b554-c9c1f0a7f128
This commit is contained in:
Richard Mudgett 2012-03-23 19:35:23 +00:00
parent 17649b363b
commit a7eaec1aaa
4 changed files with 50 additions and 23 deletions

13
pri.c
View File

@ -973,7 +973,7 @@ void pri_copy_party_name_to_q931(struct q931_party_name *q931_name, const struct
q931_party_name_init(q931_name);
if (pri_name->valid) {
q931_name->valid = 1;
q931_name->presentation = pri_name->presentation;
q931_name->presentation = pri_name->presentation & PRI_PRES_RESTRICTION;
q931_name->char_set = pri_name->char_set;
libpri_copy_string(q931_name->str, pri_name->str, sizeof(q931_name->str));
}
@ -992,7 +992,8 @@ void pri_copy_party_number_to_q931(struct q931_party_number *q931_number, const
q931_party_number_init(q931_number);
if (pri_number->valid) {
q931_number->valid = 1;
q931_number->presentation = pri_number->presentation;
q931_number->presentation = pri_number->presentation
& (PRI_PRES_RESTRICTION | PRI_PRES_NUMBER_TYPE);
q931_number->plan = pri_number->plan;
libpri_copy_string(q931_number->str, pri_number->str, sizeof(q931_number->str));
}
@ -1962,13 +1963,14 @@ int pri_sr_set_caller(struct pri_sr *sr, char *caller, char *callername, int cal
q931_party_id_init(&sr->caller);
if (caller) {
sr->caller.number.valid = 1;
sr->caller.number.presentation = callerpres;
sr->caller.number.presentation = callerpres
& (PRI_PRES_RESTRICTION | PRI_PRES_NUMBER_TYPE);
sr->caller.number.plan = callerplan;
libpri_copy_string(sr->caller.number.str, caller, sizeof(sr->caller.number.str));
if (callername) {
sr->caller.name.valid = 1;
sr->caller.name.presentation = callerpres;
sr->caller.name.presentation = callerpres & PRI_PRES_RESTRICTION;
sr->caller.name.char_set = PRI_CHAR_SET_ISO8859_1;
libpri_copy_string(sr->caller.name.str, callername,
sizeof(sr->caller.name.str));
@ -1992,7 +1994,8 @@ int pri_sr_set_redirecting(struct pri_sr *sr, char *num, int plan, int pres, int
q931_party_redirecting_init(&sr->redirecting);
if (num && num[0]) {
sr->redirecting.from.number.valid = 1;
sr->redirecting.from.number.presentation = pres;
sr->redirecting.from.number.presentation = pres
& (PRI_PRES_RESTRICTION | PRI_PRES_NUMBER_TYPE);
sr->redirecting.from.number.plan = plan;
libpri_copy_string(sr->redirecting.from.number.str, num,
sizeof(sr->redirecting.from.number.str));

View File

@ -2219,8 +2219,7 @@ void pri_cc_ptp_request(struct pri *ctrl, q931_call *call, int msgtype, const st
party_a.number.presentation =
PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED;
} else {
party_a.number.presentation =
PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_UNSCREENED;
party_a.number.presentation = PRES_NUMBER_NOT_AVAILABLE;
}
} else {
party_a.number.presentation =

View File

@ -632,6 +632,9 @@ void rose_copy_presented_number_screened_to_q931(struct pri *ctrl,
rose_copy_number_to_q931(ctrl, q931_number,
&rose_presented->screened.number);
break;
case 2: /* numberNotAvailableDueToInterworking */
q931_number->presentation = PRES_NUMBER_NOT_AVAILABLE;
break;
default:
q931_number->presentation |= PRI_PRES_USER_NUMBER_UNSCREENED;
break;
@ -660,6 +663,9 @@ void rose_copy_presented_number_unscreened_to_q931(struct pri *ctrl,
case 3: /* presentationRestrictedNumber */
rose_copy_number_to_q931(ctrl, q931_number, &rose_presented->number);
break;
case 2: /* numberNotAvailableDueToInterworking */
q931_number->presentation = PRES_NUMBER_NOT_AVAILABLE;
break;
default:
break;
}
@ -693,6 +699,9 @@ void rose_copy_presented_address_screened_to_id_q931(struct pri *ctrl,
rose_copy_subaddress_to_q931(ctrl, &q931_address->subaddress,
&rose_presented->screened.subaddress);
break;
case 2: /* numberNotAvailableDueToInterworking */
q931_address->number.presentation = PRES_NUMBER_NOT_AVAILABLE;
break;
default:
q931_address->number.presentation |= PRI_PRES_USER_NUMBER_UNSCREENED;
break;
@ -1871,6 +1880,7 @@ int pri_mwi_indicate_v2(struct pri *ctrl, const struct pri_party_id *mailbox,
}
pri_copy_party_id_to_q931(&called, mailbox);
q931_party_id_fixup(ctrl, &called);
if (rose_mwi_indicate_encode(ctrl, call, vm_id, basic_service, num_messages,
caller_id, timestamp, message_reference, message_status)
|| q931_facility_called(ctrl, call, &called)) {
@ -4564,8 +4574,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
party_id.number.presentation =
PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED;
} else {
party_id.number.presentation =
PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_UNSCREENED;
party_id.number.presentation = PRES_NUMBER_NOT_AVAILABLE;
}
} else {
q931_party_number_init(&party_id.number);

44
q931.c
View File

@ -432,7 +432,7 @@ void q931_party_name_init(struct q931_party_name *name)
void q931_party_number_init(struct q931_party_number *number)
{
number->valid = 0;
number->presentation = PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_UNSCREENED;
number->presentation = PRES_NUMBER_NOT_AVAILABLE;
number->plan = (PRI_TON_UNKNOWN << 4) | PRI_NPI_E163_E164;
number->str[0] = '\0';
}
@ -730,7 +730,7 @@ void q931_party_name_copy_to_pri(struct pri_party_name *pri_name, const struct q
pri_name->valid = 0;
pri_name->presentation = PRI_PRES_UNAVAILABLE;
pri_name->char_set = PRI_CHAR_SET_ISO8859_1;
pri_name->str[0] = 0;
pri_name->str[0] = '\0';
}
}
@ -751,9 +751,9 @@ void q931_party_number_copy_to_pri(struct pri_party_number *pri_number, const st
libpri_copy_string(pri_number->str, q931_number->str, sizeof(pri_number->str));
} else {
pri_number->valid = 0;
pri_number->presentation = PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_UNSCREENED;
pri_number->presentation = PRES_NUMBER_NOT_AVAILABLE;
pri_number->plan = (PRI_TON_UNKNOWN << 4) | PRI_NPI_E163_E164;
pri_number->str[0] = 0;
pri_number->str[0] = '\0';
}
}
@ -854,7 +854,8 @@ void q931_party_id_fixup(const struct pri *ctrl, struct q931_party_id *id)
case PRI_SWITCH_DMS100:
case PRI_SWITCH_ATT4ESS:
/* Doesn't like certain presentation types */
if (id->number.valid && !(id->number.presentation & 0x7c)) {
if (id->number.valid
&& (id->number.presentation & PRI_PRES_RESTRICTION) == PRI_PRES_ALLOWED) {
/* i.e., If presentation is allowed it must be a network number */
id->number.presentation = PRES_ALLOWED_NETWORK_NUMBER;
}
@ -932,6 +933,9 @@ int q931_party_id_presentation(const struct q931_party_id *id)
if (name_priority < number_priority) {
number_value = name_value;
}
if (number_value == PRI_PRES_UNAVAILABLE) {
return PRES_NUMBER_NOT_AVAILABLE;
}
return number_value | number_screening;
}
@ -2043,16 +2047,28 @@ static char *cpc2str(int plan)
char *pri_pres2str(int pres)
{
static struct msgtype press[] = {
{ PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, "Presentation permitted, user number not screened" },
{ PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, "Presentation permitted, user number passed network screening" },
{ PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, "Presentation permitted, user number failed network screening" },
{ PRES_ALLOWED_NETWORK_NUMBER, "Presentation allowed of network provided number" },
{ PRES_PROHIB_USER_NUMBER_NOT_SCREENED, "Presentation prohibited, user number not screened" },
{ PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, "Presentation prohibited, user number passed network screening" },
{ PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, "Presentation prohibited, user number failed network screening" },
{ PRES_PROHIB_NETWORK_NUMBER, "Presentation prohibited of network provided number" },
{ PRES_NUMBER_NOT_AVAILABLE, "Number not available" },
{ PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED, "Presentation allowed, User-provided, not screened" },
{ PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_PASSED_SCREEN, "Presentation allowed, User-provided, verified and passed" },
{ PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_FAILED_SCREEN, "Presentation allowed, User-provided, verified and failed" },
{ PRI_PRES_ALLOWED | PRI_PRES_NETWORK_NUMBER, "Presentation allowed, Network provided" },
{ PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED, "Presentation restricted, User-provided, not screened" },
{ PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_PASSED_SCREEN, "Presentation restricted, User-provided, verified and passed" },
{ PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_FAILED_SCREEN, "Presentation restricted, User-provided, verified and failed" },
{ PRI_PRES_RESTRICTED | PRI_PRES_NETWORK_NUMBER, "Presentation restricted, Network provided" },
{ PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_UNSCREENED, "Number not available, User-provided, not screened" },
{ PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_PASSED_SCREEN, "Number not available, User-provided, verified and passed" },
{ PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_FAILED_SCREEN, "Number not available, User-provided, verified and failed" },
{ PRI_PRES_UNAVAILABLE | PRI_PRES_NETWORK_NUMBER, "Number not available, Network provided" },
{ PRI_PRES_RESERVED | PRI_PRES_USER_NUMBER_UNSCREENED, "Reserved, User-provided, not screened" },
{ PRI_PRES_RESERVED | PRI_PRES_USER_NUMBER_PASSED_SCREEN, "Reserved, User-provided, verified and passed" },
{ PRI_PRES_RESERVED | PRI_PRES_USER_NUMBER_FAILED_SCREEN, "Reserved, User-provided, verified and failed" },
{ PRI_PRES_RESERVED | PRI_PRES_NETWORK_NUMBER, "Reserved, Network provided" },
};
pres &= (PRI_PRES_RESTRICTION & PRI_PRES_NUMBER_TYPE);
return code2str(pres, press, sizeof(press) / sizeof(press[0]));
}