[asterisk-commits] rmudgett: branch rmudgett/iax_fracks r419910 - in /team/rmudgett/iax_fracks/c...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Aug 1 19:06:53 CDT 2014


Author: rmudgett
Date: Fri Aug  1 19:06:47 2014
New Revision: 419910

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=419910
Log:
chan_iax2: Set new channel native codec ordering to user preferences.

* Address concern that the channel's native codec ordering are not
according to the user's wishes.

* Rearange code some to make user preferences available to when the native
codec capability struct is created.

Modified:
    team/rmudgett/iax_fracks/channels/chan_iax2.c
    team/rmudgett/iax_fracks/channels/iax2/codec_pref.c
    team/rmudgett/iax_fracks/channels/iax2/format_compatibility.c
    team/rmudgett/iax_fracks/channels/iax2/include/codec_pref.h
    team/rmudgett/iax_fracks/channels/iax2/include/format_compatibility.h

Modified: team/rmudgett/iax_fracks/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/iax_fracks/channels/chan_iax2.c?view=diff&rev=419910&r1=419909&r2=419910
==============================================================================
--- team/rmudgett/iax_fracks/channels/chan_iax2.c (original)
+++ team/rmudgett/iax_fracks/channels/chan_iax2.c Fri Aug  1 19:06:47 2014
@@ -4602,6 +4602,7 @@
 struct create_addr_info {
 	iax2_format capability;
 	uint64_t flags;
+	struct iax2_codec_pref prefs;
 	int maxtime;
 	int encmethods;
 	int found;
@@ -4611,7 +4612,6 @@
 	char secret[80];
 	char outkey[80];
 	char timezone[80];
-	char prefs[32];
 	char cid_num[80];
 	char cid_name[80];
 	char context[AST_MAX_CONTEXT];
@@ -4661,7 +4661,7 @@
 				ao2_ref(format, -1);
 			}
 		}
-		iax2_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
+		cai->prefs = ourprefs;
 		return 0;
 	}
 
@@ -4694,7 +4694,7 @@
 			ao2_ref(tmpfmt, -1);
 		}
 	}
-	iax2_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
+	cai->prefs = ourprefs;
 	ast_copy_string(cai->context, peer->context, sizeof(cai->context));
 	ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
 	ast_copy_string(cai->username, peer->username, sizeof(cai->username));
@@ -5101,6 +5101,7 @@
 	unsigned char osp_block_index;
 	unsigned int osp_block_length;
 	unsigned char osp_buffer[256];
+	char encoded_prefs[32];
 	iax2_format iax2_tmpfmt;
 
 	if ((ast_channel_state(c) != AST_STATE_DOWN) && (ast_channel_state(c) != AST_STATE_RESERVED)) {
@@ -5169,7 +5170,8 @@
 	}
 
 	/* WARNING: this breaks down at 190 bits! */
-	iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
+	iax2_codec_pref_convert(&cai.prefs, encoded_prefs, sizeof(encoded_prefs), 1);
+	iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, encoded_prefs);
 
 	if (l) {
 		iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
@@ -5828,7 +5830,9 @@
 }
 
 /*! \brief  Create new call, interface with the PBX core */
