[asterisk-commits] rmudgett: branch rmudgett/cid r260341 - in /team/rmudgett/cid: include/asteri...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Apr 30 13:18:44 CDT 2010


Author: rmudgett
Date: Fri Apr 30 13:18:41 2010
New Revision: 260341

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=260341
Log:
Initial work so far.  Most certainly a work in progress.

Modified:
    team/rmudgett/cid/include/asterisk/channel.h
    team/rmudgett/cid/main/channel.c

Modified: team/rmudgett/cid/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/cid/include/asterisk/channel.h?view=diff&rev=260341&r1=260340&r2=260341
==============================================================================
--- team/rmudgett/cid/include/asterisk/channel.h (original)
+++ team/rmudgett/cid/include/asterisk/channel.h Fri Apr 30 13:18:41 2010
@@ -187,6 +187,65 @@
 	void (*digit)(struct ast_channel *chan, char digit);
 };
 
+/*! Party name character set enumeration values (values from Q.SIG) */
+enum AST_PARTY_CHAR_SET {
+	AST_PARTY_CHAR_SET_UNKNOWN = 0,
+	AST_PARTY_CHAR_SET_ISO8859_1 = 1,
+	AST_PARTY_CHAR_SET_WITHDRAWN = 2,/* ITU withdrew this enum value. */
+	AST_PARTY_CHAR_SET_ISO8859_2 = 3,
+	AST_PARTY_CHAR_SET_ISO8859_3 = 4,
+	AST_PARTY_CHAR_SET_ISO8859_4 = 5,
+	AST_PARTY_CHAR_SET_ISO8859_5 = 6,
+	AST_PARTY_CHAR_SET_ISO8859_7 = 7,
+	AST_PARTY_CHAR_SET_ISO10646_BMPSTRING = 8,
+	AST_PARTY_CHAR_SET_ISO10646_UTF_8STRING = 9,
+};
+
+/*!
+ * \since 1.8
+ * \brief Information needed to specify a name in a call.
+ * \note All string fields here are malloc'ed, so they need to be
+ * freed when the structure is deleted.
+ * \note NULL and "" must be considered equivalent.
+ */
+struct ast_party_name {
+	/*! \brief Subscriber name (Malloced) */
+	char *str;
+	/*!
+	 * \brief Character set the name is using.
+	 * \see enum AST_PARTY_CHAR_SET
+	 * \note
+	 * Set to AST_PARTY_CHAR_SET_ISO8859_1 if unsure what to use.
+	 * \todo Start using the party name character set value.  Not currently used.
+	 */
+	int char_set;
+	/*!
+	 * \brief Q.931 encoded presentation-indicator encoded field
+	 * \note Must tollerate the Q.931 screening-indicator field values being present.
+	 */
+	int presentation;
+	/*! \brief TRUE if the name information is valid/present */
+	unsigned char valid;
+};
+
+/*!
+ * \since 1.8
+ * \brief Information needed to specify a number in a call.
+ * \note All string fields here are malloc'ed, so they need to be
+ * freed when the structure is deleted.
+ * \note NULL and "" must be considered equivalent.
+ */
+struct ast_party_number {
+	/*! \brief Subscriber phone number (Malloced) */
+	char *str;
+	/*! \brief Q.931 Type-Of-Number and Numbering-Plan encoded fields */
+	int plan;
+	/*! \brief Q.931 presentation-indicator and screening-indicator encoded fields */
+	int presentation;
+	/*! \brief TRUE if the number information is valid/present */
+	unsigned char valid;
+};
+
 /*!
  * \since 1.8
  * \brief Information needed to specify a subaddress in a call.
@@ -233,6 +292,7 @@
  *       Osten Asklund or Oesten Aasklund depending upon language and person...
  *       We need automatic routines for incoming calls and static settings for
  *       our own accounts.
+ * BUGBUG to be deleted.
  */
 struct ast_callerid {
 	/*!
@@ -314,14 +374,43 @@
 	/*! \brief Subscriber name (Malloced) */
 	char *name;
 
+	/*! \brief Q.931 encoded type-of-number/numbering-plan fields */
+	int number_type;
+
+	/*! \brief Q.931 encoded number presentation/screening fields */
+	int number_presentation;
+
+/* BUGBUG XXX_name XXX_number */
+	/*! \brief Subscriber name */
+	struct ast_party_name XXX_name;
+	/*! \brief Subscriber phone number */
+	struct ast_party_number XXX_number;
 	/*! \brief Subscriber subaddress. */
 	struct ast_party_subaddress subaddress;
-
-	/*! \brief Q.931 encoded type-of-number/numbering-plan fields */
-	int number_type;
-
-	/*! \brief Q.931 encoded number presentation/screening fields */
-	int number_presentation;
+};
+
+/*!
+ * \since 1.8
+ * \brief Dialed/Called Party information.
+ * \note Dialed Number Identifier (DNID)
+ * \note All string fields here are malloc'ed, so they need to be
+ * freed when the structure is deleted.
+ * \note NULL and "" must be considered equivalent.
+ */
+struct ast_party_dialed {
+	/*!
+	 * \brief Dialed/Called number
+	 * \note ast_party_dialed.number.presentation is not used.
+	 */
+	struct ast_party_number number;
+	/*! \brief Dialed/Called subaddress */
+	struct ast_party_subaddress subaddress;
+	/*!
+	 * \brief Transit Network Select
+	 * \note Currently this value is just passed around the system.
+	 * You can read it and set it but it is never used for anything.
+	 */
+	int transit_network_select;
 };
 
 /*!
@@ -330,11 +419,25 @@
  * \note All string fields here are malloc'ed, so they need to be
  * freed when the structure is deleted.
  * \note NULL and "" must be considered equivalent.
+ *
+ * \note SIP and IAX2 has UTF8 encoded Unicode Caller ID names.
+ * In some cases, we also have an alternative (RPID) E.164 number that can
+ * be used as Caller ID on numeric E.164 phone networks (DAHDI or SIP/IAX2 to
+ * PSTN gateway).
+ *
+ * \todo Implement settings for transliteration between UTF8 Caller ID names in
+ *       to ASCII Caller ID's (DAHDI). Östen Åsklund might be transliterated into
+ *       Osten Asklund or Oesten Aasklund depending upon language and person...
+ *       We need automatic routines for incoming calls and static settings for
+ *       our own accounts.
  */
 struct ast_party_caller {
 	struct ast_party_id id;		/*! \brief Caller party ID */
 
-	/*! \brief Automatic Number Identification (ANI) (Malloced) */
+	/*!
+	 * \brief Automatic Number Identification (ANI) (Malloced)
+	 * \todo BUGBUG Maybe this should be an ast_party_id instead.
+	 */
 	char *ani;
 
 	/*! \brief Automatic Number Identification 2 (Info Digits) */
@@ -355,6 +458,7 @@
 	 * \brief Automatic Number Identification (ANI) (Malloced)
 	 * \note Not really part of connected line data but needed to
 	 * save the corresponding caller id value.
+	 * \todo BUGBUG Maybe this should be an ast_party_id instead.
 	 */
 	char *ani;
 
@@ -687,10 +791,25 @@
 
 	/*!
 	 * \brief Channel Caller ID information.
+	 * BUGBUG to be deleted.
 	 * \note The caller id information is the caller id of this
 	 * channel when it is used to initiate a call.
 	 */
 	struct ast_callerid cid;
+
+	/*!
+	 * \brief Dialed/Called information.
+	 * \note Set on incoming channels to indicate the originally dialed party.
+	 * \note Dialed Number Identifier (DNID)
+	 */
+	struct ast_party_dialed dialed;
+
+	/*!
+	 * \brief Channel Caller ID information.
+	 * \note The caller id information is the caller id of this
+	 * channel when it is used to initiate a call.
+	 */
+	struct ast_party_caller caller;
 
 	/*!
 	 * \brief Channel Connected Line ID information.
@@ -2393,7 +2512,7 @@
 
 /*!
  * \since 1.8
- * \brief Initialize the given party subadress structure using the given guide
+ * \brief Initialize the given party subaddress structure using the given guide
  * for a set update operation.
  *
  * \details
@@ -2403,7 +2522,7 @@
  * String values are simply set to NULL pointers if they are not going
  * to be updated.
  *
- * \param init Party Subaddress structure to initialize.
+ * \param init Party subaddress structure to initialize.
  * \param guide Source party subaddress to use as a guide in initializing.
  *
  * \return Nothing
@@ -2430,6 +2549,26 @@
  * \return Nothing
  */
 void ast_party_subaddress_free(struct ast_party_subaddress *doomed);
+
+/*!
+ * \brief Determine the overall presentation value for the given party.
+ * \since 1.8
+ *
+ * \param id Party to determine the overall presentation value.
+ *
+ * \return Overall presentation value for the given party.
+ */
+int ast_party_id_presentation(const struct ast_party_id *id);
+
+/*!
+ * \brief Copy the source dialed party information to the destination dialed party.
+ *
+ * \param dest Destination dialed party
+ * \param src Source dialed party
+ *
+ * \return Nothing
+ */
+void ast_party_dialed_copy(struct ast_party_dialed *dest, const struct ast_party_dialed *src);
 
 /*!
  * \since 1.8

Modified: team/rmudgett/cid/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/cid/main/channel.c?view=diff&rev=260341&r1=260340&r2=260341
==============================================================================
--- team/rmudgett/cid/main/channel.c (original)
+++ team/rmudgett/cid/main/channel.c Fri Apr 30 13:18:41 2010
@@ -843,6 +843,8 @@
 
 static void ast_channel_destructor(void *obj);
 static void ast_dummy_channel_destructor(void *obj);
+static void ast_party_dialed_init(struct ast_party_dialed *init);
+static void ast_party_redirecting_init(struct ast_party_redirecting *init);
 
 /*! \brief Create a new channel structure */
 static struct ast_channel * attribute_malloc __attribute__((format(printf, 13, 0)))
@@ -885,6 +887,11 @@
 	if ((ast_string_field_init(tmp, 128))) {
 		return ast_channel_unref(tmp);
 	}
+
+	ast_party_dialed_init(&tmp->dialed);
+	ast_party_caller_init(&tmp->caller);
+	ast_party_connected_line_init(&tmp->connected);
+	ast_party_redirecting_init(&tmp->redirecting);
 
 	if (cid_name) {
 		if (!(tmp->cid.cid_name = ast_strdup(cid_name))) {
@@ -1520,14 +1527,10 @@
 
 static void free_cid(struct ast_callerid *cid)
 {
-	if (cid->cid_dnid)
-		ast_free(cid->cid_dnid);
-	if (cid->cid_num)
-		ast_free(cid->cid_num);	
-	if (cid->cid_name)
-		ast_free(cid->cid_name);	
-	if (cid->cid_ani)
-		ast_free(cid->cid_ani);
+	ast_free(cid->cid_dnid);
+	ast_free(cid->cid_num);
+	ast_free(cid->cid_name);
+	ast_free(cid->cid_ani);
 	cid->cid_dnid = cid->cid_num = cid->cid_name = cid->cid_ani = NULL;
 	ast_party_subaddress_free(&cid->subaddress);
 	ast_party_subaddress_free(&cid->dialed_subaddress);
@@ -1538,6 +1541,224 @@
 	/* Safe, even if already unlinked. */
 	ao2_unlink(channels, chan);
 	return ast_channel_unref(chan);
+}
+
+/*!
+ * \internal
+ * \since 1.8
+ * \brief Initialize the given name structure.
+ *
+ * \param init Name structure to initialize.
+ *
+ * \return Nothing
+ */
+static void ast_party_name_init(struct ast_party_name *init)
+{
+	init->str = NULL;
+	init->char_set = 1;/* iso8859-1 */
+	init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
+	init->valid = 0;
+}
+
+/*!
+ * \internal
+ * \since 1.8
+ * \brief Copy the source party name information to the destination party name.
+ *
+ * \param dest Destination party name
+ * \param src Source party name
+ *
+ * \return Nothing
+ */
+static void ast_party_name_copy(struct ast_party_name *dest, const struct ast_party_name *src)
+{
+	if (dest == src) {
+		/* Don't copy to self */
+		return;
+	}
+
+	ast_free(dest->str);
+	dest->str = ast_strdup(src->str);
+	dest->char_set = src->char_set;
+	dest->presentation = src->presentation;
+	dest->valid = src->valid;
+}
+
+/*!
+ * \internal
+ * \since 1.8
+ * \brief Initialize the given party name structure using the given guide
+ * for a set update operation.
+ *
+ * \details
+ * The initialization is needed to allow a set operation to know if a
+ * value needs to be updated.  Simple integers need the guide's original
+ * value in case the set operation is not trying to set a new value.
+ * String values are simply set to NULL pointers if they are not going
+ * to be updated.
+ *
+ * \param init Party name structure to initialize.
+ * \param guide Source party name to use as a guide in initializing.
+ *
+ * \return Nothing
+ */
+static void ast_party_name_set_init(struct ast_party_name *init, const struct ast_party_name *guide)
+{
+	init->str = NULL;
+	init->char_set = guide->char_set;
+	init->presentation = guide->presentation;
+	init->valid = guide->valid;
+}
+
+/*!
+ * \internal
+ * \since 1.8
+ * \brief Set the source party name information into the destination party name.
+ *
+ * \param dest Destination party name
+ * \param src Source party name
+ *
+ * \return Nothing
+ */
+static void ast_party_name_set(struct ast_party_name *dest, const struct ast_party_name *src)
+{
+	if (dest == src) {
+		/* Don't set to self */
+		return;
+	}
+
+	if (src->str && src->str != dest->str) {
+		ast_free(dest->str);
+		dest->str = ast_strdup(src->str);
+	}
+
+	dest->char_set = src->char_set;
+	dest->presentation = src->presentation;
+	dest->valid = src->valid;
+}
+
+/*!
+ * \internal
+ * \since 1.8
+ * \brief Destroy the party name contents
+ *
+ * \param doomed The party name to destroy.
+ *
+ * \return Nothing
+ */
+static void ast_party_name_free(struct ast_party_name *doomed)
+{
+	ast_free(doomed->str);
+	doomed->str = NULL;
+}
+
+/*!
+ * \internal
+ * \since 1.8
+ * \brief Initialize the given number structure.
+ *
+ * \param init Number structure to initialize.
+ *
+ * \return Nothing
+ */
+static void ast_party_number_init(struct ast_party_number *init)
+{
+	init->str = NULL;
+	init->plan = 0;/* Unknown */
+	init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
+	init->valid = 0;
+}
+
+/*!
+ * \internal
+ * \since 1.8
+ * \brief Copy the source party number information to the destination party number.
+ *
+ * \param dest Destination party number
+ * \param src Source party number
+ *
+ * \return Nothing
+ */
+static void ast_party_number_copy(struct ast_party_number *dest, const struct ast_party_number *src)
+{
+	if (dest == src) {
+		/* Don't copy to self */
+		return;
+	}
+
+	ast_free(dest->str);
+	dest->str = ast_strdup(src->str);
+	dest->plan = src->plan;
+	dest->presentation = src->presentation;
+	dest->valid = src->valid;
+}
+
+/*!
+ * \internal
+ * \since 1.8
+ * \brief Initialize the given party number structure using the given guide
+ * for a set update operation.
+ *
+ * \details
+ * The initialization is needed to allow a set operation to know if a
+ * value needs to be updated.  Simple integers need the guide's original
+ * value in case the set operation is not trying to set a new value.
+ * String values are simply set to NULL pointers if they are not going
+ * to be updated.
+ *
+ * \param init Party number structure to initialize.
+ * \param guide Source party number to use as a guide in initializing.
+ *
+ * \return Nothing
+ */
+static void ast_party_number_set_init(struct ast_party_number *init, const struct ast_party_number *guide)
+{
+	init->str = NULL;
+	init->plan = guide->plan;
+	init->presentation = guide->presentation;
+	init->valid = guide->valid;
+}
+
+/*!
+ * \internal
+ * \since 1.8
+ * \brief Set the source party number information into the destination party number.
+ *
+ * \param dest Destination party number
+ * \param src Source party number
+ *
+ * \return Nothing
+ */
+static void ast_party_number_set(struct ast_party_number *dest, const struct ast_party_number *src)
+{
+	if (dest == src) {
+		/* Don't set to self */
+		return;
+	}
+
+	if (src->str && src->str != dest->str) {
+		ast_free(dest->str);
+		dest->str = ast_strdup(src->str);
+	}
+
+	dest->plan = src->plan;
+	dest->presentation = src->presentation;
+	dest->valid = src->valid;
+}
+
+/*!
+ * \internal
+ * \since 1.8
+ * \brief Destroy the party number contents
+ *
+ * \param doomed The party number to destroy.
+ *
+ * \return Nothing
+ */
+static void ast_party_number_free(struct ast_party_number *doomed)
+{
+	ast_free(doomed->str);
+	doomed->str = NULL;
 }
 
 void ast_party_subaddress_init(struct ast_party_subaddress *init)
@@ -1555,9 +1776,7 @@
 		return;
 	}
 
-	if (dest->str) {
-		ast_free(dest->str);
-	}
+	ast_free(dest->str);
 	dest->str = ast_strdup(src->str);
 	dest->type = src->type;
 	dest->odd_even_indicator = src->odd_even_indicator;
@@ -1580,9 +1799,7 @@
 	}
 
 	if (src->str && src->str != dest->str) {
-		if (dest->str) {
-			ast_free(dest->str);
-		}
+		ast_free(dest->str);
 		dest->str = ast_strdup(src->str);
 	}
 
@@ -1593,10 +1810,8 @@
 
 void ast_party_subaddress_free(struct ast_party_subaddress *doomed)
 {
-	if (doomed->str) {
-		ast_free(doomed->str);
-		doomed->str = NULL;
-	}
+	ast_free(doomed->str);
+	doomed->str = NULL;
 }
 
 /*!
@@ -1609,10 +1824,14 @@
  */
 static void ast_party_id_init(struct ast_party_id *init)
 {
+#if 1/* BUGBUG */
 	init->number = NULL;
 	init->name = NULL;
 	init->number_type = 0;	/* Unknown */
 	init->number_presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
+#endif
+	ast_party_name_init(&init->XXX_name);
+	ast_party_number_init(&init->XXX_number);
 	ast_party_subaddress_init(&init->subaddress);
 }
 
@@ -1632,18 +1851,18 @@
 		return;
 	}
 
