[svn-commits] rmudgett: branch group/issue14068 r854 - /team/group/issue14068/
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Thu Jun 4 11:46:23 CDT 2009
Author: rmudgett
Date: Thu Jun 4 11:46:19 2009
New Revision: 854
URL: http://svn.asterisk.org/svn-view/libpri?view=rev&rev=854
Log:
Q.SIG COLP feature completed.
* Augmented Q.SIG DivertingLegInformation2 to support multiple diversions.
(Original called number)
* Replaced q931_party_id.status enum with q931_party_id.valid boolean since
the changed value was not needed.
* Fixed enc_qsig_call_transfer_complete() so it can send the new local party name.
* Made the behaviour of DivertingLegInformation1-3 closer to the standard.
* Eliminated the cd_active party and ct_complete party since they are the just
the remote_id party.
* Added handling of the CallTransferUpdate message for join transfer updates.
* Enhanced the libpri party id structure with more information. (valid flag,
separate name and number presentation, name character set)
* Eliminated the connected-line source parameter as it did not do anything.
* Merged the original calling party id into the redirecting party structure.
* Eliminated several added API fields in events. The connected-line and
redirecting subcommands pass the information instead.
Modified:
team/group/issue14068/libpri.h
team/group/issue14068/pri.c
team/group/issue14068/pri_facility.c
team/group/issue14068/pri_internal.h
team/group/issue14068/q931.c
Modified: team/group/issue14068/libpri.h
URL: http://svn.asterisk.org/svn-view/libpri/team/group/issue14068/libpri.h?view=diff&rev=854&r1=853&r2=854
==============================================================================
--- team/group/issue14068/libpri.h (original)
+++ team/group/issue14068/libpri.h Thu Jun 4 11:46:19 2009
@@ -344,41 +344,71 @@
typedef struct q931_call q931_call;
-/*! \brief Connected line update source code */
-enum PRI_CONNECTED_LINE_UPDATE_SOURCE {
- /*! Update for unknown reason (May be interpreted to mean from answer) */
- PRI_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN,
- /*! Update from normal call answering */
- PRI_CONNECTED_LINE_UPDATE_SOURCE_ANSWER,
- /*! Update from call transfer(active) (Party has already answered) */
- PRI_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER,
- /*! Update from call transfer(alerting) (Party has not answered yet) */
- PRI_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER_ALERTING
+/* Name character set enumeration values */
+#define PRI_CHAR_SET_UNKNOWN 0
+#define PRI_CHAR_SET_ISO8859_1 1
+#define PRI_CHAR_SET_WITHDRAWN 2
+#define PRI_CHAR_SET_ISO8859_2 3
+#define PRI_CHAR_SET_ISO8859_3 4
+#define PRI_CHAR_SET_ISO8859_4 5
+#define PRI_CHAR_SET_ISO8859_5 6
+#define PRI_CHAR_SET_ISO8859_7 7
+#define PRI_CHAR_SET_ISO10646_BMPSTRING 8
+#define PRI_CHAR_SET_ISO10646_UTF_8STRING 9
+
+/*! \brief Q.SIG name information. */
+struct pri_party_name {
+ /*! \brief TRUE if the name information is valid/present */
+ int valid;
+ /*!
+ * \brief Q.931 presentation-indicator encoded field
+ * \note Must tollerate the Q.931 screening-indicator field values being present.
+ */
+ int presentation;
+ /*!
+ * \brief Character set the name 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)
+ * \details
+ * Set to iso8859-1(1) if unsure what to use.
+ */
+ int char_set;
+ /*! \brief Name data with null terminator. */
+ char str[64];
+};
+
+struct pri_party_number {
+ /*! \brief TRUE if the number information is valid/present */
+ int valid;
+ /*! \brief Q.931 presentation-indicator and screening-indicator encoded fields */
+ int presentation;
+ /*! \brief Q.931 Type-Of-Number and numbering-plan encoded fields */
+ int plan;
+ /*! \brief Number data with null terminator. */
+ char str[64];
};
/*! \brief Information needed to identify an endpoint in a call. */
struct pri_party_id {
- /*! Subscriber phone number */
- char number[64];
- /*! Subscriber name */
- char name[64];
- /*! Q.931 encoded "type of number" and "numbering plan identification" */
- int number_type;
- /*! Q.931 encoded "presentation indicator" and "screening indicator" */
- int number_presentation;
+ /*! \brief Subscriber name */
+ struct pri_party_name name;
+ /*! \brief Subscriber phone number */
+ struct pri_party_number number;
};
/*! \brief Connected Line/Party information */
struct pri_party_connected_line {
/*! Connected party ID */
struct pri_party_id id;
- /*!
- * \brief Information about the source of an update.
- * \details
- * enum PRI_CONNECTED_LINE_UPDATE_SOURCE values
- * for Normal-Answer, Call-transfer
- */
- int source;
};
/*!
@@ -392,9 +422,13 @@
struct pri_party_id from;
/*! Call is redirecting to a new party (Sent to the caller) */
struct pri_party_id to;
+ /*! Originally called party (in cases of multiple redirects) */
+ struct pri_party_id orig_called;
/*! Number of times the call was redirected */
int count;
- /*! Redirection reasons */
+ /*! Original reason for redirect (in cases of multiple redirects) */
+ int orig_reason;
+ /*! Redirection reason */
int reason;
};
@@ -403,11 +437,11 @@
#define PRI_SUBCMD_CONNECTED_LINE 2
-struct pri_subcmd_connected_line {
+struct pri_subcmd_connected_line {/* BUGBUG eliminate this struct since it is not adding anything useful. */
struct pri_party_connected_line party;
};
-struct pri_subcmd_redirecting {
+struct pri_subcmd_redirecting {/* BUGBUG eliminate this struct since it is not adding anything useful. */
struct pri_party_redirecting party;
};
@@ -419,11 +453,11 @@
char reserve_space[512];
struct pri_subcmd_connected_line connected_line;
struct pri_subcmd_redirecting redirecting;
- };
+ } u;
};
/* Max number of subcommands per event message */
-#define PRI_MAX_SUBCOMMANDS 6
+#define PRI_MAX_SUBCOMMANDS 8
struct pri_subcommands {
int counter_subcmd;
@@ -454,10 +488,6 @@
int progressmask;
q931_call *call;
char useruserinfo[260]; /* User->User info */
- char calledname[256];
- char callednum[256];
- int calledpres;
- int calledplan;
struct pri_subcommands *subcmds;
} pri_event_ringing;
@@ -469,11 +499,6 @@
int progressmask;
q931_call *call;
char useruserinfo[260]; /* User->User info */
- char connectednum[256];
- char connectedname[256];
- int connectedpres;
- int connectedplan;
- int source;
struct pri_subcommands *subcmds;
} pri_event_answer;
@@ -533,8 +558,6 @@
char origcallednum[256];
int callingplanorigcalled; /* Dialing plan of Originally Called Number */
int origredirectingreason;
- int redirectingpres;
- int redirectingcount;
struct pri_subcommands *subcmds;
} pri_event_ring;
@@ -704,11 +727,17 @@
Set non-isdn to non-zero if you are not connecting to ISDN equipment */
int pri_answer(struct pri *pri, q931_call *call, int channel, int nonisdn);
-/*! \brief Give connected line information to a call */
-int pri_connected_line_update(struct pri *pri, q931_call *call, struct pri_party_connected_line *connected);
-
-/*! \brief Give redirection information to a call */
-int pri_redirecting_update(struct pri *pri, q931_call *call, struct pri_party_redirecting *redirecting);
+/*!
+ * \brief Give connected line information to a call
+ * \note Could be used instead of pri_sr_set_caller() before calling pri_setup().
+ */
+int pri_connected_line_update(struct pri *pri, q931_call *call, const struct pri_party_connected_line *connected);
+
+/*!
+ * \brief Give redirection information to a call
+ * \note Should be used instead of pri_sr_set_redirecting() before calling pri_setup().
+ */
+int pri_redirecting_update(struct pri *pri, q931_call *call, const struct pri_party_redirecting *redirecting);
/* Set CRV reference for GR-303 calls */
@@ -764,9 +793,11 @@
int pri_sr_set_channel(struct pri_sr *sr, int channel, int exclusive, int nonisdn);
int pri_sr_set_bearer(struct pri_sr *sr, int transmode, int userl1);
int pri_sr_set_called(struct pri_sr *sr, char *called, int calledplan, int complete);
+/*! \note Use pri_connected_line_update() instead to pass more precise caller information. */
int pri_sr_set_caller(struct pri_sr *sr, char *caller, char *callername, int callerplan, int callerpres);
+/*! \note Use pri_redirecting_update() instead to pass more precise redirecting information. */
int pri_sr_set_redirecting(struct pri_sr *sr, char *num, int plan, int pres, int reason);
-void pri_sr_set_redirecting_name(struct pri_sr *sr, char *name);
+
#define PRI_USER_USER_TX
/* Set the user user field. Warning! don't send binary data accross this field */
void pri_sr_set_useruser(struct pri_sr *sr, const char *userchars);
Modified: team/group/issue14068/pri.c
URL: http://svn.asterisk.org/svn-view/libpri/team/group/issue14068/pri.c?view=diff&rev=854&r1=853&r2=854
==============================================================================
--- team/group/issue14068/pri.c (original)
+++ team/group/issue14068/pri.c Thu Jun 4 11:46:19 2009
@@ -560,142 +560,181 @@
return q931_connect(pri, call, channel, nonisdn);
}
-int pri_connected_line_update(struct pri *pri, q931_call *call, struct pri_party_connected_line *connected)
-{
- if (!pri || !call)
- return -1;
-
- call->local_id.number.status = Q931_PARTY_DATA_STATUS_CHANGED;
- call->local_id.number.presentation = connected->id.number_presentation;
- call->local_id.number.plan = connected->id.number_type;
- libpri_copy_string(call->local_id.number.str, connected->id.number,
- sizeof(call->local_id.number.str));
-
- if (connected->id.name[0]) {
- call->local_id.name.status = Q931_PARTY_DATA_STATUS_CHANGED;
- call->local_id.name.presentation = connected->id.number_presentation;
- call->local_id.name.char_set = 1; /* iso8859-1 */
- libpri_copy_string(call->local_id.name.str, connected->id.name,
- sizeof(call->local_id.name.str));
- } else {
- q931_party_name_init(&call->local_id.name);
- }
-
- if (pri->switchtype == PRI_SWITCH_QSIG) {
- switch (call->ourcallstate) {
- case Q931_CALL_STATE_ACTIVE:
- /* immediately send callTransferComplete APDU, callStatus=answered(0) */
- qsig_initiate_call_transfer_complete(pri, call, 0);
- break;
- case Q931_CALL_STATE_OVERLAP_RECEIVING:
- case Q931_CALL_STATE_INCOMING_CALL_PROCEEDING:
- /* queue updates for next ALERTING */
- if (call->local_id.name.str[0]) {
- /* queue connectedName to be send with next Q931_ALERTING */
- rose_called_name_encode(pri, call, Q931_ALERTING);
- }
-
- if (call->redirecting.state != DIVERTEDSTATE_NONE) {
- call->redirecting.to = call->local_id;
-
- if ((call->redirecting.state == DIVERTEDSTATE_DIVERTED) && call->redirecting.to.number.str[0]) {
- /* immediately send divertingLegInformation1 APDU */
- qsig_initiate_diverting_leg_information1(pri, call);
- call->redirecting.state = DIVERTEDSTATE_DIVLEGINFO1SEND;
- }
- if ((call->redirecting.state == DIVERTEDSTATE_DIVLEGINFO1SEND) && call->redirecting.to.name.str[0]) {
- /* queue divertingLegInformation3 to be send with next Q931_ALERTING */
- rose_diverting_leg_information3_encode(pri, call, Q931_ALERTING);
- call->redirecting.state = DIVERTEDSTATE_DIVLEGINFO3SEND;
- }
- }
- break;
- case Q931_CALL_STATE_CALL_RECEIVED:
- /* queue updates for next CONNECT */
- if (call->local_id.name.str[0] && ((call->redirecting.state == DIVERTEDSTATE_NONE) || (call->redirecting.state == DIVERTEDSTATE_DIVLEGINFO3SEND))) {
- /* queue connectedName to be send with next Q931_CONNECT */
- rose_connected_name_encode(pri, call, Q931_CONNECT);
- }
-
- if (call->redirecting.state != DIVERTEDSTATE_NONE) {
- call->redirecting.to = call->local_id;
-
- if ((call->redirecting.state == DIVERTEDSTATE_DIVERTED) && call->redirecting.to.number.str[0]) {
- /* queue divertingLegInformation1 to be send with next Q931_FACILITY */
- rose_diverting_leg_information1_encode(pri, call);
- call->redirecting.state = DIVERTEDSTATE_DIVLEGINFO1SEND;
-
- if (call->redirecting.to.name.str[0]) {
- /* queue divertingLegInformation3 to be send with next Q931_FACILITY */
- rose_diverting_leg_information3_encode(pri, call, Q931_FACILITY);
- call->redirecting.state = DIVERTEDSTATE_DIVLEGINFO3SEND;
- }
-
- /* immediately send Q931_FACILITY */
- if (q931_facility(pri, call)) {
- pri_message(pri, "Could not schedule facility message for divertingLegInfo1+3\n");
- }
- }
- if ((call->redirecting.state == DIVERTEDSTATE_DIVLEGINFO1SEND) && call->redirecting.to.name.str[0]) {
- /* queue divertingLegInformation3 to be send with next Q931_CONNECT */
- rose_diverting_leg_information3_encode(pri, call, Q931_CONNECT);
- call->redirecting.state = DIVERTEDSTATE_DIVLEGINFO3SEND;
- }
- }
- break;
- }
- }
-
- return 0;
-}
-
-int pri_redirecting_update(struct pri *pri, q931_call *call, struct pri_party_redirecting *redirecting)
-{
- if (!pri || !call)
- return -1;
-
- call->redirecting.to.number.status = Q931_PARTY_DATA_STATUS_CHANGED;
- call->redirecting.to.number.presentation = redirecting->to.number_presentation;
- call->redirecting.to.number.plan = redirecting->to.number_type;
- libpri_copy_string(call->redirecting.to.number.str, redirecting->to.number,
- sizeof(call->redirecting.to.number.str));
-
- if (redirecting->to.name[0]) {
- call->redirecting.to.name.status = Q931_PARTY_DATA_STATUS_CHANGED;
- call->redirecting.to.name.presentation = redirecting->to.number_presentation;
- call->redirecting.to.name.char_set = 1; /* iso8859-1 */
- libpri_copy_string(call->redirecting.to.name.str, redirecting->to.name,
- sizeof(call->redirecting.to.name.str));
- } else {
- q931_party_name_init(&call->redirecting.to.name);
- }
- call->redirecting.reason = redirecting->reason;
-
- if (pri->switchtype == PRI_SWITCH_QSIG) {
- switch (call->ourcallstate) {
- case Q931_CALL_STATE_ACTIVE:
- /* immediately send callTransferComplete APDU, callStatus=alerting(1) */
- qsig_initiate_call_transfer_complete(pri, call, 1);
- break;
- case Q931_CALL_STATE_OVERLAP_RECEIVING:
- case Q931_CALL_STATE_INCOMING_CALL_PROCEEDING:
- call->redirecting.state = DIVERTEDSTATE_DIVERTED;
-
- if (call->redirecting.to.number.str[0]) {
- /* immediately send divertingLegInformation1 APDU */
- qsig_initiate_diverting_leg_information1(pri, call);
- call->redirecting.state = DIVERTEDSTATE_DIVLEGINFO1SEND;
- }
- if ((call->redirecting.state == DIVERTEDSTATE_DIVLEGINFO1SEND) && call->redirecting.to.name.str[0]) {
- /* queue divertingLegInformation3 to be send with next Q931_ALERTING */
- rose_diverting_leg_information3_encode(pri, call, Q931_ALERTING);
- call->redirecting.state = DIVERTEDSTATE_DIVLEGINFO3SEND;
+/*!
+ * \internal
+ * \brief Copy the PRI party name to the Q.931 party name structure.
+ *
+ * \param q931_name Q.931 party name structure
+ * \param pri_name PRI party name structure
+ *
+ * \return Nothing
+ */
+static void pri_copy_party_name_to_q931(struct q931_party_name *q931_name, const struct pri_party_name *pri_name)
+{
+ q931_party_name_init(q931_name);
+ if (pri_name->valid) {
+ q931_name->valid = 1;
+ q931_name->presentation = pri_name->presentation;
+ q931_name->char_set = pri_name->char_set;
+ libpri_copy_string(q931_name->str, pri_name->str, sizeof(q931_name->str));
+ }
+}
+
+/*!
+ * \internal
+ * \brief Copy the PRI party number to the Q.931 party number structure.
+ *
+ * \param ctrl D channel controller.
+ * \param q931_number Q.931 party number structure
+ * \param pri_number PRI party number structure
+ *
+ * \return Nothing
+ */
+static void pri_copy_party_number_to_q931(struct pri *ctrl, struct q931_party_number *q931_number, const struct pri_party_number *pri_number)
+{
+ q931_party_number_init(q931_number);
+ if (pri_number->valid) {
+ q931_number->valid = 1;
+ q931_number->presentation = pri_number->presentation;
+ switch (ctrl->switchtype) {
+ case PRI_SWITCH_DMS100:
+ case PRI_SWITCH_ATT4ESS:
+ /* Doesn't like certain presentation types */
+ if (!(q931_number->presentation & 0x7c)) {
+ q931_number->presentation = PRES_ALLOWED_NETWORK_NUMBER;
}
break;
default:
- pri_message(pri, "Redirecting update in state %d\n", call->ourcallstate);
break;
}
+ q931_number->plan = pri_number->plan;
+ libpri_copy_string(q931_number->str, pri_number->str, sizeof(q931_number->str));
+ }
+}
+
+/*!
+ * \internal
+ * \brief Copy the PRI party id to the Q.931 party id structure.
+ *
+ * \param ctrl D channel controller.
+ * \param q931_id Q.931 party id structure
+ * \param pri_id PRI party id structure
+ *
+ * \return Nothing
+ */
+static void pri_copy_party_id_to_q931(struct pri *ctrl, struct q931_party_id *q931_id, const struct pri_party_id *pri_id)
+{
+ pri_copy_party_name_to_q931(&q931_id->name, &pri_id->name);
+ pri_copy_party_number_to_q931(ctrl, &q931_id->number, &pri_id->number);
+}
+
+int pri_connected_line_update(struct pri *ctrl, q931_call *call, const struct pri_party_connected_line *connected)
+{
+ struct q931_party_id party_id;
+
+ if (!ctrl || !call) {
+ return -1;
+ }
+
+ pri_copy_party_id_to_q931(ctrl, &party_id, &connected->id);
+ if (!q931_party_id_cmp(&party_id, &call->local_id)) {
+ /* The local party information did not change so do nothing. */
+ return 0;
+ }
+ call->local_id = party_id;
+
+ switch (ctrl->switchtype) {
+ case PRI_SWITCH_QSIG:
+ switch (call->ourcallstate) {
+ case Q931_CALL_STATE_CALL_INITIATED:
+ case Q931_CALL_STATE_OVERLAP_SENDING:
+ case Q931_CALL_STATE_OUTGOING_CALL_PROCEEDING:
+ case Q931_CALL_STATE_CALL_DELIVERED:
+ /*
+ * The local party transferred to someone else before
+ * the remote end answered.
+ */
+ case Q931_CALL_STATE_ACTIVE:
+ /* Immediately send CallTransferComplete APDU, callStatus=answered(0) */
+ qsig_initiate_call_transfer_complete(ctrl, call, 0);
+ break;
+ default:
+ /* Just save the data for further developments. */
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+int pri_redirecting_update(struct pri *ctrl, q931_call *call, const struct pri_party_redirecting *redirecting)
+{
+ if (!ctrl || !call) {
+ return -1;
+ }
+
+ /* Save redirecting.to information and reason. */
+ pri_copy_party_id_to_q931(ctrl, &call->redirecting.to, &redirecting->to);
+ call->redirecting.reason = redirecting->reason;
+
+ switch (call->ourcallstate) {
+ case Q931_CALL_STATE_NULL:
+ /* Save the remaining redirecting information before we place a call. */
+ pri_copy_party_id_to_q931(ctrl, &call->redirecting.from, &redirecting->from);
+ pri_copy_party_id_to_q931(ctrl, &call->redirecting.orig_called, &redirecting->orig_called);
+ call->redirecting.orig_reason = redirecting->orig_reason;
+ if (redirecting->count <= 0) {
+ if (call->redirecting.from.number.valid) {
+ call->redirecting.count = 1;
+ } else {
+ call->redirecting.count = 0;
+ }
+ } else if (redirecting->count < PRI_MAX_REDIRECTS) {
+ call->redirecting.count = redirecting->count;
+ } else {
+ call->redirecting.count = PRI_MAX_REDIRECTS;
+ }
+ break;
+ case Q931_CALL_STATE_OVERLAP_RECEIVING:
+ case Q931_CALL_STATE_INCOMING_CALL_PROCEEDING:
+ case Q931_CALL_STATE_CALL_RECEIVED:
+ /* This is an incoming call that has not connected yet. */
+ if (!call->redirecting.to.number.valid) {
+ /* Not being redirected toward valid number data. Ignore. */
+ break;
+ }
+
+ switch (ctrl->switchtype) {
+ case PRI_SWITCH_QSIG:
+ if (call->redirecting.state != Q931_REDIRECTING_STATE_PENDING_TX_DIV_LEG_3
+ || strcmp(call->redirecting.to.number.str, call->called_number.str) != 0) {
+ /* immediately send divertingLegInformation1 APDU */
+ if (rose_diverting_leg_information1_encode(ctrl, call)
+ || q931_facility(ctrl, call)) {
+ pri_message(ctrl,
+ "Could not schedule facility message for divertingLegInfo1\n");
+ }
+ }
+ call->redirecting.state = Q931_REDIRECTING_STATE_IDLE;
+
+ /* immediately send divertingLegInformation3 APDU */
+ if (rose_diverting_leg_information3_encode(ctrl, call, Q931_FACILITY)
+ || q931_facility(ctrl, call)) {
+ pri_message(ctrl,
+ "Could not schedule facility message for divertingLegInfo3\n");
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ pri_message(ctrl, "Ignored redirecting update because call in state %s(%d).\n",
+ q931_call_state_str(call->ourcallstate), call->ourcallstate);
+ break;
}
return 0;
@@ -1094,8 +1133,3 @@
sr->redirectingreason = reason;
return 0;
}
-
-void pri_sr_set_redirecting_name(struct pri_sr *sr, char *name)
-{
- sr->redirectingname = name;
-}
Modified: team/group/issue14068/pri_facility.c
URL: http://svn.asterisk.org/svn-view/libpri/team/group/issue14068/pri_facility.c?view=diff&rev=854&r1=853&r2=854
==============================================================================
--- team/group/issue14068/pri_facility.c (original)
+++ team/group/issue14068/pri_facility.c Thu Jun 4 11:46:19 2009
@@ -597,31 +597,34 @@
msg.operation = ROSE_QSIG_DivertingLegInformation2;
msg.invoke_id = get_invokeid(ctrl);
- /* diversionCounter always is 1 because other isn't available in the current design */
- msg.args.qsig.DivertingLegInformation2.diversion_counter = 1;
+ /* diversionCounter is the redirecting.count */
+ msg.args.qsig.DivertingLegInformation2.diversion_counter = call->redirecting.count;
msg.args.qsig.DivertingLegInformation2.diversion_reason =
redirectingreason_from_q931(ctrl, call->redirecting.reason);
/* divertingNr is the redirecting.from.number */
msg.args.qsig.DivertingLegInformation2.diverting_present = 1;
- msg.args.qsig.DivertingLegInformation2.diverting.presentation =
- presentation_from_q931(ctrl, call->redirecting.from.number.presentation,
- call->redirecting.from.number.str[0]);
- msg.args.qsig.DivertingLegInformation2.diverting.number.plan =
- numbering_plan_from_q931(ctrl, call->redirecting.from.number.plan);
- msg.args.qsig.DivertingLegInformation2.diverting.number.ton =
- typeofnumber_from_q931(ctrl, call->redirecting.from.number.plan);
- libpri_copy_string((char *)
- msg.args.qsig.DivertingLegInformation2.diverting.number.str,
- call->redirecting.from.number.str,
- sizeof(msg.args.qsig.DivertingLegInformation2.diverting.number.str));
- msg.args.qsig.DivertingLegInformation2.diverting.number.length =
- strlen((char *) msg.args.qsig.DivertingLegInformation2.diverting.number.str);
+ if (call->redirecting.from.number.valid) {
+ msg.args.qsig.DivertingLegInformation2.diverting.presentation =
+ presentation_from_q931(ctrl, call->redirecting.from.number.presentation,
+ call->redirecting.from.number.str[0]);
+ msg.args.qsig.DivertingLegInformation2.diverting.number.plan =
+ numbering_plan_from_q931(ctrl, call->redirecting.from.number.plan);
+ msg.args.qsig.DivertingLegInformation2.diverting.number.ton =
+ typeofnumber_from_q931(ctrl, call->redirecting.from.number.plan);
+ libpri_copy_string((char *)
+ msg.args.qsig.DivertingLegInformation2.diverting.number.str,
+ call->redirecting.from.number.str,
+ sizeof(msg.args.qsig.DivertingLegInformation2.diverting.number.str));
+ msg.args.qsig.DivertingLegInformation2.diverting.number.length =
+ strlen((char *) msg.args.qsig.DivertingLegInformation2.diverting.number.str);
+ } else {
+ msg.args.qsig.DivertingLegInformation2.diverting.presentation = 2;/* numberNotAvailableDueToInterworking */
+ }
/* redirectingName is the redirecting.from.name */
- if (call->redirecting.from.name.status != Q931_PARTY_DATA_STATUS_INVALID) {
- call->redirecting.from.name.status = Q931_PARTY_DATA_STATUS_VALID;
+ if (call->redirecting.from.name.valid) {
msg.args.qsig.DivertingLegInformation2.redirecting_name_present = 1;
msg.args.qsig.DivertingLegInformation2.redirecting_name.presentation =
qsig_name_presentation_from_q931(ctrl,
@@ -637,6 +640,53 @@
msg.args.qsig.DivertingLegInformation2.redirecting_name.data);
}
+ if (1 < call->redirecting.count) {
+ msg.args.qsig.DivertingLegInformation2.original_diversion_reason_present = 1;
+ msg.args.qsig.DivertingLegInformation2.original_called_present = 1;
+ if (call->redirecting.orig_called.number.valid) {
+ msg.args.qsig.DivertingLegInformation2.original_diversion_reason =
+ redirectingreason_from_q931(ctrl, call->redirecting.orig_reason);
+
+ /* originalCalledNr is the redirecting.orig_called.number */
+ msg.args.qsig.DivertingLegInformation2.original_called.presentation =
+ presentation_from_q931(ctrl, call->redirecting.orig_called.number.presentation,
+ call->redirecting.orig_called.number.str[0]);
+ msg.args.qsig.DivertingLegInformation2.original_called.number.plan =
+ numbering_plan_from_q931(ctrl, call->redirecting.orig_called.number.plan);
+ msg.args.qsig.DivertingLegInformation2.original_called.number.ton =
+ typeofnumber_from_q931(ctrl, call->redirecting.orig_called.number.plan);
+ libpri_copy_string((char *)
+ msg.args.qsig.DivertingLegInformation2.original_called.number.str,
+ call->redirecting.orig_called.number.str,
+ sizeof(msg.args.qsig.DivertingLegInformation2.original_called.number.str));
+ msg.args.qsig.DivertingLegInformation2.original_called.number.length =
+ strlen((char *)
+ msg.args.qsig.DivertingLegInformation2.original_called.number.str);
+ } else {
+ msg.args.qsig.DivertingLegInformation2.original_diversion_reason =
+ QSIG_DIVERT_REASON_UNKNOWN;
+ msg.args.qsig.DivertingLegInformation2.original_called.presentation = 2;/* numberNotAvailableDueToInterworking */
+ }
+
+ /* originalCalledName is the redirecting.orig_called.name */
+ if (call->redirecting.orig_called.name.valid) {
+ msg.args.qsig.DivertingLegInformation2.original_called_name_present = 1;
+ msg.args.qsig.DivertingLegInformation2.original_called_name.presentation =
+ qsig_name_presentation_from_q931(ctrl,
+ call->redirecting.orig_called.name.presentation,
+ call->redirecting.orig_called.name.str[0]);
+ msg.args.qsig.DivertingLegInformation2.original_called_name.char_set =
+ call->redirecting.orig_called.name.char_set;
+ libpri_copy_string((char *)
+ msg.args.qsig.DivertingLegInformation2.original_called_name.data,
+ call->redirecting.orig_called.name.str,
+ sizeof(msg.args.qsig.DivertingLegInformation2.original_called_name.data));
+ msg.args.qsig.DivertingLegInformation2.original_called_name.length =
+ strlen((char *)
+ msg.args.qsig.DivertingLegInformation2.original_called_name.data);
+ }
+ }
+
pos = rose_encode_invoke(ctrl, pos, end, &msg);
return pos;
@@ -704,8 +754,7 @@
msg.args.qsig.DivertingLegInformation3.presentation_allowed_indicator = 1; /* TRUE */
/* redirectionName is the redirecting.to.name */
- if (call->redirecting.to.name.status != Q931_PARTY_DATA_STATUS_INVALID) {
- call->redirecting.to.name.status = Q931_PARTY_DATA_STATUS_VALID;
+ if (call->redirecting.to.name.valid) {
msg.args.qsig.DivertingLegInformation3.redirection_name_present = 1;
msg.args.qsig.DivertingLegInformation3.redirection_name.presentation =
qsig_name_presentation_from_q931(ctrl,
@@ -979,7 +1028,7 @@
unsigned char *end;
int mymessage;
- if (call->local_id.name.status == Q931_PARTY_DATA_STATUS_INVALID) {
+ if (!call->local_id.name.valid) {
return 0;
}
@@ -1000,7 +1049,6 @@
}
/* CallingName is the local_id.name */
- call->local_id.name.status = Q931_PARTY_DATA_STATUS_VALID;
end = enc_qsig_calling_name(ctrl, buffer, buffer + sizeof(buffer),
&call->local_id.name);
if (!end) {
@@ -1647,8 +1695,8 @@
msg.args.qsig.CallTransferComplete.redirection.screened.number.str);
/* redirectionName is the local_id.name */
- if (call->local_id.name.status != Q931_PARTY_DATA_STATUS_INVALID) {
- call->local_id.name.status = Q931_PARTY_DATA_STATUS_VALID;
+ if (call->local_id.name.valid) {
+ msg.args.qsig.CallTransferComplete.redirection_name_present = 1;
msg.args.qsig.CallTransferComplete.redirection_name.presentation =
qsig_name_presentation_from_q931(ctrl,
call->local_id.name.presentation,
@@ -1917,9 +1965,14 @@
if (pri->switchtype == PRI_SWITCH_QSIG) {
/* For Q.SIG it does network and cpe operations */
- if (call->redirecting.from.number.status != Q931_PARTY_DATA_STATUS_INVALID) {
- call->redirecting.from.number.status = Q931_PARTY_DATA_STATUS_VALID;
+ if (call->redirecting.count) {
rose_diverting_leg_information2_encode(pri, call);
+
+ /*
+ * Expect a DivertingLegInformation3 to update the COLR of the
+ * redirecting-to party we are attempting to call now.
+ */
+ call->redirecting.state = Q931_REDIRECTING_STATE_EXPECTING_RX_DIV_LEG_3;
}
add_callername_facility_ies(pri, call, 1);
return 0;
@@ -2186,6 +2239,9 @@
void rose_handle_invoke(struct pri *ctrl, q931_call *call, q931_ie *ie,
const struct fac_extension_header *header, const struct rose_msg_invoke *invoke)
{
+ struct pri_subcommand *subcmd;
+ struct q931_party_id party_id;
+
switch (invoke->operation) {
#if 0 /* Not handled yet */
case ROSE_ETSI_ActivationDiversion:
@@ -2273,7 +2329,8 @@
#endif /* Not handled yet */
case ROSE_QSIG_CallingName:
/* CallingName is put in remote_id.name */
- call->remote_id.name.status = Q931_PARTY_DATA_STATUS_CHANGED;
+ q931_party_name_init(&call->remote_id.name);
+ call->remote_id.name.valid = 1;
call->remote_id.name.presentation = qsig_name_presentation_for_q931(ctrl,
invoke->args.qsig.CallingName.name.presentation);
call->remote_id.name.char_set = invoke->args.qsig.CallingName.name.char_set;
@@ -2283,17 +2340,28 @@
break;
case ROSE_QSIG_CalledName:
/* CalledName is put in remote_id.name */
- call->remote_id.name.status = Q931_PARTY_DATA_STATUS_CHANGED;
+ q931_party_name_init(&call->remote_id.name);
+ call->remote_id.name.valid = 1;
call->remote_id.name.presentation = qsig_name_presentation_for_q931(ctrl,
invoke->args.qsig.CalledName.name.presentation);
call->remote_id.name.char_set = invoke->args.qsig.CalledName.name.char_set;
libpri_copy_string(call->remote_id.name.str,
(char *) invoke->args.qsig.CalledName.name.data,
sizeof(call->remote_id.name.str));
+
+ /* Setup connected line subcommand */
+ subcmd = q931_alloc_subcommand(ctrl);
+ if (!subcmd) {
+ pri_error(ctrl, "ERROR: Too many facility subcommands\n");
+ break;
+ }
+ subcmd->cmd = PRI_SUBCMD_CONNECTED_LINE;
+ q931_party_id_copy_to_pri(&subcmd->u.connected_line.party.id, &call->remote_id);
break;
case ROSE_QSIG_ConnectedName:
/* ConnectedName is put in remote_id.name */
- call->remote_id.name.status = Q931_PARTY_DATA_STATUS_CHANGED;
+ q931_party_name_init(&call->remote_id.name);
+ call->remote_id.name.valid = 1;
call->remote_id.name.presentation = qsig_name_presentation_for_q931(ctrl,
invoke->args.qsig.ConnectedName.name.presentation);
call->remote_id.name.char_set =
@@ -2333,64 +2401,63 @@
break;
#endif /* Not handled yet */
case ROSE_QSIG_CallTransferActive:
- call->ctactiveflag = 1;
-
- /* connectedAddress is put in ct_active.number */
- call->ct_active.number.status = Q931_PARTY_DATA_STATUS_CHANGED;
- call->ct_active.number.presentation =
+ call->incoming_ct_state = INCOMING_CT_STATE_POST_CONNECTED_LINE;
+
+ /* connectedAddress is put in remote_id.number */
+ q931_party_number_init(&call->remote_id.number);
+ call->remote_id.number.valid = 1;
+ call->remote_id.number.presentation =
presentation_for_q931(ctrl,
invoke->args.qsig.CallTransferActive.connected.presentation);
switch (invoke->args.qsig.CallTransferActive.connected.presentation) {
case 0: /* presentationAllowedAddress */
case 3: /* presentationRestrictedAddress */
- libpri_copy_string(call->ct_active.number.str, (char *)
+ libpri_copy_string(call->remote_id.number.str, (char *)
invoke->args.qsig.CallTransferActive.connected.screened.number.str,
- sizeof(call->ct_active.number.str));
- call->ct_active.number.presentation |=
+ sizeof(call->remote_id.number.str));
+ call->remote_id.number.presentation |=
invoke->args.qsig.CallTransferActive.connected.screened.
screening_indicator;
- call->ct_active.number.plan =
+ call->remote_id.number.plan =
numbering_plan_for_q931(ctrl,
invoke->args.qsig.CallTransferActive.connected.screened.number.plan)
| typeofnumber_for_q931(ctrl,
invoke->args.qsig.CallTransferActive.connected.screened.number.ton);
break;
default:
- call->ct_active.number.str[0] = '\0';
- call->ct_active.number.plan = PRI_UNKNOWN;
- break;
- }
-
- /* connectedName is put in ct_active.name */
- call->ct_active.name.str[0] = '\0';
+ break;
+ }
+
+ /* connectedName is put in remote_id.name */
if (invoke->args.qsig.CallTransferActive.connected_name_present) {
- call->ct_active.name.status = Q931_PARTY_DATA_STATUS_CHANGED;
- call->ct_active.name.presentation = qsig_name_presentation_for_q931(ctrl,
+ q931_party_name_init(&call->remote_id.name);
+ call->remote_id.name.valid = 1;
+ call->remote_id.name.presentation = qsig_name_presentation_for_q931(ctrl,
invoke->args.qsig.CallTransferActive.connected_name.presentation);
- call->ct_active.name.char_set =
+ call->remote_id.name.char_set =
invoke->args.qsig.CallTransferActive.connected_name.char_set;
- libpri_copy_string(call->ct_active.name.str,
+ libpri_copy_string(call->remote_id.name.str,
(char *) invoke->args.qsig.CallTransferActive.connected_name.data,
- sizeof(call->ct_active.name.str));
+ sizeof(call->remote_id.name.str));
}
break;
case ROSE_QSIG_CallTransferComplete:
- call->ctcompleteflag = 1;
-
- /* redirectionNumber is put in ct_complete.number */
- call->ct_complete.number.presentation =
+ /* redirectionNumber is put in remote_id.number */
+ q931_party_number_init(&call->remote_id.number);
+ call->remote_id.number.valid = 1;
+ call->remote_id.number.presentation =
presentation_for_q931(ctrl,
invoke->args.qsig.CallTransferComplete.redirection.presentation);
switch (invoke->args.qsig.CallTransferComplete.redirection.presentation) {
case 0: /* presentationAllowedNumber */
case 3: /* presentationRestrictedNumber */
- libpri_copy_string(call->ct_complete.number.str, (char *)
+ libpri_copy_string(call->remote_id.number.str, (char *)
invoke->args.qsig.CallTransferComplete.redirection.screened.number.str,
- sizeof(call->ct_complete.number.str));
- call->ct_complete.number.presentation |=
+ sizeof(call->remote_id.number.str));
+ call->remote_id.number.presentation |=
invoke->args.qsig.CallTransferComplete.redirection.screened.
screening_indicator;
- call->ct_complete.number.plan =
+ call->remote_id.number.plan =
numbering_plan_for_q931(ctrl,
invoke->args.qsig.CallTransferComplete.redirection.screened.number.
plan)
@@ -2399,54 +2466,82 @@
ton);
break;
default:
- call->ct_complete.number.str[0] = '\0';
- call->ct_complete.number.plan = PRI_UNKNOWN;
- break;
- }
-
- call->ctcompletecallstatus = invoke->args.qsig.CallTransferComplete.call_status;
-
- /* redirectionName is put in ct_complete.name */
- call->ct_complete.name.str[0] = '\0';
+ break;
+ }
+
+ /* redirectionName is put in remote_id.name */
if (invoke->args.qsig.CallTransferComplete.redirection_name_present) {
- call->ct_complete.name.status = Q931_PARTY_DATA_STATUS_CHANGED;
- call->ct_complete.name.presentation = qsig_name_presentation_for_q931(ctrl,
+ q931_party_name_init(&call->remote_id.name);
+ call->remote_id.name.valid = 1;
+ call->remote_id.name.presentation = qsig_name_presentation_for_q931(ctrl,
invoke->args.qsig.CallTransferComplete.redirection_name.presentation);
- call->ct_complete.name.char_set =
+ call->remote_id.name.char_set =
invoke->args.qsig.CallTransferComplete.redirection_name.char_set;
- libpri_copy_string(call->ct_complete.name.str,
+ libpri_copy_string(call->remote_id.name.str,
(char *) invoke->args.qsig.CallTransferComplete.redirection_name.data,
- sizeof(call->ct_complete.name.str));
- }
- break;
-#if 0 /* This was incomplete */
+ sizeof(call->remote_id.name.str));
+ }
+
+ if (invoke->args.qsig.CallTransferComplete.call_status == 1) {
+ /* The remote party for the transfer has not answered yet. */
+ call->incoming_ct_state = INCOMING_CT_STATE_EXPECT_CT_ACTIVE;
+ } else {
+ call->incoming_ct_state = INCOMING_CT_STATE_POST_CONNECTED_LINE;
+ }
+ break;
case ROSE_QSIG_CallTransferUpdate:
+ party_id = call->remote_id;
+
+ /* redirectionNumber is put in party_id.number */
+ q931_party_number_init(&party_id.number);
+ party_id.number.valid = 1;
+ party_id.number.presentation =
+ presentation_for_q931(ctrl,
+ invoke->args.qsig.CallTransferUpdate.redirection.presentation);
switch (invoke->args.qsig.CallTransferUpdate.redirection.presentation) {
case 0: /* presentationAllowedNumber */
case 3: /* presentationRestrictedNumber */
- libpri_copy_string(call->remote_id.number.str, (char *)
+ libpri_copy_string(party_id.number.str, (char *)
invoke->args.qsig.CallTransferUpdate.redirection.screened.number.str,
- sizeof(call->remote_id.number.str));
+ sizeof(party_id.number.str));
+ party_id.number.presentation |=
+ invoke->args.qsig.CallTransferUpdate.redirection.screened.
+ screening_indicator;
+ party_id.number.plan =
+ numbering_plan_for_q931(ctrl,
+ invoke->args.qsig.CallTransferUpdate.redirection.screened.number.plan)
+ | typeofnumber_for_q931(ctrl,
+ invoke->args.qsig.CallTransferUpdate.redirection.screened.number.ton);
break;
default:
- call->remote_id.number.str[0] = '\0';
- break;
- }
- call->remote_id.name.str[0] = '\0';
+ break;
+ }
+
+ /* redirectionName is put in party_id.name */
if (invoke->args.qsig.CallTransferUpdate.redirection_name_present) {
- switch (invoke->args.qsig.CallTransferUpdate.redirection_name.presentation) {
- case 1: /* presentation_allowed */
- case 2: /* presentation_restricted */
- libpri_copy_string(call->remote_id.name.str,
- (char *) invoke->args.qsig.CallTransferUpdate.redirection_name.data,
- sizeof(call->remote_id.name.str));
+ q931_party_name_init(&party_id.name);
+ party_id.name.valid = 1;
+ party_id.name.presentation = qsig_name_presentation_for_q931(ctrl,
+ invoke->args.qsig.CallTransferUpdate.redirection_name.presentation);
+ party_id.name.char_set =
+ invoke->args.qsig.CallTransferUpdate.redirection_name.char_set;
+ libpri_copy_string(party_id.name.str,
+ (char *) invoke->args.qsig.CallTransferUpdate.redirection_name.data,
+ sizeof(party_id.name.str));
+ }
+
+ if (q931_party_id_cmp(&party_id, &call->remote_id)) {
+ /* The remote_id data has changed. */
+ call->remote_id = party_id;
+ switch (call->incoming_ct_state) {
+ case INCOMING_CT_STATE_IDLE:
+ call->incoming_ct_state = INCOMING_CT_STATE_POST_CONNECTED_LINE;
break;
default:
break;
}
}
break;
-#endif /* This was incomplete */
#if 0 /* Not handled yet */
case ROSE_QSIG_SubaddressTransfer:
break;
@@ -2467,10 +2562,9 @@
break;
#endif /* Not handled yet */
case ROSE_QSIG_DivertingLegInformation1:
- call->divleginfo1activeflag = 1;
-
/* nominatedNr is put in redirecting.to.number */
- call->redirecting.to.number.status = Q931_PARTY_DATA_STATUS_CHANGED;
+ q931_party_number_init(&call->redirecting.to.number);
+ call->redirecting.to.number.valid = 1;
if (invoke->args.qsig.DivertingLegInformation1.subscription_option ==
QSIG_NOTIFICATION_WITH_DIVERTED_TO_NR) {
call->redirecting.to.number.presentation =
@@ -2481,7 +2575,6 @@
} else {
call->redirecting.to.number.presentation =
PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
- call->redirecting.to.number.str[0] = '\0';
}
call->redirecting.to.number.plan =
numbering_plan_for_q931(ctrl,
@@ -2491,24 +2584,25 @@
call->redirecting.reason = redirectingreason_for_q931(ctrl,
[... 1238 lines stripped ...]
More information about the svn-commits
mailing list