Browse Source

TT#14008 offload flags parsing for play_dtmf/media

Since we're already doing the full parsing of the request flags, use the
same function to parse all required flags

Change-Id: I0880ccbbbc36eae7b172440ce51afc1c544583a1
pull/1487/head
Richard Fuchs 4 years ago
parent
commit
e8f16dba4f
3 changed files with 66 additions and 47 deletions
  1. +3
    -2
      README.md
  2. +57
    -45
      daemon/call_interfaces.c
  3. +6
    -0
      include/call_interfaces.h

+ 3
- 2
README.md View File

@ -1591,7 +1591,7 @@ Optionally included keys are:
and `random` in negative dB. The default is -10 dB. The highest and `random` in negative dB. The default is -10 dB. The highest
possible volume is 0 dB and the lowest possible volume is -63 dB. possible volume is 0 dB and the lowest possible volume is -63 dB.
* `digit`
* `digit` or `code`
Sets the replacement digit for `DTMF-security=DTMF`. Sets the replacement digit for `DTMF-security=DTMF`.
@ -2069,7 +2069,8 @@ be selected in the same way as described under the `play media` message above (i
of using the `all` flag). The selected call participant is the one generating the DTMF event, not the of using the `all` flag). The selected call participant is the one generating the DTMF event, not the
one receiving it. one receiving it.
The dictionary key `code` must be present in the message, indicating the DTMF event to be generated. It can
The dictionary key `code` (or alternatively `digit`) must be present in the message,
indicating the DTMF event to be generated. It can
be either an integer with values 0-15, or a string containing a single character be either an integer with values 0-15, or a string containing a single character
(`0` - `9`, `*`, `#`, `A` - `D`). Additional optional dictionary keys are: `duration` indicating the duration (`0` - `9`, `*`, `#`, `A` - `D`). Additional optional dictionary keys are: `duration` indicating the duration
of the event in milliseconds (defaults to 250 ms, with a minimum of 100 and a maximum of 5000); of the event in milliseconds (defaults to 250 ms, with a minimum of 100 and a maximum of 5000);


+ 57
- 45
daemon/call_interfaces.c View File

