[libpri-commits] rmudgett: branch group/ccss r1240 - /team/group/ccss/

SVN commits to the libpri project libpri-commits at lists.digium.com
Thu Oct 22 12:42:01 CDT 2009


Author: rmudgett
Date: Thu Oct 22 12:41:57 2009
New Revision: 1240

URL: http://svnview.digium.com/svn/libpri?view=rev&rev=1240
Log:
Merged revisions 1230 via svnmerge from 
https://origsvn.digium.com/svn/libpri/branches/1.4

........
  r1230 | rmudgett | 2009-10-22 11:16:50 -0500 (Thu, 22 Oct 2009) | 15 lines
  
  Add support for calling and called subaddress.  Partial support for COLP subaddress.
  
  The Telecom Specs in NZ suggests that SUB ADDRESS is always on, so doing
  "desk to desk" between offices each with an asterisk box over the ISDN
  should then be possible, without a whole load of DDI numbers required.
  
  (closes issue #15604)
  Reported by: alecdavis
  Patches:
        libpri_subaddr_trunk.diff11.txt uploaded by alecdavis (license 585)
        Some minor modificatons were made.
  Tested by: alecdavis, rmudgett
  
  Review:	https://reviewboard.asterisk.org/r/406/
........

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

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

Propchange: team/group/ccss/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Thu Oct 22 12:41:57 2009
@@ -1,1 +1,1 @@
-/branches/1.4:1-1220
+/branches/1.4:1-1237

Modified: team/group/ccss/libpri.h
URL: http://svnview.digium.com/svn/libpri/team/group/ccss/libpri.h?view=diff&rev=1240&r1=1239&r2=1240
==============================================================================
--- team/group/ccss/libpri.h (original)
+++ team/group/ccss/libpri.h Thu Oct 22 12:41:57 2009
@@ -434,7 +434,7 @@
 	 * \note The null terminator is a convenience only since the data could be
 	 * BCD/binary and thus have a null byte as part of the contents.
 	 */
-	char data[32];
+	unsigned char data[32];
 };
 
 /*! \brief Addressing information needed to identify an endpoint in a call. */
@@ -817,7 +817,7 @@
 	int layer1;					/* User layer 1 */
 	int complete;				/* Have we seen "Complete" i.e. no more number? */
 	q931_call *call;			/* Opaque call pointer */
-	char callingsubaddr[256];	/* Calling parties subaddress */
+	char callingsubaddr[256];	/* Calling parties subaddress, backwards compatibility */
 	int progress;
 	int progressmask;
 	char origcalledname[256];
@@ -826,6 +826,8 @@
 	int origredirectingreason;
 	int reversecharge;
 	struct pri_subcommands *subcmds;
+	struct pri_party_id calling;			/* Calling Party's info, initially subaddress' */
+	struct pri_party_subaddress called_subaddress;	/* Called party's subaddress */
 } pri_event_ring;
 
 typedef struct pri_event_hangup {
@@ -1069,8 +1071,8 @@
 extern pri_event *pri_schedule_run_tv(struct pri *pri, const struct timeval *now);
 
 int pri_call(struct pri *pri, q931_call *c, int transmode, int channel,
-   int exclusive, int nonisdn, char *caller, int callerplan, char *callername, int callerpres,
-	 char *called,int calledplan, int ulayer1);
+    int exclusive, int nonisdn, char *caller, int callerplan, char *callername, int callerpres,
+    char *called, int calledplan, int ulayer1);
 
 struct pri_sr *pri_sr_new(void);
 void pri_sr_free(struct pri_sr *sr);
@@ -1090,6 +1092,26 @@
 void pri_sr_set_caller_party(struct pri_sr *sr, const struct pri_party_id *caller);
 /*! \note Use pri_sr_set_caller_party() instead to pass more precise caller information. */
 int pri_sr_set_caller(struct pri_sr *sr, char *caller, char *callername, int callerplan, int callerpres);
