[svn-commits] rmudgett: branch rmudgett/iax_fracks r419907 - in /team/rmudgett/iax_fracks/c...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Aug 1 14:03:25 CDT 2014


Author: rmudgett
Date: Fri Aug  1 14:03:18 2014
New Revision: 419907

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=419907
Log:
chan_iax2: Setup initial prefs list when loading config.

* Setup the prefs list for the bandwidth option and initial config
loading.  The new iax2_codec_pref_from_bitfield() does the work.

* Rename the global prefs list to prefs_global.  Less confusion between
prefs and pref that way.

* Fixed codec_pref_remove_index() if the prefs array is full.

* Fixed iax2_codec_pref_remove_missing() to not interfere with itself if
any preferences are removed to match the given formats bitfield.

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

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=419907&r1=419906&r2=419907
==============================================================================
--- team/rmudgett/iax_fracks/channels/chan_iax2.c (original)
+++ team/rmudgett/iax_fracks/channels/chan_iax2.c Fri Aug  1 14:03:18 2014
@@ -285,7 +285,7 @@
 /* Sample over last 100 units to determine historic jitter */
 #define GAMMA (0.01)
 
-static struct iax2_codec_pref prefs;
+static struct iax2_codec_pref prefs_global;
 
 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
 
@@ -1918,12 +1918,14 @@
 	}
 
 	res = ast_format_cap_update_by_allow_disallow(cap, list, allowing);
+
+	/* Adjust formats bitfield and pref list to match. */
 	*formats = iax2_format_compatibility_cap2bitfield(cap);
-
 	iax2_codec_pref_remove_missing(pref, *formats);
 
 	for (i = 0; i < ast_format_cap_count(cap); i++) {
 		struct ast_format *fmt = ast_format_cap_get_format(cap, i);
+
 		iax2_codec_pref_append(pref, fmt, ast_format_cap_get_format_framing(cap, fmt));
 		ao2_ref(fmt, -1);
 	}
@@ -2229,7 +2231,7 @@
 		return NULL;
 	}
 
-	tmp->prefs = prefs;
+	tmp->prefs = prefs_global;
 	tmp->pingid = -1;
 	tmp->lagid = -1;
 	tmp->autoid = -1;
@@ -4648,7 +4650,7 @@
 		 * However, move the calling channel's native codec to
 		 * the top of the preference list.
 		 */
-		ourprefs = prefs;
+		ourprefs = prefs_global;
 		if (c) {
 			int i;
 
@@ -12809,7 +12811,7 @@
 				ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO);
 				peer->expiry = min_reg_expire;
 			}
-			peer->prefs = prefs;
+			peer->prefs = prefs_global;
 			peer->capability = iax2_capability;
 			peer->smoothing = 0;
 			peer->pokefreqok = DEFAULT_FREQ_OK;
@@ -13126,7 +13128,7 @@
 			}
 			user->maxauthreq = maxauthreq;
 			user->curauthreq = oldcurauthreq;
-			user->prefs = prefs;
+			user->prefs = prefs_global;
 			user->capability = iax2_capability;
 			user->encmethods = iax2_encryption;
 			user->adsi = adsi;
