normalize code in preparation to module changes
[asterisk/asterisk.git] / res / res_clioriginate.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2005, Digium, Inc.
5  *
6  * Russell Bryant <russell@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 /*! 
20  * \file
21  *
22  * \brief Originate calls via the CLI
23  * 
24  */
25
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
29
30 #include "asterisk.h"
31
32 ASTERISK_FILE_VERSION(__FILE__, "$Revision$");
33
34 #include "asterisk/channel.h"
35 #include "asterisk/pbx.h"
36 #include "asterisk/logger.h"
37 #include "asterisk/module.h"
38 #include "asterisk/cli.h"
39 #include "asterisk/utils.h"
40 #include "asterisk/frame.h"
41
42 /*! The timeout for originated calls, in seconds */
43 #define TIMEOUT 30
44
45 STANDARD_USECOUNT_DECL;
46
47 static char orig_help[] = 
48 "  There are two ways to use this command. A call can be originated between a\n"
49 "channel and a specific application, or between a channel and an extension in\n"
50 "the dialplan. This is similar to call files or the manager originate action.\n"
51 "Calls originated with this command are given a timeout of 30 seconds.\n\n"
52
53 "Usage1: originate <tech/data> application <appname> [appdata]\n"
54 "  This will originate a call between the specified channel tech/data and the\n"
55 "given application. Arguments to the application are optional. If the given\n"
56 "arguments to the application include spaces, all of the arguments to the\n"
57 "application need to be placed in quotation marks.\n\n"
58
59 "Usage2: originate <tech/data> extension [exten@][context]\n"
60 "  This will originate a call between the specified channel tech/data and the\n"
61 "given extension. If no context is specified, the 'default' context will be\n"
62 "used. If no extension is given, the 's' extension will be used.\n";
63
64 static int handle_orig(int fd, int argc, char *argv[]);
65 static char *complete_orig(const char *line, const char *word, int pos, int state);
66
67 struct ast_cli_entry cli_orig = { { "originate", NULL }, handle_orig, "Originate a call", orig_help, complete_orig };
68
69 static int orig_app(const char *chan, const char *app, const char *appdata)
70 {
71         char *chantech;
72         char *chandata;
73         int reason = 0;
74         
75         if (ast_strlen_zero(app))
76                 return RESULT_SHOWUSAGE;
77
78         chandata = ast_strdupa(chan);
79         if (!chandata) {
80                 ast_log(LOG_ERROR, "Out of Memory!\n");
81                 return RESULT_FAILURE;
82         }
83         chantech = strsep(&chandata, "/");
84         if (!chandata) {
85                 ast_log(LOG_ERROR, "No dial string.\n");
86                 return RESULT_SHOWUSAGE;
87         }
88
89         ast_pbx_outgoing_app(chantech, AST_FORMAT_SLINEAR, chandata, TIMEOUT * 1000, app, appdata, &reason, 1, NULL, NULL, NULL, NULL, NULL);
90
91         return RESULT_SUCCESS;
92 }
93
94 static int orig_exten(const char *chan, const char *data)
95 {
96         char *chantech;
97         char *chandata;
98         char *exten = NULL;
99         char *context = NULL;
100         int reason = 0;
101
102         chandata = ast_strdupa(chan);
103         if (!chandata) {
104                 ast_log(LOG_ERROR, "Out of Memory!\n");
105                 return RESULT_FAILURE;
106         }
107         chantech = strsep(&chandata, "/");
108
109         if (!ast_strlen_zero(data)) {
110                 context = ast_strdupa(data);
111                 if (!context) {
112                         ast_log(LOG_ERROR, "Out of Memory!\n");
113                         return RESULT_FAILURE;
114                 }
115                 exten = strsep(&context, "@");
116         }
117
118         if (ast_strlen_zero(exten))
119                 exten = "s";
120         if (ast_strlen_zero(context))
121                 context = "default";
122         
123         ast_pbx_outgoing_exten(chantech, AST_FORMAT_SLINEAR, chandata, TIMEOUT * 1000, context, exten, 1, &reason, 1, NULL, NULL, NULL, NULL, NULL);
124
125         return RESULT_SUCCESS;
126 }
127
128 static int handle_orig(int fd, int argc, char *argv[])
129 {
130         int res;
131
132         if (ast_strlen_zero(argv[1]) || ast_strlen_zero(argv[2]))
133                 return RESULT_SHOWUSAGE;
134
135         STANDARD_INCREMENT_USECOUNT;
136
137         if (!strcasecmp("application", argv[2])) {
138                 res = orig_app(argv[1], argv[3], argv[4]);      
139         } else if (!strcasecmp("extension", argv[2])) {
140                 res = orig_exten(argv[1], argv[3]);
141         } else
142                 res = RESULT_SHOWUSAGE;
143
144         STANDARD_DECREMENT_USECOUNT;
145
146         return res;
147 }
148
149 static char *complete_orig(const char *line, const char *word, int pos, int state)
150 {
151         static char *choices[] = { "application", "extension", NULL };
152         char *ret;
153
154         if (pos != 2)
155                 return NULL;
156
157         STANDARD_INCREMENT_USECOUNT;
158
159         ret = ast_cli_complete(word, choices, state);
160
161         STANDARD_DECREMENT_USECOUNT;
162
163         return ret;
164 }
165
166 int unload_module(void)
167 {
168         return ast_cli_unregister(&cli_orig);
169 }
170
171 int load_module(void)
172 {
173         return ast_cli_register(&cli_orig);
174 }
175
176 const char *description(void)
177 {
178         return "Call origination from the CLI";
179
180 }
181
182 int usecount(void)
183 {
184         return 0;
185 }
186
187 const char *key(void)
188 {
189         return ASTERISK_GPL_KEY;
190 }
191