+
+/*!
+ * \brief Set the calling subaddress information in the call SETUP record.
+ *
+ * \param sr New call SETUP record.
+ * \param subaddress information to set.
+ *
+ * \return Nothing
+ */
+void pri_sr_set_caller_subaddress(struct pri_sr *sr, const struct pri_party_subaddress *subaddress);
+
+/*!
+ * \brief Set the called subaddress information in the call SETUP record.
+ *
+ * \param sr New call SETUP record.
+ * \param subaddress information to set.
+ *
+ * \return Nothing
+ */
+void pri_sr_set_called_subaddress(struct pri_sr *sr, const struct pri_party_subaddress *subaddress);
 
 /*!
  * \brief Set the redirecting information in the call SETUP record.

Modified: team/group/ccss/pri.c
URL: http://svnview.digium.com/svn/libpri/team/group/ccss/pri.c?view=diff&rev=1240&r1=1239&r2=1240
==============================================================================
--- team/group/ccss/pri.c (original)
+++ team/group/ccss/pri.c Thu Oct 22 12:41:57 2009
@@ -661,6 +661,40 @@
 
 /*!
  * \internal
+ * \brief Copy the PRI party subaddress to the Q.931 party subaddress structure.
+ *
+ * \param q931_subaddress Q.931 party subaddress structure
+ * \param pri_subaddress PRI party subaddress structure
+ *
+ * \return Nothing
+ */
+static void pri_copy_party_subaddress_to_q931(struct q931_party_subaddress *q931_subaddress, const struct pri_party_subaddress *pri_subaddress)
+{
+	int length;
+	int maxlen = sizeof(q931_subaddress->data) - 1;
+
+	q931_party_subaddress_init(q931_subaddress);
+
+	if (!pri_subaddress->valid) {
+		return;
+	}
+
+	q931_subaddress->valid = 1;
+	q931_subaddress->type = pri_subaddress->type;
+
+	length = pri_subaddress->length;
+	if (length > maxlen){
+		length = maxlen;
+	} else {
+		q931_subaddress->odd_even_indicator = pri_subaddress->odd_even_indicator;
+	}
+	q931_subaddress->length = length;
+	memcpy(q931_subaddress->data, pri_subaddress->data, length);
+	q931_subaddress->data[length] = '\0';
+}
+
+/*!
+ * \internal
  * \brief Copy the PRI party id to the Q.931 party id structure.
  *
  * \param q931_id Q.931 party id structure
@@ -672,6 +706,7 @@
 {
 	pri_copy_party_name_to_q931(&q931_id->name, &pri_id->name);
 	pri_copy_party_number_to_q931(&q931_id->number, &pri_id->number);
+	pri_copy_party_subaddress_to_q931(&q931_id->subaddress, &pri_id->subaddress);
 }
 
 int pri_connected_line_update(struct pri *ctrl, q931_call *call, const struct pri_party_connected_line *connected)
@@ -1075,7 +1110,7 @@
 
 int pri_call(struct pri *pri, q931_call *c, int transmode, int channel, int exclusive, 
 					int nonisdn, char *caller, int callerplan, char *callername, int callerpres, char *called,
-					int calledplan,int ulayer1)
+					int calledplan, int ulayer1)
 {
 	struct pri_sr req;
 	if (!pri || !c)
@@ -1364,6 +1399,11 @@
 	return 0;
 }
 
+void pri_sr_set_called_subaddress(struct pri_sr *sr, const struct pri_party_subaddress *subaddress)
+{
+	pri_copy_party_subaddress_to_q931(&sr->called.subaddress, subaddress);
+}
+
 int pri_sr_set_caller(struct pri_sr *sr, char *caller, char *callername, int callerplan, int callerpres)
 {
 	q931_party_id_init(&sr->caller);
@@ -1382,6 +1422,11 @@
 		}
 	}
 	return 0;
+}
+
+void pri_sr_set_caller_subaddress(struct pri_sr *sr, const struct pri_party_subaddress *subaddress)
+{
+	pri_copy_party_subaddress_to_q931(&sr->caller.subaddress, subaddress);
 }
 
 void pri_sr_set_caller_party(struct pri_sr *sr, const struct pri_party_id *caller)

Modified: team/group/ccss/pri_internal.h
URL: http://svnview.digium.com/svn/libpri/team/group/ccss/pri_internal.h?view=diff&rev=1240&r1=1239&r2=1240
==============================================================================
--- team/group/ccss/pri_internal.h (original)
+++ team/group/ccss/pri_internal.h Thu Oct 22 12:41:57 2009
@@ -188,7 +188,6 @@
 /*! \brief Maximum subaddress length plus null terminator */
 #define PRI_MAX_SUBADDRESS_LEN	(20 + 1)
 
-#if defined(POSSIBLE_FUTURE_SUBADDRESS_SUPPORT)
 struct q931_party_subaddress {
 	/*! \brief TRUE if the subaddress information is valid/present */
 	unsigned char valid;
@@ -212,17 +211,14 @@
 	 * \note The null terminator is a convenience only since the data could be
 	 * BCD/binary and thus have a null byte as part of the contents.
 	 */
-	char data[PRI_MAX_SUBADDRESS_LEN];
-};
-#endif	/* defined(POSSIBLE_FUTURE_SUBADDRESS_SUPPORT) */
+	unsigned char data[PRI_MAX_SUBADDRESS_LEN];
+};
 
 struct q931_party_address {
 	/*! \brief Subscriber phone number */
 	struct q931_party_number number;
-#if defined(POSSIBLE_FUTURE_SUBADDRESS_SUPPORT)
 	/*! \brief Subscriber subaddress */
 	struct q931_party_subaddress subaddress;
-#endif	/* defined(POSSIBLE_FUTURE_SUBADDRESS_SUPPORT) */
 };
 
 /*! \brief Information needed to identify an endpoint in a call. */
