Asterisk - The Open Source Telephony Project  GIT-master-a24979a
Macros | Enumerations | Functions | Variables
app_mf.c File Reference

MF sender and receiver applications. More...

#include "asterisk.h"
#include "asterisk/file.h"
#include "asterisk/pbx.h"
#include "asterisk/channel.h"
#include "asterisk/dsp.h"
#include "asterisk/app.h"
#include "asterisk/module.h"
#include "asterisk/indications.h"
#include "asterisk/conversions.h"
Include dependency graph for app_mf.c:

Go to the source code of this file.

Macros

#define BUFFER_SIZE   256
 
#define MF_BETWEEN_MS   50
 
#define MF_DURATION   55
 
#define MF_KP_DURATION   120
 
#define MF_ST_DURATION   65
 

Enumerations

enum  { OPT_ARG_MAXDIGITS , OPT_ARG_ARRAY_SIZE }
 
enum  read_option_flags {
  OPT_DELAY = (1 << 0) , OPT_MUTE = (1 << 1) , OPT_QUELCH = (1 << 2) , OPT_RELAXED = (1 << 3) ,
  OPT_LAX_KP = (1 << 4) , OPT_PROCESS = (1 << 5) , OPT_NO_KP = (1 << 6) , OPT_NO_ST = (1 << 7) ,
  OPT_KP_OVERRIDE = (1 << 8) , OPT_MAXDIGITS = (1 << 9) , OPT_SKIP = (1 << 0) , OPT_INDICATION = (1 << 1) ,
  OPT_NOANSWER = (1 << 2) , OPT_TERMINATOR = (1 << 3) , OPT_DELAY = (1 << 0) , OPT_MUTE = (1 << 1) ,
  OPT_QUELCH = (1 << 2) , OPT_RELAXED = (1 << 3) , OPT_EXTRAPULSES = (1 << 4)
}
 

Functions

 AST_MODULE_INFO_STANDARD_EXTENDED (ASTERISK_GPL_KEY, "MF Sender and Receiver Applications")
 
static int load_module (void)
 
static int manager_play_mf (struct mansession *s, const struct message *m)
 
static int read_mf_digits (struct ast_channel *chan, char *buf, int buflen, int timeout, int features, int laxkp, int override, int no_kp, int no_st, int maxdigits)
 Detects MF digits on channel using DSP, terminated by ST, STP, ST2P, or ST3P. More...
 
static int read_mf_exec (struct ast_channel *chan, const char *data)
 
static int sendmf_exec (struct ast_channel *chan, const char *vdata)
 
static int unload_module (void)
 

Variables

static const struct ast_app_option read_app_options [128] = { [ 'd' ] = { .flag = OPT_DELAY }, [ 'l' ] = { .flag = OPT_LAX_KP }, [ 'k' ] = { .flag = OPT_NO_KP }, [ 'm' ] = { .flag = OPT_MUTE }, [ 'n' ] = { .flag = OPT_MAXDIGITS , .arg_index = OPT_ARG_MAXDIGITS + 1 }, [ 'o' ] = { .flag = OPT_KP_OVERRIDE }, [ 'p' ] = { .flag = OPT_PROCESS }, [ 'q' ] = { .flag = OPT_QUELCH }, [ 'r' ] = { .flag = OPT_RELAXED }, [ 's' ] = { .flag = OPT_NO_ST }, }
 
static const char * readmf_name = "ReceiveMF"
 
static const char sendmf_name [] = "SendMF"
 

Detailed Description

MF sender and receiver applications.

Author
Naveen Albert aster.nosp@m.isk@.nosp@m.phrea.nosp@m.knet.nosp@m..org

Definition in file app_mf.c.

Macro Definition Documentation

◆ BUFFER_SIZE

#define BUFFER_SIZE   256

◆ MF_BETWEEN_MS

#define MF_BETWEEN_MS   50

Definition at line 225 of file app_mf.c.

◆ MF_DURATION

#define MF_DURATION   55

Definition at line 226 of file app_mf.c.

◆ MF_KP_DURATION

#define MF_KP_DURATION   120

Definition at line 227 of file app_mf.c.

◆ MF_ST_DURATION

#define MF_ST_DURATION   65

Definition at line 228 of file app_mf.c.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
OPT_ARG_MAXDIGITS 
OPT_ARG_ARRAY_SIZE 

Definition at line 203 of file app_mf.c.

203  {
205  /* Must be the last element */
207 };
@ OPT_ARG_MAXDIGITS
Definition: app_mf.c:204
@ OPT_ARG_ARRAY_SIZE
Definition: app_mf.c:206