@ -1385,6 +1385,7 @@ static void call_ng_main_flags(struct sdp_ng_flags *out, str *key, bencode_item_
case CSH_LOOKUP("volume"): case CSH_LOOKUP("volume"):
out->volume = bencode_get_integer_str(value, out->volume); out->volume = bencode_get_integer_str(value, out->volume);
break; break;
case CSH_LOOKUP("code"):
case CSH_LOOKUP("digit"): case CSH_LOOKUP("digit"):
out->digit = bencode_get_integer_str(value, out->digit); out->digit = bencode_get_integer_str(value, out->digit);
if (s.len == 1) if (s.len == 1)
@ -1447,6 +1448,24 @@ static void call_ng_main_flags(struct sdp_ng_flags *out, str *key, bencode_item_
out->delay_buffer = bencode_get_integer_str(value, out->delay_buffer); out->delay_buffer = bencode_get_integer_str(value, out->delay_buffer);
break; break;
#endif #endif
case CSH_LOOKUP("repeat-times"):
out->repeat_times = bencode_get_integer_str(value, out->repeat_times);
break;
case CSH_LOOKUP("file"):
out->file = s;
break;
case CSH_LOOKUP("blob"):
out->blob = s;
break;
case CSH_LOOKUP("db-id"):
out->db_id = bencode_get_integer_str(value, out->db_id);
break;
case CSH_LOOKUP("duration"):
out->duration = bencode_get_integer_str(value, out->duration);
break;
case CSH_LOOKUP("pause"):
out->pause = bencode_get_integer_str(value, out->pause);
break;
case CSH_LOOKUP("command"): case CSH_LOOKUP("command"):
break; break;
default: default:
@ -2723,14 +2742,12 @@ static const char *play_media_select_party(struct call **call, GQueue *monologue
const char *call_play_media_ng(bencode_item_t *input, bencode_item_t *output) { const char *call_play_media_ng(bencode_item_t *input, bencode_item_t *output) {
#ifdef WITH_TRANSCODING #ifdef WITH_TRANSCODING
str str;
AUTO_CLEANUP_NULL(struct call *call, call_unlock_release); AUTO_CLEANUP_NULL(struct call *call, call_unlock_release);
AUTO_CLEANUP(GQueue monologues, g_queue_clear); AUTO_CLEANUP(GQueue monologues, g_queue_clear);
const char *err = NULL; const char *err = NULL;
long long db_id;
long long repeat_times = 1;
AUTO_CLEANUP(struct sdp_ng_flags flags, call_ng_free_flags);
err = play_media_select_party(&call, &monologues, input, NULL);
err = play_media_select_party(&call, &monologues, input, &flags);
if (err) if (err)
return err; return err;
@ -2739,17 +2756,18 @@ const char *call_play_media_ng(bencode_item_t *input, bencode_item_t *output) {
if (!monologue->player) if (!monologue->player)
monologue->player = media_player_new(monologue); monologue->player = media_player_new(monologue);
repeat_times = bencode_dictionary_get_int_str(input, "repeat-times", 1);
if (bencode_dictionary_get_str(input, "file", &str)) {
if (media_player_play_file(monologue->player, &str,repeat_times))
if (flags.repeat_times <= 0)
flags.repeat_times = 1;
if (flags.file.len) {
if (media_player_play_file(monologue->player, &flags.file, flags.repeat_times))
return "Failed to start media playback from file"; return "Failed to start media playback from file";
} }
else if (bencode_dictionary_get_str(input, "blob", &str)) {
if (media_player_play_blob(monologue->player, &str,repeat_times))
else if (flags.blob.len) {
if (media_player_play_blob(monologue->player, &flags.blob, flags.repeat_times))
return "Failed to start media playback from blob"; return "Failed to start media playback from blob";
} }
else if ((db_id = bencode_dictionary_get_int_str(input, "db-id", 0)) > 0) {
if (media_player_play_db(monologue->player, db_id,repeat_times))
else if (flags.db_id > 0) {
if (media_player_play_db(monologue->player, flags.db_id, flags.repeat_times))
return "Failed to start media playback from database"; return "Failed to start media playback from database";
} }
else else
@ -2796,54 +2814,50 @@ const char *call_play_dtmf_ng(bencode_item_t *input, bencode_item_t *output) {
#ifdef WITH_TRANSCODING #ifdef WITH_TRANSCODING
AUTO_CLEANUP_NULL(struct call *call, call_unlock_release); AUTO_CLEANUP_NULL(struct call *call, call_unlock_release);
AUTO_CLEANUP(GQueue monologues, g_queue_clear); AUTO_CLEANUP(GQueue monologues, g_queue_clear);
str str;
const char *err = NULL; const char *err = NULL;
AUTO_CLEANUP(struct sdp_ng_flags flags, call_ng_free_flags);
err = play_media_select_party(&call, &monologues, input, NULL);
err = play_media_select_party(&call, &monologues, input, &flags);
if (err) if (err)
return err; return err;
// validate input parameters // validate input parameters
long long duration = bencode_dictionary_get_int_str(input, "duration", 250);
if (duration < 100) {
duration = 100;
ilog(LOG_WARN, "Invalid duration (%lli ms) specified, using 100 ms instead", duration);
if (!flags.duration)
flags.duration = 250;
if (flags.duration < 100) {
flags.duration = 100;
ilog(LOG_WARN, "Invalid duration (%lli ms) specified, using 100 ms instead", flags.duration);
} }
else if (duration > 5000) {
duration = 5000;
ilog(LOG_WARN, "Invalid duration (%lli ms) specified, using 5000 ms instead", duration);
else if (flags.duration > 5000) {
flags.duration = 5000;
ilog(LOG_WARN, "Invalid duration (%lli ms) specified, using 5000 ms instead", flags.duration);
} }
long long pause = bencode_dictionary_get_int_str(input, "pause", 100);
if (pause < 100) {
pause = 100;
ilog(LOG_WARN, "Invalid pause (%lli ms) specified, using 100 ms instead", pause);
if (!flags.pause)
flags.pause = 100;
if (flags.pause < 100) {
flags.pause = 100;
ilog(LOG_WARN, "Invalid pause (%lli ms) specified, using 100 ms instead", flags.pause);
} }
else if (pause > 5000) {
pause = 5000;
ilog(LOG_WARN, "Invalid pause (%lli ms) specified, using 5000 ms instead", pause);
else if (flags.pause > 5000) {
flags.pause = 5000;
ilog(LOG_WARN, "Invalid pause (%lli ms) specified, using 5000 ms instead", flags.pause);
} }
long long code = bencode_dictionary_get_int_str(input, "code", -1);
if (code == -1) {
// try a string code
if (!bencode_dictionary_get_str(input, "code", &str))
return "No valid 'code' specified";
if (str.len != 1)
return "Given 'code' is not a single digit";
code = dtmf_code_from_char(str.s[0]);
if (code == -1)
return "Invalid 'code' character";
}
else if (code < 0)
int code;
if (dtmf_code_to_char(flags.digit))
code = flags.digit; // already a code
else
code = dtmf_code_from_char(flags.digit); // convert digit to code
if (code < 0)
return "Out of range 'code' specified"; return "Out of range 'code' specified";
else if (code > 15) else if (code > 15)
return "Out of range 'code' specified"; return "Out of range 'code' specified";
long long volume = bencode_dictionary_get_int_str(input, "volume", 8);
if (volume > 0)
volume *= -1;
if (flags.volume > 0)
flags.volume *= -1;
for (GList *l = monologues.head; l; l = l->next) { for (GList *l = monologues.head; l; l = l->next) {
struct call_monologue *monologue = l->data; struct call_monologue *monologue = l->data;
@ -2854,8 +2868,6 @@ const char *call_play_dtmf_ng(bencode_item_t *input, bencode_item_t *output) {
media = l->data; media = l->data;
if (media->type_id != MT_AUDIO) if (media->type_id != MT_AUDIO)
continue; continue;
// if (!media->dtmf_injector)
// continue;
goto found; goto found;
} }
@ -2877,7 +2889,7 @@ found:
return "Sink monologue has no media capable of DTMF playback"; return "Sink monologue has no media capable of DTMF playback";
found_sink: found_sink:
err = dtmf_inject(media, code, volume, duration, pause, sink);
err = dtmf_inject(media, code, flags.volume, flags.duration, flags.pause, sink);
if (err) if (err)
return err; return err;
} }


+ 6
- 0
include/call_interfaces.h View File

@ -88,6 +88,12 @@ struct sdp_ng_flags {
int trigger_end_digits; int trigger_end_digits;
int trigger_end_ms; int trigger_end_ms;
int dtmf_delay; int dtmf_delay;
int repeat_times;
str file;
str blob;
long long db_id;
long long duration;
long long pause;
unsigned int asymmetric:1, unsigned int asymmetric:1,
protocol_accept:1, protocol_accept:1,
no_redis_update:1, no_redis_update:1,


Loading…
Cancel
Save