#include "asterisk.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/features.h"
#include "asterisk/options.h"
#include "asterisk/say.h"
#include "asterisk/lock.h"
#include "asterisk/utils.h"
Include dependency graph for app_parkandannounce.c:
Go to the source code of this file.
Functions | |
AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"Call Parking and Announce Application") | |
static int | load_module (void) |
static int | parkandannounce_exec (struct ast_channel *chan, void *data) |
static int | unload_module (void) |
Variables | |
static char * | app = "ParkAndAnnounce" |
static char * | descrip |
static char * | synopsis = "Park and Announce" |
Definition in file app_parkandannounce.c.
AST_MODULE_INFO_STANDARD | ( | ASTERISK_GPL_KEY | , | |
"Call Parking and Announce Application" | ||||
) |
static int load_module | ( | void | ) | [static] |
Definition at line 254 of file app_parkandannounce.c.
References ast_register_application(), and parkandannounce_exec().
00255 { 00256 /* return ast_register_application(app, park_exec); */ 00257 return ast_register_application(app, parkandannounce_exec, synopsis, descrip); 00258 }
static int parkandannounce_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 77 of file app_parkandannounce.c.
References __ast_request_and_dial(), ast_channel::_state, ARRAY_LEN, ast_exists_extension(), AST_FORMAT_SLINEAR, ast_hangup(), ast_log(), ast_masq_park_call(), ast_module_user_add, ast_module_user_remove, ast_say_digits(), AST_STATE_UP, ast_stopstream(), ast_strdupa, ast_streamfile(), ast_strlen_zero(), ast_variable_new(), ast_verbose(), ast_waitstream(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_channel::context, context, ast_channel::exten, exten, LOG_WARNING, option_verbose, ast_channel::priority, s, strsep(), VERBOSE_PREFIX_3, and VERBOSE_PREFIX_4.
Referenced by load_module().
00078 { 00079 int res=0; 00080 char *return_context; 00081 int lot, timeout = 0, dres; 00082 char *working, *context, *exten, *priority, *dial, *dialtech, *dialstr; 00083 char *template, *tpl_working, *tpl_current; 00084 char *tmp[100]; 00085 char buf[13]; 00086 int looptemp=0,i=0; 00087 char *s; 00088 00089 struct ast_channel *dchan; 00090 struct outgoing_helper oh; 00091 int outstate; 00092 00093 struct ast_module_user *u; 00094 00095 if (ast_strlen_zero(data)) { 00096 ast_log(LOG_WARNING, "ParkAndAnnounce requires arguments: (announce:template|timeout|dial|[return_context])\n"); 00097 return -1; 00098 } 00099 00100 u = ast_module_user_add(chan); 00101 00102 s = ast_strdupa(data); 00103 00104 template=strsep(&s,"|"); 00105 if(! template) { 00106 ast_log(LOG_WARNING, "PARK: An announce template must be defined\n"); 00107 ast_module_user_remove(u); 00108 return -1; 00109 } 00110 00111 if(s) { 00112 timeout = atoi(strsep(&s, "|")); 00113 timeout *= 1000; 00114 } 00115 dial=strsep(&s, "|"); 00116 if(!dial) { 00117 ast_log(LOG_WARNING, "PARK: A dial resource must be specified i.e: Console/dsp or Zap/g1/5551212\n"); 00118 ast_module_user_remove(u); 00119 return -1; 00120 } else { 00121 dialtech=strsep(&dial, "/"); 00122 dialstr=dial; 00123 ast_verbose( VERBOSE_PREFIX_3 "Dial Tech,String: (%s,%s)\n", dialtech,dialstr); 00124 } 00125 00126 return_context = s; 00127 00128 if(return_context != NULL) { 00129 /* set the return context. Code borrowed from the Goto builtin */ 00130 00131 working = return_context; 00132 context = strsep(&working, "|"); 00133 exten = strsep(&working, "|"); 00134 if(!exten) { 00135 /* Only a priority in this one */ 00136 priority = context; 00137 exten = NULL; 00138 context = NULL; 00139 } else { 00140 priority = strsep(&working, "|"); 00141 if(!priority) { 00142 /* Only an extension and priority in this one */ 00143 priority = exten; 00144 exten = context; 00145 context = NULL; 00146 } 00147 } 00148 if(atoi(priority) < 0) { 00149 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0\n", priority); 00150 ast_module_user_remove(u); 00151 return -1; 00152 } 00153 /* At this point we have a priority and maybe an extension and a context */ 00154 chan->priority = atoi(priority); 00155 if (exten) 00156 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 00157 if (context) 00158 ast_copy_string(chan->context, context, sizeof(chan->context)); 00159 } else { /* increment the priority by default*/ 00160 chan->priority++; 00161 } 00162 00163 if(option_verbose > 2) { 00164 ast_verbose( VERBOSE_PREFIX_3 "Return Context: (%s,%s,%d) ID: %s\n", chan->context,chan->exten, chan->priority, chan->cid.cid_num); 00165 if(!ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num)) { 00166 ast_verbose( VERBOSE_PREFIX_3 "Warning: Return Context Invalid, call will return to default|s\n"); 00167 } 00168 } 00169 00170 /* we are using masq_park here to protect * from touching the channel once we park it. If the channel comes out of timeout 00171 before we are done announcing and the channel is messed with, Kablooeee. So we use Masq to prevent this. */ 00172 00173 ast_masq_park_call(chan, NULL, timeout, &lot); 00174 00175 res=-1; 00176 00177 ast_verbose( VERBOSE_PREFIX_3 "Call Parking Called, lot: %d, timeout: %d, context: %s\n", lot, timeout, return_context); 00178 00179 /* Now place the call to the extention */ 00180 00181 snprintf(buf, sizeof(buf), "%d", lot); 00182 memset(&oh, 0, sizeof(oh)); 00183 oh.parent_channel = chan; 00184 oh.vars = ast_variable_new("_PARKEDAT", buf); 00185 dchan = __ast_request_and_dial(dialtech, AST_FORMAT_SLINEAR, dialstr,30000, &outstate, chan->cid.cid_num, chan->cid.cid_name, &oh); 00186 00187 if(dchan) { 00188 if(dchan->_state == AST_STATE_UP) { 00189 if(option_verbose > 3) 00190 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", dchan->name); 00191 } else { 00192 if(option_verbose > 3) 00193 ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", dchan->name); 00194 ast_log(LOG_WARNING, "PARK: Channel %s was never answered for the announce.\n", dchan->name); 00195 ast_hangup(dchan); 00196 ast_module_user_remove(u); 00197 return -1; 00198 } 00199 } else { 00200 ast_log(LOG_WARNING, "PARK: Unable to allocate announce channel.\n"); 00201 ast_module_user_remove(u); 00202 return -1; 00203 } 00204 00205 ast_stopstream(dchan); 00206 00207 /* now we have the call placed and are ready to play stuff to it */ 00208 00209 ast_verbose(VERBOSE_PREFIX_4 "Announce Template:%s\n", template); 00210 00211 tpl_working = template; 00212 tpl_current=strsep(&tpl_working, ":"); 00213 00214 while(tpl_current && looptemp < ARRAY_LEN(tmp)) { 00215 tmp[looptemp]=tpl_current; 00216 looptemp++; 00217 tpl_current=strsep(&tpl_working,":"); 00218 } 00219 00220 for(i=0; i<looptemp; i++) { 00221 ast_verbose(VERBOSE_PREFIX_4 "Announce:%s\n", tmp[i]); 00222 if(!strcmp(tmp[i], "PARKED")) { 00223 ast_say_digits(dchan, lot, "", dchan->language); 00224 } else { 00225 dres = ast_streamfile(dchan, tmp[i], dchan->language); 00226 if(!dres) { 00227 dres = ast_waitstream(dchan, ""); 00228 } else { 00229 ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", tmp[i], dchan->name); 00230 dres = 0; 00231 } 00232 } 00233 } 00234 00235 ast_stopstream(dchan); 00236 ast_hangup(dchan); 00237 00238 ast_module_user_remove(u); 00239 00240 return res; 00241 }
static int unload_module | ( | void | ) | [static] |
Definition at line 243 of file app_parkandannounce.c.
References ast_module_user_hangup_all, and ast_unregister_application().
00244 { 00245 int res; 00246 00247 res = ast_unregister_application(app); 00248 00249 ast_module_user_hangup_all(); 00250 00251 return res; 00252 }
char* app = "ParkAndAnnounce" [static] |
Definition at line 54 of file app_parkandannounce.c.
char* descrip [static] |
Definition at line 58 of file app_parkandannounce.c.
char* synopsis = "Park and Announce" [static] |
Definition at line 56 of file app_parkandannounce.c.