◆ read_option_flags

Enumerator
OPT_DELAY 
OPT_MUTE 
OPT_QUELCH 
OPT_RELAXED 
OPT_LAX_KP 
OPT_PROCESS 
OPT_NO_KP 
OPT_NO_ST 
OPT_KP_OVERRIDE 
OPT_MAXDIGITS 
OPT_SKIP 
OPT_INDICATION 
OPT_NOANSWER 
OPT_TERMINATOR 
OPT_DELAY 
OPT_MUTE 
OPT_QUELCH 
OPT_RELAXED 
OPT_EXTRAPULSES 

Definition at line 190 of file app_mf.c.

190  {
191  OPT_DELAY = (1 << 0),
192  OPT_MUTE = (1 << 1),
193  OPT_QUELCH = (1 << 2),
194  OPT_RELAXED = (1 << 3),
195  OPT_LAX_KP = (1 << 4),
196  OPT_PROCESS = (1 << 5),
197  OPT_NO_KP = (1 << 6),
198  OPT_NO_ST = (1 << 7),
199  OPT_KP_OVERRIDE = (1 << 8),
200  OPT_MAXDIGITS = (1 << 9),
201 };
@ OPT_PROCESS
Definition: app_mf.c:196
@ OPT_MUTE
Definition: app_mf.c:192
@ OPT_NO_KP
Definition: app_mf.c:197
@ OPT_LAX_KP
Definition: app_mf.c:195
@ OPT_RELAXED
Definition: app_mf.c:194
@ OPT_MAXDIGITS
Definition: app_mf.c:200
@ OPT_QUELCH
Definition: app_mf.c:193
@ OPT_DELAY
Definition: app_mf.c:191
@ OPT_KP_OVERRIDE
Definition: app_mf.c:199
@ OPT_NO_ST
Definition: app_mf.c:198

Function Documentation

◆ AST_MODULE_INFO_STANDARD_EXTENDED()

AST_MODULE_INFO_STANDARD_EXTENDED ( ASTERISK_GPL_KEY  ,
"MF Sender and Receiver Applications"   
)

◆ load_module()

static int load_module ( void  )
static

Definition at line 535 of file app_mf.c.

536 {
537  int res;
538 
542 
543  return res;
544 }
static int sendmf_exec(struct ast_channel *chan, const char *vdata)
Definition: app_mf.c:423
static const char * readmf_name
Definition: app_mf.c:222
static const char sendmf_name[]
Definition: app_mf.c:223
static int manager_play_mf(struct mansession *s, const struct message *m)
Definition: app_mf.c:483
static int read_mf_exec(struct ast_channel *chan, const char *data)
Definition: app_mf.c:345
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:191
#define EVENT_FLAG_CALL
Definition: manager.h:76
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:626

References ast_manager_register_xml, ast_register_application_xml, EVENT_FLAG_CALL, manager_play_mf(), read_mf_exec(), readmf_name, sendmf_exec(), and sendmf_name.

◆ manager_play_mf()

static int manager_play_mf ( struct mansession s,
const struct message m 
)
static

Definition at line 483 of file app_mf.c.

484 {
485  const char *channel = astman_get_header(m, "Channel");
486  const char *digit = astman_get_header(m, "Digit");
487  const char *duration = astman_get_header(m, "Duration");
488  struct ast_channel *chan;
489  unsigned int duration_ms = MF_DURATION;
490 
491  if (!(chan = ast_channel_get_by_name(channel))) {
492  astman_send_error(s, m, "Channel not found");
493  return 0;
494  }
495 
496  if (ast_strlen_zero(digit)) {
497  astman_send_error(s, m, "No digit specified");
498  chan = ast_channel_unref(chan);
499  return 0;
500  }
501 
502  /* Override default duration with KP or ST-specific default durations */
503  if (!strcmp(digit, "*"))
504  duration_ms = MF_KP_DURATION;
505 
506  if (!strcmp(digit, "#") || !strcmp(digit, "A") || !strcmp(digit, "B") || !strcmp(digit, "C"))
507  duration_ms = MF_ST_DURATION;
508 
509  if (!ast_strlen_zero(duration) && (sscanf(duration, "%30u", &duration_ms) != 1)) {
510  astman_send_error(s, m, "Could not convert Duration parameter");
511  chan = ast_channel_unref(chan);
512  return 0;
513  }
514 
515  ast_mf_stream(chan, NULL, NULL, digit, 0, duration_ms, duration_ms, duration_ms, 1);
516 
517  chan = ast_channel_unref(chan);
518 
519  astman_send_ack(s, m, "MF successfully queued");
520 
521  return 0;
522 }
char digit
#define MF_DURATION
Definition: app_mf.c:226
#define MF_ST_DURATION
Definition: app_mf.c:228
#define MF_KP_DURATION
Definition: app_mf.c:227
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2958
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1448
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3166
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3198
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition: manager.c:2827
int ast_mf_stream(struct ast_channel *chan, struct ast_channel *peer, struct ast_channel *chan2, const char *digits, int between, unsigned int duration, unsigned int durationkp, unsigned int durationst, int is_external)
Send a string of MF digits to a channel.
Definition: main/app.c:1183
#define NULL
Definition: resample.c:96
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
Main Channel structure associated with a channel.