-	if (dest->number) {
-		ast_free(dest->number);
-	}
+#if 1/* BUGBUG */
+	ast_free(dest->number);
 	dest->number = ast_strdup(src->number);
 
-	if (dest->name) {
-		ast_free(dest->name);
-	}
+	ast_free(dest->name);
 	dest->name = ast_strdup(src->name);
 
 	dest->number_type = src->number_type;
 	dest->number_presentation = src->number_presentation;
+#endif
+	ast_party_name_copy(&dest->XXX_name, &src->XXX_name);
+	ast_party_number_copy(&dest->XXX_number, &src->XXX_number);
 	ast_party_subaddress_copy(&dest->subaddress, &src->subaddress);
 }
 
@@ -1666,10 +1885,14 @@
  */
 static void ast_party_id_set_init(struct ast_party_id *init, const struct ast_party_id *guide)
 {
+#if 1/* BUGBUG */
 	init->number = NULL;
 	init->name = NULL;
 	init->number_type = guide->number_type;
 	init->number_presentation = guide->number_presentation;
+#endif
+	ast_party_name_set_init(&init->XXX_name, &guide->XXX_name);
+	ast_party_number_set_init(&init->XXX_number, &guide->XXX_number);
 	ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress);
 }
 
@@ -1689,22 +1912,22 @@
 		return;
 	}
 