-static struct ast_channel *ast_iax2_new(int callno, int state, iax2_format capability, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, unsigned int cachable)
+static struct ast_channel *ast_iax2_new(int callno, int state, iax2_format capability,
+	struct iax2_codec_pref *prefs, const struct ast_assigned_ids *assignedids,
+	const struct ast_channel *requestor, unsigned int cachable)
 {
 	struct ast_channel *tmp = NULL;
 	struct chan_iax2_pvt *i;
@@ -5853,9 +5857,7 @@
 	if (!native) {
 		return NULL;
 	}
-/* BUGBUG we really should use the cai.prefs on outgoing calls to generate the native codec ordering. */
-/* BUGBUG need to investigate the prefs ordering for incoming calls to generate the native codec ordering. */
-	if (iax2_format_compatibility_bitfield2cap_best(capability, native)
+	if (iax2_codec_pref_best_bitfield2cap(capability, prefs, native)
 		|| !ast_format_cap_count(native)) {
 		ast_log(LOG_WARNING, "No requested formats available for call to: IAX2/%s-%d\n",
 			i->host, i->callno);
@@ -7877,8 +7879,10 @@
 	/* Use provided preferences until told otherwise for actual preferences */
 	if (ies->codec_prefs) {
 		iax2_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
-		iax2_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
-	}
+	} else {
+		memset(&iaxs[callno]->rprefs, 0, sizeof(iaxs[callno]->rprefs));
+	}
+	iaxs[callno]->prefs = iaxs[callno]->rprefs;
 
 	if (!gotcapability) {
 		iaxs[callno]->peercapability = iaxs[callno]->peerformat;
@@ -10526,8 +10530,9 @@
 		    (f.frametype == AST_FRAME_IAX)) {
 			if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
 				ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
-				if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL, NULL,
-						  ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED))) {
+				if (!ast_iax2_new(fr->callno, AST_STATE_RING,
+					iaxs[fr->callno]->chosenformat, &iaxs[fr->callno]->rprefs, NULL, NULL,
+					ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED))) {
 					ast_variables_destroy(ies.vars);
 					ast_mutex_unlock(&iaxsl[fr->callno]);
 					return 1;
@@ -11081,7 +11086,9 @@
 						struct ast_str *cap_buf = ast_str_alloca(64);
 
 						/* Switch us to use a compatible format */
-						iax2_format_compatibility_bitfield2cap_best(iaxs[fr->callno]->peerformat, native);
+						iax2_codec_pref_best_bitfield2cap(
+							iaxs[fr->callno]->peerformat, &iaxs[fr->callno]->rprefs,
+							native);
 						ast_channel_nativeformats_set(iaxs[fr->callno]->owner, native);
 						ast_verb(3, "Format for call is %s\n", ast_format_cap_get_names(ast_channel_nativeformats(iaxs[fr->callno]->owner), &cap_buf));
 
@@ -11400,9 +11407,11 @@
 											using_prefs);
 
 							ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
-							if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL, NULL, 1)))
+							c = ast_iax2_new(fr->callno, AST_STATE_RING, format,
+								&iaxs[fr->callno]->rprefs, NULL, NULL, 1);
+							if (!c) {
 								iax2_destroy(fr->callno);
-							else if (ies.vars) {
+							} else if (ies.vars) {
 								struct ast_datastore *variablestore;
 								struct ast_variable *var, *prev = NULL;
 								AST_LIST_HEAD(, ast_var_t) *varlist;
@@ -11474,9 +11483,12 @@
 								iax2_getformatname_multiple(iaxs[fr->callno]->peerformat, &cap_buf));
 						ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
 						send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
-						if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL, NULL, 1)))
+						c = ast_iax2_new(fr->callno, AST_STATE_RING,
+							iaxs[fr->callno]->peerformat, &iaxs[fr->callno]->rprefs,
+							NULL, NULL, 1);
+						if (!c) {
 							iax2_destroy(fr->callno);
-						else if (ies.vars) {
+						} else if (ies.vars) {
 							struct ast_datastore *variablestore;
 							struct ast_variable *var, *prev = NULL;
 							AST_LIST_HEAD(, ast_var_t) *varlist;
@@ -12499,7 +12511,8 @@
 		ast_string_field_set(iaxs[callno], host, pds.peer);
 	}
 
-	c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, assignedids, requestor, cai.found);
+	c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, &cai.prefs, assignedids,
+		requestor, cai.found);
 
 	ast_mutex_unlock(&iaxsl[callno]);
 