References ast_channel_get_by_name(), ast_channel_unref, ast_mf_stream(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), digit, MF_DURATION, MF_KP_DURATION, MF_ST_DURATION, and NULL.

Referenced by load_module().

◆ read_mf_digits()

static int read_mf_digits ( struct ast_channel chan,
char *  buf,
int  buflen,
int  timeout,
int  features,
int  laxkp,
int  override,
int  no_kp,
int  no_st,
int  maxdigits 
)
static

Detects MF digits on channel using DSP, terminated by ST, STP, ST2P, or ST3P.

Parameters
chanchannel on which to read digits
bufBuffer in which to store digits
buflenSize of buffer
timeoutms to wait for all digits before giving up
featuresAny additional DSP features to use
overrideStart over if we receive additional KPs
no_kpDon't include KP in the output
no_stDon't include start digits in the output
maxdigitsIf greater than 0, only read this many digits no matter what
Return values
0if successful
-1if unsuccessful (including hangup).

Definition at line 246 of file app_mf.c.

246  {
247  struct ast_dsp *dsp;
248  struct ast_frame *frame = NULL;
249  struct timeval start;
250  int remaining_time = timeout;
251  int digits_read = 0;
252  int is_start_digit = 0;
253  char *str = buf;
254  int res = 0;
255 
256  if (!(dsp = ast_dsp_new())) {
257  ast_log(LOG_WARNING, "Unable to allocate DSP!\n");
258  pbx_builtin_setvar_helper(chan, "RECEIVEMFSTATUS", "ERROR");
259  return -1;
260  }
262  ast_dsp_set_digitmode(dsp, DSP_DIGITMODE_MF | features);
263 
264  start = ast_tvnow();
265  *str = 0; /* start with empty output buffer */
266 
267  /* based on app_read and generic_fax_exec from res_fax */
268  while (timeout == 0 || remaining_time > 0) {
269  if (timeout > 0) {
270  remaining_time = ast_remaining_ms(start, timeout);
271  if (remaining_time <= 0) {
272  pbx_builtin_setvar_helper(chan, "RECEIVEMFSTATUS", "TIMEOUT");
273  break;
274  }
275  }
276  if ((maxdigits && digits_read >= maxdigits) || digits_read >= (buflen - 1)) { /* we don't have room to store any more digits (very unlikely to happen for a legitimate reason) */
277  /* This result will probably not be usable, so status should not be START */
278  pbx_builtin_setvar_helper(chan, "RECEIVEMFSTATUS", "MAXDIGITS");
279  break;
280  }
281  /* ast_waitfordigit only waits for DTMF frames, we need to do DSP on voice frames */
282  if (ast_waitfor(chan, 1000) > 0) {
283  frame = ast_read(chan);
284  if (!frame) {
285  ast_debug(1, "Channel '%s' did not return a frame; probably hung up.\n", ast_channel_name(chan));
286  pbx_builtin_setvar_helper(chan, "RECEIVEMFSTATUS", "HANGUP");
287  break;
288  } else if (frame->frametype == AST_FRAME_VOICE) {
289  frame = ast_dsp_process(chan, dsp, frame);
290  /* AST_FRAME_DTMF is used all over the DSP code for DTMF, MF, fax, etc.
291  It's used because we can use the frame to store the digit detected.
292  All this means is that we received something we care about. */
293  if (frame->frametype == AST_FRAME_DTMF) {
294  char result = frame->subclass.integer;
295  if (digits_read == 0 && !laxkp && result != '*') {
296  ast_debug(1, "Received MF digit, but no KP yet, ignoring: %c\n", result);
297  ast_frfree(frame);
298  continue;
299  }
300  ast_debug(1, "Received MF digit: %c\n", result);
301  if (result == '*') {
302  /* We received an additional KP, start over? */
303  if (override && digits_read > 0) {
304  ast_debug(1, "Received another KP, starting over\n");
305  str = buf;
306  *str = 0;
307  digits_read = 1; /* we just detected a KP */
308  } else {
309  digits_read++;
310  }
311  /* if we were told not to include the KP digit in the output string, then skip it */
312  if (no_kp) {
313  ast_frfree(frame);
314  continue;
315  }
316  } else {
317  digits_read++;
318  }
319  is_start_digit = (strchr("#", result) || strchr("A", result) || strchr("B", result) || strchr("C", result));
320  /* if we were told not to include the ST digit in the output string, then skip it */
321  if (!no_st || !is_start_digit) {
322  *str++ = result; /* won't write past allotted memory, because of buffer check at top of loop */
323  *str = 0;
324  }
325  /* we received a ST digit (ST, STP, ST2P, or ST3P), so we're done */
326  if (is_start_digit) {
327  pbx_builtin_setvar_helper(chan, "RECEIVEMFSTATUS", "START");
328  ast_frfree(frame);
329  break;
330  }
331  /* only free frame if it was a DSP match. The MF itself should not be muted. */
332  ast_frfree(frame);
333  }
334  }
335  } else {
336  pbx_builtin_setvar_helper(chan, "RECEIVEMFSTATUS", "HANGUP");
337  res = -1;
338  }
339  }
340  ast_dsp_free(dsp);
341  ast_debug(3, "channel '%s' - event loop stopped { timeout: %d, remaining_time: %d }\n", ast_channel_name(chan), timeout, remaining_time);
342  return res;
343 }
const char * str
Definition: app_jack.c:147
#define ast_log
Definition: astobj2.c:42
static PGresult * result
Definition: cel_pgsql.c:84
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
Definition: channel.c:3163
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4292
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1773
struct ast_dsp * ast_dsp_new(void)
Allocates a new dsp, assumes 8khz for internal sample rate.
Definition: dsp.c:1748
#define DSP_DIGITMODE_MF
Definition: dsp.h:32
#define DSP_FEATURE_DIGIT_DETECT
Definition: dsp.h:28
int ast_dsp_set_digitmode(struct ast_dsp *dsp, int digitmode)
Set digit mode.
Definition: dsp.c:1847
struct ast_frame * ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *inf)
Return AST_FRAME_NULL frames when there is silence, AST_FRAME_BUSY on busies, and call progress,...
Definition: dsp.c:1497
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1758
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define AST_FRAME_DTMF
#define ast_frfree(fr)
@ AST_FRAME_VOICE
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_WARNING
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name.
Definition: dsp.c:407
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
enum ast_frame_type frametype
int ast_remaining_ms(struct timeval start, int max_ms)
Calculate remaining milliseconds given a starting timestamp and upper bound.
Definition: main/utils.c:2179
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:157