+#if 1/* BUGBUG */
 	if (src->name && src->name != dest->name) {
-		if (dest->name) {
-			ast_free(dest->name);
-		}
+		ast_free(dest->name);
 		dest->name = ast_strdup(src->name);
 	}
 
 	if (src->number && src->number != dest->number) {
-		if (dest->number) {
-			ast_free(dest->number);
-		}
+		ast_free(dest->number);
 		dest->number = ast_strdup(src->number);
 	}
 
 	dest->number_type = src->number_type;
 	dest->number_presentation = src->number_presentation;
+#endif
+	ast_party_name_set(&dest->XXX_name, &src->XXX_name);
+	ast_party_number_set(&dest->XXX_number, &src->XXX_number);
 	ast_party_subaddress_set(&dest->subaddress, &src->subaddress);
 }
 
@@ -1718,15 +1941,118 @@
  */
 static void ast_party_id_free(struct ast_party_id *doomed)
 {
-	if (doomed->number) {
-		ast_free(doomed->number);
-		doomed->number = NULL;
-	}
-
-	if (doomed->name) {
-		ast_free(doomed->name);
-		doomed->name = NULL;
-	}
+#if 1/* BUGBUG */
+	ast_free(doomed->number);
+	doomed->number = NULL;
+
+	ast_free(doomed->name);
+	doomed->name = NULL;
+#endif
+	ast_party_name_free(&doomed->XXX_name);
+	ast_party_number_free(&doomed->XXX_number);
+	ast_party_subaddress_free(&doomed->subaddress);
+}
+
+int ast_party_id_presentation(const struct ast_party_id *id)
+{
+	int number_priority;
+	int number_value;
+	int number_screening;
+	int name_priority;
+	int name_value;
+
+	/* Determine name presentation priority. */
+	if (!id->XXX_name.valid) {
+		name_value = AST_PRES_UNAVAILABLE;
+		name_priority = 3;
+	} else {
+		name_value = id->XXX_name.presentation & AST_PRES_RESTRICTION;
+		switch (name_value) {
+		case AST_PRES_RESTRICTED:
+			name_priority = 0;
+			break;
+		case AST_PRES_ALLOWED:
+			name_priority = 1;
+			break;
+		case AST_PRES_UNAVAILABLE:
+			name_priority = 2;
+			break;
+		default:
+			name_value = AST_PRES_UNAVAILABLE;
+			name_priority = 3;
+			break;
+		}
+	}
+
+	/* Determine number presentation priority. */
+	if (!id->XXX_number.valid) {
+		number_screening = AST_PRES_USER_NUMBER_UNSCREENED;
+		number_value = AST_PRES_UNAVAILABLE;
+		number_priority = 3;
+	} else {
+		number_screening = id->XXX_number.presentation & AST_PRES_NUMBER_TYPE;
+		number_value = id->XXX_number.presentation & AST_PRES_RESTRICTION;
+		switch (number_value) {
+		case AST_PRES_RESTRICTED:
+			number_priority = 0;
+			break;
+		case AST_PRES_ALLOWED:
+			number_priority = 1;
+			break;
+		case AST_PRES_UNAVAILABLE:
+			number_priority = 2;
+			break;
+		default:
+			number_screening = AST_PRES_USER_NUMBER_UNSCREENED;
+			number_value = AST_PRES_UNAVAILABLE;
+			number_priority = 3;
+			break;
+		}
+	}
+
+	/* Select the wining presentation value. */
+	if (name_priority < number_priority) {
+		number_value = name_value;
+	}
+
+	return number_value | number_screening;
+}
+
+/*!
+ * \internal
+ * \since 1.8
+ * \brief Initialize the given dialed structure.
+ *
+ * \param init Dialed structure to initialize.
+ *
+ * \return Nothing
+ */
+static void ast_party_dialed_init(struct ast_party_dialed *init)
+{
+	ast_party_number_init(&init->number);
+	ast_party_subaddress_init(&init->subaddress);
+	init->transit_network_select = 0;
+}
+
+void ast_party_dialed_copy(struct ast_party_dialed *dest, const struct ast_party_dialed *src)
+{
+	ast_party_number_copy(&dest->number, &src->number);
+	ast_party_subaddress_copy(&dest->subaddress, &src->subaddress);
+	dest->transit_network_select = src->transit_network_select;
+}
+
+/*!
+ * \internal
+ * \since 1.8
+ * \brief Destroy the dialed party contents
+ *
+ * \param doomed The dialed party to destroy.
+ *
+ * \return Nothing
+ */
+static void ast_party_dialed_free(struct ast_party_dialed *doomed)
+{
+	ast_party_number_free(&doomed->number);
 	ast_party_subaddress_free(&doomed->subaddress);
 }
 
