[asterisk-commits] dlee: branch dlee/stasis-http r380808 - in /team/dlee/stasis-http: ./ bridges...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Feb 4 10:34:03 CST 2013


Author: dlee
Date: Mon Feb  4 10:33:59 2013
New Revision: 380808

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=380808
Log:
Merged revisions to 380792 from http://svn.asterisk.org/svn/asterisk/trunk

Added:
    team/dlee/stasis-http/channels/iax2/   (props changed)
      - copied from r380792, trunk/channels/iax2/
Removed:
    team/dlee/stasis-http/channels/iax2-parser.c
    team/dlee/stasis-http/channels/iax2-parser.h
    team/dlee/stasis-http/channels/iax2-provision.c
    team/dlee/stasis-http/channels/iax2-provision.h
    team/dlee/stasis-http/channels/iax2.h
Modified:
    team/dlee/stasis-http/   (props changed)
    team/dlee/stasis-http/bridges/bridge_multiplexed.c
    team/dlee/stasis-http/channels/Makefile
    team/dlee/stasis-http/channels/chan_agent.c
    team/dlee/stasis-http/channels/chan_dahdi.c
    team/dlee/stasis-http/channels/chan_iax2.c
    team/dlee/stasis-http/channels/chan_sip.c
    team/dlee/stasis-http/channels/chan_skinny.c
    team/dlee/stasis-http/configure
    team/dlee/stasis-http/configure.ac
    team/dlee/stasis-http/funcs/func_frame_trace.c
    team/dlee/stasis-http/include/asterisk/bridging.h
    team/dlee/stasis-http/include/asterisk/channel.h
    team/dlee/stasis-http/main/channel.c
    team/dlee/stasis-http/main/frame.c
    team/dlee/stasis-http/main/sorcery.c
    team/dlee/stasis-http/res/pjproject/aconfigure
    team/dlee/stasis-http/res/pjproject/aconfigure.ac
    team/dlee/stasis-http/res/pjproject/build/cc-auto.mak.in
    team/dlee/stasis-http/res/pjproject/build/rules.mak
    team/dlee/stasis-http/res/pjproject/pjlib-util/build/Makefile
    team/dlee/stasis-http/res/pjproject/pjlib/build/Makefile
    team/dlee/stasis-http/res/pjproject/pjlib/include/pj/config_site.h
    team/dlee/stasis-http/res/pjproject/pjlib/src/pj/log.c
    team/dlee/stasis-http/res/pjproject/pjlib/src/pj/pool_buf.c
    team/dlee/stasis-http/res/pjproject/pjlib/src/pj/ssl_sock_ossl.c
    team/dlee/stasis-http/res/pjproject/pjmedia/build/Makefile
    team/dlee/stasis-http/res/pjproject/pjmedia/src/test/test.c
    team/dlee/stasis-http/res/pjproject/pjnath/build/Makefile
    team/dlee/stasis-http/res/pjproject/pjsip-apps/build/Makefile
    team/dlee/stasis-http/res/pjproject/pjsip-apps/src/samples/icedemo.c
    team/dlee/stasis-http/res/pjproject/pjsip/build/Makefile
    team/dlee/stasis-http/res/res_calendar_icalendar.c
    team/dlee/stasis-http/tests/test_sorcery.c

Propchange: team/dlee/stasis-http/
------------------------------------------------------------------------------
Binary property 'branch-11-merged' - no diff available.

Propchange: team/dlee/stasis-http/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Mon Feb  4 10:33:59 2013
@@ -1,1 +1,1 @@
-/trunk:1-380384
+/trunk:1-380807

Modified: team/dlee/stasis-http/bridges/bridge_multiplexed.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/bridges/bridge_multiplexed.c?view=diff&rev=380808&r1=380807&r2=380808
==============================================================================
--- team/dlee/stasis-http/bridges/bridge_multiplexed.c (original)
+++ team/dlee/stasis-http/bridges/bridge_multiplexed.c Mon Feb  4 10:33:59 2013
@@ -50,23 +50,23 @@
 /*! \brief Number of buckets our multiplexed thread container can have */
 #define MULTIPLEXED_BUCKETS 53
 
-/*! \brief Number of channels we handle in a single thread */
-#define MULTIPLEXED_MAX_CHANNELS 8
+/*! \brief Number of bridges we handle in a single thread */
+#define MULTIPLEXED_MAX_BRIDGES		4
 
 /*! \brief Structure which represents a single thread handling multiple 2 channel bridges */
 struct multiplexed_thread {
 	/*! Thread itself */
 	pthread_t thread;
+	/*! Channels serviced by this thread */
+	struct ast_channel *chans[2 * MULTIPLEXED_MAX_BRIDGES];
 	/*! Pipe used to wake up the multiplexed thread */
 	int pipe[2];
-	/*! Channels in this thread */
-	struct ast_channel *chans[MULTIPLEXED_MAX_CHANNELS];
-	/*! Number of channels in this thread */
-	unsigned int count;
-	/*! Bit used to indicate that the thread is waiting on channels */
-	unsigned int waiting:1;
 	/*! Number of channels actually being serviced by this thread */
 	unsigned int service_count;
+	/*! Number of bridges in this thread */
+	unsigned int bridges;
+	/*! TRUE if the thread is waiting on channels */
+	unsigned int waiting:1;
 };
 
 /*! \brief Container of all operating multiplexed threads */
@@ -76,7 +76,8 @@
 static int find_multiplexed_thread(void *obj, void *arg, int flags)
 {
 	struct multiplexed_thread *muxed_thread = obj;
-	return (muxed_thread->count <= (MULTIPLEXED_MAX_CHANNELS - 2)) ? CMP_MATCH | CMP_STOP : 0;
+
+	return (muxed_thread->bridges < MULTIPLEXED_MAX_BRIDGES) ? CMP_MATCH | CMP_STOP : 0;
 }
 
 /*! \brief Destroy callback for a multiplexed thread structure */
@@ -147,8 +148,8 @@
 		ast_debug(1, "Found multiplexed thread '%p' for bridge '%p'\n", muxed_thread, bridge);
 	}
 