@@ -231,10 +227,8 @@
 	struct q931_party_name name;
 	/*! \brief Subscriber phone number */
 	struct q931_party_number number;
-#if defined(POSSIBLE_FUTURE_SUBADDRESS_SUPPORT)
 	/*! \brief Subscriber subaddress */
 	struct q931_party_subaddress subaddress;
-#endif	/* defined(POSSIBLE_FUTURE_SUBADDRESS_SUPPORT) */
 };
 
 enum Q931_REDIRECTING_STATE {
@@ -544,12 +538,14 @@
 
 void q931_party_name_init(struct q931_party_name *name);
 void q931_party_number_init(struct q931_party_number *number);
+void q931_party_subaddress_init(struct q931_party_subaddress *subaddr);
 void q931_party_address_init(struct q931_party_address *address);
 void q931_party_id_init(struct q931_party_id *id);
 void q931_party_redirecting_init(struct q931_party_redirecting *redirecting);
 
 int q931_party_name_cmp(const struct q931_party_name *left, const struct q931_party_name *right);
 int q931_party_number_cmp(const struct q931_party_number *left, const struct q931_party_number *right);
+int q931_party_subaddress_cmp(const struct q931_party_subaddress *left, const struct q931_party_subaddress *right);
 int q931_party_address_cmp(const struct q931_party_address *left, const struct q931_party_address *right);
 int q931_party_id_cmp(const struct q931_party_id *left, const struct q931_party_id *right);
 int q931_party_id_cmp_address(const struct q931_party_id *left, const struct q931_party_id *right);
@@ -559,6 +555,7 @@
 
 void q931_party_name_copy_to_pri(struct pri_party_name *pri_name, const struct q931_party_name *q931_name);
 void q931_party_number_copy_to_pri(struct pri_party_number *pri_number, const struct q931_party_number *q931_number);
+void q931_party_subaddress_copy_to_pri(struct pri_party_subaddress *pri_subaddress, const struct q931_party_subaddress *q931_subaddress);
 void q931_party_address_copy_to_pri(struct pri_party_address *pri_address, const struct q931_party_address *q931_address);
 void q931_party_id_copy_to_pri(struct pri_party_id *pri_id, const struct q931_party_id *q931_id);
 void q931_party_redirecting_copy_to_pri(struct pri_party_redirecting *pri_redirecting, const struct q931_party_redirecting *q931_redirecting);

Modified: team/group/ccss/pri_q931.h
URL: http://svnview.digium.com/svn/libpri/team/group/ccss/pri_q931.h?view=diff&rev=1240&r1=1239&r2=1240
==============================================================================
--- team/group/ccss/pri_q931.h (original)
+++ team/group/ccss/pri_q931.h Thu Oct 22 12:41:57 2009
@@ -175,8 +175,9 @@
 #define Q931_IE_SEGMENTED_MSG			0x00
 #define Q931_IE_CHANGE_STATUS			0x01
 #define Q931_IE_ORIGINATING_LINE_INFO		(0x01 | Q931_CODESET(6))
-#define Q931_IE_CONNECTED_ADDR			0x0C
-#define Q931_IE_CONNECTED_NUM			0x4C
+#define Q931_IE_CONNECTED_ADDR			0x0c
+#define Q931_IE_CONNECTED_NUM			0x4c
+#define Q931_IE_CONNECTED_SUBADDR		0x4d
 #define Q931_IE_CALL_IDENTITY			0x10
 #define Q931_IE_FACILITY				0x1c
 #define Q931_IE_ENDPOINT_ID				0x26

Modified: team/group/ccss/q931.c
URL: http://svnview.digium.com/svn/libpri/team/group/ccss/q931.c?view=diff&rev=1240&r1=1239&r2=1240
==============================================================================
--- team/group/ccss/q931.c (original)
+++ team/group/ccss/q931.c Thu Oct 22 12:41:57 2009
@@ -321,6 +321,22 @@
 }
 
 /*!
+ * \brief Initialize the given struct q931_party_subaddress
+ *
+ * \param subaddress Structure to initialize
+ *
+ * \return Nothing
+ */
+void q931_party_subaddress_init(struct q931_party_subaddress *subaddress)
+{
+	subaddress->valid = 0;
+	subaddress->type = 0;
+	subaddress->odd_even_indicator = 0;
+	subaddress->length = 0;
+	subaddress->data[0] = '\0';
+}
+
+/*!
  * \brief Initialize the given struct q931_party_address
  *
  * \param address Structure to initialize
@@ -330,6 +346,7 @@
 void q931_party_address_init(struct q931_party_address *address)
 {
 	q931_party_number_init(&address->number);
+	q931_party_subaddress_init(&address->subaddress);
 }
 
 /*!
@@ -343,6 +360,7 @@
 {
 	q931_party_name_init(&id->name);
 	q931_party_number_init(&id->number);
+	q931_party_subaddress_init(&id->subaddress);
 }
 
 /*!
@@ -432,6 +450,45 @@
 }
 
 /*!
+ * \brief Compare the left and right party subaddress.
+ *
+ * \param left Left parameter party subaddress.
+ * \param right Right parameter party subaddress.
+ *
+ * \retval < 0 when left < right.
+ * \retval == 0 when left == right.
+ * \retval > 0 when left > right.
+ */
+int q931_party_subaddress_cmp(const struct q931_party_subaddress *left, const struct q931_party_subaddress *right)
+{
+	int cmp;
+
+	if (!left->valid) {
+		if (!right->valid) {
+			return 0;
+		}
+		return -1;
+	} else if (!right->valid) {
+		return 1;
+	}
+	cmp = left->type - right->type;
+	if (cmp) {
+		return cmp;
+	}
+	cmp = memcmp(left->data, right->data,
+		(left->length < right->length) ? left->length : right->length);
+	if (cmp) {
+		return cmp;
+	}
+	cmp = left->length - right->length;
+	if (cmp) {
+		return cmp;
+	}
+	cmp = left->odd_even_indicator - right->odd_even_indicator;
+	return cmp;
+}
+
+/*!
  * \brief Compare the left and right party address.
  *
  * \param left Left parameter party address.
@@ -446,6 +503,10 @@
 	int cmp;
 
 	cmp = q931_party_number_cmp(&left->number, &right->number);
+	if (cmp) {
+		return cmp;
+	}
+	cmp = q931_party_subaddress_cmp(&left->subaddress, &right->subaddress);
 	return cmp;
 }
 
@@ -467,6 +528,10 @@
 	if (cmp) {
 		return cmp;
 	}
+	cmp = q931_party_subaddress_cmp(&left->subaddress, &right->subaddress);
+	if (cmp) {
+		return cmp;
+	}
 	cmp = q931_party_name_cmp(&left->name, &right->name);
 	return cmp;
 }
@@ -486,6 +551,10 @@
 	int cmp;
 
 	cmp = q931_party_number_cmp(&left->number, &right->number);
+	if (cmp) {
+		return cmp;
+	}
+	cmp = q931_party_subaddress_cmp(&left->subaddress, &right->subaddress);
 	return cmp;
 }
 
@@ -504,6 +573,10 @@
 	int cmp;
 
 	cmp = q931_party_number_cmp(&id->number, &address->number);
+	if (cmp) {
+		return cmp;
+	}
+	cmp = q931_party_subaddress_cmp(&id->subaddress, &address->subaddress);
 	return cmp;
 }
 
@@ -518,6 +591,7 @@
 void q931_party_id_copy_to_address(struct q931_party_address *address, const struct q931_party_id *id)
 {
 	address->number = id->number;
+	address->subaddress = id->subaddress;
 }
 
 /*!
@@ -567,6 +641,42 @@
 }
 
 /*!
+ * \brief Copy the Q.931 party subaddress to the PRI party subaddress structure.
+ *
+ * \param pri_subaddress PRI party subaddress structure
+ * \param q931_subaddress Q.931 party subaddress structure
+ *
+ * \return Nothing
+ */
+void q931_party_subaddress_copy_to_pri(struct pri_party_subaddress *pri_subaddress, const struct q931_party_subaddress *q931_subaddress)
+{
+	int length;
+
+	/*
+	 * The size of pri_subaddress->data[] is not the same as the size of
+	 * q931_subaddress->data[].
+	 */
+
+	if (!q931_subaddress->valid) {
+		pri_subaddress->valid = 0;
+		pri_subaddress->type = 0;
+		pri_subaddress->odd_even_indicator = 0;
+		pri_subaddress->length = 0;
+		pri_subaddress->data[0] = '\0';
+		return;
+	}
+
+	pri_subaddress->valid = 1;
+	pri_subaddress->type = q931_subaddress->type;
+	pri_subaddress->odd_even_indicator = q931_subaddress->odd_even_indicator;
+
+	length = q931_subaddress->length;
+	pri_subaddress->length = length;
+	memcpy(pri_subaddress->data, q931_subaddress->data, length);
+	pri_subaddress->data[length] = '\0';
+}
+
+/*!
  * \brief Copy the Q.931 party address to the PRI party address structure.
  *
  * \param pri_address PRI party address structure
@@ -577,13 +687,7 @@
 void q931_party_address_copy_to_pri(struct pri_party_address *pri_address, const struct q931_party_address *q931_address)
 {
 	q931_party_number_copy_to_pri(&pri_address->number, &q931_address->number);
-
-	/* Subaddresses are not supported yet. */
-	pri_address->subaddress.valid = 0;
-	pri_address->subaddress.type = 0;	/* nsap */
-	pri_address->subaddress.odd_even_indicator = 0;
-	pri_address->subaddress.length = 0;
-	pri_address->subaddress.data[0] = '\0';
+	q931_party_subaddress_copy_to_pri(&pri_address->subaddress, &q931_address->subaddress);
 }
 
 /*!
@@ -598,6 +702,7 @@
 {
 	q931_party_name_copy_to_pri(&pri_id->name, &q931_id->name);
 	q931_party_number_copy_to_pri(&pri_id->number, &q931_id->number);
+	q931_party_subaddress_copy_to_pri(&pri_id->subaddress, &q931_id->subaddress);
 }
 
 /*!
@@ -1478,6 +1583,93 @@
 	num[len] = 0;
 }
 
+static void q931_get_subaddr_specific(unsigned char *num, int maxlen, unsigned char *src, int len, char oddflag)
+{
+	/* User Specified */
+	int x;
+	char *ptr = (char *) num;
+
+	if (len <= 0) {
+		num[0] = '\0';
+		return;
+	}
+
+	if (((len * 2) + 1) > maxlen) {
+		len = (maxlen / 2) - 1;
+	}
+
+	for (x = 0; x < (len - 1); ++x) {
+		ptr += sprintf(ptr, "%02x", src[x]);
+	}
+
+	if (oddflag) {
+		/* ODD */
+		sprintf(ptr, "%01x", (src[len - 1]) >> 4);
+	} else {
+		/* EVEN */
+		sprintf(ptr, "%02x", src[len - 1]);
+	}
+}
+
+static int transmit_subaddr_helper(int full_ie, struct pri *ctrl, struct q931_party_subaddress *q931_subaddress, int msgtype, q931_ie *ie, int offset, int len, int order)
+{
+	size_t datalen;
+
+	if (!q931_subaddress->valid) {
+		return 0;
+	}
+
+	datalen = q931_subaddress->length;
+	if (!q931_subaddress->type) {
+		/* 0 = NSAP */
+		/* 0 = Odd/Even indicator */
+		ie->data[0] = 0x80;
+	} else {
+		/* 2 = User Specified */
+		ie->data[0] = q931_subaddress->odd_even_indicator ? 0xA8 : 0xA0;
+	}
+	memcpy(ie->data + offset, q931_subaddress->data, datalen);
+
+	return datalen + (offset + 2);
+}
+
+static int receive_subaddr_helper(int full_ie, struct pri *ctrl, struct q931_party_subaddress *q931_subaddress, int msgtype, q931_ie *ie, int offset, int len)
+{
+	if (len <= 0) {
+		return -1;
+	}
+
+	q931_subaddress->valid = 1;
+	q931_subaddress->length = len;
+	/* type: 0 = NSAP, 2 = User Specified */
+	q931_subaddress->type = ((ie->data[0] & 0x70) >> 4);
+	q931_subaddress->odd_even_indicator = (ie->data[0] & 0x08) ? 1 : 0;
+	q931_get_number(q931_subaddress->data, sizeof(q931_subaddress->data),
+		ie->data + offset, len);
+
+	return 0;
+}
+
+static void dump_subaddr_helper(int full_ie, struct pri *ctrl, q931_ie *ie, int offset, int len, int datalen, char prefix, const char *named)
+{
+	unsigned char cnum[256];
+
+	if (!(ie->data[0] & 0x70)) {
+		/* NSAP */
+		q931_get_number(cnum, sizeof(cnum), ie->data + offset, datalen);
+	} else {
+		/* User Specified */
+		q931_get_subaddr_specific(cnum, sizeof(cnum), ie->data + offset, datalen,
+			ie->data[0] & 0x08);
+	}
+
+	pri_message(ctrl,
+		"%c %s Sub-Address (len=%2d) [ Ext: %d  Type: %s (%d)  O: %d  '%s' ]\n",
+		prefix, named, len, ie->data[0] >> 7,
+		subaddrtype2str((ie->data[0] & 0x70) >> 4), (ie->data[0] & 0x70) >> 4,
+		(ie->data[0] & 0x08) >> 3, cnum);
+}
+
 static void dump_called_party_number(int full_ie, struct pri *ctrl, q931_ie *ie, int len, char prefix)
 {
 	unsigned char cnum[256];
@@ -1489,12 +1681,7 @@
 
 static void dump_called_party_subaddr(int full_ie, struct pri *ctrl, q931_ie *ie, int len, char prefix)
 {
-	unsigned char cnum[256];
-	q931_get_number(cnum, sizeof(cnum), ie->data + 1, len - 3);
-	pri_message(ctrl, "%c Called Sub-Address (len=%2d) [ Ext: %d  Type: %s (%d)  O: %d  '%s' ]\n",
-		prefix, len, ie->data[0] >> 7,
-		subaddrtype2str((ie->data[0] & 0x70) >> 4), (ie->data[0] & 0x70) >> 4,
-		(ie->data[0] & 0x08) >> 3, cnum);
+	dump_subaddr_helper(full_ie, ctrl, ie, 1 , len, len - 3, prefix, "Called");
 }
 
 static void dump_calling_party_number(int full_ie, struct pri *ctrl, q931_ie *ie, int len, char prefix)
@@ -1513,12 +1700,7 @@
 
 static void dump_calling_party_subaddr(int full_ie, struct pri *ctrl, q931_ie *ie, int len, char prefix)
 {
-	unsigned char cnum[256];
-	q931_get_number(cnum, sizeof(cnum), ie->data + 1, len - 3);
-	pri_message(ctrl, "%c Calling Sub-Address (len=%2d) [ Ext: %d  Type: %s (%d)  O: %d  '%s' ]\n",
-		prefix, len, ie->data[0] >> 7,
-		subaddrtype2str((ie->data[0] & 0x70) >> 4), (ie->data[0] & 0x70) >> 4,
-		(ie->data[0] & 0x08) >> 3, cnum);
+	dump_subaddr_helper(full_ie, ctrl, ie, 1 , len, len - 3, prefix, "Calling");
 }
 
 static void dump_redirecting_number(int full_ie, struct pri *ctrl, q931_ie *ie, int len, char prefix)
@@ -1635,6 +1817,26 @@
 	pri_message(ctrl, "  '%s' ]\n", cnum);
 }
 
