[libpri-commits] rmudgett: branch group/issue14292 r857 - /team/group/issue14292/

SVN commits to the libpri project libpri-commits at lists.digium.com
Thu Jun 4 13:27:33 CDT 2009


Author: rmudgett
Date: Thu Jun  4 13:27:30 2009
New Revision: 857

URL: http://svn.asterisk.org/svn-view/libpri?view=rev&rev=857
Log:
Merged revisions 854,856 via svnmerge from 
https://origsvn.digium.com/svn/libpri/team/group/issue14068

........
  r854 | rmudgett | 2009-06-04 11:46:19 -0500 (Thu, 04 Jun 2009) | 18 lines
  
  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.
........
  r856 | rmudgett | 2009-06-04 12:27:18 -0500 (Thu, 04 Jun 2009) | 5 lines
  
  Eliminated the need for some libpri structs that did not add anything useful.
  
  struct pri_subcmd_connected_line
  struct pri_subcmd_redirecting
........

Modified:
    team/group/issue14292/   (props changed)
    team/group/issue14292/libpri.h
    team/group/issue14292/pri.c
    team/group/issue14292/pri_facility.c
    team/group/issue14292/pri_internal.h
    team/group/issue14292/q931.c

Propchange: team/group/issue14292/
------------------------------------------------------------------------------
    automerge = *

Propchange: team/group/issue14292/
------------------------------------------------------------------------------
--- issue14292-integrated (original)
+++ issue14292-integrated Thu Jun  4 13:27:30 2009
@@ -1,1 +1,1 @@
-/team/group/issue14068:1-850
+/team/group/issue14068:1-856

Modified: team/group/issue14292/libpri.h
URL: http://svn.asterisk.org/svn-view/libpri/team/group/issue14292/libpri.h?view=diff&rev=857&r1=856&r2=857
==============================================================================
--- team/group/issue14292/libpri.h (original)
+++ team/group/issue14292/libpri.h Thu Jun  4 13:27:30 2009
@@ -350,41 +350,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;
 };
 
 /*!
@@ -398,9 +428,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;
 };
 
@@ -438,14 +472,6 @@
 #define PRI_CCERROR_REMOTE_USER_BUSY_AGAIN	1012
 #define PRI_CCERROR_FAILURE_TO_MATCH		1013
 
-struct pri_subcmd_connected_line {
-	struct pri_party_connected_line party;
-};
-
-struct pri_subcmd_redirecting {
-	struct pri_party_redirecting party;
-};
-
 struct pri_subcmd_cc_ccbs_rr {
 	struct pri_qsig_cc_request_res cc_request_res;
 };
@@ -480,8 +506,8 @@
 	union {
 		/*! Reserve room for possible expansion to maintain ABI compatibility. */
 		char reserve_space[512];
-		struct pri_subcmd_connected_line connected_line;
-		struct pri_subcmd_redirecting redirecting;
+		struct pri_party_connected_line connected_line;
+		struct pri_party_redirecting redirecting;
 		struct pri_subcmd_cc_ccbs_rr cc_ccbs_rr;
 		struct pri_subcmd_cc_ccnr_rr cc_ccnr_rr;
 		struct pri_subcmd_cc_cancel_inv cc_cancel_inv;
@@ -489,11 +515,11 @@
 		struct pri_subcmd_cc_suspend_inv cc_suspend_inv;
 		struct pri_subcmd_cc_ringout_inv cc_ringout_inv;
 		struct pri_subcmd_cc_error cc_error;
-	};
+	} u;
 };
 
 /* Max number of subcommands per event message */
-#define PRI_MAX_SUBCOMMANDS	6
+#define PRI_MAX_SUBCOMMANDS	8
 
 struct pri_subcommands {
 	int counter_subcmd;
@@ -524,10 +550,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;
 
@@ -539,11 +561,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;
 
@@ -603,8 +620,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;
 
@@ -774,11 +789,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 */
 
@@ -839,9 +860,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);
+
 
 int pri_sr_set_ccringout(struct pri_sr *sr, int ccringout);
 int pri_sr_set_ccbsnr(struct pri_sr *sr, int ccbsnr);