References ast_channel_name(), ast_debug, ast_dsp_free(), ast_dsp_new(), ast_dsp_process(), ast_dsp_set_digitmode(), ast_dsp_set_features(), AST_FRAME_DTMF, AST_FRAME_VOICE, ast_frfree, ast_log, ast_read(), ast_remaining_ms(), ast_tvnow(), ast_waitfor(), buf, DSP_DIGITMODE_MF, DSP_FEATURE_DIGIT_DETECT, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, NULL, pbx_builtin_setvar_helper(), result, str, and ast_frame::subclass.

Referenced by read_mf_exec().

◆ read_mf_exec()

static int read_mf_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 345 of file app_mf.c.

346 {
347 #define BUFFER_SIZE 256
348  char tmp[BUFFER_SIZE] = "";
349  int to = 0;
350  double tosec;
351  struct ast_flags flags = {0};
352  char *optargs[OPT_ARG_ARRAY_SIZE];
353  char *argcopy = NULL;
354  int res, features = 0, maxdigits = 0;
355 
356  AST_DECLARE_APP_ARGS(arglist,
357  AST_APP_ARG(variable);
358  AST_APP_ARG(timeout);
360  );
361 
362  if (ast_strlen_zero(data)) {
363  ast_log(LOG_WARNING, "ReceiveMF requires an argument (variable)\n");
364  return -1;
365  }
366 
367  argcopy = ast_strdupa(data);
368 
369  AST_STANDARD_APP_ARGS(arglist, argcopy);
370 
371  if (!ast_strlen_zero(arglist.options)) {
372  ast_app_parse_options(read_app_options, &flags, optargs, arglist.options);
373  }
374 
375  if (!ast_strlen_zero(arglist.timeout)) {
376  tosec = atof(arglist.timeout);
377  if (tosec <= 0) {
378  to = 0;
379  } else {
380  to = tosec * 1000.0;
381  }
382  }
383 
384  if (ast_strlen_zero(arglist.variable)) {
385  ast_log(LOG_WARNING, "Invalid! Usage: ReceiveMF(variable[,timeout][,option])\n");
386  return -1;
387  }
389  maxdigits = atoi(optargs[OPT_ARG_MAXDIGITS]);
390  if (maxdigits <= 0) {
391  ast_log(LOG_WARNING, "Invalid maximum number of digits, ignoring: '%s'\n", optargs[OPT_ARG_MAXDIGITS]);
392  maxdigits = 0;
393  }
394  }
395 
396  if (ast_test_flag(&flags, OPT_DELAY)) {
397  features |= DSP_DIGITMODE_MUTEMAX;
398  }
399 
400  if (ast_test_flag(&flags, OPT_MUTE)) {
401  features |= DSP_DIGITMODE_MUTECONF;
402  }
403 
404  if (!ast_test_flag(&flags, OPT_QUELCH)) {
405  features |= DSP_DIGITMODE_NOQUELCH;
406  }
407 
409  features |= DSP_DIGITMODE_RELAXDTMF;
410  }
411 
412  res = read_mf_digits(chan, tmp, BUFFER_SIZE, to, features, (ast_test_flag(&flags, OPT_LAX_KP)),
414  pbx_builtin_setvar_helper(chan, arglist.variable, tmp);
415  if (!ast_strlen_zero(tmp)) {
416  ast_verb(3, "MF digits received: '%s'\n", tmp);
417  } else if (!res) { /* if channel hung up, don't print anything out */
418  ast_verb(3, "No MF digits received.\n");
419  }
420  return res;
421 }
#define BUFFER_SIZE
static int read_mf_digits(struct ast_channel *chan, char *buf, int buflen, int timeout, int features, int laxkp, int override, int no_kp, int no_st, int maxdigits)
Detects MF digits on channel using DSP, terminated by ST, STP, ST2P, or ST3P.
Definition: app_mf.c:246
static const struct ast_app_option read_app_options[128]
Definition: app_mf.c:220
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
static int tmp()
Definition: bt_open.c:389
#define DSP_DIGITMODE_NOQUELCH
Definition: dsp.h:34
#define DSP_DIGITMODE_MUTEMAX
Definition: dsp.h:36
#define DSP_DIGITMODE_MUTECONF
Definition: dsp.h:35
#define DSP_DIGITMODE_RELAXDTMF
Definition: dsp.h:37
#define AST_APP_ARG(name)
Define an application argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: main/app.c:3126
#define ast_verb(level,...)
Structure used to handle boolean flags.
Definition: utils.h:199
unsigned int flags
Definition: utils.h:200
static struct test_options options
#define ast_test_flag(p, flag)
Definition: utils.h:63