-	/* Bump the count of the thread structure up by two since the channels for this bridge will be joining shortly */
-	muxed_thread->count += 2;
+	/* Increase the number of bridges using this multiplexed bridge */
+	++muxed_thread->bridges;
 
 	ao2_unlock(muxed_threads);
 
@@ -157,7 +158,17 @@
 	return 0;
 }
 
-/*! \brief Internal function which nudges the thread */
+/*!
+ * \internal
+ * \brief Nudges the multiplex thread.
+ * \since 12.0.0
+ *
+ * \param muxed_thread Controller to poke the thread.
+ *
+ * \note This function assumes the muxed_thread is locked.
+ *
+ * \return Nothing
+ */
 static void multiplexed_nudge(struct multiplexed_thread *muxed_thread)
 {
 	int nudge = 0;
@@ -179,28 +190,39 @@
 static int multiplexed_bridge_destroy(struct ast_bridge *bridge)
 {
 	struct multiplexed_thread *muxed_thread;
+	pthread_t thread;
 
 	muxed_thread = bridge->bridge_pvt;
 	if (!muxed_thread) {
 		return -1;
 	}
+	bridge->bridge_pvt = NULL;
 
 	ao2_lock(muxed_threads);
 
-	muxed_thread->count -= 2;
-
-	if (!muxed_thread->count) {
-		ast_debug(1, "Unlinking multiplexed thread '%p' since nobody is using it anymore\n", muxed_thread);
+	if (--muxed_thread->bridges) {
+		/* Other bridges are still using the multiplexed thread. */
+		ao2_unlock(muxed_threads);
+	} else {
+		ast_debug(1, "Unlinking multiplexed thread '%p' since nobody is using it anymore\n",
+			muxed_thread);
 		ao2_unlink(muxed_threads, muxed_thread);
-	}
-
-	multiplexed_nudge(muxed_thread);
-
-	ao2_unlock(muxed_threads);
+		ao2_unlock(muxed_threads);
+
+		/* Stop the multiplexed bridge thread. */
+		ao2_lock(muxed_thread);
+		multiplexed_nudge(muxed_thread);
+		thread = muxed_thread->thread;
+		muxed_thread->thread = AST_PTHREADT_STOP;
+		ao2_unlock(muxed_thread);
+
+		if (thread != AST_PTHREADT_NULL) {
+			/* Wait for multiplexed bridge thread to die. */
+			pthread_join(thread, NULL);
+		}
+	}
 
 	ao2_ref(muxed_thread, -1);
-	bridge->bridge_pvt = NULL;
-
 	return 0;
 }
 
@@ -210,20 +232,24 @@
 	struct multiplexed_thread *muxed_thread = data;
 	int fds = muxed_thread->pipe[0];
 
+	ast_debug(1, "Starting actual thread for multiplexed thread '%p'\n", muxed_thread);
+
 	ao2_lock(muxed_thread);
-
-	ast_debug(1, "Starting actual thread for multiplexed thread '%p'\n", muxed_thread);
 
 	while (muxed_thread->thread != AST_PTHREADT_STOP) {
 		struct ast_channel *winner;
-		struct ast_channel *first = muxed_thread->chans[0];
 		int to = -1;
 		int outfd = -1;
 
-		/* Move channels around so not just the first one gets priority */
-		memmove(muxed_thread->chans, muxed_thread->chans + 1,
-			sizeof(struct ast_channel *) * (muxed_thread->service_count - 1));
-		muxed_thread->chans[muxed_thread->service_count - 1] = first;
+		if (1 < muxed_thread->service_count) {
+			struct ast_channel *first;
+
+			/* Move channels around so not just the first one gets priority */
+			first = muxed_thread->chans[0];
+			memmove(muxed_thread->chans, muxed_thread->chans + 1,
+				sizeof(struct ast_channel *) * (muxed_thread->service_count - 1));
+			muxed_thread->chans[muxed_thread->service_count - 1] = first;
+		}
 
 		muxed_thread->waiting = 1;
 		ao2_unlock(muxed_thread);
@@ -263,70 +289,108 @@
 		}
 	}
 
-	muxed_thread->thread = AST_PTHREADT_NULL;
+	ao2_unlock(muxed_thread);
 
 	ast_debug(1, "Stopping actual thread for multiplexed thread '%p'\n", muxed_thread);
-
-	ao2_unlock(muxed_thread);
 	ao2_ref(muxed_thread, -1);
 
 	return NULL;
 }
 
