make app_queue 1.2 jump compliant (issue #5580)
[asterisk/asterisk.git] / apps / app_url.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  * \brief App to transmit a URL
21  * 
22  * \ingroup applications
23  */
24  
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <string.h>
28
29 #include "asterisk.h"
30
31 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
32
33 #include "asterisk/lock.h"
34 #include "asterisk/file.h"
35 #include "asterisk/logger.h"
36 #include "asterisk/channel.h"
37 #include "asterisk/pbx.h"
38 #include "asterisk/module.h"
39 #include "asterisk/translate.h"
40 #include "asterisk/image.h"
41 #include "asterisk/options.h"
42
43 static char *tdesc = "Send URL Applications";
44
45 static char *app = "SendURL";
46
47 static char *synopsis = "Send a URL";
48
49 static char *descrip = 
50 "  SendURL(URL[|option]): Requests client go to URL (IAX2) or sends the \n"
51 "URL to the client (other channels).\n"
52 "Result is returned in the SENDURLSTATUS channel variable:\n"
53 "    SUCCESS       URL successfully sent to client\n"
54 "    FAILURE       Failed to send URL\n"
55 "    NOLOAD        Clien failed to load URL (wait enabled)\n"
56 "    UNSUPPORTED   Channel does not support URL transport\n"
57 "\n"
58 "If the option 'wait' is specified, execution will wait for an\n"
59 "acknowledgement that the URL has been loaded before continuing\n"
60 "and will return -1 if the peer is unable to load the URL\n"
61 "\n"
62 "Old behaviour (deprecated): \n"
63 " If the client does not support Asterisk \"html\" transport, \n"
64 " and there exists a step with priority n + 101, then execution will\n"
65 " continue at that step.\n"
66 " Otherwise, execution will continue at the next priority level.\n"
67 " SendURL only returns 0 if the URL was sent correctly  or if\n"
68 " the channel does not support HTML transport, and -1 otherwise.\n";
69
70 STANDARD_LOCAL_USER;
71
72 LOCAL_USER_DECL;
73
74 static int sendurl_exec(struct ast_channel *chan, void *data)
75 {
76         int res = 0;
77         struct localuser *u;
78         char *tmp;
79         char *options;
80         int local_option_wait=0;
81         int local_option_jump = 0;
82         struct ast_frame *f;
83         char *stringp=NULL;
84         char *status = "FAILURE";
85         
86         if (ast_strlen_zero(data)) {
87                 ast_log(LOG_WARNING, "SendURL requires an argument (URL)\n");
88                 pbx_builtin_setvar_helper(chan, "SENDURLSTATUS", status);
89                 return -1;
90         }
91
92         LOCAL_USER_ADD(u);
93
94         tmp = ast_strdupa(data);
95         if (!tmp) {
96                 ast_log(LOG_ERROR, "Out of memory\n");
97                 LOCAL_USER_REMOVE(u);
98                 return -1;
99         }
100
101         stringp=tmp;
102         strsep(&stringp, "|");
103         options = strsep(&stringp, "|");
104         if (options && !strcasecmp(options, "wait"))
105                 local_option_wait = 1;
106         if (options && !strcasecmp(options, "j"))
107                 local_option_jump = 1;
108         
109         if (!ast_channel_supports_html(chan)) {
110                 /* Does not support transport */
111                 if (local_option_jump || option_priority_jumping)
112                          ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
113                 pbx_builtin_setvar_helper(chan, "SENDURLSTATUS", "UNSUPPORTED");
114                 LOCAL_USER_REMOVE(u);
115                 return 0;
116         }
117         res = ast_channel_sendurl(chan, tmp);
118         if (res == -1) {
119                 pbx_builtin_setvar_helper(chan, "SENDURLSTATUS", "FAILURE");
120                 LOCAL_USER_REMOVE(u);
121                 return res;
122         }
123         status = "SUCCESS";
124         if (local_option_wait) {
125                 for(;;) {
126                         /* Wait for an event */
127                         res = ast_waitfor(chan, -1);
128                         if (res < 0) 
129                                 break;
130                         f = ast_read(chan);
131                         if (!f) {
132                                 res = -1;
133                                 status = "FAILURE";
134                                 break;
135                         }
136                         if (f->frametype == AST_FRAME_HTML) {
137                                 switch(f->subclass) {
138                                 case AST_HTML_LDCOMPLETE:
139                                         res = 0;
140                                         ast_frfree(f);
141                                         status = "NOLOAD";
142                                         goto out;
143                                         break;
144                                 case AST_HTML_NOSUPPORT:
145                                         /* Does not support transport */
146                                         status ="UNSUPPORTED";
147                                         if (local_option_jump || option_priority_jumping)
148                                                 ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
149                                         res = 0;
150                                         goto out;
151                                         break;
152                                 default:
153                                         ast_log(LOG_WARNING, "Don't know what to do with HTML subclass %d\n", f->subclass);
154                                 };
155                         }
156                         ast_frfree(f);
157                 }
158         } 
159 out:    
160         pbx_builtin_setvar_helper(chan, "SENDURLSTATUS", status);
161         LOCAL_USER_REMOVE(u);
162         return res;
163 }
164
165 int unload_module(void)
166 {
167         int res;
168
169         res = ast_unregister_application(app);
170         
171         STANDARD_HANGUP_LOCALUSERS;
172
173         return res;     
174 }
175
176 int load_module(void)
177 {
178         return ast_register_application(app, sendurl_exec, synopsis, descrip);
179 }
180
181 char *description(void)
182 {
183         return tdesc;
184 }
185
186 int usecount(void)
187 {
188         int res;
189         STANDARD_USECOUNT(res);
190         return res;
191 }
192
193 char *key()
194 {
195         return ASTERISK_GPL_KEY;
196 }