@@ -1746,26 +2072,17 @@
 
 #if 1
 	/* Copy caller-id specific information ONLY from struct ast_callerid */
-	if (dest->cid_num)
-	{
-		ast_free(dest->cid_num);
-	}
+	ast_free(dest->cid_num);
 	dest->cid_num = ast_strdup(src->cid_num);
 
-	if (dest->cid_name)
-	{
-		ast_free(dest->cid_name);
-	}
+	ast_free(dest->cid_name);
 	dest->cid_name = ast_strdup(src->cid_name);
 
 	dest->cid_ton = src->cid_ton;
 	dest->cid_pres = src->cid_pres;
 
 
-	if (dest->cid_ani)
-	{
-		ast_free(dest->cid_ani);
-	}
+	ast_free(dest->cid_ani);
 	dest->cid_ani = ast_strdup(src->cid_ani);
 
 	dest->cid_ani2 = src->cid_ani2;
@@ -1779,13 +2096,28 @@
 
 	ast_party_id_copy(&dest->id, &src->id);
 
-	if (dest->ani) {
-		ast_free(dest->ani);
-	}
+	ast_free(dest->ani);
 	dest->ani = ast_strdup(src->ani);
 
 	dest->ani2 = src->ani2;
 #endif
+}
+
+/*!
+ * \internal
+ * \since 1.8
+ * \brief Destroy the caller party contents
+ *
+ * \param doomed The caller party to destroy.
+ *
+ * \return Nothing
+ */
+static void ast_party_caller_free(struct ast_party_caller *doomed)
+{
+	ast_party_id_free(&doomed->id);
+
+	ast_free(doomed->ani);
+	doomed->ani = NULL;
 }
 
 void ast_party_connected_line_init(struct ast_party_connected_line *init)