-/*! \brief Helper function which adds or removes a channel and nudges the thread */
-static void multiplexed_add_or_remove(struct multiplexed_thread *muxed_thread, struct ast_channel *chan, int add)
-{
-	int idx;
-	pthread_t thread = AST_PTHREADT_NULL;
-
-	ao2_lock(muxed_thread);
-
-	multiplexed_nudge(muxed_thread);
-
-	for (idx = 0; idx < ARRAY_LEN(muxed_thread->chans); ++idx) {
-		if (muxed_thread->chans[idx] == chan) {
-			if (!add) {
-				memmove(muxed_thread->chans + idx,
-					muxed_thread->chans + idx + 1,
-					sizeof(struct ast_channel *) * (ARRAY_LEN(muxed_thread->chans) - (idx + 1)));
-				muxed_thread->chans[ARRAY_LEN(muxed_thread->chans) - 1] = NULL;
-				--muxed_thread->service_count;
-			}
-			break;
-		}
-		if (!muxed_thread->chans[idx]) {
-			if (add) {
-				muxed_thread->chans[idx] = chan;
-				++muxed_thread->service_count;
-			}
-			break;
-		}
-	}
-	if (ARRAY_LEN(muxed_thread->chans) == idx && add) {
-		ast_log(LOG_ERROR, "Could not add channel %s to multiplexed thread %p.  Array not large enough.\n",
-			ast_channel_name(chan), muxed_thread);
-		ast_assert(0);
-	}
-
+/*!
+ * \internal
+ * \brief Check to see if the multiplexed bridge thread needs to be started.
+ * \since 12.0.0
+ *
+ * \param muxed_thread Controller to check if need to start thread.
+ *
+ * \note This function assumes the muxed_thread is locked.
+ *
+ * \return Nothing
+ */
+static void multiplexed_thread_start(struct multiplexed_thread *muxed_thread)
+{
 	if (muxed_thread->service_count && muxed_thread->thread == AST_PTHREADT_NULL) {
 		ao2_ref(muxed_thread, +1);
 		if (ast_pthread_create(&muxed_thread->thread, NULL, multiplexed_thread_function, muxed_thread)) {
+			muxed_thread->thread = AST_PTHREADT_NULL;/* For paranoia's sake. */
 			ao2_ref(muxed_thread, -1);
-			ast_log(LOG_WARNING, "Failed to create the bridge thread for multiplexed thread '%p', trying next time\n",
+			ast_log(LOG_WARNING, "Failed to create the common thread for multiplexed thread '%p', trying next time\n",
 				muxed_thread);
 		}
-	} else if (!muxed_thread->service_count
-		&& muxed_thread->thread != AST_PTHREADT_NULL
-		&& muxed_thread->thread != AST_PTHREADT_STOP) {
-		thread = muxed_thread->thread;
-		muxed_thread->thread = AST_PTHREADT_STOP;
-	}
+	}
+}
+
+/*!
+ * \internal
+ * \brief Add a channel to the multiplexed bridge.
+ * \since 12.0.0
+ *
+ * \param muxed_thread Controller to add a channel.
+ * \param chan Channel to add to the channel service array.
+ *
+ * \return Nothing
+ */
+static void multiplexed_chan_add(struct multiplexed_thread *muxed_thread, struct ast_channel *chan)
+{
+	int idx;
+
+	ao2_lock(muxed_thread);
+
+	multiplexed_nudge(muxed_thread);
+
+	/* Check if already in the channel service array for safety. */
+	for (idx = 0; idx < muxed_thread->service_count; ++idx) {
+		if (muxed_thread->chans[idx] == chan) {
+			break;
+		}
+	}
+	if (idx == muxed_thread->service_count) {
+		/* Channel to add was not already in the array. */
+		if (muxed_thread->service_count < ARRAY_LEN(muxed_thread->chans)) {
+			muxed_thread->chans[muxed_thread->service_count++] = chan;
+		} else {
+			ast_log(LOG_ERROR, "Could not add channel %s to multiplexed thread %p.  Array not large enough.\n",
+				ast_channel_name(chan), muxed_thread);
+			ast_assert(0);
+		}
+	}
+
+	multiplexed_thread_start(muxed_thread);
 
 	ao2_unlock(muxed_thread);
-
-	if (thread != AST_PTHREADT_NULL) {
-		pthread_join(thread, NULL);
-	}
+}
+
+/*!
+ * \internal
+ * \brief Remove a channel from the multiplexed bridge.
+ * \since 12.0.0
+ *
+ * \param muxed_thread Controller to remove a channel.
+ * \param chan Channel to remove from the channel service array.
+ *
+ * \return Nothing
+ */
+static void multiplexed_chan_remove(struct multiplexed_thread *muxed_thread, struct ast_channel *chan)
+{
+	int idx;
+
+	ao2_lock(muxed_thread);
+
+	multiplexed_nudge(muxed_thread);
+
+	/* Remove channel from service array. */
+	for (idx = 0; idx < muxed_thread->service_count; ++idx) {
+		if (muxed_thread->chans[idx] != chan) {
+			continue;
+		}
+		muxed_thread->chans[idx] = muxed_thread->chans[--muxed_thread->service_count];
+		break;
+	}
+
+	multiplexed_thread_start(muxed_thread);
+
+	ao2_unlock(muxed_thread);
 }
 
 /*! \brief Join function which actually adds the channel into the array to be monitored */
@@ -338,7 +402,7 @@
 
 	ast_debug(1, "Adding channel '%s' to multiplexed thread '%p' for monitoring\n", ast_channel_name(bridge_channel->chan), muxed_thread);
 
-	multiplexed_add_or_remove(muxed_thread, bridge_channel->chan, 1);
+	multiplexed_chan_add(muxed_thread, bridge_channel->chan);
 
 	/* If the second channel has not yet joined do not make things compatible */
 	if (c0 == c1) {
@@ -361,7 +425,7 @@
 
 	ast_debug(1, "Removing channel '%s' from multiplexed thread '%p'\n", ast_channel_name(bridge_channel->chan), muxed_thread);
 
-	multiplexed_add_or_remove(muxed_thread, bridge_channel->chan, 0);
+	multiplexed_chan_remove(muxed_thread, bridge_channel->chan);
 
 	return 0;
 }
@@ -373,7 +437,7 @@
 
 	ast_debug(1, "Suspending channel '%s' from multiplexed thread '%p'\n", ast_channel_name(bridge_channel->chan), muxed_thread);
 
-	multiplexed_add_or_remove(muxed_thread, bridge_channel->chan, 0);
+	multiplexed_chan_remove(muxed_thread, bridge_channel->chan);
 }
 
 /*! \brief Unsuspend function which means control of the channel is coming back to us */
@@ -383,7 +447,7 @@
 
 	ast_debug(1, "Unsuspending channel '%s' from multiplexed thread '%p'\n", ast_channel_name(bridge_channel->chan), muxed_thread);
 
-	multiplexed_add_or_remove(muxed_thread, bridge_channel->chan, 1);
+	multiplexed_chan_add(muxed_thread, bridge_channel->chan);
 }
 
 /*! \brief Write function for writing frames into the bridge */

