Delay processing of facility ie's after all other ie's are processed.
* Some ROSE message processing depends on the presence of other ies. The DivertingLegInformation1, and 3 messages will be used as the default connected line number if the connected number ie is not present. The redirecting number ie is used as a default to the redirecting number in the DivertingLegInformation2 message if the ROSE message does not contain it and the redirecting number ie is present. * Some ROSE message processing depends upon other ie values. The StatusRequest, CCBS-T-Call, and CcRingout messages collectively need the BC, HLC, LLC, called number, called subaddress, calling number, and calling subaddress ie information to be available. git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@1345 2fbb986a-6c06-0410-b554-c9c1f0a7f128
This commit is contained in:
@@ -3555,27 +3555,31 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
break;
|
||||
#endif /* Not handled yet */
|
||||
case ROSE_ETSI_DivertingLegInformation1:
|
||||
/*
|
||||
* Unless otherwise indicated by CONNECT, the divertedToNumber will be
|
||||
* the remote_id.number.
|
||||
*
|
||||
* Fortunately, the connected number ie is supposed to come after the
|
||||
* facility ie in the same message so it will be processed later.
|
||||
*/
|
||||
if (invoke->args.etsi.DivertingLegInformation1.diverted_to_present) {
|
||||
rose_copy_presented_number_unscreened_to_q931(ctrl, &call->remote_id.number,
|
||||
rose_copy_presented_number_unscreened_to_q931(ctrl, &party_id.number,
|
||||
&invoke->args.etsi.DivertingLegInformation1.diverted_to);
|
||||
/*
|
||||
* We set the presentation value since the sender cannot know the
|
||||
* presentation value preference of the destination party.
|
||||
*/
|
||||
if (call->remote_id.number.str[0]) {
|
||||
call->remote_id.number.presentation =
|
||||
if (party_id.number.str[0]) {
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
q931_party_number_init(&call->remote_id.number);
|
||||
call->remote_id.number.valid = 1;
|
||||
q931_party_number_init(&party_id.number);
|
||||
party_id.number.valid = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unless otherwise indicated by CONNECT, the divertedToNumber will be
|
||||
* the remote_id.number.
|
||||
*/
|
||||
if (!call->connected_number_in_message) {
|
||||
call->remote_id.number = party_id.number;
|
||||
}
|
||||
|
||||
/* divertedToNumber is put in redirecting.to.number */
|
||||
@@ -3589,7 +3593,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
|
||||
break;
|
||||
case 2: /* notificationWithDivertedToNr */
|
||||
call->redirecting.to.number = call->remote_id.number;
|
||||
call->redirecting.to.number = party_id.number;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3616,7 +3620,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
rose_copy_presented_number_unscreened_to_q931(ctrl,
|
||||
&call->redirecting.from.number,
|
||||
&invoke->args.etsi.DivertingLegInformation2.diverting);
|
||||
} else {
|
||||
} else if (!call->redirecting_number_in_message) {
|
||||
q931_party_number_init(&call->redirecting.from.number);
|
||||
call->redirecting.from.number.valid = 1;
|
||||
}
|
||||
@@ -3636,15 +3640,14 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
/*
|
||||
* Unless otherwise indicated by CONNECT, this will be the
|
||||
* remote_id.number.presentation.
|
||||
*
|
||||
* Fortunately, the connected number ie is supposed to come after the
|
||||
* facility ie in the same message so it will be processed later.
|
||||
*/
|
||||
if (!invoke->args.etsi.DivertingLegInformation3.presentation_allowed_indicator) {
|
||||
call->remote_id.number.presentation =
|
||||
PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
|
||||
call->redirecting.to.number.presentation =
|
||||
PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
|
||||
if (!call->connected_number_in_message) {
|
||||
call->remote_id.number.presentation =
|
||||
PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
|
||||
}
|
||||
}
|
||||
|
||||
switch (call->redirecting.state) {
|
||||
@@ -3949,19 +3952,20 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
&deflection);
|
||||
break;
|
||||
case ROSE_QSIG_DivertingLegInformation1:
|
||||
q931_party_number_init(&party_id.number);
|
||||
rose_copy_number_to_q931(ctrl, &party_id.number,
|
||||
&invoke->args.qsig.DivertingLegInformation1.nominated_number);
|
||||
if (party_id.number.str[0]) {
|
||||
party_id.number.presentation =
|
||||
PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unless otherwise indicated by CONNECT, the nominatedNr will be
|
||||
* the remote_id.number.
|
||||
*
|
||||
* Fortunately, the connected number ie is supposed to come after the
|
||||
* facility ie in the same message so it will be processed later.
|
||||
*/
|
||||
q931_party_number_init(&call->remote_id.number);
|
||||
rose_copy_number_to_q931(ctrl, &call->remote_id.number,
|
||||
&invoke->args.qsig.DivertingLegInformation1.nominated_number);
|
||||
if (call->remote_id.number.str[0]) {
|
||||
call->remote_id.number.presentation =
|
||||
PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED;
|
||||
if (!call->connected_number_in_message) {
|
||||
call->remote_id.number = party_id.number;
|
||||
}
|
||||
|
||||
/* nominatedNr is put in redirecting.to.number */
|
||||
@@ -3975,7 +3979,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
|
||||
break;
|
||||
case QSIG_NOTIFICATION_WITH_DIVERTED_TO_NR:
|
||||
call->redirecting.to.number = call->remote_id.number;
|
||||
call->redirecting.to.number = party_id.number;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -4002,7 +4006,7 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
rose_copy_presented_number_unscreened_to_q931(ctrl,
|
||||
&call->redirecting.from.number,
|
||||
&invoke->args.qsig.DivertingLegInformation2.diverting);
|
||||
} else {
|
||||
} else if (!call->redirecting_number_in_message) {
|
||||
q931_party_number_init(&call->redirecting.from.number);
|
||||
call->redirecting.from.number.valid = 1;
|
||||
}
|
||||
@@ -4042,15 +4046,14 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
/*
|
||||
* Unless otherwise indicated by CONNECT, this will be the
|
||||
* remote_id.number.presentation.
|
||||
*
|
||||
* Fortunately, the connected number ie is supposed to come after the
|
||||
* facility ie in the same message so it will be processed later.
|
||||
*/
|
||||
if (!invoke->args.qsig.DivertingLegInformation3.presentation_allowed_indicator) {
|
||||
call->remote_id.number.presentation =
|
||||
PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
|
||||
call->redirecting.to.number.presentation =
|
||||
PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
|
||||
if (!call->connected_number_in_message) {
|
||||
call->remote_id.number.presentation =
|
||||
PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
|
||||
}
|
||||
}
|
||||
|
||||
/* redirectionName is put in redirecting.to.name */
|
||||
|
||||
@@ -52,6 +52,9 @@ struct pri_sched {
|
||||
/*! Maximum number of scheduled events active at the same time. */
|
||||
#define MAX_SCHED 128
|
||||
|
||||
/*! Maximum number of facility ie's to handle per incoming message. */
|
||||
#define MAX_FACILITY_IES 8
|
||||
|
||||
/*! \brief D channel controller structure */
|
||||
struct pri {
|
||||
int fd; /* File descriptor for D-Channel */
|
||||
@@ -143,6 +146,16 @@ struct pri {
|
||||
|
||||
short last_invoke; /* Last ROSE invoke ID (Valid in master record only) */
|
||||
unsigned char sendfacility;
|
||||
|
||||
/*! For delayed processing of facility ie's. */
|
||||
struct {
|
||||
/*! Array of facility ie locations in the current received message. */
|
||||
q931_ie *ie[MAX_FACILITY_IES];
|
||||
/*! Codeset facility ie found within. */
|
||||
unsigned char codeset[MAX_FACILITY_IES];
|
||||
/*! Number of facility ie's in the array from the current received message. */
|
||||
unsigned char count;
|
||||
} facility;
|
||||
};
|
||||
|
||||
/*! \brief Maximum name length plus null terminator (From ECMA-164) */
|
||||
@@ -469,6 +482,10 @@ struct q931_call {
|
||||
int hold_timer;
|
||||
|
||||
int deflection_in_progress; /*!< CallDeflection for NT PTMP in progress. */
|
||||
/*! TRUE if the connected number ie was in the current received message. */
|
||||
int connected_number_in_message;
|
||||
/*! TRUE if the redirecting number ie was in the current received message. */
|
||||
int redirecting_number_in_message;
|
||||
|
||||
int useruserprotocoldisc;
|
||||
char useruserinfo[256];
|
||||
|
||||
45
q931.c
45
q931.c
@@ -1740,6 +1740,7 @@ static int receive_connected_number(int full_ie, struct pri *ctrl, q931_call *ca
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
call->connected_number_in_message = 1;
|
||||
call->remote_id.number.valid = 1;
|
||||
call->remote_id.number.presentation =
|
||||
PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED;
|
||||
@@ -1824,6 +1825,7 @@ static int receive_redirecting_number(int full_ie, struct pri *ctrl, q931_call *
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
call->redirecting_number_in_message = 1;
|
||||
call->redirecting.from.number.valid = 1;
|
||||
call->redirecting.from.number.presentation =
|
||||
PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED;
|
||||
@@ -2343,6 +2345,25 @@ static int transmit_facility(int full_ie, struct pri *ctrl, q931_call *call, int
|
||||
}
|
||||
|
||||
static int receive_facility(int full_ie, struct pri *ctrl, q931_call *call, int msgtype, q931_ie *ie, int len)
|
||||
{
|
||||
/* Delay processing facility ie's till after all other ie's are processed. */
|
||||
if (MAX_FACILITY_IES <= ctrl->facility.count) {
|
||||
pri_message(ctrl, "!! Too many facility ie's to delay.\n");
|
||||
return -1;
|
||||
}
|
||||
/* Make sure we have enough room for the protocol profile ie octet(s) */
|
||||
if (ie->data + ie->len < ie->data + 2) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Save the facility ie location for delayed decode. */
|
||||
ctrl->facility.ie[ctrl->facility.count] = ie;
|
||||
ctrl->facility.codeset[ctrl->facility.count] = Q931_IE_CODESET((unsigned) full_ie);
|
||||
++ctrl->facility.count;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int process_facility(struct pri *ctrl, q931_call *call, int msgtype, q931_ie *ie)
|
||||
{
|
||||
struct fac_extension_header header;
|
||||
struct rose_message rose;
|
||||
@@ -2416,6 +2437,24 @@ static int receive_facility(int full_ie, struct pri *ctrl, q931_call *call, int
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void q931_handle_facilities(struct pri *ctrl, q931_call *call, int msgtype)
|
||||
{
|
||||
unsigned idx;
|
||||
unsigned codeset;
|
||||
unsigned full_ie;
|
||||
q931_ie *ie;
|
||||
|
||||
for (idx = 0; idx < ctrl->facility.count; ++idx) {
|
||||
ie = ctrl->facility.ie[idx];
|
||||
if (ctrl->debug & PRI_DEBUG_Q931_STATE) {
|
||||
codeset = ctrl->facility.codeset[idx];
|
||||
full_ie = Q931_FULL_IE(codeset, ie->ie);
|
||||
pri_message(ctrl, "-- Delayed processing IE %d (cs%d, %s)\n", ie->ie, codeset, ie2str(full_ie));
|
||||
}
|
||||
process_facility(ctrl, call, msgtype, ie);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -5798,6 +5837,9 @@ int q931_receive(struct pri *ctrl, q931_h *h, int len)
|
||||
}
|
||||
|
||||
/* Preliminary handling */
|
||||
ctrl->facility.count = 0;
|
||||
c->connected_number_in_message = 0;
|
||||
c->redirecting_number_in_message = 0;
|
||||
if ((h->pd == MAINTENANCE_PROTOCOL_DISCRIMINATOR_1) || (h->pd == MAINTENANCE_PROTOCOL_DISCRIMINATOR_2)) {
|
||||
prepare_to_handle_maintenance_message(ctrl, mh, c);
|
||||
} else {
|
||||
@@ -5892,6 +5934,9 @@ int q931_receive(struct pri *ctrl, q931_h *h, int len)
|
||||
}
|
||||
}
|
||||
|
||||
/* Now handle the facility ie's after all the other ie's were processed. */
|
||||
q931_handle_facilities(ctrl, c, mh->msg);
|
||||
|
||||
/* Post handling */
|
||||
if ((h->pd == MAINTENANCE_PROTOCOL_DISCRIMINATOR_1) || (h->pd == MAINTENANCE_PROTOCOL_DISCRIMINATOR_2)) {
|
||||
res = post_handle_maintenance_message(ctrl, h->pd, mh, c);
|
||||
|
||||
Reference in New Issue
Block a user