+static int receive_connected_subaddr(int full_ie, struct pri *ctrl, q931_call *call, int msgtype, q931_ie *ie, int len)
+{
+	if (len < 3) {
+		return -1;
+	}
+
+	return receive_subaddr_helper(full_ie, ctrl, &call->remote_id.subaddress, msgtype, ie,
+		1, len - 3);
+}
+
+static int transmit_connected_subaddr(int full_ie, struct pri *ctrl, q931_call *call, int msgtype, q931_ie *ie, int len, int order)
+{
+	return transmit_subaddr_helper(full_ie, ctrl, &call->local_id.subaddress, msgtype, ie,
+		1, len, order);
+}
+
+static void dump_connected_subaddr(int full_ie, struct pri *ctrl, q931_ie *ie, int len, char prefix)
+{
+	dump_subaddr_helper(full_ie, ctrl, ie, 1 , len, len - 3, prefix, "Connected");
+}
 
 static int receive_redirecting_number(int full_ie, struct pri *ctrl, q931_call *call, int msgtype, q931_ie *ie, int len)
 {
@@ -1691,12 +1893,7 @@
 
 static void dump_redirecting_subaddr(int full_ie, struct pri *ctrl, q931_ie *ie, int len, char prefix)
 {
-	unsigned char cnum[256];
-	q931_get_number(cnum, sizeof(cnum), ie->data + 2, len - 4);
-	pri_message(ctrl, "%c Redirecting Sub-Address (len=%2d) [ Ext: %d  Type: %s (%d)  O: %d  '%s' ]\n",
-		prefix, len, ie->data[0] >> 7,
-		subaddrtype2str((ie->data[0] & 0x70) >> 4), (ie->data[0] & 0x70) >> 4,
-		(ie->data[0] & 0x08) >> 3, cnum);
+	dump_subaddr_helper(full_ie, ctrl, ie, 2, len, len - 4, prefix, "Redirecting");
 }
 
 static int receive_redirection_number(int full_ie, struct pri *ctrl, q931_call *call, int msgtype, q931_ie *ie, int len)
@@ -1744,9 +1941,33 @@
 
 static int receive_calling_party_subaddr(int full_ie, struct pri *ctrl, q931_call *call, int msgtype, q931_ie *ie, int len)
 {
-	/* copy digits to call->callingsubaddr */
- 	q931_get_number((unsigned char *) call->callingsubaddr, sizeof(call->callingsubaddr), ie->data + 1, len - 3);
-	return 0;
+	if (len < 3) {
+		return -1;
+	}
+
+	return receive_subaddr_helper(full_ie, ctrl, &call->remote_id.subaddress, msgtype, ie,
+		1, len - 3);
+}
+
+static int transmit_calling_party_subaddr(int full_ie, struct pri *ctrl, q931_call *call, int msgtype, q931_ie *ie, int len, int order)
+{
+	return transmit_subaddr_helper(full_ie, ctrl, &call->local_id.subaddress, msgtype, ie,
+		1, len, order);
+}
+
+static int receive_called_party_subaddr(int full_ie, struct pri *ctrl, q931_call *call, int msgtype, q931_ie *ie, int len)
+{
+	if (len < 3) {
+		return -1;
+	}
+	return receive_subaddr_helper(full_ie, ctrl, &call->called.subaddress, msgtype, ie, 1,
+		len - 3);
+}
+
+static int transmit_called_party_subaddr(int full_ie, struct pri *ctrl, q931_call *call, int msgtype, q931_ie *ie, int len, int order)
+{
+	return transmit_subaddr_helper(full_ie, ctrl, &call->called.subaddress, msgtype, ie,
+		1, len, order);
 }
 
 static int receive_called_party_number(int full_ie, struct pri *ctrl, q931_call *call, int msgtype, q931_ie *ie, int len)
@@ -2942,9 +3163,9 @@
 	{ 1, Q931_CLOSED_USER_GROUP, "Closed User Group" },
 	{ 1, Q931_REVERSE_CHARGE_INDIC, "Reverse Charging Indication", dump_reverse_charging_indication, receive_reverse_charging_indication, transmit_reverse_charging_indication },
 	{ 1, Q931_CALLING_PARTY_NUMBER, "Calling Party Number", dump_calling_party_number, receive_calling_party_number, transmit_calling_party_number },
-	{ 1, Q931_CALLING_PARTY_SUBADDR, "Calling Party Subaddress", dump_calling_party_subaddr, receive_calling_party_subaddr },
+	{ 1, Q931_CALLING_PARTY_SUBADDR, "Calling Party Subaddress", dump_calling_party_subaddr, receive_calling_party_subaddr, transmit_calling_party_subaddr },
 	{ 1, Q931_CALLED_PARTY_NUMBER, "Called Party Number", dump_called_party_number, receive_called_party_number, transmit_called_party_number },
-	{ 1, Q931_CALLED_PARTY_SUBADDR, "Called Party Subaddress", dump_called_party_subaddr },
+	{ 1, Q931_CALLED_PARTY_SUBADDR, "Called Party Subaddress", dump_called_party_subaddr, receive_called_party_subaddr, transmit_called_party_subaddr },
 	{ 0, Q931_REDIRECTING_NUMBER, "Redirecting Number", dump_redirecting_number, receive_redirecting_number, transmit_redirecting_number },
 	{ 1, Q931_REDIRECTING_SUBADDR, "Redirecting Subaddress", dump_redirecting_subaddr },
 	{ 0, Q931_TRANSIT_NET_SELECT, "Transit Network Selection" },
@@ -2973,6 +3194,7 @@
 	{ 1, Q931_IE_CHANGE_STATUS, "Change Status", dump_change_status, receive_change_status, transmit_change_status },
 	{ 1, Q931_IE_CONNECTED_ADDR, "Connected Number", dump_connected_number },
 	{ 1, Q931_IE_CONNECTED_NUM, "Connected Number", dump_connected_number, receive_connected_number, transmit_connected_number },
+	{ 1, Q931_IE_CONNECTED_SUBADDR, "Connected Subaddress", dump_connected_subaddr, receive_connected_subaddr, transmit_connected_subaddr },
 	{ 1, Q931_IE_ORIGINAL_CALLED_NUMBER, "Original Called Number", dump_redirecting_number, receive_redirecting_number, transmit_redirecting_number },
 	{ 1, Q931_IE_USER_USER_FACILITY, "User-User Facility" },
 	{ 1, Q931_IE_UPDATE, "Update" },
@@ -3942,7 +4164,15 @@
 	q931_hangup(ctrl, c, cause);
 }
 
