|
|
|
@ -256,23 +256,43 @@ const char *dtmf_inject(struct call_media *media, int code, int volume, int dura |
|
|
|
|
|
|
|
// create RFC DTMF events. we do this by simulating a detected PCM DTMF event |
|
|
|
// find payload type to use |
|
|
|
struct codec_handler *ch = NULL; |
|
|
|
struct codec_ssrc_handler *csh = NULL; |
|
|
|
int pt = -1; |
|
|
|
for (int i = 0; i < ssrc_in->tracker.most_len; i++) { |
|
|
|
pt = ssrc_in->tracker.most[i]; |
|
|
|
if (pt != 255) |
|
|
|
if (pt == 255) |
|
|
|
continue; |
|
|
|
if (pt < 0) |
|
|
|
break; |
|
|
|
|
|
|
|
ch = codec_handler_get(media, pt); |
|
|
|
if (!ch) |
|
|
|
continue; |
|
|
|
if (ch->output_handler && ch->output_handler->ssrc_hash) // context switch if we have multiple inputs going to one output |
|
|
|
ch = ch->output_handler; |
|
|
|
|
|
|
|
ilog(LOG_DEBUG, "DTMF injection: Using PT %i/%i -> %i (%i), SSRC %" PRIx32, |
|
|
|
pt, |
|
|
|
ch->source_pt.payload_type, |
|
|
|
ch->dest_pt.payload_type, |
|
|
|
ch->dtmf_payload_type, |
|
|
|
ssrc_in->parent->h.ssrc); |
|
|
|
|
|
|
|
if (!ch->ssrc_hash) |
|
|
|
continue; |
|
|
|
csh = get_ssrc(ssrc_in->parent->h.ssrc, ch->ssrc_hash); |
|
|
|
if (!csh) |
|
|
|
continue; |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
if (pt < 0 || pt == 255) |
|
|
|
return "No RTP payload type found to be in use"; // XXX generate stream |
|
|
|
|
|
|
|
struct codec_handler *ch = codec_handler_get(media, pt); |
|
|
|
if (!ch) |
|
|
|
return "No matching codec handler"; |
|
|
|
if (ch->output_handler && ch->output_handler->ssrc_hash) // context switch if we have multiple inputs going to one output |
|
|
|
ch = ch->output_handler; |
|
|
|
if (!ch->ssrc_hash) |
|
|
|
return "No suitable codec handler present"; |
|
|
|
struct codec_ssrc_handler *csh = get_ssrc(ssrc_in->parent->h.ssrc, ch->ssrc_hash); |
|
|
|
if (!csh) |
|
|
|
return "No matching codec SSRC handler"; |
|
|
|
|
|
|
|
|