Modified: team/rmudgett/iax_fracks/channels/iax2/codec_pref.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/iax_fracks/channels/iax2/codec_pref.c?view=diff&rev=419910&r1=419909&r2=419910
==============================================================================
--- team/rmudgett/iax_fracks/channels/iax2/codec_pref.c (original)
+++ team/rmudgett/iax_fracks/channels/iax2/codec_pref.c Fri Aug  1 19:06:47 2014
@@ -96,15 +96,84 @@
 
 	for (idx = 0; idx < ARRAY_LEN(pref->order); ++idx) {
 		uint64_t pref_bitfield;
+		struct ast_format *pref_format;
 
 		if (!pref->order[idx]) {
 			break;
 		}
+
 		pref_bitfield = iax2_codec_pref_order_value_to_format_bitfield(pref->order[idx]);
-		ast_format_cap_append(cap,
-			ast_format_compatibility_bitfield2format(pref_bitfield),
-			pref->framing[idx]);
-	}
+		pref_format = ast_format_compatibility_bitfield2format(pref_bitfield);
+		if (pref_format) {
+			ast_format_cap_append(cap, pref_format, pref->framing[idx]);
+		}
+	}
+}
+
+int iax2_codec_pref_best_bitfield2cap(uint64_t bitfield, struct iax2_codec_pref *prefs, struct ast_format_cap *cap)
+{
+	uint64_t best_bitfield;
+	struct ast_format *format;
+
+	/* Add any user preferred codecs first. */
+	if (prefs) {
+		int idx;
+
+		for (idx = 0; bitfield && idx < ARRAY_LEN(prefs->order); ++idx) {
+			if (!prefs->order[idx]) {
+				break;
+			}
+
+			best_bitfield = iax2_codec_pref_order_value_to_format_bitfield(prefs->order[idx]);
+			if (best_bitfield & bitfield) {
+				format = ast_format_compatibility_bitfield2format(best_bitfield);
+				if (format && ast_format_cap_append(cap, format, prefs->framing[idx])) {
+					return -1;
+				}
+
+				/* Remove just added codec. */
+				bitfield &= ~best_bitfield;
+			}
+		}
+	}
+
+	/* Add the hard coded "best" codecs. */
+	while (bitfield) {
+		best_bitfield = iax2_format_compatibility_bitfield2best(bitfield);
+		if (!best_bitfield) {
+			/* No more codecs considered best. */
+			break;
+		}
+
+		format = ast_format_compatibility_bitfield2format(best_bitfield);
+		/* The best_bitfield should always be convertible to a format. */
+		ast_assert(format != NULL);
+
+		if (ast_format_cap_append(cap, format, 0)) {
+			return -1;
+		}
+
+		/* Remove just added "best" codec to find the next "best". */
+		bitfield &= ~best_bitfield;
+	}
+
+	/* Add any remaining codecs. */
+	if (bitfield) {
+		int bit;
+
+		for (bit = 0; bit < 64; ++bit) {
+			uint64_t mask = (1ULL << bit);
+
+			if (mask & bitfield) {
+				format = ast_format_compatibility_bitfield2format(mask);
+				if (format && ast_format_cap_append(cap, format, 0)) {
+					return -1;
+				}
+			}
+		}
+	}
+
+	return 0;
 }
 
 int iax2_codec_pref_string(struct iax2_codec_pref *pref, char *buf, size_t size)

Modified: team/rmudgett/iax_fracks/channels/iax2/format_compatibility.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/iax_fracks/channels/iax2/format_compatibility.c?view=diff&rev=419910&r1=419909&r2=419910
==============================================================================
--- team/rmudgett/iax_fracks/channels/iax2/format_compatibility.c (original)
+++ team/rmudgett/iax_fracks/channels/iax2/format_compatibility.c Fri Aug  1 19:06:47 2014
@@ -58,6 +58,26 @@
 	return bitfield;
 }
 
