2 * Asterisk -- A telephony toolkit for Linux.
4 * Time of day - Report the time of day
6 * Copyright (C) 1999, Mark Spencer
8 * Mark Spencer <markster@linux-support.net>
10 * This program is free software, distributed under the terms of
11 * the GNU General Public License
14 #include <asterisk/lock.h>
15 #include <asterisk/file.h>
16 #include <asterisk/logger.h>
17 #include <asterisk/channel.h>
18 #include <asterisk/pbx.h>
19 #include <asterisk/options.h>
20 #include <asterisk/config.h>
21 #include <asterisk/module.h>
22 #include <asterisk/utils.h>
23 #include <asterisk/causes.h>
24 #include <asterisk/astosp.h>
31 static char *tdesc = "OSP Lookup";
33 static char *app = "OSPLookup";
34 static char *app2 = "OSPNext";
35 static char *app3 = "OSPFinish";
37 static char *synopsis = "Lookup number in OSP";
38 static char *synopsis2 = "Lookup next OSP entry";
39 static char *synopsis3 = "Record OSP entry";
41 static char *descrip =
42 " OSPLookup(exten[|provider[|options]]): Looks up an extension via OSP and sets\n"
43 "the variables, where 'n' is the number of the result beginning with 1:\n"
44 " ${OSPTECH}: The technology to use for the call\n"
45 " ${OSPDEST}: The destination to use for the call\n"
46 " ${OSPTOKEN}: The actual OSP token as a string\n"
47 " ${OSPHANDLE}: The OSP Handle for anything remaining\n"
48 " ${OSPRESULTS}: The number of OSP results total remaining\n"
50 "If the lookup was *not* successful and there exists a priority n + 101,\n"
51 "then that priority will be taken next.\n" ;
53 static char *descrip2 =
54 " OSPNext: Looks up the next OSP Destination for ${OSPHANDLE}\n"
55 "See OSPLookup for more information\n"
57 "If the lookup was *not* successful and there exists a priority n + 101,\n"
58 "then that priority will be taken next.\n" ;
60 static char *descrip3 =
61 " OSPFinish(status): Records call state for ${OSPHANDLE}, according to\n"
62 "status, which should be one of BUSY, CONGESTION, ANSWER, NOANSWER, or NOCHANAVAIL\n"
63 "or coincidentally, just what the Dial application stores in its ${DIALSTATUS}\n"
65 "If the finishing was *not* successful and there exists a priority n + 101,\n"
66 "then that priority will be taken next.\n" ;
72 static int str2cause(char *cause)
74 if (!strcasecmp(cause, "BUSY"))
75 return AST_CAUSE_BUSY;
76 if (!strcasecmp(cause, "CONGESTION"))
77 return AST_CAUSE_CONGESTION;
78 if (!strcasecmp(cause, "ANSWER"))
79 return AST_CAUSE_NORMAL;
80 if (!strcasecmp(cause, "CANCEL"))
81 return AST_CAUSE_NORMAL;
82 if (!strcasecmp(cause, "NOANSWER"))
83 return AST_CAUSE_NOANSWER;
84 if (!strcasecmp(cause, "NOCHANAVAIL"))
85 return AST_CAUSE_CONGESTION;
86 ast_log(LOG_WARNING, "Unknown cause '%s', using NORMAL\n", cause);
87 return AST_CAUSE_NORMAL;
90 static int osplookup_exec(struct ast_channel *chan, void *data)
95 char *provider, *opts=NULL;
96 struct ast_osp_result result;
97 if (!data || ast_strlen_zero(data) || !(temp = ast_strdupa(data))) {
98 ast_log(LOG_WARNING, "OSPLookup requires an argument (extension)\n");
101 provider = strchr(temp, '|');
105 opts = strchr(provider, '|');
112 ast_log(LOG_DEBUG, "Whoo hoo, looking up OSP on '%s' via '%s'\n", temp, provider ? provider : "<default>");
113 if ((res = ast_osp_lookup(chan, provider, temp, chan->callerid, &result)) > 0) {
115 snprintf(tmp, sizeof(tmp), "%d", result.handle);
116 pbx_builtin_setvar_helper(chan, "OSPHANDLE", tmp);
117 pbx_builtin_setvar_helper(chan, "OSPTECH", result.tech);
118 pbx_builtin_setvar_helper(chan, "OSPDEST", result.dest);
119 pbx_builtin_setvar_helper(chan, "OSPTOKEN", result.token);
120 snprintf(tmp, sizeof(tmp), "%d", result.numresults);
121 pbx_builtin_setvar_helper(chan, "OSPRESULTS", tmp);
124 ast_log(LOG_NOTICE, "OSP Lookup failed for '%s' (provider '%s')\n", temp, provider ? provider : "<default>");
126 ast_log(LOG_DEBUG, "Got hangup on '%s' while doing OSP Lookup for '%s' (provider '%s')!\n", chan->name, temp, provider ? provider : "<default>" );
129 /* Look for a "busy" place */
130 if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
131 chan->priority += 100;
134 LOCAL_USER_REMOVE(u);
138 static int ospnext_exec(struct ast_channel *chan, void *data)
144 struct ast_osp_result result;
145 if (!data || ast_strlen_zero(data)) {
146 ast_log(LOG_WARNING, "OSPNext should have an argument (cause)\n");
149 cause = str2cause((char *)data);
150 temp = pbx_builtin_getvar_helper(chan, "OSPHANDLE");
152 if (temp && strlen(temp) && (sscanf(temp, "%i", &result.handle) == 1) && (result.handle > -1)) {
153 if ((res = ast_osp_next(&result, cause)) > 0) {
155 snprintf(tmp, sizeof(tmp), "%d", result.handle);
156 pbx_builtin_setvar_helper(chan, "OSPHANDLE", tmp);
157 pbx_builtin_setvar_helper(chan, "OSPTECH", result.tech);
158 pbx_builtin_setvar_helper(chan, "OSPDEST", result.dest);
159 pbx_builtin_setvar_helper(chan, "OSPTOKEN", result.token);
160 snprintf(tmp, sizeof(tmp), "%d", result.numresults);
161 pbx_builtin_setvar_helper(chan, "OSPRESULTS", tmp);
165 if (result.handle < 0)
166 ast_log(LOG_NOTICE, "OSP Lookup Next failed for handle '%d'\n", result.handle);
168 ast_log(LOG_DEBUG, "No OSP handle specified\n");
170 ast_log(LOG_DEBUG, "Got hangup on '%s' while doing OSP Next!\n", chan->name);
173 /* Look for a "busy" place */
174 if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
175 chan->priority += 100;
178 LOCAL_USER_REMOVE(u);
182 static int ospfinished_exec(struct ast_channel *chan, void *data)
188 time_t start=0, duration=0;
189 struct ast_osp_result result;
190 if (!data || ast_strlen_zero(data)) {
191 ast_log(LOG_WARNING, "OSPFinish should have an argument (cause)\n");
194 start = chan->cdr->answer.tv_sec;
196 duration = time(NULL) - start;
200 ast_log(LOG_WARNING, "OSPFinish called on channel '%s' with no CDR!\n", chan->name);
202 cause = str2cause((char *)data);
203 temp = pbx_builtin_getvar_helper(chan, "OSPHANDLE");
205 if (temp && strlen(temp) && (sscanf(temp, "%i", &result.handle) == 1) && (result.handle > -1)) {
206 if (!ast_osp_terminate(result.handle, cause, start, duration)) {
207 pbx_builtin_setvar_helper(chan, "OSPHANDLE", "");
212 if (result.handle > -1)
213 ast_log(LOG_NOTICE, "OSP Finish failed for handle '%d'\n", result.handle);
215 ast_log(LOG_DEBUG, "No OSP handle specified\n");
217 ast_log(LOG_DEBUG, "Got hangup on '%s' while doing OSP Terminate!\n", chan->name);
220 /* Look for a "busy" place */
221 if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
222 chan->priority += 100;
225 LOCAL_USER_REMOVE(u);
230 int unload_module(void)
233 STANDARD_HANGUP_LOCALUSERS;
234 res = ast_unregister_application(app3);
235 res |= ast_unregister_application(app2);
236 res |= ast_unregister_application(app);
240 int load_module(void)
243 res = ast_register_application(app, osplookup_exec, synopsis, descrip);
246 res = ast_register_application(app2, ospnext_exec, synopsis2, descrip2);
249 res = ast_register_application(app3, ospfinished_exec, synopsis3, descrip3);
261 char *description(void)
269 STANDARD_USECOUNT(res);
275 return ASTERISK_GPL_KEY;