-static int connect_ies[] = { Q931_CHANNEL_IDENT, Q931_IE_FACILITY, Q931_PROGRESS_INDICATOR, Q931_DISPLAY, Q931_IE_CONNECTED_NUM, -1 };
+static int connect_ies[] = {
+	Q931_CHANNEL_IDENT,
+	Q931_IE_FACILITY,
+	Q931_PROGRESS_INDICATOR,
+	Q931_DISPLAY,
+	Q931_IE_CONNECTED_NUM,
+	Q931_IE_CONNECTED_SUBADDR,
+	-1
+};
 
 int q931_connect(struct pri *ctrl, q931_call *c, int channel, int nonisdn)
 {
@@ -4075,7 +4305,9 @@
 	Q931_DISPLAY,
 	Q931_REVERSE_CHARGE_INDIC,
 	Q931_CALLING_PARTY_NUMBER,
+	Q931_CALLING_PARTY_SUBADDR,
 	Q931_CALLED_PARTY_NUMBER,
+	Q931_CALLED_PARTY_SUBADDR,
 	Q931_REDIRECTING_NUMBER,
 	Q931_IE_USER_USER,
 	Q931_SENDING_COMPLETE,
@@ -4096,7 +4328,9 @@
 	Q931_CHANNEL_IDENT,
 	Q931_IE_FACILITY,
 	Q931_CALLING_PARTY_NUMBER,
+	Q931_CALLING_PARTY_SUBADDR,
 	Q931_CALLED_PARTY_NUMBER,
+	Q931_CALLED_PARTY_SUBADDR,
 	Q931_SENDING_COMPLETE,
 	-1
 };