Modified: team/dlee/stasis-http/channels/Makefile
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/channels/Makefile?view=diff&rev=380808&r1=380807&r2=380808
==============================================================================
--- team/dlee/stasis-http/channels/Makefile (original)
+++ team/dlee/stasis-http/channels/Makefile Mon Feb  4 10:33:59 2013
@@ -64,13 +64,14 @@
 clean::
 	$(MAKE) -C misdn clean
 	rm -f sip/*.o sip/*.i
+	rm -f iax2/*.o iax2/*.i
 	rm -f h323/libchanh323.a h323/Makefile.ast h323/*.o h323/*.dep
 
 dist-clean::
 	rm -f h323/Makefile
 
-$(if $(filter chan_iax2,$(EMBEDDED_MODS)),modules.link,chan_iax2.so): iax2-parser.o iax2-provision.o
-iax2-parser.o iax2-provision.o: _ASTCFLAGS+=$(call MOD_ASTCFLAGS,chan_iax2)
+$(if $(filter chan_iax2,$(EMBEDDED_MODS)),modules.link,chan_iax2.so): $(subst .c,.o,$(wildcard iax2/*.c))
+$(subst .c,.o,$(wildcard iax2/*.c)): _ASTCFLAGS+=$(call MOD_ASTCFLAGS,chan_iax2)
 $(if $(filter chan_sip,$(EMBEDDED_MODS)),modules.link,chan_sip.so): $(subst .c,.o,$(wildcard sip/*.c))
 $(subst .c,.o,$(wildcard sip/*.c)): _ASTCFLAGS+=$(call MOD_ASTCFLAGS,chan_sip)
 $(if $(filter chan_dahdi,$(EMBEDDED_MODS)),modules.link,chan_dahdi.so): sig_analog.o sig_pri.o sig_ss7.o

Modified: team/dlee/stasis-http/channels/chan_agent.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/channels/chan_agent.c?view=diff&rev=380808&r1=380807&r2=380808
==============================================================================
--- team/dlee/stasis-http/channels/chan_agent.c (original)
+++ team/dlee/stasis-http/channels/chan_agent.c Mon Feb  4 10:33:59 2013
@@ -344,7 +344,6 @@
 static struct ast_channel *agent_bridgedchannel(struct ast_channel *chan, struct ast_channel *bridge);
 static char *complete_agent_logoff_cmd(const char *line, const char *word, int pos, int state);
 static struct ast_channel* agent_get_base_channel(struct ast_channel *chan);
-static int agent_set_base_channel(struct ast_channel *chan, struct ast_channel *base);
 static int agent_logoff(const char *agent, int soft);
 
 /*! \brief Channel interface description for PBX integration */
@@ -368,7 +367,6 @@
 	.fixup = agent_fixup,
 	.bridged_channel = agent_bridgedchannel,
 	.get_base_channel = agent_get_base_channel,
-	.set_base_channel = agent_set_base_channel,
 };
 
 /*!
@@ -625,17 +623,10 @@
 		ast_copy_flags(ast_channel_flags(p->chan), ast_channel_flags(ast), AST_FLAG_EXCEPTION);
 		ast_channel_fdno_set(p->chan, (ast_channel_fdno(ast) == AST_AGENT_FD) ? AST_TIMING_FD : ast_channel_fdno(ast));
 		f = ast_read(p->chan);
+		ast_channel_fdno_set(ast, -1);
 	} else
 		f = &ast_null_frame;
-	if (!f) {
-		/* If there's a channel, make it NULL */
-		if (p->chan) {
-			ast_channel_internal_bridged_channel_set(p->chan, NULL);
-			p->chan = NULL;
-			ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "Agent/%s", p->agent);
-			p->acknowledged = 0;
-		}
-	} else {
+	if (f) {
 		/* if acknowledgement is not required, and the channel is up, we may have missed
 			an AST_CONTROL_ANSWER (if there was one), so mark the call acknowledged anyway */
 		if (!p->ackcall && !p->acknowledged && p->chan && (ast_channel_state(p->chan) == AST_STATE_UP)) {
@@ -840,9 +831,8 @@
 static int agent_call(struct ast_channel *ast, const char *dest, int timeout)
 {
 	struct agent_pvt *p = ast_channel_tech_pvt(ast);
-	int res = -1;
+	int res;
 	int newstate=0;
-	struct ast_channel *chan;
 
 	ast_mutex_lock(&p->lock);
 	p->acknowledged = 0;
@@ -854,29 +844,20 @@
 		return 0;
 	}
 
-	if (!p->chan) {
-		ast_log(LOG_DEBUG, "Agent disconnected while we were connecting the call\n");
-		ast_mutex_unlock(&p->lock);
-		return res;
-	}
+	ast_assert(p->chan != NULL);
 	ast_verb(3, "agent_call, call to agent '%s' call on '%s'\n", p->agent, ast_channel_name(p->chan));
 	ast_debug(3, "Playing beep, lang '%s'\n", ast_channel_language(p->chan));
-	
-	chan = p->chan;
+
 	ast_mutex_unlock(&p->lock);
 
-	res = ast_streamfile(chan, beep, ast_channel_language(chan));
+	res = ast_streamfile(p->chan, beep, ast_channel_language(p->chan));
 	ast_debug(3, "Played beep, result '%d'\n", res);
 	if (!res) {
-		res = ast_waitstream(chan, "");
+		res = ast_waitstream(p->chan, "");
 		ast_debug(3, "Waited for stream, result '%d'\n", res);
 	}
 	
 	ast_mutex_lock(&p->lock);
-	if (!p->chan) {
-		/* chan went away while we were streaming, this shouldn't be possible */
-		res = -1;
-	}
 
 	if (!res) {
 		struct ast_format tmpfmt;
@@ -884,10 +865,6 @@
 		ast_debug(3, "Set read format, result '%d'\n", res);
 		if (res)
 			ast_log(LOG_WARNING, "Unable to set read format to %s\n", ast_getformatname(&tmpfmt));
-	} else {
-		/* Agent hung-up */
-		p->chan = NULL;
-		ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "Agent/%s", p->agent);
 	}
 
 	if (!res) {
@@ -912,7 +889,7 @@
 	ast_mutex_unlock(&p->lock);
 	if (newstate)
 		ast_setstate(ast, newstate);
-	return res;
+	return res ? -1 : 0;
 }
 
 /*! \brief return the channel or base channel if one exists.  This function assumes the channel it is called on is already locked */
@@ -932,23 +909,6 @@
 	return base;
 }
 
-int agent_set_base_channel(struct ast_channel *chan, struct ast_channel *base)
-{
-	struct agent_pvt *p = NULL;
-	
-	if (!chan || !base) {
-		ast_log(LOG_ERROR, "whoa, you need a channel (0x%ld) and a base channel (0x%ld) for setting.\n", (long)chan, (long)base);
-		return -1;
-	}
-	p = ast_channel_tech_pvt(chan);
-	if (!p) {
-		ast_log(LOG_ERROR, "whoa, channel %s is missing his tech_pvt structure!!.\n", ast_channel_name(chan));
-		return -1;
-	}
-	p->chan = base;
-	return 0;
-}
-
 static int agent_hangup(struct ast_channel *ast)
 {
 	struct agent_pvt *p = ast_channel_tech_pvt(ast);
@@ -964,12 +924,7 @@
 	ast_mutex_lock(&p->lock);
 	p->owner = NULL;
 	ast_channel_tech_pvt_set(ast, NULL);
-	p->app_sleep_cond = 1;
 	p->acknowledged = 0;
-
-	/* Release ownership of the agent to other threads (presumably running the login app). */
-	p->app_lock_flag = 0;
-	ast_cond_signal(&p->app_complete_cond);
 
 	/* if they really are hung up then set start to 0 so the test
 	 * later if we're called on an already downed channel
@@ -999,26 +954,26 @@
 		indicate_chan = ast_channel_unref(indicate_chan);
 	}
 
-	/* Only register a device state change if the agent is still logged in */
-	if (p->loginstart) {
-		ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Agent/%s", p->agent);
-	}
-
+	ast_mutex_lock(&p->lock);
 	if (p->abouttograb) {
 		/* Let the "about to grab" thread know this isn't valid anymore, and let it
 		   kill it later */
 		p->abouttograb = 0;
 	} else if (p->dead) {
+		ast_mutex_unlock(&p->lock);
 		agent_pvt_destroy(p);
+		return 0;
 	} else {
-		if (p->chan) {
-			/* Not dead -- check availability now */
-			ast_mutex_lock(&p->lock);
-			/* Store last disconnect time */
-			p->lastdisc = ast_tvadd(ast_tvnow(), ast_samp2tv(p->wrapuptime, 1000));
-			ast_mutex_unlock(&p->lock);
-		}
-	}
+		/* Store last disconnect time */
+		p->lastdisc = ast_tvadd(ast_tvnow(), ast_samp2tv(p->wrapuptime, 1000));
+	}
+
+	/* Release ownership of the agent to other threads (presumably running the login app). */
+	p->app_sleep_cond = 1;
+	p->app_lock_flag = 0;
+	ast_cond_signal(&p->app_complete_cond);
+
+	ast_mutex_unlock(&p->lock);
 	return 0;
 }
 
