Wed Jan 8 2020 09:49:40

Asterisk developer's documentation


app_parkandannounce.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2006, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * Author: Ben Miller <bgmiller@dccinc.com>
9  * With TONS of help from Mark!
10  *
11  * See http://www.asterisk.org for more information about
12  * the Asterisk project. Please do not directly contact
13  * any of the maintainers of this project for assistance;
14  * the project provides a web site, mailing lists and IRC
15  * channels for your use.
16  *
17  * This program is free software, distributed under the terms of
18  * the GNU General Public License Version 2. See the LICENSE file
19  * at the top of the source tree.
20  */
21 
22 /*! \file
23  *
24  * \brief ParkAndAnnounce application for Asterisk
25  *
26  * \author Ben Miller <bgmiller@dccinc.com>
27  * \arg With TONS of help from Mark!
28  *
29  * \ingroup applications
30  */
31 
32 /*** MODULEINFO
33  <support_level>core</support_level>
34  ***/
35 
36 #include "asterisk.h"
37 
38 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 381916 $")
39 
40 #include "asterisk/file.h"
41 #include "asterisk/channel.h"
42 #include "asterisk/pbx.h"
43 #include "asterisk/module.h"
44 #include "asterisk/features.h"
45 #include "asterisk/say.h"
46 #include "asterisk/lock.h"
47 #include "asterisk/utils.h"
48 #include "asterisk/app.h"
49 
50 /*** DOCUMENTATION
51  <application name="ParkAndAnnounce" language="en_US">
52  <synopsis>
53  Park and Announce.
54  </synopsis>
55  <syntax>
56  <parameter name="announce_template" required="true" argsep=":">
57  <argument name="announce" required="true">
58  <para>Colon-separated list of files to announce. The word
59  <literal>PARKED</literal> will be replaced by a say_digits of the extension in which
60  the call is parked.</para>
61  </argument>
62  <argument name="announce1" multiple="true" />
63  </parameter>
64  <parameter name="timeout" required="true">
65  <para>Time in seconds before the call returns into the return
66  context.</para>
67  </parameter>
68  <parameter name="dial" required="true">
69  <para>The app_dial style resource to call to make the
70  announcement. Console/dsp calls the console.</para>
71  </parameter>
72  <parameter name="return_context">
73  <para>The goto-style label to jump the call back into after
74  timeout. Default <literal>priority+1</literal>.</para>
75  </parameter>
76  </syntax>
77  <description>
78  <para>Park a call into the parkinglot and announce the call to another channel.</para>
79  <para>The variable <variable>PARKEDAT</variable> will contain the parking extension
80  into which the call was placed. Use with the Local channel to allow the dialplan to make
81  use of this information.</para>
82  </description>
83  <see-also>
84  <ref type="application">Park</ref>
85  <ref type="application">ParkedCall</ref>
86  </see-also>
87  </application>
88  ***/
89 
90 static char *app = "ParkAndAnnounce";
91 
92 static int parkandannounce_exec(struct ast_channel *chan, const char *data)
93 {
94  int res = -1;
95  int lot, timeout = 0, dres;
96  char *dialtech, *tmp[100], buf[13];
97  int looptemp, i;
98  char *s;
99  struct ast_party_id caller_id;
100 
101  struct ast_channel *dchan;
102  struct outgoing_helper oh = { 0, };
103  int outstate;
105  AST_APP_ARG(template);
106  AST_APP_ARG(timeout);
107  AST_APP_ARG(dial);
108  AST_APP_ARG(return_context);
109  );
110  if (ast_strlen_zero(data)) {
111  ast_log(LOG_WARNING, "ParkAndAnnounce requires arguments: (announce_template,timeout,dial,[return_context])\n");
112  return -1;
113  }
114 
115  s = ast_strdupa(data);
117 
118  if (args.timeout)
119  timeout = atoi(args.timeout) * 1000;
120 
121  if (ast_strlen_zero(args.dial)) {
122  ast_log(LOG_WARNING, "PARK: A dial resource must be specified i.e: Console/dsp or DAHDI/g1/5551212\n");
123  return -1;
124  }
125 
126  dialtech = strsep(&args.dial, "/");
127  ast_verb(3, "Dial Tech,String: (%s,%s)\n", dialtech, args.dial);
128 
129  if (!ast_strlen_zero(args.return_context)) {
131  ast_parseable_goto(chan, args.return_context);
132  } else {
133  chan->priority++;
134  }
135 
136  ast_verb(3, "Return Context: (%s,%s,%d) ID: %s\n", chan->context, chan->exten,
137  chan->priority,
138  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""));
139  if (!ast_exists_extension(chan, chan->context, chan->exten, chan->priority,
140  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
141  ast_verb(3, "Warning: Return Context Invalid, call will return to default|s\n");
142  }
143 
144  /* Save the CallerID because the masquerade turns chan into a ZOMBIE. */
145  ast_party_id_init(&caller_id);
146  ast_channel_lock(chan);
147  ast_party_id_copy(&caller_id, &chan->caller.id);
148  ast_channel_unlock(chan);
149 
150  /* we are using masq_park here to protect * from touching the channel once we park it. If the channel comes out of timeout
151  before we are done announcing and the channel is messed with, Kablooeee. So we use Masq to prevent this. */
152 
153  res = ast_masq_park_call(chan, NULL, timeout, &lot);
154  if (res) {
155  /* Parking failed. */
156  ast_party_id_free(&caller_id);
157  return -1;
158  }
159 
160  ast_verb(3, "Call parked in space: %d, timeout: %d, return-context: %s\n",
161  lot, timeout, args.return_context ? args.return_context : "");
162 
163  /* Now place the call to the extension */
164 
165  snprintf(buf, sizeof(buf), "%d", lot);
166  oh.parent_channel = chan;
167  oh.vars = ast_variable_new("_PARKEDAT", buf, "");
168  dchan = __ast_request_and_dial(dialtech, AST_FORMAT_SLINEAR, chan, args.dial, 30000,
169  &outstate,
170  S_COR(caller_id.number.valid, caller_id.number.str, NULL),
171  S_COR(caller_id.name.valid, caller_id.name.str, NULL),
172  &oh);
174  ast_party_id_free(&caller_id);
175  if (dchan) {
176  if (dchan->_state == AST_STATE_UP) {
177  ast_verb(4, "Channel %s was answered.\n", dchan->name);
178  } else {
179  ast_verb(4, "Channel %s was never answered.\n", dchan->name);
180  ast_log(LOG_WARNING, "PARK: Channel %s was never answered for the announce.\n", dchan->name);
181  ast_hangup(dchan);
182  return -1;
183  }
184  } else {
185  ast_log(LOG_WARNING, "PARK: Unable to allocate announce channel.\n");
186  return -1;
187  }
188 
189  ast_stopstream(dchan);
190 
191  /* now we have the call placed and are ready to play stuff to it */
192 
193  ast_verb(4, "Announce Template:%s\n", args.template);
194 
195  for (looptemp = 0; looptemp < ARRAY_LEN(tmp); looptemp++) {
196  if ((tmp[looptemp] = strsep(&args.template, ":")) != NULL)
197  continue;
198  else
199  break;
200  }
201 
202  for (i = 0; i < looptemp; i++) {
203  ast_verb(4, "Announce:%s\n", tmp[i]);
204  if (!strcmp(tmp[i], "PARKED")) {
205  ast_say_digits(dchan, lot, "", dchan->language);
206  } else {
207  dres = ast_streamfile(dchan, tmp[i], dchan->language);
208  if (!dres) {
209  dres = ast_waitstream(dchan, "");
210  } else {
211  ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", tmp[i], dchan->name);
212  }
213  }
214  }
215 
216  ast_stopstream(dchan);
217  ast_hangup(dchan);
218 
219  return res;
220 }
221 
222 static int unload_module(void)
223 {
224  return ast_unregister_application(app);
225 }
226 
227 static int load_module(void)
228 {
229  /* return ast_register_application(app, park_exec); */
231 }
232 
233 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Call Parking and Announce Application");
int ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2804
Information needed to identify an endpoint in a call.
Definition: channel.h:288
#define ast_channel_lock(chan)
Definition: channel.h:2466
Main Channel structure associated with a channel.
Definition: channel.h:742
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:396
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:946
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
char * strsep(char **str, const char *delims)
int priority
Definition: channel.h:841
struct ast_channel * parent_channel
Definition: channel.h:1006
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
struct ast_channel * __ast_request_and_dial(const char *type, format_t format, const struct ast_channel *requestor, void *data, int timeout, int *reason, const char *cid_num, const char *cid_name, struct outgoing_helper *oh)
Request a channel of a given type, with data as optional information used by the low level module and...
Definition: channel.c:5456
#define LOG_WARNING
Definition: logger.h:144
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
void ast_party_id_copy(struct ast_party_id *dest, const struct ast_party_id *src)
Copy the source party id information to the destination party id.
Definition: channel.c:2095
char * str
Subscriber name (Malloced)
Definition: channel.h:214
int ast_say_digits(struct ast_channel *chan, int num, const char *ints, const char *lang)
says digits
Definition: channel.c:8409
void ast_party_id_free(struct ast_party_id *doomed)
Destroy the party id contents.
Definition: channel.c:2141
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: config.c:586
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx.c:7705
#define ast_verb(level,...)
Definition: logger.h:243
struct ast_variable * vars
Definition: channel.h:1005
static char * app
Utility functions.
int ast_masq_park_call(struct ast_channel *park_me, struct ast_channel *parker, int timeout, int *extout)
Park a call via a masqueraded channel.
Definition: features.c:1857
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
General Asterisk PBX channel definitions.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
int ast_parseable_goto(struct ast_channel *chan, const char *goto_string)
Definition: pbx.c:11326
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:83
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:5400
Core PBX routines and definitions.
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static struct @350 args
enum ast_channel_state _state
Definition: channel.h:839
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_channel_unlock(chan)
Definition: channel.h:2467
static int load_module(void)
void ast_party_id_init(struct ast_party_id *init)
Initialize the given party id structure.
Definition: channel.c:2087
#define ast_clear_flag(p, flag)
Definition: utils.h:77
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
static int parkandannounce_exec(struct ast_channel *chan, const char *data)
int timeout
Definition: dial.c:49
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1343
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
Call Parking and Pickup API Includes code and algorithms from the Zapata library. ...
Say numbers and dates (maybe words one day too)
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:38
Asterisk module definitions.
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
const ast_string_field language
Definition: channel.h:787
static int unload_module(void)
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:128
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:437
struct ast_variable * ast_variable_new(const char *name, const char *value, const char *filename)
Definition: config.c:278
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
Definition: asterisk.h:180
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292