T.140: Fix format ref and memory leaks.

* channel.c:ast_sendtext(): Fix T.140 SendText memory leak.

* format_compatibility.c: T.140 RED and T.140 were swapped.

* res_rtp_asterisk.c:rtp_red_init(): Fix ast_format_t140_red ref leak.

* res_rtp_asterisk.c:rtp_red_init(): Fix data race after starting periodic
scheduled red_write().

* res_rtp_asterisk.c: Some other minor misc tweaks.

Change-Id: Ifa27a2e0f8a966b1cf628607c86fc4374b0b88cb
changes/98/4798/2
Richard Mudgett 8 years ago
parent e51193bf72
commit c54f9d2bf0

@ -4889,16 +4889,18 @@ int ast_sendtext(struct ast_channel *chan, const char *text)
if (ast_channel_tech(chan)->write_text && (ast_format_cap_has_type(ast_channel_nativeformats(chan), AST_MEDIA_TYPE_TEXT))) { if (ast_channel_tech(chan)->write_text && (ast_format_cap_has_type(ast_channel_nativeformats(chan), AST_MEDIA_TYPE_TEXT))) {
struct ast_frame f; struct ast_frame f;
memset(&f, 0, sizeof(f));
f.frametype = AST_FRAME_TEXT; f.frametype = AST_FRAME_TEXT;
f.src = "DIALPLAN"; f.src = "DIALPLAN";
f.mallocd = AST_MALLOCD_DATA; f.mallocd = AST_MALLOCD_DATA;
f.datalen = strlen(text); f.datalen = strlen(text);
f.data.ptr = ast_strdup(text); f.data.ptr = ast_strdup(text);
f.offset = 0;
f.seqno = 0;
f.subclass.format = ast_format_t140; f.subclass.format = ast_format_t140;
if (f.data.ptr) {
res = ast_channel_tech(chan)->write_text(chan, &f); res = ast_channel_tech(chan)->write_text(chan, &f);
ast_frfree(&f);
}
} else if (ast_channel_tech(chan)->send_text) { } else if (ast_channel_tech(chan)->send_text) {
res = ast_channel_tech(chan)->send_text(chan, text); res = ast_channel_tech(chan)->send_text(chan, text);
} }

@ -264,10 +264,10 @@ struct ast_format *ast_format_compatibility_bitfield2format(uint64_t bitfield)
/*! T.140 RED Text format RFC 4103 */ /*! T.140 RED Text format RFC 4103 */
case AST_FORMAT_T140_RED: case AST_FORMAT_T140_RED:
return ast_format_t140; return ast_format_t140_red;
/*! T.140 Text format - ITU T.140, RFC 4103 */ /*! T.140 Text format - ITU T.140, RFC 4103 */
case AST_FORMAT_T140: case AST_FORMAT_T140:
return ast_format_t140_red; return ast_format_t140;
} }
return NULL; return NULL;
} }

@ -232,6 +232,7 @@ struct dtls_details {
/*! \brief RTP session description */ /*! \brief RTP session description */
struct ast_rtp { struct ast_rtp {
int s; int s;
/*! \note The f.subclass.format holds a ref. */
struct ast_frame f; struct ast_frame f;
unsigned char rawdata[8192 + AST_FRIENDLY_OFFSET]; unsigned char rawdata[8192 + AST_FRIENDLY_OFFSET];
unsigned int ssrc; /*!< Synchronization source, RFC 3550, page 10. */ unsigned int ssrc; /*!< Synchronization source, RFC 3550, page 10. */
@ -2767,6 +2768,7 @@ static int ast_rtp_destroy(struct ast_rtp_instance *instance)
if (rtp->red) { if (rtp->red) {
AST_SCHED_DEL(rtp->sched, rtp->red->schedid); AST_SCHED_DEL(rtp->sched, rtp->red->schedid);
ast_free(rtp->red); ast_free(rtp->red);
rtp->red = NULL;
} }
#ifdef HAVE_PJPROJECT #ifdef HAVE_PJPROJECT
@ -3487,7 +3489,8 @@ static int ast_rtp_raw_write(struct ast_rtp_instance *instance, struct ast_frame
return 0; return 0;
} }
static struct ast_frame *red_t140_to_red(struct rtp_red *red) { static struct ast_frame *red_t140_to_red(struct rtp_red *red)
{
unsigned char *data = red->t140red.data.ptr; unsigned char *data = red->t140red.data.ptr;
int len = 0; int len = 0;
int i; int i;
@ -5062,22 +5065,21 @@ static int rtp_red_init(struct ast_rtp_instance *instance, int buffer_time, int
struct ast_rtp *rtp = ast_rtp_instance_get_data(instance); struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
int x; int x;
if (!(rtp->red = ast_calloc(1, sizeof(*rtp->red)))) { rtp->red = ast_calloc(1, sizeof(*rtp->red));
if (!rtp->red) {
return -1; return -1;
} }
rtp->red->t140.frametype = AST_FRAME_TEXT; rtp->red->t140.frametype = AST_FRAME_TEXT;
ao2_replace(rtp->red->t140.subclass.format, ast_format_t140_red); rtp->red->t140.subclass.format = ast_format_t140_red;
rtp->red->t140.data.ptr = &rtp->red->buf_data; rtp->red->t140.data.ptr = &rtp->red->buf_data;
rtp->red->t140.ts = 0;
rtp->red->t140red = rtp->red->t140; rtp->red->t140red = rtp->red->t140;
rtp->red->t140red.data.ptr = &rtp->red->t140red_data; rtp->red->t140red.data.ptr = &rtp->red->t140red_data;
rtp->red->t140red.datalen = 0;
rtp->red->ti = buffer_time; rtp->red->ti = buffer_time;
rtp->red->num_gen = generations; rtp->red->num_gen = generations;
rtp->red->hdrlen = generations * 4 + 1; rtp->red->hdrlen = generations * 4 + 1;
rtp->red->prev_ts = 0;
for (x = 0; x < generations; x++) { for (x = 0; x < generations; x++) {
rtp->red->pt[x] = payloads[x]; rtp->red->pt[x] = payloads[x];
@ -5087,8 +5089,6 @@ static int rtp_red_init(struct ast_rtp_instance *instance, int buffer_time, int
rtp->red->t140red_data[x*4] = rtp->red->pt[x] = payloads[x]; /* primary pt */ rtp->red->t140red_data[x*4] = rtp->red->pt[x] = payloads[x]; /* primary pt */
rtp->red->schedid = ast_sched_add(rtp->sched, generations, red_write, instance); rtp->red->schedid = ast_sched_add(rtp->sched, generations, red_write, instance);
rtp->red->t140.datalen = 0;
return 0; return 0;
} }
@ -5216,7 +5216,7 @@ static void ast_rtp_stop(struct ast_rtp_instance *instance)
if (rtp->red) { if (rtp->red) {
AST_SCHED_DEL(rtp->sched, rtp->red->schedid); AST_SCHED_DEL(rtp->sched, rtp->red->schedid);
free(rtp->red); ast_free(rtp->red);
rtp->red = NULL; rtp->red = NULL;
} }

Loading…
Cancel
Save