Index: channels/chan_sip.c =================================================================== --- channels/chan_sip.c (revision 235381) +++ channels/chan_sip.c (working copy) @@ -4849,6 +4849,7 @@ p->chanvars = NULL; } +ast_log(LOG_WARNING, "jpeeler: freed contents of sip_pvt %p and mohsuggest = %p %s\n", p, p->mohsuggest, p->mohsuggest); ast_string_field_free_memory(p); if (p->socket.tcptls_session) { @@ -7806,9 +7807,11 @@ ast_clear_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */ } else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) { int already_on_hold = ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD); +ast_log(LOG_WARNING, "jpeeler: inside sip_pvt %p MOH suggest %s\n", p, p->mohsuggest); ast_queue_control_data(p->owner, AST_CONTROL_HOLD, S_OR(p->mohsuggest, NULL), !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0); + //ast_queue_hangup_with_cause(p->owner, AST_CAUSE_PROTOCOL_ERROR); if (sendonly) ast_rtp_stop(p->rtp); /* RTCP needs to go ahead, even if we're on hold!!! */ Index: include/asterisk/channel.h =================================================================== --- include/asterisk/channel.h (revision 235381) +++ include/asterisk/channel.h (working copy) @@ -736,8 +736,11 @@ * \retval 0 success * \retval non-zero failure */ -int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f); +int __ast_queue_frame(struct ast_channel *chan, struct ast_frame *f, const char *file, int line, const char *function); +#define ast_queue_frame(chan, f) \ + __ast_queue_frame(chan, f, __FILE__, __LINE__, __FUNCTION__) + /*! * \brief Queue one or more frames to the head of a channel's frame queue * @@ -750,14 +753,18 @@ * \retval 0 success * \retval non-zero failure */ -int ast_queue_frame_head(struct ast_channel *chan, struct ast_frame *f); +int __ast_queue_frame_head(struct ast_channel *chan, struct ast_frame *f, const char *file, int line, const char *function); +#define ast_queue_frame_head(chan, f) \ + __ast_queue_frame_head(chan, f, __FILE__, __LINE__, __FUNCTION__) /*! * \brief Queue a hangup frame * * \note The channel does not need to be locked before calling this function. */ -int ast_queue_hangup(struct ast_channel *chan); +int __ast_queue_hangup(struct ast_channel *chan, const char *file, int line, const char *function); +#define ast_queue_hangup(chan) \ + __ast_queue_hangup(chan, __FILE__, __LINE__, __FUNCTION__) /*! * \brief Queue a hangup frame with hangupcause set @@ -768,7 +775,9 @@ * \return 0 on success, -1 on error * \since 1.6.1 */ -int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause); +int __ast_queue_hangup_with_cause(struct ast_channel *chan, int cause, const char *file, int line, const char *function); +#define ast_queue_hangup_with_cause(chan, cause) \ + __ast_queue_hangup_with_cause(chan, cause, __FILE__, __LINE__, __FUNCTION__) /*! * \brief Queue a control frame with payload @@ -781,7 +790,9 @@ * \retval zero on success * \retval non-zero on failure */ -int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control); +int __ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control, const char *file, int line, const char *function); +#define ast_queue_control(chan, control) \ + __ast_queue_control(chan, control, __FILE__, __LINE__, __FUNCTION__) /*! * \brief Queue a control frame with payload @@ -807,8 +818,10 @@ * * \note The channel does not need to be locked before calling this function. */ -int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, - const void *data, size_t datalen); +int __ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, + const void *data, size_t datalen, const char *file, int line, const char *function); +#define ast_queue_control_data(chan, control, data, datalen) \ + __ast_queue_control_data(chan, control, data, datalen, __FILE__, __LINE__, __FUNCTION__) /*! * \brief Change channel name Index: include/asterisk/frame.h =================================================================== --- include/asterisk/frame.h (revision 235381) +++ include/asterisk/frame.h (working copy) @@ -483,7 +483,9 @@ * Duplicates a frame -- should only rarely be used, typically frisolate is good enough * \return Returns a frame on success, NULL on error */ -struct ast_frame *ast_frdup(const struct ast_frame *fr); +struct ast_frame *__ast_frdup(const struct ast_frame *fr, const char *file, int line, const char *function); +#define ast_frdup(fr) \ + __ast_frdup(fr, __FILE__, __LINE__, __FUNCTION__) void ast_swapcopy_samples(void *dst, const void *src, int samples); Index: main/channel.c =================================================================== --- main/channel.c (revision 235381) +++ main/channel.c (working copy) @@ -980,7 +980,7 @@ return result; } -static int __ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin, int head, struct ast_frame *after) +static int __ast_queue_frame_helper(struct ast_channel *chan, struct ast_frame *fin, int head, struct ast_frame *after, const char *file, int line, const char *function) { struct ast_frame *f; struct ast_frame *cur; @@ -1004,13 +1004,21 @@ /* Build copies of all the frames and count them */ AST_LIST_HEAD_INIT_NOLOCK(&frames); for (cur = fin; cur; cur = AST_LIST_NEXT(cur, frame_list)) { - if (!(f = ast_frdup(cur))) { + if (!(f = __ast_frdup(cur, file, line, function))) { ast_frfree(AST_LIST_FIRST(&frames)); return -1; } +if (f->frametype == AST_FRAME_CONTROL && (f->subclass == AST_CONTROL_HOLD || f->subclass == AST_CONTROL_UNHOLD)) { + ast_log(LOG_WARNING, "jpeeler: %p inserting frame %p into frame list with datalen %d and data at %p...", (void *) pthread_self(), f, f->datalen, f->datalen ? f->data.ptr : &f->data.uint32); + if (f->datalen) + ast_log(LOG_WARNING, "jpeeler: with data with length %s\n", (char *) f->data.ptr); + else + ast_log(LOG_WARNING, "jpeeler: with data %u\n", f->data.uint32); +} AST_LIST_INSERT_TAIL(&frames, f, frame_list); new_frames++; + ast_log(LOG_WARNING, "jpeeler: new frames count %d\n", new_frames); if (f->frametype == AST_FRAME_VOICE) { new_voice_frames++; } @@ -1019,6 +1027,7 @@ /* Count how many frames exist on the queue */ AST_LIST_TRAVERSE(&chan->readq, cur, frame_list) { queued_frames++; + ast_log(LOG_WARNING, "jpeeler: checking frame %p in readq with datalen %d and data.ptr %p\n", cur, cur->datalen, cur->datalen ? cur->data.ptr : &cur->data.uint32); if (cur->frametype == AST_FRAME_VOICE) { queued_voice_frames++; } @@ -1068,18 +1077,18 @@ return 0; } -int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin) +int __ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin, const char *file, int line, const char *function) { - return __ast_queue_frame(chan, fin, 0, NULL); + return __ast_queue_frame_helper(chan, fin, 0, NULL, file, line, function); } -int ast_queue_frame_head(struct ast_channel *chan, struct ast_frame *fin) +int __ast_queue_frame_head(struct ast_channel *chan, struct ast_frame *fin, const char *file, int line, const char *function) { - return __ast_queue_frame(chan, fin, 1, NULL); + return __ast_queue_frame_helper(chan, fin, 1, NULL, file, line, function); } /*! \brief Queue a hangup frame for channel */ -int ast_queue_hangup(struct ast_channel *chan) +int __ast_queue_hangup(struct ast_channel *chan, const char *file, int line, const char *function) { struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP }; /* Yeah, let's not change a lock-critical value without locking */ @@ -1087,11 +1096,11 @@ chan->_softhangup |= AST_SOFTHANGUP_DEV; ast_channel_unlock(chan); } - return ast_queue_frame(chan, &f); + return __ast_queue_frame(chan, &f, file, line, function); } /*! \brief Queue a hangup frame for channel */ -int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause) +int __ast_queue_hangup_with_cause(struct ast_channel *chan, int cause, const char *file, int line, const char *function) { struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP }; @@ -1107,30 +1116,33 @@ ast_channel_unlock(chan); } - return ast_queue_frame(chan, &f); + return __ast_queue_frame(chan, &f, file, line, function); } /*! \brief Queue a control frame */ -int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control) +int __ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control, const char *file, int line, const char *function) { struct ast_frame f = { AST_FRAME_CONTROL, }; f.subclass = control; - return ast_queue_frame(chan, &f); + return __ast_queue_frame(chan, &f, file, line, function); } /*! \brief Queue a control frame with payload */ -int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, - const void *data, size_t datalen) +int __ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, + const void *data, size_t datalen, const char *file, int line, const char *function) { struct ast_frame f = { AST_FRAME_CONTROL, }; + //ast_assert(datalen > 0 ? data != NULL : data == NULL); +ast_log(LOG_WARNING, "jpeeler datalen %d data %p\n", (int) datalen, data); + f.subclass = control; f.data.ptr = (void *) data; f.datalen = datalen; - return ast_queue_frame(chan, &f); + return __ast_queue_frame(chan, &f, file, line, function); } /*! \brief Set defer DTMF flag on channel */ @@ -2968,7 +2980,7 @@ if (!readq_tail) { ast_queue_frame_head(chan, AST_LIST_NEXT(f, frame_list)); } else { - __ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list), 0, readq_tail); + __ast_queue_frame_helper(chan, AST_LIST_NEXT(f, frame_list), 0, readq_tail, __FILE__, __LINE__, __FUNCTION__); } ast_frfree(AST_LIST_NEXT(f, frame_list)); AST_LIST_NEXT(f, frame_list) = NULL; @@ -3001,6 +3013,12 @@ if (chan->music_state && chan->generator && chan->generator->digit && f && f->frametype == AST_FRAME_DTMF_END) chan->generator->digit(chan, f->subclass); +if (f && f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HOLD && f->datalen==0 && f->data.ptr) { + ast_log(LOG_WARNING,"jpeeler: Found frame with datalen=0 but initialized data pointer!!!---------------------------------------------------\n"); + ast_frame_dump(chan->name, f, "<<"); + /* Fix the frame */ + f->data.ptr = NULL; +} ast_channel_unlock(chan); return f; } @@ -3378,6 +3396,7 @@ CHECK_BLOCKING(chan); switch (fr->frametype) { case AST_FRAME_CONTROL: + ast_log(LOG_WARNING, "jpeeler: music on hold class %s\n", (char *) fr->data.ptr); res = (chan->tech->indicate == NULL) ? 0 : chan->tech->indicate(chan, fr->subclass, fr->data.ptr, fr->datalen); break; @@ -4763,6 +4782,7 @@ if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) { int bridge_exit = 0; +ast_log(LOG_WARNING, "jpeeler: %p frame datalen = %d subclass = %d data.ptr = %p reading '%s'\n", (void *) pthread_self(), f->datalen, f->subclass, f->data.ptr, (char *) f->data.ptr); switch (f->subclass) { case AST_CONTROL_HOLD: case AST_CONTROL_UNHOLD: Index: main/frame.c =================================================================== --- main/frame.c (revision 235381) +++ main/frame.c (working copy) @@ -332,10 +332,13 @@ { if (ast_test_flag(fr, AST_FRFLAG_FROM_TRANSLATOR)) { ast_translate_frame_freed(fr); +//ast_log(LOG_WARNING, "jpeeler frametype %d subclass %d\n", fr->frametype, fr->subclass); } else if (ast_test_flag(fr, AST_FRFLAG_FROM_DSP)) { ast_dsp_frame_freed(fr); +//ast_log(LOG_WARNING, "jpeeler frametype %d subclass %d\n", fr->frametype, fr->subclass); } else if (ast_test_flag(fr, AST_FRFLAG_FROM_FILESTREAM)) { ast_filestream_frame_freed(fr); +//ast_log(LOG_WARNING, "jpeeler frametype %d subclass %d\n", fr->frametype, fr->subclass); } if (!fr->mallocd) @@ -467,7 +470,7 @@ return out; } -struct ast_frame *ast_frdup(const struct ast_frame *f) +struct ast_frame *__ast_frdup(const struct ast_frame *f, const char *file, int line, const char *function) { struct ast_frame *out = NULL; int len, srclen = 0; @@ -526,8 +529,10 @@ if (out->datalen) { out->data.ptr = buf + sizeof(*out) + AST_FRIENDLY_OFFSET; memcpy(out->data.ptr, f->data.ptr, out->datalen); +ast_log(LOG_WARNING, "jpeeler: frametype=%d data.ptr set to %p %s and out %p %s %s:%d %s\n", f->frametype, f->data.ptr, (char *) f->data.ptr, out->data.ptr, (char *) out->data.ptr, file, line, function); } else { out->data.uint32 = f->data.uint32; +ast_log(LOG_WARNING, "jpeeler: frametype=%d data.uint32 set to %p %u and out %p %u %s:%d %s\n", f->frametype, &f->data.uint32, f->data.uint32, &out->data.uint32, out->data.uint32, file, line, function); } if (srclen > 0) { /* This may seem a little strange, but it's to avoid a gcc (4.2.4) compiler warning */