@@ -1805,9 +2137,7 @@
 
 	ast_party_id_copy(&dest->id, &src->id);
 
-	if (dest->ani) {
-		ast_free(dest->ani);
-	}
+	ast_free(dest->ani);
 	dest->ani = ast_strdup(src->ani);
 
 	dest->ani2 = src->ani2;
@@ -1827,9 +2157,7 @@
 	ast_party_id_set(&dest->id, &src->id);
 
 	if (src->ani && src->ani != dest->ani) {
-		if (dest->ani) {
-			ast_free(dest->ani);
-		}
+		ast_free(dest->ani);
 		dest->ani = ast_strdup(src->ani);
 	}
 
@@ -1854,10 +2182,25 @@
 {
 	ast_party_id_free(&doomed->id);
 
-	if (doomed->ani) {
-		ast_free(doomed->ani);
-		doomed->ani = NULL;
-	}
+	ast_free(doomed->ani);
+	doomed->ani = NULL;
+}
+
+/*!
+ * \internal
+ * \since 1.8
+ * \brief Initialize the given redirecting structure.
+ *
+ * \param init Redirecting structure to initialize.
+ *
+ * \return Nothing
+ */
+static void ast_party_redirecting_init(struct ast_party_redirecting *init)
+{
+	ast_party_id_init(&init->from);
+	ast_party_id_init(&init->to);
+	init->count = 0;
+	init->reason = AST_REDIRECTING_REASON_UNKNOWN;
 }
 
 void ast_party_redirecting_copy(struct ast_party_redirecting *dest, const struct ast_party_redirecting *src)
@@ -1948,6 +2291,8 @@
 		ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
 
 	free_cid(&chan->cid);
+	ast_party_dialed_free(&chan->dialed);
+	ast_party_caller_free(&chan->caller);
 	ast_party_connected_line_free(&chan->connected);
 	ast_party_redirecting_free(&chan->redirecting);
 
@@ -5571,18 +5916,15 @@
 	ast_channel_lock(chan);
 
 	if (cid_num) {
-		if (chan->cid.cid_num)
-			ast_free(chan->cid.cid_num);
+		ast_free(chan->cid.cid_num);
 		chan->cid.cid_num = ast_strdup(cid_num);
 	}
 	if (cid_name) {
-		if (chan->cid.cid_name)
-			ast_free(chan->cid.cid_name);
+		ast_free(chan->cid.cid_name);
 		chan->cid.cid_name = ast_strdup(cid_name);
 	}
 	if (cid_ani) {
-		if (chan->cid.cid_ani)
-			ast_free(chan->cid.cid_ani);
+		ast_free(chan->cid.cid_ani);
 		chan->cid.cid_ani = ast_strdup(cid_ani);
 	}
 