@@ -13439,7 +13441,7 @@
 static int set_config(const char *config_file, int reload, int forced)
 {
 	struct ast_config *cfg, *ucfg;
-	iax2_format capability = iax2_capability;
+	iax2_format capability;
 	struct ast_variable *v;
 	char *cat;
 	const char *utype;
@@ -13454,9 +13456,7 @@
 	struct ast_netsock *ns;
 	struct ast_flags config_flags = { (reload && !forced) ? CONFIG_FLAG_FILEUNCHANGED : 0 };
 	struct ast_sockaddr bindaddr;
-#if 0
-	static unsigned short int last_port=0;
-#endif
+	struct iax2_codec_pref prefs_new;
 
 	cfg = ast_config_load(config_file, config_flags);
 
@@ -13497,10 +13497,8 @@
 
 	ast_sockaddr_parse(&bindaddr, "0.0.0.0:0", 0);
 
-	/* Reset global codec prefs */
-/* BUGBUG Use a local prefs list until after config is loaded */
-/* BUGBUG Need to setup the prefs list in with the initial capability setting. */
-	memset(&prefs, 0 , sizeof(struct iax2_codec_pref));
+	/* Setup new codec prefs */
+	capability = iax2_codec_pref_from_bitfield(&prefs_new, IAX_CAPABILITY_FULLBANDWIDTH);
 
 	/* Reset Global Flags */
 	memset(&globalflags, 0, sizeof(globalflags));
@@ -13724,19 +13722,22 @@
 				autokill = 0;
 			}
 		} else if (!strcasecmp(v->name, "bandwidth")) {
-/* BUGBUG The bandwidth option needs to update the prefs list as well. */
 			if (!strcasecmp(v->value, "low")) {
-				capability = IAX_CAPABILITY_LOWBANDWIDTH;
+				capability = iax2_codec_pref_from_bitfield(&prefs_new,
+					IAX_CAPABILITY_LOWBANDWIDTH);
 			} else if (!strcasecmp(v->value, "medium")) {
-				capability = IAX_CAPABILITY_MEDBANDWIDTH;
+				capability = iax2_codec_pref_from_bitfield(&prefs_new,
+					IAX_CAPABILITY_MEDBANDWIDTH);
 			} else if (!strcasecmp(v->value, "high")) {
-				capability = IAX_CAPABILITY_FULLBANDWIDTH;
-			} else
+				capability = iax2_codec_pref_from_bitfield(&prefs_new,
+					IAX_CAPABILITY_FULLBANDWIDTH);
+			} else {
 				ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
+			}
 		} else if (!strcasecmp(v->name, "allow")) {
-			iax2_parse_allow_disallow(&prefs, &capability, v->value, 1);
+			iax2_parse_allow_disallow(&prefs_new, &capability, v->value, 1);
 		} else if (!strcasecmp(v->name, "disallow")) {
-			iax2_parse_allow_disallow(&prefs, &capability, v->value, 0);
+			iax2_parse_allow_disallow(&prefs_new, &capability, v->value, 0);
 		} else if (!strcasecmp(v->name, "register")) {
 			iax2_register(v->value, v->lineno);
 		} else if (!strcasecmp(v->name, "iaxcompat")) {
@@ -13854,6 +13855,7 @@
 			min_reg_expire, max_reg_expire, max_reg_expire);
 		min_reg_expire = max_reg_expire;
 	}
