[asterisk-commits] mmichelson: branch group/CCSS r225312 - in /team/group/CCSS: ./ channels/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Oct 21 17:16:58 CDT 2009
Author: mmichelson
Date: Wed Oct 21 17:16:55 2009
New Revision: 225312
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=225312
Log:
sync with trunk
Modified:
team/group/CCSS/ (props changed)
team/group/CCSS/channels/chan_iax2.c
Propchange: team/group/CCSS/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.
Propchange: team/group/CCSS/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Wed Oct 21 17:16:55 2009
@@ -1,1 +1,1 @@
-/trunk:1-225252
+/trunk:1-225311
Modified: team/group/CCSS/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/channels/chan_iax2.c?view=diff&rev=225312&r1=225311&r2=225312
==============================================================================
--- team/group/CCSS/channels/chan_iax2.c (original)
+++ team/group/CCSS/channels/chan_iax2.c Wed Oct 21 17:16:55 2009
@@ -820,6 +820,15 @@
int frames_received;
/*! num bytes used for calltoken ie, even an empty ie should contain 2 */
unsigned char calltoken_ie_len;
+ /*! hold all signaling frames from the pbx thread until we have a destination callno */
+ char hold_signaling;
+ /*! frame queue for signaling frames from pbx thread waiting for destination callno */
+ AST_LIST_HEAD_NOLOCK(signaling_queue, signaling_queue_entry) signaling_queue;
+};
+
+struct signaling_queue_entry {
+ struct ast_frame f;
+ AST_LIST_ENTRY(signaling_queue_entry) next;
};
/*! table of available call numbers */
@@ -1703,10 +1712,56 @@
return 0;
}
+static void free_signaling_queue_entry(struct signaling_queue_entry *s)
+{
+ ast_free(s->f.data.ptr);
+ ast_free(s);
+}
+
+/*! \brief This function must be called once we are sure the other side has
+ * given us a call number. All signaling is held here until that point. */
+static void send_signaling(struct chan_iax2_pvt *pvt)
+{
+ struct signaling_queue_entry *s = NULL;
+
+ while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
+ iax2_send(pvt, &s->f, 0, -1, 0, 0, 0);
+ free_signaling_queue_entry(s);
+ }
+ pvt->hold_signaling = 0;
+}
+
+/*! \brief All frames other than that of type AST_FRAME_IAX must be held until
+ * we have received a destination call number. */
+static int queue_signalling(struct chan_iax2_pvt *pvt, struct ast_frame *f)
+{
+ struct signaling_queue_entry *new;
+
+ if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) {
+ return 1; /* do not queue this frame */
+ } else if (!(new = ast_calloc(1, sizeof(struct signaling_queue_entry)))) {
+ return -1; /* out of memory */
+ }
+
+ memcpy(&new->f, f, sizeof(new->f)); /* copy ast_frame into our queue entry */
+
+ if (new->f.datalen) { /* if there is data in this frame copy it over as well */
+ if (!(new->f.data.ptr = ast_calloc(1, new->f.datalen))) {
+ free_signaling_queue_entry(new);
+ return -1;
+ }
+ memcpy(new->f.data.ptr, f->data.ptr, sizeof(*new->f.data.ptr));
+ }
+ AST_LIST_INSERT_TAIL(&pvt->signaling_queue, new, next);
+
+ return 0;
+}
+
static void pvt_destructor(void *obj)
{
struct chan_iax2_pvt *pvt = obj;
struct iax_frame *cur = NULL;
+ struct signaling_queue_entry *s = NULL;
ast_mutex_lock(&iaxsl[pvt->callno]);
@@ -1724,6 +1779,10 @@
}
ast_mutex_unlock(&iaxsl[pvt->callno]);
+
+ while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
+ free_signaling_queue_entry(s);
+ }
if (pvt->reg) {
pvt->reg->callno = 0;
@@ -1780,6 +1839,9 @@
jb_setconf(tmp->jb,&jbconf);
AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries);
+
+ tmp->hold_signaling = 1;
+ AST_LIST_HEAD_INIT_NOLOCK(&tmp->signaling_queue);
return tmp;
}
@@ -7148,12 +7210,17 @@
int now, int transfer, int final)
{
struct ast_frame f = { 0, };
+ int res = 0;
f.frametype = type;
f.subclass = command;
f.datalen = datalen;
f.src = __FUNCTION__;
f.data.ptr = (void *) data;
+
+ if ((res = queue_signalling(i, &f)) <= 0) {
+ return res;
+ }
return iax2_send(i, &f, ts, seqno, now, transfer, final);
}
@@ -9634,19 +9701,15 @@
int check_dcallno = 0;
/*
- * We enforce accurate destination call numbers for all full frames except
- * LAGRQ and PING commands. This is because older versions of Asterisk
- * schedule these commands to get sent very quickly, and they will sometimes
- * be sent before they receive the first frame from the other side. When
- * that happens, it doesn't contain the destination call number. However,
- * not checking it for these frames is safe.
- *
+ * We enforce accurate destination call numbers for ACKs. This forces the other
+ * end to know the destination call number before call setup can complete.
+ *
* Discussed in the following thread:
* http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html
*/
- if (ntohs(mh->callno) & IAX_FLAG_FULL) {
- check_dcallno = f.frametype == AST_FRAME_IAX ? (f.subclass != IAX_COMMAND_PING && f.subclass != IAX_COMMAND_LAGRQ) : 1;
+ if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass == IAX_COMMAND_ACK))) {
+ check_dcallno = 1;
}
if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) {
@@ -9920,6 +9983,12 @@
if (ies.vars) {
ast_debug(1, "I have IAX variables, but they were not processed\n");
}
+ }
+
+ /* once we receive our first IAX Full Frame that is not CallToken related, send all
+ * queued signaling frames that were being held. */
+ if ((f.frametype == AST_FRAME_IAX) && (f.subclass != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) {
+ send_signaling(iaxs[fr->callno]);
}
if (f.frametype == AST_FRAME_VOICE) {
More information about the asterisk-commits
mailing list