@@ -6766,23 +7108,17 @@
 {
 #if 1
 	/* Must manually fill in struct ast_party_id until struct ast_callerid goes away */
-	if (dest->id.number) {
-		ast_free(dest->id.number);
-	}
+	ast_free(dest->id.number);
 	dest->id.number = ast_strdup(src->cid_num);
 
-	if (dest->id.name) {
-		ast_free(dest->id.name);
-	}
+	ast_free(dest->id.name);
 	dest->id.name = ast_strdup(src->cid_name);
 
 	dest->id.number_type = src->cid_ton;
 	dest->id.number_presentation = src->cid_pres;
 
 
-	if (dest->ani) {
-		ast_free(dest->ani);
-	}
+	ast_free(dest->ani);
 	dest->ani = ast_strdup(src->cid_ani);
 
 	dest->ani2 = src->cid_ani2;
@@ -6795,9 +7131,7 @@
 
 	ast_party_id_copy(&dest->id, &src->id);
 
-	if (dest->ani) {
-		ast_free(dest->ani);
-	}
+	ast_free(dest->ani);
 	dest->ani = ast_strdup(src->ani);
 
 	dest->ani2 = src->ani2;
@@ -6808,23 +7142,17 @@
 {
 #if 1
 	/* Must manually extract from struct ast_party_id until struct ast_callerid goes away */
-	if (dest->cid_num) {
-		ast_free(dest->cid_num);
-	}
+	ast_free(dest->cid_num);
 	dest->cid_num = ast_strdup(src->id.number);
 
-	if (dest->cid_name) {
-		ast_free(dest->cid_name);
-	}
+	ast_free(dest->cid_name);
 	dest->cid_name = ast_strdup(src->id.name);
 
 	dest->cid_ton = src->id.number_type;
 	dest->cid_pres = src->id.number_presentation;
 
 
-	if (dest->cid_ani) {
-		ast_free(dest->cid_ani);
-	}
+	ast_free(dest->cid_ani);
 	dest->cid_ani = ast_strdup(src->ani);
 
 	dest->cid_ani2 = src->ani2;
@@ -6837,9 +7165,7 @@
 
 	ast_party_id_copy(&dest->id, &src->id);
 
-	if (dest->ani) {
-		ast_free(dest->ani);
-	}
+	ast_free(dest->ani);
 	dest->ani = ast_strdup(src->ani);
 
 	dest->ani2 = src->ani2;
@@ -6856,6 +7182,298 @@
 	ast_channel_lock(chan);
 	ast_party_connected_line_set(&chan->connected, connected);
 	ast_channel_unlock(chan);
+}
+
+/*! \note Should follow struct ast_party_name */
+struct ast_party_name_ies {
+	/*! \brief Subscriber name ie */
+	int str;
+	/*! \brief Character set ie. */
+	int char_set;
+	/*! \brief presentation-indicator ie */
+	int presentation;
+	/*! \brief valid/present ie */
+	int valid;
+};
+
+/*!
+ * \internal
+ * \since 1.8
+ * \brief Build a party name information data frame component.
+ *
+ * \param data Buffer to fill with the frame data
+ * \param datalen Size of the buffer to fill
+ * \param name Party name information
+ * \param label Name of particular party name
+ * \param ies Data frame ie values for the party name components
+ *
+ * \retval -1 if error
+ * \retval Amount of data buffer used
+ */
+static int ast_party_name_build_data(unsigned char *data, size_t datalen, const struct ast_party_name *name, const char *label, const struct ast_party_name_ies *ies)
+{
+	size_t length;
+	size_t pos = 0;
+
+	/*
+	 * The size of integer values must be fixed in case the frame is
+	 * shipped to another machine.
+	 */
+	if (name->str) {
+		length = strlen(name->str);
+		if (datalen < pos + (sizeof(data[0]) * 2) + length) {
+			ast_log(LOG_WARNING, "No space left for %s name\n", label);
+			return -1;
+		}
+		data[pos++] = ies->str;
+		data[pos++] = length;
+		memcpy(data + pos, name->str, length);
+		pos += length;
+	}
+
+	if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
+		ast_log(LOG_WARNING, "No space left for %s name char set\n", label);
+		return -1;
+	}
+	data[pos++] = ies->char_set;
+	data[pos++] = 1;
+	data[pos++] = name->char_set;
+
+	if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
+		ast_log(LOG_WARNING, "No space left for %s name presentation\n", label);
+		return -1;
+	}
+	data[pos++] = ies->presentation;
+	data[pos++] = 1;
+	data[pos++] = name->presentation;
+
+	if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
+		ast_log(LOG_WARNING, "No space left for %s name valid\n", label);
+		return -1;
+	}
+	data[pos++] = ies->valid;
+	data[pos++] = 1;
+	data[pos++] = name->valid;
+
+	return pos;
+}
+
+/*! \note Should follow struct ast_party_number */
+struct ast_party_number_ies {
+	/*! \brief Subscriber phone number ie */
+	int str;
+	/*! \brief Type-Of-Number and Numbering-Plan ie */
+	int plan;
+	/*! \brief presentation-indicator ie */
+	int presentation;
+	/*! \brief valid/present ie */
+	int valid;
+};
+
+/*!
+ * \internal
+ * \since 1.8
+ * \brief Build a party number information data frame component.
+ *
+ * \param data Buffer to fill with the frame data
+ * \param datalen Size of the buffer to fill
+ * \param number Party number information
+ * \param label Name of particular party number
+ * \param ies Data frame ie values for the party number components
+ *
+ * \retval -1 if error
+ * \retval Amount of data buffer used
+ */
+static int ast_party_number_build_data(unsigned char *data, size_t datalen, const struct ast_party_number *number, const char *label, const struct ast_party_number_ies *ies)
+{
+	size_t length;
+	size_t pos = 0;
+
+	/*
+	 * The size of integer values must be fixed in case the frame is
+	 * shipped to another machine.
+	 */
+	if (number->str) {
+		length = strlen(number->str);
+		if (datalen < pos + (sizeof(data[0]) * 2) + length) {
+			ast_log(LOG_WARNING, "No space left for %s number\n", label);
+			return -1;
+		}
+		data[pos++] = ies->str;
+		data[pos++] = length;
+		memcpy(data + pos, number->str, length);
+		pos += length;
+	}
+
+	if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
+		ast_log(LOG_WARNING, "No space left for %s numbering plan\n", label);
+		return -1;
+	}
+	data[pos++] = ies->plan;
+	data[pos++] = 1;
+	data[pos++] = number->plan;
+
+	if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
+		ast_log(LOG_WARNING, "No space left for %s number presentation\n", label);
+		return -1;
+	}
+	data[pos++] = ies->presentation;
+	data[pos++] = 1;
+	data[pos++] = number->presentation;
+
+	if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
+		ast_log(LOG_WARNING, "No space left for %s number valid\n", label);
+		return -1;
+	}
+	data[pos++] = ies->valid;
+	data[pos++] = 1;
+	data[pos++] = number->valid;
+
+	return pos;
+}
+
+/*! \note Should follow struct ast_party_subaddress */
+struct ast_party_subaddress_ies {
+	/*! \brief subaddress ie. */
+	int str;
+	/*! \brief subaddress type ie */
+	int type;
+	/*! \brief odd/even indicator ie */
+	int odd_even_indicator;
+	/*! \brief valid/present ie */
+	int valid;
+};
+
+/*!
+ * \internal
+ * \since 1.8
+ * \brief Build a party subaddress information data frame component.
+ *
+ * \param data Buffer to fill with the frame data
+ * \param datalen Size of the buffer to fill
+ * \param subaddress Party subaddress information
+ * \param label Name of particular party subaddress
+ * \param ies Data frame ie values for the party subaddress components
+ *
+ * \retval -1 if error
+ * \retval Amount of data buffer used
+ */
+static int ast_party_subaddress_build_data(unsigned char *data, size_t datalen, const struct ast_party_subaddress *subaddress, const char *label, const struct ast_party_subaddress_ies *ies)
+{
+	size_t length;
+	size_t pos = 0;
+
+	/*
+	 * The size of integer values must be fixed in case the frame is
+	 * shipped to another machine.
+	 */
+	if (subaddress->str) {
+		length = strlen(subaddress->str);
+		if (datalen < pos + (sizeof(data[0]) * 2) + length) {
+			ast_log(LOG_WARNING, "No space left for %s subaddress\n", label);
+			return -1;
+		}
+		data[pos++] = ies->str;
+		data[pos++] = length;
+		memcpy(data + pos, subaddress->str, length);
+		pos += length;
+	}
+
+	if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
+		ast_log(LOG_WARNING, "No space left for %s type of subaddress\n", label);
+		return -1;
+	}
+	data[pos++] = ies->type;
+	data[pos++] = 1;
+	data[pos++] = subaddress->type;
+
+	if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
+		ast_log(LOG_WARNING,
+			"No space left for %s subaddress odd-even indicator\n", label);
+		return -1;
+	}
+	data[pos++] = ies->odd_even_indicator;
+	data[pos++] = 1;
+	data[pos++] = subaddress->odd_even_indicator;
+
+	if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
+		ast_log(LOG_WARNING, "No space left for %s subaddress valid\n", label);
+		return -1;
+	}
+	data[pos++] = ies->valid;
+	data[pos++] = 1;
+	data[pos++] = subaddress->valid;
+
+	return pos;
+}
+
+/*! \note Should follow struct ast_party_id */
+struct ast_party_id_ies {
+	/*! \brief Subscriber name ies */
+	struct ast_party_name_ies name;
+	/*! \brief Subscriber phone number ies */
+	struct ast_party_number_ies number;
+	/*! \brief Subscriber subaddress ies. */
+	struct ast_party_subaddress_ies subaddress;
+	/*! \brief Combined name and number presentation ie. */
+	int combined_presentation;
+};
+
+/*!
+ * \internal
+ * \since 1.8
+ * \brief Build a party id information data frame component.
+ *
+ * \param data Buffer to fill with the frame data
+ * \param datalen Size of the buffer to fill
+ * \param id Party id information
+ * \param label Name of particular party id
+ * \param ies Data frame ie values for the party id components
+ *
+ * \retval -1 if error
+ * \retval Amount of data buffer used
+ */
+static int ast_party_id_build_data(unsigned char *data, size_t datalen, const struct ast_party_id *id, const char *label, const struct ast_party_id_ies *ies)
+{
+	size_t pos = 0;
+	int res;
+
+	/*
+	 * The size of integer values must be fixed in case the frame is
+	 * shipped to another machine.
+	 */
+
+	res = ast_party_name_build_data(data + pos, datalen - pos, &id->XXX_name, label,
+		&ies->name);
+	if (res < 0) {
+		return -1;
+	}
+	pos += res;
+
+	res = ast_party_number_build_data(data + pos, datalen - pos, &id->XXX_number, label,
+		&ies->number);
+	if (res < 0) {
+		return -1;
+	}
+	pos += res;
+
+	res = ast_party_subaddress_build_data(data + pos, datalen - pos, &id->subaddress,
+		label, &ies->subaddress);
+	if (res < 0) {
+		return -1;
+	}
+	pos += res;
+
+	/* *************** Party id combined presentation *************** */
+	if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
+		ast_log(LOG_WARNING, "No space left for %s combined presentation\n", label);
+		return -1;
+	}
+	data[pos++] = ies->combined_presentation;
+	data[pos++] = 1;
+	data[pos++] = ast_party_id_presentation(id);
+
+	return pos;
 }
 
 /*!
@@ -6865,66 +7483,55 @@
 enum {
 	AST_CONNECTED_LINE_NUMBER,
 	AST_CONNECTED_LINE_NAME,
-	AST_CONNECTED_LINE_NUMBER_TYPE,
-	AST_CONNECTED_LINE_NUMBER_PRESENTATION,
+	AST_CONNECTED_LINE_NUMBER_PLAN,
+	AST_CONNECTED_LINE_ID_PRESENTATION,/* Combined number and name presentation. */
 	AST_CONNECTED_LINE_SOURCE,
 	AST_CONNECTED_LINE_SUBADDRESS,
 	AST_CONNECTED_LINE_SUBADDRESS_TYPE,
 	AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN,
