Index: main/autoservice.c =================================================================== --- main/autoservice.c (revision 116589) +++ main/autoservice.c (working copy) @@ -72,28 +72,14 @@ static int as_chan_list_state; -static void defer_frame(struct ast_channel *chan, struct ast_frame *f) -{ - struct ast_frame *dup_f; - struct asent *as; - - AST_LIST_LOCK(&aslist); - AST_LIST_TRAVERSE(&aslist, as, list) { - if (as->chan != chan) - continue; - if ((dup_f = ast_frdup(f))) - AST_LIST_INSERT_TAIL(&as->dtmf_frames, dup_f, frame_list); - } - AST_LIST_UNLOCK(&aslist); -} - static void *autoservice_run(void *ign) { for (;;) { struct ast_channel *mons[MAX_AUTOMONS]; + struct asent *ents[MAX_AUTOMONS]; struct ast_channel *chan; struct asent *as; - int x = 0, ms = 50; + int i, x = 0, ms = 50; AST_LIST_LOCK(&aslist); @@ -106,9 +92,10 @@ AST_LIST_TRAVERSE(&aslist, as, list) { if (!as->chan->_softhangup) { - if (x < MAX_AUTOMONS) + if (x < MAX_AUTOMONS) { + ents[x] = as; mons[x++] = as->chan; - else + } else ast_log(LOG_WARNING, "Exceeded maximum number of automatic monitoring events. Fix autoservice.c\n"); } } @@ -118,6 +105,7 @@ chan = ast_waitfor_n(mons, x, &ms); if (chan) { struct ast_frame *f = ast_read(chan); + struct ast_frame *defer_frame = NULL; if (!f) { struct ast_frame hangup_frame = { 0, }; @@ -130,35 +118,49 @@ hangup_frame.frametype = AST_FRAME_CONTROL; hangup_frame.subclass = AST_CONTROL_HANGUP; - defer_frame(chan, &hangup_frame); + defer_frame = &hangup_frame; continue; - } + } else { - /* Do not add a default entry in this switch statement. Each new - * frame type should be addressed directly as to whether it should - * be queued up or not. */ - switch (f->frametype) { - /* Save these frames */ - case AST_FRAME_DTMF_END: - case AST_FRAME_CONTROL: - case AST_FRAME_TEXT: - case AST_FRAME_IMAGE: - case AST_FRAME_HTML: - defer_frame(chan, f); - break; + /* Do not add a default entry in this switch statement. Each new + * frame type should be addressed directly as to whether it should + * be queued up or not. */ + switch (f->frametype) { + /* Save these frames */ + case AST_FRAME_DTMF_END: + case AST_FRAME_CONTROL: + case AST_FRAME_TEXT: + case AST_FRAME_IMAGE: + case AST_FRAME_HTML: + defer_frame = f; + break; - /* Throw these frames away */ - case AST_FRAME_DTMF_BEGIN: - case AST_FRAME_VOICE: - case AST_FRAME_VIDEO: - case AST_FRAME_NULL: - case AST_FRAME_IAX: - case AST_FRAME_CNG: - case AST_FRAME_MODEM: - break; + /* Throw these frames away */ + case AST_FRAME_DTMF_BEGIN: + case AST_FRAME_VOICE: + case AST_FRAME_VIDEO: + case AST_FRAME_NULL: + case AST_FRAME_IAX: + case AST_FRAME_CNG: + case AST_FRAME_MODEM: + break; + } } + if (defer_frame) { + for (i = 0; i < x; i++) { + if (mons[i] == chan) { + struct ast_frame *dup_f; + if ((dup_f = ast_frdup(f))) { + AST_LIST_INSERT_TAIL(&ents[i]->dtmf_frames, dup_f, frame_list); + } + break; + } + } + + } + if (f) ast_frfree(f); }