@@ -4827,8 +5061,16 @@
 		sizeof(ctrl->ev.ring.callingnum));
 	libpri_copy_string(ctrl->ev.ring.callingname, call->remote_id.name.str,
 		sizeof(ctrl->ev.ring.callingname));
-	libpri_copy_string(ctrl->ev.ring.callingsubaddr, call->callingsubaddr,
-		sizeof(ctrl->ev.ring.callingsubaddr));
+	q931_party_id_copy_to_pri(&ctrl->ev.ring.calling, &call->remote_id);
+	/* for backwards compatibility, still need ctrl->ev.ring.callingsubaddr */
+	if (!call->remote_id.subaddress.type) {
+		/* NSAP: Type = 0 */
+		libpri_copy_string(ctrl->ev.ring.callingsubaddr,
+			(char *) call->remote_id.subaddress.data,
+			sizeof(ctrl->ev.ring.callingsubaddr));
+	} else {
+		ctrl->ev.ring.callingsubaddr[0] = '\0';
+	}
 
 	ctrl->ev.ring.ani2 = call->ani2;
 
@@ -4836,6 +5078,8 @@
 	ctrl->ev.ring.calledplan = call->called.number.plan;
 	libpri_copy_string(ctrl->ev.ring.callednum, call->called.number.str,
 		sizeof(ctrl->ev.ring.callednum));