References AST_APP_ARG, ast_app_parse_options(), AST_DECLARE_APP_ARGS, ast_log, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_verb, BUFFER_SIZE, DSP_DIGITMODE_MUTECONF, DSP_DIGITMODE_MUTEMAX, DSP_DIGITMODE_NOQUELCH, DSP_DIGITMODE_RELAXDTMF, ast_flags::flags, LOG_WARNING, NULL, OPT_ARG_ARRAY_SIZE, OPT_ARG_MAXDIGITS, OPT_DELAY, OPT_KP_OVERRIDE, OPT_LAX_KP, OPT_MAXDIGITS, OPT_MUTE, OPT_NO_KP, OPT_NO_ST, OPT_QUELCH, OPT_RELAXED, options, pbx_builtin_setvar_helper(), read_app_options, read_mf_digits(), and tmp().

Referenced by load_module().

◆ sendmf_exec()

static int sendmf_exec ( struct ast_channel chan,
const char *  vdata 
)
static

Definition at line 423 of file app_mf.c.

424 {
425  int res;
426  char *data;
427  int dinterval = 0, duration = 0, durationkp = 0, durationst = 0;
428  struct ast_channel *chan_found = NULL;
429  struct ast_channel *chan_dest = chan;
430  struct ast_channel *chan_autoservice = NULL;
432  AST_APP_ARG(digits);
433  AST_APP_ARG(dinterval);
434  AST_APP_ARG(duration);
435  AST_APP_ARG(durationkp);
436  AST_APP_ARG(durationst);
437  AST_APP_ARG(channel);
438  );
439 
440  if (ast_strlen_zero(vdata)) {
441  ast_log(LOG_WARNING, "SendMF requires an argument\n");
442  return 0;
443  }
444 
445  data = ast_strdupa(vdata);
447 
448  if (ast_strlen_zero(args.digits)) {
449  ast_log(LOG_WARNING, "The digits argument is required (0-9,*#ABC,wf)\n");
450  return 0;
451  }
452  if (!ast_strlen_zero(args.dinterval)) {
453  ast_app_parse_timelen(args.dinterval, &dinterval, TIMELEN_MILLISECONDS);
454  }
455  if (!ast_strlen_zero(args.duration)) {
456  ast_app_parse_timelen(args.duration, &duration, TIMELEN_MILLISECONDS);
457  }
458  if (!ast_strlen_zero(args.durationkp)) {
459  ast_app_parse_timelen(args.durationkp, &durationkp, TIMELEN_MILLISECONDS);
460  }
461  if (!ast_strlen_zero(args.durationst)) {
462  ast_app_parse_timelen(args.durationst, &durationst, TIMELEN_MILLISECONDS);
463  }
464  if (!ast_strlen_zero(args.channel)) {
465  chan_found = ast_channel_get_by_name(args.channel);
466  if (!chan_found) {
467  ast_log(LOG_WARNING, "No such channel: %s\n", args.channel);
468  return 0;
469  }
470  chan_dest = chan_found;
471  if (chan_found != chan) {
472  chan_autoservice = chan;
473  }
474  }
475  res = ast_mf_stream(chan_dest, chan_autoservice, NULL, args.digits, dinterval <= 0 ? MF_BETWEEN_MS : dinterval,
476  duration <= 0 ? MF_DURATION : duration, durationkp <= 0 ? MF_KP_DURATION : durationkp,
477  durationst <= 0 ? MF_ST_DURATION : durationst, 0);
478  ast_channel_cleanup(chan_found);
479 
480  return chan_autoservice ? 0 : res;
481 }
#define MF_BETWEEN_MS
Definition: app_mf.c:225
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2969
int ast_app_parse_timelen(const char *timestr, int *result, enum ast_timelen defunit)
Common routine to parse time lengths, with optional time unit specifier.
Definition: main/app.c:3333
@ TIMELEN_MILLISECONDS
const char * data
const char * args