-	AST_CONNECTED_LINE_SUBADDRESS_VALID
+	AST_CONNECTED_LINE_SUBADDRESS_VALID,
+	AST_CONNECTED_LINE_NAME_VALID,
+	AST_CONNECTED_LINE_NAME_CHAR_SET,
+	AST_CONNECTED_LINE_NAME_PRESENTATION,
+	AST_CONNECTED_LINE_NUMBER_VALID,
+	AST_CONNECTED_LINE_NUMBER_PRESENTATION,
 };
 
 int ast_connected_line_build_data(unsigned char *data, size_t datalen, const struct ast_party_connected_line *connected)
 {
 	int32_t value;
-	size_t length;
 	size_t pos = 0;
+	int res;
+
+	static const struct ast_party_id_ies ies = {
+		.name.str = AST_CONNECTED_LINE_NAME,
+		.name.char_set = AST_CONNECTED_LINE_NAME_CHAR_SET,
+		.name.presentation = AST_CONNECTED_LINE_NAME_PRESENTATION,
+		.name.valid = AST_CONNECTED_LINE_NAME_VALID,
+
+		.number.str = AST_CONNECTED_LINE_NUMBER,
+		.number.plan = AST_CONNECTED_LINE_NUMBER_PLAN,
+		.number.presentation = AST_CONNECTED_LINE_NUMBER_PRESENTATION,
+		.number.valid = AST_CONNECTED_LINE_NUMBER_VALID,
+
+		.subaddress.str = AST_CONNECTED_LINE_SUBADDRESS,
+		.subaddress.type = AST_CONNECTED_LINE_SUBADDRESS_TYPE,
+		.subaddress.odd_even_indicator = AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN,
+		.subaddress.valid = AST_CONNECTED_LINE_SUBADDRESS_VALID,
+
+		.combined_presentation = AST_CONNECTED_LINE_ID_PRESENTATION,
+	};
 
 	/*
 	 * The size of integer values must be fixed in case the frame is
 	 * shipped to another machine.
 	 */
-
-	/* *************** Connected line party id *************** */
-	if (connected->id.number) {
-		length = strlen(connected->id.number);
-		if (datalen < pos + (sizeof(data[0]) * 2) + length) {
-			ast_log(LOG_WARNING, "No space left for connected line number\n");
-			return -1;
-		}
-		data[pos++] = AST_CONNECTED_LINE_NUMBER;
-		data[pos++] = length;
-		memcpy(data + pos, connected->id.number, length);
-		pos += length;
-	}
-
-	if (connected->id.name) {
-		length = strlen(connected->id.name);
-		if (datalen < pos + (sizeof(data[0]) * 2) + length) {
-			ast_log(LOG_WARNING, "No space left for connected line name\n");
-			return -1;
-		}
-		data[pos++] = AST_CONNECTED_LINE_NAME;
-		data[pos++] = length;
-		memcpy(data + pos, connected->id.name, length);
-		pos += length;
-	}
-
-	if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
-		ast_log(LOG_WARNING, "No space left for connected line type of number\n");
+	res = ast_party_id_build_data(data + pos, datalen - pos, &connected->id,
+		"connected line", &ies);
+	if (res < 0) {
 		return -1;
 	}
-	data[pos++] = AST_CONNECTED_LINE_NUMBER_TYPE;
-	data[pos++] = 1;
-	data[pos++] = connected->id.number_type;
-
-	if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
-		ast_log(LOG_WARNING, "No space left for connected line presentation\n");
-		return -1;
-	}
-	data[pos++] = AST_CONNECTED_LINE_NUMBER_PRESENTATION;
-	data[pos++] = 1;
-	data[pos++] = connected->id.number_presentation;
+	pos = res;
 
 	/* Connected line source */
 	if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