@@ -1450,7 +1405,8 @@
 				hasagent++;
 			}
 			now = ast_tvnow();
-			if (!p->lastdisc.tv_sec || (now.tv_sec >= p->lastdisc.tv_sec)) {
+			if (p->loginstart
+				&& (!p->lastdisc.tv_sec || ast_tvdiff_ms(now, p->lastdisc) > 0)) {
 				p->lastdisc = ast_tv(0, 0);
 				/* Agent must be registered, but not have any active call, and not be in a waiting state */
 				if (!p->owner && p->chan) {
@@ -1499,10 +1455,10 @@
 		}
 
 		if (!p->chan) {
-			ast_log(LOG_DEBUG, "Agent disconnected while we were connecting the call\n");
+			ast_debug(1, "Agent disconnected before we could connect the call\n");
+			ast_mutex_unlock(&p->lock);
+			ast_hangup(chan);
 			*cause = AST_CAUSE_UNREGISTERED;
-			ast_mutex_unlock(&p->lock);
-			agent_hangup(chan);
 			return NULL;
 		}
 
@@ -1510,18 +1466,14 @@
 		 * thread */
 		p->app_sleep_cond = 0;
 		p->app_lock_flag = 1;
-
 		ast_queue_frame(p->chan, &ast_null_frame);
 		ast_cond_wait(&p->login_wait_cond, &p->lock);
 
 		if (!p->chan) {
-			ast_log(LOG_DEBUG, "Agent disconnected while we were connecting the call\n");
-			p->app_sleep_cond = 1;
-			p->app_lock_flag = 0;
-			ast_cond_signal(&p->app_complete_cond);
+			ast_debug(1, "Agent disconnected while we were connecting the call\n");
 			ast_mutex_unlock(&p->lock);
+			ast_hangup(chan);
 			*cause = AST_CAUSE_UNREGISTERED;
-			agent_hangup(chan);
 			return NULL;
 		}
 
@@ -1933,10 +1885,9 @@
 	int tries = 0;
 	int max_login_tries = maxlogintries;
 	struct agent_pvt *p;
-	char user[AST_MAX_AGENT] = "";
+	char user[AST_MAX_AGENT];
 	char pass[AST_MAX_AGENT];
-	char agent[AST_MAX_AGENT] = "";
-	char xpass[AST_MAX_AGENT] = "";
+	char xpass[AST_MAX_AGENT];
 	char *errmsg;
 	char *parse;
 	AST_DECLARE_APP_ARGS(args,
@@ -1948,7 +1899,9 @@
 	int play_announcement = 1;
 	char agent_goodbye[AST_MAX_FILENAME_LEN];
 	int update_cdr = updatecdr;
-	char *filename = "agent-loginok";
+
+	user[0] = '\0';
+	xpass[0] = '\0';
 
 	parse = ast_strdupa(data);
 
@@ -2020,14 +1973,11 @@
 		AST_LIST_LOCK(&agents);
 		AST_LIST_TRAVERSE(&agents, p, list) {
 			int unlock_channel = 1;
+
 			ast_channel_lock(chan);
 			ast_mutex_lock(&p->lock);
 			if (!strcmp(p->agent, user) &&
 			    !strcmp(p->password, pass) && !p->pending) {
-
-				/* Ensure we can't be gotten until we're done */
-				p->lastdisc = ast_tvnow();
-				p->lastdisc.tv_sec++;
 
 				/* Set Channel Specific Agent Overrides */
 				if (!ast_strlen_zero(pbx_builtin_getvar_helper(chan, "AGENTACKCALL"))) {
@@ -2077,20 +2027,13 @@
 				ast_channel_unlock(chan);
 				unlock_channel = 0;
 				/* End Channel Specific Agent Overrides */
+
 				if (!p->chan) {
-					long logintime;
-					snprintf(agent, sizeof(agent), "Agent/%s", p->agent);
+					/* Ensure nobody else can be this agent until we're done. */
+					p->chan = chan;
 
 					p->acknowledged = 0;
-					
-					ast_mutex_unlock(&p->lock);
-					AST_LIST_UNLOCK(&agents);
-					if( !res && play_announcement==1 )
-						res = ast_streamfile(chan, filename, ast_channel_language(chan));
-					if (!res)
-						ast_waitstream(chan, "");
-					AST_LIST_LOCK(&agents);
-					ast_mutex_lock(&p->lock);
+
 					if (!res) {
 						struct ast_format tmpfmt;
 						res = ast_set_read_format_from_cap(chan, ast_channel_nativeformats(chan));
@@ -2105,15 +2048,32 @@
 							ast_log(LOG_WARNING, "Unable to set write format to %s\n", ast_getformatname(&tmpfmt));
 						}
 					}
-					/* Check once more just in case */
-					if (p->chan)
-						res = -1;
+					if (!res && play_announcement == 1) {
+						ast_mutex_unlock(&p->lock);
+						AST_LIST_UNLOCK(&agents);
+						res = ast_streamfile(chan, "agent-loginok", ast_channel_language(chan));
+						if (!res) {
+							ast_waitstream(chan, "");
+						}
+						AST_LIST_LOCK(&agents);
+						ast_mutex_lock(&p->lock);
+					}
+
 					if (!res) {
+						long logintime;
+						char agent[AST_MAX_AGENT];
+
+						snprintf(agent, sizeof(agent), "Agent/%s", p->agent);
+
+						/* Login this channel and wait for it to go away */
 						ast_indicate_data(chan, AST_CONTROL_HOLD, 
 							S_OR(p->moh, NULL), 
 							!ast_strlen_zero(p->moh) ? strlen(p->moh) + 1 : 0);
-						if (p->loginstart == 0)
-							time(&p->loginstart);
+
+						/* Must be done after starting HOLD. */
+						p->lastdisc = ast_tvnow();
+						time(&p->loginstart);
+
 						/*** DOCUMENTATION
 							<managerEventInstance>
 								<synopsis>Raised when an Agent has logged in.</synopsis>
@@ -2134,41 +2094,31 @@
 							      "Uniqueid: %s\r\n",
 							      p->agent, ast_channel_name(chan), ast_channel_uniqueid(chan));
 						if (update_cdr && ast_channel_cdr(chan))
-							snprintf(ast_channel_cdr(chan)->channel, sizeof(ast_channel_cdr(chan)->channel), "Agent/%s", p->agent);
+							snprintf(ast_channel_cdr(chan)->channel, sizeof(ast_channel_cdr(chan)->channel), "%s", agent);
 						ast_queue_log("NONE", ast_channel_uniqueid(chan), agent, "AGENTLOGIN", "%s", ast_channel_name(chan));
 						ast_verb(2, "Agent '%s' logged in (format %s/%s)\n", p->agent,
 								    ast_getformatname(ast_channel_readformat(chan)), ast_getformatname(ast_channel_writeformat(chan)));
-						/* Login this channel and wait for it to go away */
-						p->chan = chan;
-						if (p->ackcall) {
-							check_beep(p, 0);
-						} else {
-							check_availability(p, 0);
-						}
+
 						ast_mutex_unlock(&p->lock);
 						AST_LIST_UNLOCK(&agents);
-						ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Agent/%s", p->agent);
+
 						while (res >= 0) {
 							ast_mutex_lock(&p->lock);
-							if (p->deferlogoff && p->chan) {
-								ast_softhangup(p->chan, AST_SOFTHANGUP_EXPLICIT);
+							if (p->deferlogoff) {
 								p->deferlogoff = 0;
+								ast_softhangup(chan, AST_SOFTHANGUP_EXPLICIT);
+								ast_mutex_unlock(&p->lock);
+								break;
 							}
-							if (p->chan != chan)
-								res = -1;
 							ast_mutex_unlock(&p->lock);
-							/* Yield here so other interested threads can kick in. */
-							sched_yield();
-							if (res)
-								break;
 
 							AST_LIST_LOCK(&agents);
 							ast_mutex_lock(&p->lock);
 							if (p->lastdisc.tv_sec) {
 								if (ast_tvdiff_ms(ast_tvnow(), p->lastdisc) > 0) {
-									ast_debug(1, "Wrapup time for %s expired!\n", p->agent);
+									ast_debug(1, "Wrapup time for %s expired!\n", agent);
 									p->lastdisc = ast_tv(0, 0);
-									ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "Agent/%s", p->agent);
+									ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "%s", agent);
 									if (p->ackcall) {
 										check_beep(p, 0);
 									} else {
@@ -2179,47 +2129,53 @@
 							ast_mutex_unlock(&p->lock);
 							AST_LIST_UNLOCK(&agents);
 
-							/*	Synchronize channel ownership between call to agent and itself. */
+							/* Synchronize channel ownership between call to agent and itself. */
 							ast_mutex_lock(&p->lock);
-							if (p->app_lock_flag == 1) {
+							if (p->app_lock_flag) {
 								ast_cond_signal(&p->login_wait_cond);
 								ast_cond_wait(&p->app_complete_cond, &p->lock);
+								if (ast_check_hangup(chan)) {
+									/* Agent hungup */
+									ast_mutex_unlock(&p->lock);
+									break;
+								}
 							}
 							ast_mutex_unlock(&p->lock);
+
 							if (p->ackcall) {
 								res = agent_ack_sleep(p);
+								if (res == 1) {
+									AST_LIST_LOCK(&agents);
+									ast_mutex_lock(&p->lock);
+									check_availability(p, 0);
+									ast_mutex_unlock(&p->lock);
+									AST_LIST_UNLOCK(&agents);
+								}
 							} else {
 								res = ast_safe_sleep_conditional( chan, 1000, agent_cont_sleep, p );
 							}
-							if (p->ackcall && (res == 1)) {
-								AST_LIST_LOCK(&agents);
-								ast_mutex_lock(&p->lock);
-								check_availability(p, 0);
-								ast_mutex_unlock(&p->lock);
-								AST_LIST_UNLOCK(&agents);
-								res = 0;
-							}
-							sched_yield();
 						}
 						ast_mutex_lock(&p->lock);
-						/* Log us off if appropriate */
-						if (p->chan == chan) {
-							p->chan = NULL;
-						}
+
+						/* Logoff this channel */
+						p->chan = NULL;
+						logintime = time(NULL) - p->loginstart;
+						p->loginstart = 0;
 
 						/* Synchronize channel ownership between call to agent and itself. */
-						if (p->app_lock_flag == 1) {
+						if (p->app_lock_flag) {
 							ast_cond_signal(&p->login_wait_cond);
 							ast_cond_wait(&p->app_complete_cond, &p->lock);
 						}
 
-						if (res && p->owner)
+						if (p->owner) {
 							ast_log(LOG_WARNING, "Huh?  We broke out when there was still an owner?\n");
+						}
 
 						p->acknowledged = 0;
-						logintime = time(NULL) - p->loginstart;
-						p->loginstart = 0;
 						ast_mutex_unlock(&p->lock);
+
+						ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "%s", agent);
 						/*** DOCUMENTATION
 							<managerEventInstance>
 								<synopsis>Raised when an Agent has logged off.</synopsis>
@@ -2238,21 +2194,22 @@
 							      p->agent, logintime, ast_channel_uniqueid(chan));
 						ast_queue_log("NONE", ast_channel_uniqueid(chan), agent, "AGENTLOGOFF", "%s|%ld", ast_channel_name(chan), logintime);
 						ast_verb(2, "Agent '%s' logged out\n", p->agent);
+
 						/* If there is no owner, go ahead and kill it now */
-						ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "Agent/%s", p->agent);
 						if (p->dead && !p->owner) {
 							agent_pvt_destroy(p);
 						}
-					}
-					else {
+						AST_LIST_LOCK(&agents);
+					} else {
+						/* Agent hung up before could be logged in. */
+						p->chan = NULL;
+
 						ast_mutex_unlock(&p->lock);
-						p = NULL;
 					}
 					res = -1;
 				} else {
 					ast_mutex_unlock(&p->lock);
 					errmsg = "agent-alreadyon";
-					p = NULL;
 				}
 				break;
 			}
@@ -2261,8 +2218,7 @@
 				ast_channel_unlock(chan);
 			}
 		}
-		if (!p)
-			AST_LIST_UNLOCK(&agents);
+		AST_LIST_UNLOCK(&agents);
 
 		if (!res && (max_login_tries==0 || tries < max_login_tries))
 			res = ast_app_getdata(chan, errmsg, user, sizeof(user) - 1, 0);
@@ -2338,40 +2294,33 @@
 static int agent_devicestate(const char *data)
 {
 	struct agent_pvt *p;
-	const char *s;
-	ast_group_t groupmatch;
-	int groupoff;
+	const char *device = data;
 	int res = AST_DEVICE_INVALID;
-	
-	s = data;
-	if ((s[0] == '@') && (sscanf(s + 1, "%30d", &groupoff) == 1))
-		groupmatch = (1 << groupoff);
-	else if ((s[0] == ':') && (sscanf(s + 1, "%30d", &groupoff) == 1)) {
-		groupmatch = (1 << groupoff);
-	} else 
-		groupmatch = 0;
-
-	/* Check actual logged in agents first */
+
+	if (device[0] == '@' || device[0] == ':') {
+		/* Device state of groups not supported. */
+		return AST_DEVICE_INVALID;
+	}
+
+	/* Want device state of a specific agent. */
 	AST_LIST_LOCK(&agents);
 	AST_LIST_TRAVERSE(&agents, p, list) {
 		ast_mutex_lock(&p->lock);
-		if (!p->pending && ((groupmatch && (p->group & groupmatch)) || !strcmp(data, p->agent))) {
+		if (!p->pending && !strcmp(device, p->agent)) {
 			if (p->owner) {
-				if (res != AST_DEVICE_INUSE)
-					res = AST_DEVICE_BUSY;
+				res = AST_DEVICE_BUSY;
+			} else if (p->chan) {
+				if (p->lastdisc.tv_sec || p->deferlogoff) {
+					/* Agent is in wrapup time so unavailable for another call. */
+					res = AST_DEVICE_INUSE;
+				} else {
+					res = AST_DEVICE_NOT_INUSE;
+				}
 			} else {
-				if (res == AST_DEVICE_BUSY)
-					res = AST_DEVICE_INUSE;
-				if (p->chan) {
-					if (res == AST_DEVICE_INVALID)
-						res = AST_DEVICE_UNKNOWN;
-				} else if (res == AST_DEVICE_INVALID)	
-					res = AST_DEVICE_UNAVAILABLE;
+				res = AST_DEVICE_UNAVAILABLE;
 			}
-			if (!strcmp(data, p->agent)) {
-				ast_mutex_unlock(&p->lock);
-				break;
-			}
+			ast_mutex_unlock(&p->lock);
+			break;
 		}
 		ast_mutex_unlock(&p->lock);
 	}

Modified: team/dlee/stasis-http/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/channels/chan_dahdi.c?view=diff&rev=380808&r1=380807&r2=380808
==============================================================================
--- team/dlee/stasis-http/channels/chan_dahdi.c (original)
+++ team/dlee/stasis-http/channels/chan_dahdi.c Mon Feb  4 10:33:59 2013
@@ -15543,7 +15543,7 @@
 {
 #define FORMAT "%7s %-10.10s %-15.15s %-10.10s %-20.20s %-10.10s %-10.10s %-32.32s\n"
 #define FORMAT2 "%7s %-10.10s %-15.15s %-10.10s %-20.20s %-10.10s %-10.10s %-32.32s\n"
-	int targetnum = 0;
+	ast_group_t targetnum = 0;
 	int filtertype = 0;
 	struct dahdi_pvt *tmp = NULL;
 	char tmps[20] = "";
@@ -15570,9 +15570,10 @@
 	if (a->argc == 5) {
 		if (!strcasecmp(a->argv[3], "group")) {
 			targetnum = atoi(a->argv[4]);
-			if ((targetnum < 0) || (targetnum > 63))
+			if (63 < targetnum) {
 				return CLI_SHOWUSAGE;
-			targetnum = 1 << targetnum;
+			}
+			targetnum = ((ast_group_t) 1) << targetnum;
 			filtertype = 1;
 		} else if (!strcasecmp(a->argv[3], "context")) {
 			filtertype = 2;

Modified: team/dlee/stasis-http/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/channels/chan_iax2.c?view=diff&rev=380808&r1=380807&r2=380808
==============================================================================
--- team/dlee/stasis-http/channels/chan_iax2.c (original)
+++ team/dlee/stasis-http/channels/chan_iax2.c Mon Feb  4 10:33:59 2013
@@ -64,7 +64,7 @@
 #include <sys/stat.h>
 #include <regex.h>
 
-#include "asterisk/paths.h"	/* need ast_config_AST_DATA_DIR for firmware */
+#include "asterisk/paths.h"
 
 #include "asterisk/lock.h"
 #include "asterisk/frame.h" 
@@ -102,9 +102,10 @@
 #include "asterisk/data.h"
 #include "asterisk/netsock2.h"
 
-#include "iax2.h"
-#include "iax2-parser.h"
-#include "iax2-provision.h"
+#include "iax2/include/iax2.h"
+#include "iax2/include/firmware.h"
+#include "iax2/include/parser.h"
+#include "iax2/include/provision.h"
 #include "jitterbuf.h"
 
 /*** DOCUMENTATION
@@ -575,15 +576,6 @@
 
 static AST_LIST_HEAD_STATIC(tpeers, iax2_trunk_peer);
 
-struct iax_firmware {
-	AST_LIST_ENTRY(iax_firmware) list;
-	int fd;
-	int mmaplen;
-	int dead;
-	struct ast_iax2_firmware_header *fwh;
-	unsigned char *buf;
-};
-
 enum iax_reg_state {
 	REG_STATE_UNREGISTERED = 0,
 	REG_STATE_REGSENT,
@@ -950,8 +942,6 @@
 	unsigned char validated;
 };
 
-static AST_LIST_HEAD_STATIC(firmwares, iax_firmware);
-
 enum {
 	/*! Extension exists */
 	CACHE_FLAG_EXISTS      = (1 << 0),
@@ -3084,253 +3074,6 @@
 	}
 	return 0;
 }
-static void destroy_firmware(struct iax_firmware *cur)
-{
-	/* Close firmware */
-	if (cur->fwh) {
-		munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
-	}
-	close(cur->fd);
-	ast_free(cur);
-}
-
-static int try_firmware(char *s)
-{
-	struct stat stbuf;
-	struct iax_firmware *cur = NULL;
-	int ifd, fd, res, len, chunk;
-	struct ast_iax2_firmware_header *fwh, fwh2;
-	struct MD5Context md5;
-	unsigned char sum[16], buf[1024];
-	char *s2, *last;
-
-	s2 = ast_alloca(strlen(s) + 100);
-
-	last = strrchr(s, '/');
-	if (last)
-		last++;
-	else
-		last = s;
-
-	snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
-
-	if (stat(s, &stbuf) < 0) {
-		ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
-		return -1;
-	}
-
-	/* Make sure it's not a directory */
-	if (S_ISDIR(stbuf.st_mode))
-		return -1;
-	ifd = open(s, O_RDONLY);
-	if (ifd < 0) {
-		ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
-		return -1;
-	}
-	fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE);
-	if (fd < 0) {
-		ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
-		close(ifd);
-		return -1;
-	}
-	/* Unlink our newly created file */
-	unlink(s2);
-	
-	/* Now copy the firmware into it */
-	len = stbuf.st_size;
-	while(len) {
-		chunk = len;
-		if (chunk > sizeof(buf))
-			chunk = sizeof(buf);
-		res = read(ifd, buf, chunk);
-		if (res != chunk) {
-			ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
-			close(ifd);
-			close(fd);
-			return -1;
-		}
-		res = write(fd, buf, chunk);
-		if (res != chunk) {
-			ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
-			close(ifd);
-			close(fd);
-			return -1;
-		}
-		len -= chunk;
-	}
-	close(ifd);
-	/* Return to the beginning */
-	lseek(fd, 0, SEEK_SET);
-	if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
-		ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
-		close(fd);
-		return -1;
-	}
-	if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
-		ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
-		close(fd);
-		return -1;
-	}
-	if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
-		ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
-		close(fd);
-		return -1;
-	}
-	if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
-		ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
-		close(fd);
-		return -1;
-	}
-	fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 
-	if (fwh == MAP_FAILED) {
-		ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
-		close(fd);
-		return -1;
-	}
-	MD5Init(&md5);
-	MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
-	MD5Final(sum, &md5);
-	if (memcmp(sum, fwh->chksum, sizeof(sum))) {
-		ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
-		munmap((void*)fwh, stbuf.st_size);
-		close(fd);
-		return -1;
-	}
-
-	AST_LIST_TRAVERSE(&firmwares, cur, list) {
-		if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
-			/* Found a candidate */
-			if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
-				/* The version we have on loaded is older, load this one instead */
-				break;
-			/* This version is no newer than what we have.  Don't worry about it.
-			   We'll consider it a proper load anyhow though */
-			munmap((void*)fwh, stbuf.st_size);
-			close(fd);
-			return 0;
-		}
-	}
-	
-	if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) {
-		cur->fd = -1;
-		AST_LIST_INSERT_TAIL(&firmwares, cur, list);
-	}
-	
-	if (cur) {
-		if (cur->fwh)
-			munmap((void*)cur->fwh, cur->mmaplen);
-		if (cur->fd > -1)
-			close(cur->fd);
-		cur->fwh = fwh;
-		cur->fd = fd;
-		cur->mmaplen = stbuf.st_size;
-		cur->dead = 0;
-	}
-	
-	return 0;
-}
-
-static int iax_check_version(char *dev)
-{
-	int res = 0;
-	struct iax_firmware *cur = NULL;
-
-	if (ast_strlen_zero(dev))
-		return 0;
-

[... 2082 lines stripped ...]



More information about the asterisk-commits mailing list