References args, AST_APP_ARG, ast_app_parse_timelen(), ast_channel_cleanup, ast_channel_get_by_name(), AST_DECLARE_APP_ARGS, ast_log, ast_mf_stream(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_channel::data, LOG_WARNING, MF_BETWEEN_MS, MF_DURATION, MF_KP_DURATION, MF_ST_DURATION, NULL, and TIMELEN_MILLISECONDS.

Referenced by load_module().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 524 of file app_mf.c.

525 {
526  int res;
527 
530  res |= ast_manager_unregister("PlayMF");
531 
532  return res;
533 }
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:7268
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392

References ast_manager_unregister(), ast_unregister_application(), readmf_name, and sendmf_name.

Variable Documentation

◆ read_app_options

const struct ast_app_option read_app_options[128] = { [ 'd' ] = { .flag = OPT_DELAY }, [ 'l' ] = { .flag = OPT_LAX_KP }, [ 'k' ] = { .flag = OPT_NO_KP }, [ 'm' ] = { .flag = OPT_MUTE }, [ 'n' ] = { .flag = OPT_MAXDIGITS , .arg_index = OPT_ARG_MAXDIGITS + 1 }, [ 'o' ] = { .flag = OPT_KP_OVERRIDE }, [ 'p' ] = { .flag = OPT_PROCESS }, [ 'q' ] = { .flag = OPT_QUELCH }, [ 'r' ] = { .flag = OPT_RELAXED }, [ 's' ] = { .flag = OPT_NO_ST }, }
static

Definition at line 1 of file app_mf.c.

Referenced by read_mf_exec().

◆ readmf_name

const char* readmf_name = "ReceiveMF"
static

Definition at line 222 of file app_mf.c.

Referenced by load_module(), and unload_module().

◆ sendmf_name

const char sendmf_name[] = "SendMF"
static

Definition at line 223 of file app_mf.c.

Referenced by load_module(), and unload_module().