+	prefs_global = prefs_new;
 	iax2_capability = capability;
 
 	if (ucfg) {

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=419907&r1=419906&r2=419907
==============================================================================
--- team/rmudgett/iax_fracks/channels/iax2/codec_pref.c (original)
+++ team/rmudgett/iax_fracks/channels/iax2/codec_pref.c Fri Aug  1 14:03:18 2014
@@ -185,12 +185,20 @@
 
 static void codec_pref_remove_index(struct iax2_codec_pref *pref, int codec_pref_index)
 {
-	int x;
-
-	for (x = codec_pref_index; x < ARRAY_LEN(pref->order); ++x) {
-		pref->order[x] = pref->order[x + 1];
-		pref->framing[x] = pref->framing[x + 1];
-		if (!pref->order[x]) {
+	int idx;
+
+	idx = codec_pref_index;
+	if (idx == ARRAY_LEN(pref->order) - 1) {
+		/* Remove from last array entry. */
+		pref->order[idx] = 0;
+		pref->framing[idx] = 0;
+		return;
+	}
+
+	for (; idx < ARRAY_LEN(pref->order); ++idx) {
+		pref->order[idx] = pref->order[idx + 1];
+		pref->framing[idx] = pref->framing[idx + 1];
+		if (!pref->order[idx]) {
 			return;
 		}
 	}
@@ -219,23 +227,27 @@
 
 void iax2_codec_pref_remove_missing(struct iax2_codec_pref *pref, uint64_t bitfield)
 {
-	int x;
+	int idx;
 
 	if (!pref->order[0]) {
 		return;
 	}
 
-	for (x = 0; x < ARRAY_LEN(pref->order); ++x) {
+	/*
+	 * Work from the end of the list so we always deal with
+	 * unmodified entries in case we have to remove a pref.
+	 */
+	for (idx = ARRAY_LEN(pref->order); idx--;) {
 		uint64_t pref_bitfield;
 
-		if (!pref->order[x]) {
-			break;
+		if (!pref->order[idx]) {
+			continue;
 		}
 
 		/* If this format isn't in the bitfield, remove it from the prefs. */
-		pref_bitfield = iax2_codec_pref_order_value_to_format_bitfield(pref->order[x]);
+		pref_bitfield = iax2_codec_pref_order_value_to_format_bitfield(pref->order[idx]);
 		if (!(pref_bitfield & bitfield)) {
-			codec_pref_remove_index(pref, x);
+			codec_pref_remove_index(pref, idx);
 		}
 	}
 }
@@ -265,17 +277,21 @@
 	return format_index;
 }
 
-/*! \brief Append codec to list */
-void iax2_codec_pref_append(struct iax2_codec_pref *pref, struct ast_format *format, unsigned int framing)
-{
-	uint64_t bitfield;
+/*!
+ * \internal
+ * \brief Append the bitfield format to the codec preference list.
+ * \since 13.0.0
+ *
+ * \param pref Codec preference list to append the given bitfield.
+ * \param bitfield Format bitfield to append.
+ * \param framing Framing size of the codec.
+ *
+ * \return Nothing
+ */
+static void iax2_codec_pref_append_bitfield(struct iax2_codec_pref *pref, uint64_t bitfield, unsigned int framing)
+{
 	int format_index;
 	int x;
-
-	bitfield = ast_format_compatibility_format2bitfield(format);
-	if (!bitfield) {
-		return;
-	}
 
 	format_index = iax2_codec_pref_format_bitfield_to_order_value(bitfield);
 	codec_pref_remove(pref, format_index);
@@ -289,7 +305,18 @@
 	}
 }
 
-/*! \brief Prepend codec to list */
+void iax2_codec_pref_append(struct iax2_codec_pref *pref, struct ast_format *format, unsigned int framing)
+{
+	uint64_t bitfield;
+
+	bitfield = ast_format_compatibility_format2bitfield(format);
+	if (!bitfield) {
+		return;
+	}
+
+	iax2_codec_pref_append_bitfield(pref, bitfield, framing);
+}
+
 void iax2_codec_pref_prepend(struct iax2_codec_pref *pref, struct ast_format *format, unsigned int framing,
 	int only_if_existing)
 {
@@ -366,3 +393,56 @@
 
 	return -1;
 }
+
+uint64_t iax2_codec_pref_from_bitfield(struct iax2_codec_pref *pref, uint64_t bitfield)
+{
+	int bit;
+	uint64_t working_bitfield;
+	uint64_t best_bitfield;
+	struct ast_format *format;
+
+	/* Init the preference list. */
+	memset(pref, 0, sizeof(*pref));
+
+	working_bitfield = bitfield;
+
+	/* Add the "best" codecs first. */
+	while (working_bitfield) {
+		best_bitfield = iax2_format_compatibility_bitfield2best(working_bitfield);
+		if (!best_bitfield) {
+			/* No more codecs considered best. */
+			break;
+		}
+
+		/* Remove current "best" codec to find the next "best". */
+		working_bitfield &= ~best_bitfield;
+
+		format = ast_format_compatibility_bitfield2format(best_bitfield);
+		/* The best_bitfield should always be convertible to a format. */
+		ast_assert(format != NULL);
+
+		iax2_codec_pref_append_bitfield(pref, best_bitfield,
+			ast_format_get_default_ms(format));
+	}
+
+	/* Add any remaining codecs. */
+	if (working_bitfield) {
+		for (bit = 0; bit < 64; ++bit) {
+			uint64_t mask = (1ULL << bit);
+
+			if (mask & working_bitfield) {
+				format = ast_format_compatibility_bitfield2format(mask);
+				if (!format) {
+					/* The bit is not associated with any format. */
+					bitfield &= ~mask;
+					continue;
+				}
+
+				iax2_codec_pref_append_bitfield(pref, mask,
+					ast_format_get_default_ms(format));
+			}
+		}
+	}
+
+	return bitfield;
+}

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=419907&r1=419906&r2=419907
==============================================================================
--- team/rmudgett/iax_fracks/channels/iax2/format_compatibility.c (original)
+++ team/rmudgett/iax_fracks/channels/iax2/format_compatibility.c Fri Aug  1 14:03:18 2014
@@ -131,6 +131,9 @@
 		}
 
 		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;
 		}
@@ -146,7 +149,7 @@
 
 			if (mask & bitfield) {
 				format = ast_format_compatibility_bitfield2format(mask);
-				if (ast_format_cap_append(cap, format, 0)) {
+				if (format && ast_format_cap_append(cap, format, 0)) {
 					return -1;
 				}
 			}
@@ -167,7 +170,7 @@
 			struct ast_format *format;
 
 			format = ast_format_compatibility_bitfield2format(mask);
-			if (ast_format_cap_append(cap, format, 0)) {
+			if (format && ast_format_cap_append(cap, format, 0)) {
 				return -1;
 			}
 		}

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=419907&r1=419906&r2=419907
==============================================================================
--- team/rmudgett/iax_fracks/channels/iax2/include/codec_pref.h (original)
+++ team/rmudgett/iax_fracks/channels/iax2/include/codec_pref.h Fri Aug  1 14:03:18 2014
@@ -120,4 +120,15 @@
  */
 void iax2_codec_pref_convert(struct iax2_codec_pref *pref, char *buf, size_t size, int right);
 
+/*!
+ * \brief Create codec preference list from the given bitfield formats.
+ * \since 13.0.0
+ *
+ * \param pref Codec preference list to setup from the given bitfield.
+ * \param bitfield Format bitfield to guide preference list creation.
+ *
+ * \return Updated bitfield with any bits not mapped to a format cleared.
+ */
+uint64_t iax2_codec_pref_from_bitfield(struct iax2_codec_pref *pref, uint64_t bitfield);
+
 #endif /* _IAX2_CODEC_PREF_H_ */




More information about the svn-commits mailing list