+	q931_party_subaddress_copy_to_pri(&ctrl->ev.ring.called_subaddress,
+		&call->called.subaddress);
 
 	/* Original called party information (For backward compatibility) */
 	libpri_copy_string(ctrl->ev.ring.origcalledname,
@@ -5304,8 +5548,16 @@
 		ctrl->ev.ring.call = c;
 		ctrl->ev.ring.channel = q931_encode_channel(c);
 		libpri_copy_string(ctrl->ev.ring.callednum, c->overlap_digits, sizeof(ctrl->ev.ring.callednum));
-		libpri_copy_string(ctrl->ev.ring.callingsubaddr, c->callingsubaddr, sizeof(ctrl->ev.ring.callingsubaddr));
-		ctrl->ev.ring.complete = c->complete; 	/* this covers IE 33 (Sending Complete) */
+
+		q931_party_id_copy_to_pri(&ctrl->ev.ring.calling, &c->remote_id);
+		/* for backwards compatibility, still need ctrl->ev.ring.callingsubaddr */
+		if (!c->remote_id.subaddress.type) {	/* NSAP: Type = 0 */
+			libpri_copy_string(ctrl->ev.ring.callingsubaddr, (char *) c->remote_id.subaddress.data, sizeof(ctrl->ev.ring.callingsubaddr));
+		} else {
+			ctrl->ev.ring.callingsubaddr[0] = '\0';
+		}
+
+		ctrl->ev.ring.complete = c->complete;	/* this covers IE 33 (Sending Complete) */
 		return Q931_RES_HAVEEVENT;
 	case Q931_STATUS_ENQUIRY:
 		if (c->newcall) {




More information about the libpri-commits mailing list