Modified: team/group/issue14292/pri.c
URL: http://svn.asterisk.org/svn-view/libpri/team/group/issue14292/pri.c?view=diff&rev=857&r1=856&r2=857
==============================================================================
--- team/group/issue14292/pri.c (original)
+++ team/group/issue14292/pri.c Thu Jun  4 13:27:30 2009
@@ -562,142 +562,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;
@@ -1168,11 +1207,6 @@
 	return 0;
 }
 
-void pri_sr_set_redirecting_name(struct pri_sr *sr, char *name)
-{
-	sr->redirectingname = name;
-}
-
 int pri_sr_set_ccringout(struct pri_sr *sr, int ccringout)
 {
 	sr->ccringout = ccringout;

Modified: team/group/issue14292/pri_facility.c
URL: http://svn.asterisk.org/svn-view/libpri/team/group/issue14292/pri_facility.c?view=diff&rev=857&r1=856&r2=857
==============================================================================
--- team/group/issue14292/pri_facility.c (original)
+++ team/group/issue14292/pri_facility.c Thu Jun  4 13:27:30 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,
@@ -2103,9 +2151,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);
 		if (call->ccoperation) {
@@ -2230,7 +2283,7 @@
 			break;
 		}
 		subcmd->cmd = PRI_SUBCMD_CC_ERROR;
-		subcmd->cc_error.error_value = PRI_CCERROR_UNSPECIFIED;
+		subcmd->u.cc_error.error_value = PRI_CCERROR_UNSPECIFIED;
 		break;
 	default:
 		break;
@@ -2404,11 +2457,11 @@
 			break;
 		}
 		subcmd->cmd = PRI_SUBCMD_CC_CCBSREQUEST_RR;
-		subcmd->cc_ccbs_rr.cc_request_res.no_path_reservation =
+		subcmd->u.cc_ccbs_rr.cc_request_res.no_path_reservation =
 			result->args.qsig.CcbsRequest.no_path_reservation;
-		subcmd->cc_ccbs_rr.cc_request_res.retain_service =
+		subcmd->u.cc_ccbs_rr.cc_request_res.retain_service =
 			result->args.qsig.CcbsRequest.retain_service;
-		subcmd->cc_ccbs_rr.cc_request_res.cc_extension.cc_extension_tag = 0;
+		subcmd->u.cc_ccbs_rr.cc_request_res.cc_extension.cc_extension_tag = 0;
 		break;
 	case ROSE_QSIG_CcnrRequest:
 		subcmd = q931_alloc_subcommand(ctrl);
@@ -2417,11 +2470,11 @@
 			break;
 		}
 		subcmd->cmd = PRI_SUBCMD_CC_CCNRREQUEST_RR;
-		subcmd->cc_ccnr_rr.cc_request_res.no_path_reservation =
+		subcmd->u.cc_ccnr_rr.cc_request_res.no_path_reservation =
 			result->args.qsig.CcnrRequest.no_path_reservation;
-		subcmd->cc_ccnr_rr.cc_request_res.retain_service =
+		subcmd->u.cc_ccnr_rr.cc_request_res.retain_service =
 			result->args.qsig.CcnrRequest.retain_service;
-		subcmd->cc_ccnr_rr.cc_request_res.cc_extension.cc_extension_tag = 0;
+		subcmd->u.cc_ccnr_rr.cc_request_res.cc_extension.cc_extension_tag = 0;
 		break;
 #if 0	/* Not handled yet */
 	case ROSE_QSIG_CcPathReserve:
@@ -2459,6 +2512,7 @@
 	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 */
@@ -2595,7 +2649,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;
@@ -2605,17 +2660,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.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 =
@@ -2655,64 +2721,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)
@@ -2721,54 +2786,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));

[... 1383 lines stripped ...]



More information about the libpri-commits mailing list