@@ -6937,46 +7544,6 @@
 	memcpy(data + pos, &value, sizeof(value));
 	pos += sizeof(value);
 
-	/* Connected line Subaddress */
-	if (connected->id.subaddress.str) {
-		length = strlen(connected->id.subaddress.str);
-		if (datalen < pos + (sizeof(data[0]) * 2) + length) {
-			ast_log(LOG_WARNING, "No space left for connected line subaddress\n");
-			return -1;
-		}
-		data[pos++] = AST_CONNECTED_LINE_SUBADDRESS;
-		data[pos++] = length;
-		memcpy(data + pos, connected->id.subaddress.str, length);
-		pos += length;
-	}
-	/* Connected line Subaddress Type */
-	if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
-		ast_log(LOG_WARNING, "No space left for connected line type of subaddress\n");
-		return -1;
-	}
-	data[pos++] = AST_CONNECTED_LINE_SUBADDRESS_TYPE;
-	data[pos++] = 1;
-	data[pos++] = connected->id.subaddress.type;
-
-	/* Connected line Subaddress Odd/Even indicator */
-	if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
-		ast_log(LOG_WARNING,
-			"No space left for connected line subaddress odd-even indicator\n");
-		return -1;
-	}
-	data[pos++] = AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN;
-	data[pos++] = 1;
-	data[pos++] = connected->id.subaddress.odd_even_indicator;
-
-	/* Connected line Subaddress Valid */
-	if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
-		ast_log(LOG_WARNING, "No space left for connected line subaddress valid\n");
-		return -1;
-	}
-	data[pos++] = AST_CONNECTED_LINE_SUBADDRESS_VALID;
-	data[pos++] = 1;
-	data[pos++] = connected->id.subaddress.valid;
-
 	return pos;
 }
 
@@ -6986,6 +7553,10 @@
 	unsigned char ie_len;
 	unsigned char ie_id;
 	int32_t value;
+	int combined_presentation = 0;
+	int got_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */
+	int got_specific_presentation = 0;/* TRUE if got a specific name or number presentation value. */
+	int got_valid = 0;/* TRUE if got a name or number valid flag value. */
 
 	for (pos = 0; pos < datalen; pos += ie_len) {
 		if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) {
@@ -7000,52 +7571,89 @@
 		}
 
 		switch (ie_id) {
+/* Connected line party id name */
+		case AST_CONNECTED_LINE_NAME:
+			ast_free(connected->id.XXX_name.str);
+			connected->id.XXX_name.str = ast_malloc(ie_len + 1);

[... 773 lines stripped ...]



More information about the asterisk-commits mailing list