+int iax2_format_compatibility_bitfield2cap(uint64_t bitfield, struct ast_format_cap *cap)
+{
+	int bit;
+
+	for (bit = 0; bit < 64; ++bit) {
+		uint64_t mask = (1ULL << bit);
+
+		if (mask & bitfield) {
+			struct ast_format *format;
+
+			format = ast_format_compatibility_bitfield2format(mask);
+			if (format && ast_format_cap_append(cap, format, 0)) {
+				return -1;
+			}
+		}
+	}
+
+	return 0;
+}
+
 uint64_t iax2_format_compatibility_bitfield2best(uint64_t formats)
 {
 	/*
@@ -115,66 +135,3 @@
 
 	return 0;
 }
-
-int iax2_format_compatibility_bitfield2cap_best(uint64_t bitfield, struct ast_format_cap *cap)
-{
-	int bit;
-	uint64_t best_bitfield;
-	struct ast_format *format;
-
-	/* Add the "best" codecs first. */
-	while (bitfield) {
-		best_bitfield = iax2_format_compatibility_bitfield2best(bitfield);
-		if (!best_bitfield) {
-			/* No more codecs considered best. */
-			break;
-		}
-
-		format = ast_format_compatibility_bitfield2format(best_bitfield);
-		/* The best_bitfield should always be convertible to a format. */
-		ast_assert(format != NULL);
-
-		if (ast_format_cap_append(cap, format, 0)) {
-			return -1;
-		}
-
-		/* Remove just added "best" codec to find the next "best". */
-		bitfield &= ~best_bitfield;
-	}
-
-	/* Add any remaining codecs. */
-	if (bitfield) {
-		for (bit = 0; bit < 64; ++bit) {
-			uint64_t mask = (1ULL << bit);
-
-			if (mask & bitfield) {
-				format = ast_format_compatibility_bitfield2format(mask);
-				if (format && ast_format_cap_append(cap, format, 0)) {
-					return -1;
-				}
-			}
-		}
-	}
-
-	return 0;
-}
-
-int iax2_format_compatibility_bitfield2cap(uint64_t bitfield, struct ast_format_cap *cap)
-{
-	int bit;
-
-	for (bit = 0; bit < 64; ++bit) {
-		uint64_t mask = (1ULL << bit);
-
-		if (mask & bitfield) {
-			struct ast_format *format;
-
-			format = ast_format_compatibility_bitfield2format(mask);
-			if (format && ast_format_cap_append(cap, format, 0)) {
-				return -1;
-			}
-		}
-	}
-
-	return 0;
-}

Modified: team/rmudgett/iax_fracks/channels/iax2/include/codec_pref.h
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/iax_fracks/channels/iax2/include/codec_pref.h?view=diff&rev=419910&r1=419909&r2=419910
==============================================================================
--- team/rmudgett/iax_fracks/channels/iax2/include/codec_pref.h (original)
+++ team/rmudgett/iax_fracks/channels/iax2/include/codec_pref.h Fri Aug  1 19:06:47 2014
@@ -73,6 +73,20 @@
 /*! \brief Convert a preference structure to a capabilities structure */
 void iax2_codec_pref_to_cap(struct iax2_codec_pref *pref, struct ast_format_cap *cap);
 
+/*!
+ * \brief Convert a bitfield to a format capabilities structure in the "best" order.
+ *
+ * \param bitfield The bitfield for the media formats
+ * \param prefs Format preference order to use as a guide. (May be NULL)
+ * \param cap Capabilities structure to place formats into
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ *
+ * \note If failure occurs the capabilities structure may contain a partial set of formats
+ */
+int iax2_codec_pref_best_bitfield2cap(uint64_t bitfield, struct iax2_codec_pref *prefs, struct ast_format_cap *cap);
+
 /*! \brief Removes format from the pref list that aren't in the bitfield */
 void iax2_codec_pref_remove_missing(struct iax2_codec_pref *pref, uint64_t bitfield);
 

Modified: team/rmudgett/iax_fracks/channels/iax2/include/format_compatibility.h
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/iax_fracks/channels/iax2/include/format_compatibility.h?view=diff&rev=419910&r1=419909&r2=419910
==============================================================================
--- team/rmudgett/iax_fracks/channels/iax2/include/format_compatibility.h (original)
+++ team/rmudgett/iax_fracks/channels/iax2/include/format_compatibility.h Fri Aug  1 19:06:47 2014
@@ -53,19 +53,6 @@
 int iax2_format_compatibility_bitfield2cap(uint64_t bitfield, struct ast_format_cap *cap);
 
 /*!
- * \brief Convert a bitfield to a format capabilities structure in the "best" order.
- *
- * \param bitfield The bitfield for the media formats
- * \param cap Capabilities structure to place formats into
- *
- * \retval 0 on success.
- * \retval -1 on error.
- *
- * \note If failure occurs the capabilities structure may contain a partial set of formats
- */
-int iax2_format_compatibility_bitfield2cap_best(uint64_t bitfield, struct ast_format_cap *cap);
-
-/*!
  * \brief Pick the best format from the given bitfield formats.
  *
  * \param formats The bitfield for the media formats




More information about the asterisk-commits mailing list