res_pjsip_session: properly handle SDP from a forked call with early media
[asterisk/asterisk.git] / res / res_ari_device_states.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2012 - 2013, Digium, Inc.
5  *
6  * Kevin Harwell <kharwell@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  * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
21  * !!!!!                               DO NOT EDIT                        !!!!!
22  * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
23  * This file is generated by a mustache template. Please see the original
24  * template in rest-api-templates/res_ari_resource.c.mustache
25  */
26
27 /*! \file
28  *
29  * \brief Device state resources
30  *
31  * \author Kevin Harwell <kharwell@digium.com>
32  */
33
34 /*** MODULEINFO
35         <depend type="module">res_ari</depend>
36         <depend type="module">res_ari_model</depend>
37         <depend type="module">res_stasis</depend>
38         <depend type="module">res_stasis_device_state</depend>
39         <support_level>core</support_level>
40  ***/
41
42 #include "asterisk.h"
43
44 #include "asterisk/app.h"
45 #include "asterisk/module.h"
46 #include "asterisk/stasis_app.h"
47 #include "ari/resource_device_states.h"
48 #if defined(AST_DEVMODE)
49 #include "ari/ari_model_validators.h"
50 #endif
51
52 #define MAX_VALS 128
53
54 /*!
55  * \brief Parameter parsing callback for /deviceStates.
56  * \param get_params GET parameters in the HTTP request.
57  * \param path_vars Path variables extracted from the request.
58  * \param headers HTTP headers.
59  * \param[out] response Response to the HTTP request.
60  */
61 static void ast_ari_device_states_list_cb(
62         struct ast_tcptls_session_instance *ser,
63         struct ast_variable *get_params, struct ast_variable *path_vars,
64         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
65 {
66         struct ast_ari_device_states_list_args args = {};
67 #if defined(AST_DEVMODE)
68         int is_valid;
69         int code;
70 #endif /* AST_DEVMODE */
71
72         ast_ari_device_states_list(headers, &args, response);
73 #if defined(AST_DEVMODE)
74         code = response->response_code;
75
76         switch (code) {
77         case 0: /* Implementation is still a stub, or the code wasn't set */
78                 is_valid = response->message == NULL;
79                 break;
80         case 500: /* Internal Server Error */
81         case 501: /* Not Implemented */
82                 is_valid = 1;
83                 break;
84         default:
85                 if (200 <= code && code <= 299) {
86                         is_valid = ast_ari_validate_list(response->message,
87                                 ast_ari_validate_device_state_fn());
88                 } else {
89                         ast_log(LOG_ERROR, "Invalid error response %d for /deviceStates\n", code);
90                         is_valid = 0;
91                 }
92         }
93
94         if (!is_valid) {
95                 ast_log(LOG_ERROR, "Response validation failed for /deviceStates\n");
96                 ast_ari_response_error(response, 500,
97                         "Internal Server Error", "Response validation failed");
98         }
99 #endif /* AST_DEVMODE */
100
101 fin: __attribute__((unused))
102         return;
103 }
104 /*!
105  * \brief Parameter parsing callback for /deviceStates/{deviceName}.
106  * \param get_params GET parameters in the HTTP request.
107  * \param path_vars Path variables extracted from the request.
108  * \param headers HTTP headers.
109  * \param[out] response Response to the HTTP request.
110  */
111 static void ast_ari_device_states_get_cb(
112         struct ast_tcptls_session_instance *ser,
113         struct ast_variable *get_params, struct ast_variable *path_vars,
114         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
115 {
116         struct ast_ari_device_states_get_args args = {};
117         struct ast_variable *i;
118 #if defined(AST_DEVMODE)
119         int is_valid;
120         int code;
121 #endif /* AST_DEVMODE */
122
123         for (i = path_vars; i; i = i->next) {
124                 if (strcmp(i->name, "deviceName") == 0) {
125                         args.device_name = (i->value);
126                 } else
127                 {}
128         }
129         ast_ari_device_states_get(headers, &args, response);
130 #if defined(AST_DEVMODE)
131         code = response->response_code;
132
133         switch (code) {
134         case 0: /* Implementation is still a stub, or the code wasn't set */
135                 is_valid = response->message == NULL;
136                 break;
137         case 500: /* Internal Server Error */
138         case 501: /* Not Implemented */
139                 is_valid = 1;
140                 break;
141         default:
142                 if (200 <= code && code <= 299) {
143                         is_valid = ast_ari_validate_device_state(
144                                 response->message);
145                 } else {
146                         ast_log(LOG_ERROR, "Invalid error response %d for /deviceStates/{deviceName}\n", code);
147                         is_valid = 0;
148                 }
149         }
150
151         if (!is_valid) {
152                 ast_log(LOG_ERROR, "Response validation failed for /deviceStates/{deviceName}\n");
153                 ast_ari_response_error(response, 500,
154                         "Internal Server Error", "Response validation failed");
155         }
156 #endif /* AST_DEVMODE */
157
158 fin: __attribute__((unused))
159         return;
160 }
161 int ast_ari_device_states_update_parse_body(
162         struct ast_json *body,
163         struct ast_ari_device_states_update_args *args)
164 {
165         struct ast_json *field;
166         /* Parse query parameters out of it */
167         field = ast_json_object_get(body, "deviceState");
168         if (field) {
169                 args->device_state = ast_json_string_get(field);
170         }
171         return 0;
172 }
173
174 /*!
175  * \brief Parameter parsing callback for /deviceStates/{deviceName}.
176  * \param get_params GET parameters in the HTTP request.
177  * \param path_vars Path variables extracted from the request.
178  * \param headers HTTP headers.
179  * \param[out] response Response to the HTTP request.
180  */
181 static void ast_ari_device_states_update_cb(
182         struct ast_tcptls_session_instance *ser,
183         struct ast_variable *get_params, struct ast_variable *path_vars,
184         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
185 {
186         struct ast_ari_device_states_update_args args = {};
187         struct ast_variable *i;
188 #if defined(AST_DEVMODE)
189         int is_valid;
190         int code;
191 #endif /* AST_DEVMODE */
192
193         for (i = get_params; i; i = i->next) {
194                 if (strcmp(i->name, "deviceState") == 0) {
195                         args.device_state = (i->value);
196                 } else
197                 {}
198         }
199         for (i = path_vars; i; i = i->next) {
200                 if (strcmp(i->name, "deviceName") == 0) {
201                         args.device_name = (i->value);
202                 } else
203                 {}
204         }
205         if (ast_ari_device_states_update_parse_body(body, &args)) {
206                 ast_ari_response_alloc_failed(response);
207                 goto fin;
208         }
209         ast_ari_device_states_update(headers, &args, response);
210 #if defined(AST_DEVMODE)
211         code = response->response_code;
212
213         switch (code) {
214         case 0: /* Implementation is still a stub, or the code wasn't set */
215                 is_valid = response->message == NULL;
216                 break;
217         case 500: /* Internal Server Error */
218         case 501: /* Not Implemented */
219         case 404: /* Device name is missing */
220         case 409: /* Uncontrolled device specified */
221                 is_valid = 1;
222                 break;
223         default:
224                 if (200 <= code && code <= 299) {
225                         is_valid = ast_ari_validate_void(
226                                 response->message);
227                 } else {
228                         ast_log(LOG_ERROR, "Invalid error response %d for /deviceStates/{deviceName}\n", code);
229                         is_valid = 0;
230                 }
231         }
232
233         if (!is_valid) {
234                 ast_log(LOG_ERROR, "Response validation failed for /deviceStates/{deviceName}\n");
235                 ast_ari_response_error(response, 500,
236                         "Internal Server Error", "Response validation failed");
237         }
238 #endif /* AST_DEVMODE */
239
240 fin: __attribute__((unused))
241         return;
242 }
243 /*!
244  * \brief Parameter parsing callback for /deviceStates/{deviceName}.
245  * \param get_params GET parameters in the HTTP request.
246  * \param path_vars Path variables extracted from the request.
247  * \param headers HTTP headers.
248  * \param[out] response Response to the HTTP request.
249  */
250 static void ast_ari_device_states_delete_cb(
251         struct ast_tcptls_session_instance *ser,
252         struct ast_variable *get_params, struct ast_variable *path_vars,
253         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
254 {
255         struct ast_ari_device_states_delete_args args = {};
256         struct ast_variable *i;
257 #if defined(AST_DEVMODE)
258         int is_valid;
259         int code;
260 #endif /* AST_DEVMODE */
261
262         for (i = path_vars; i; i = i->next) {
263                 if (strcmp(i->name, "deviceName") == 0) {
264                         args.device_name = (i->value);
265                 } else
266                 {}
267         }
268         ast_ari_device_states_delete(headers, &args, response);
269 #if defined(AST_DEVMODE)
270         code = response->response_code;
271
272         switch (code) {
273         case 0: /* Implementation is still a stub, or the code wasn't set */
274                 is_valid = response->message == NULL;
275                 break;
276         case 500: /* Internal Server Error */
277         case 501: /* Not Implemented */
278         case 404: /* Device name is missing */
279         case 409: /* Uncontrolled device specified */
280                 is_valid = 1;
281                 break;
282         default:
283                 if (200 <= code && code <= 299) {
284                         is_valid = ast_ari_validate_void(
285                                 response->message);
286                 } else {
287                         ast_log(LOG_ERROR, "Invalid error response %d for /deviceStates/{deviceName}\n", code);
288                         is_valid = 0;
289                 }
290         }
291
292         if (!is_valid) {
293                 ast_log(LOG_ERROR, "Response validation failed for /deviceStates/{deviceName}\n");
294                 ast_ari_response_error(response, 500,
295                         "Internal Server Error", "Response validation failed");
296         }
297 #endif /* AST_DEVMODE */
298
299 fin: __attribute__((unused))
300         return;
301 }
302
303 /*! \brief REST handler for /api-docs/deviceStates.json */
304 static struct stasis_rest_handlers deviceStates_deviceName = {
305         .path_segment = "deviceName",
306         .is_wildcard = 1,
307         .callbacks = {
308                 [AST_HTTP_GET] = ast_ari_device_states_get_cb,
309                 [AST_HTTP_PUT] = ast_ari_device_states_update_cb,
310                 [AST_HTTP_DELETE] = ast_ari_device_states_delete_cb,
311         },
312         .num_children = 0,
313         .children = {  }
314 };
315 /*! \brief REST handler for /api-docs/deviceStates.json */
316 static struct stasis_rest_handlers deviceStates = {
317         .path_segment = "deviceStates",
318         .callbacks = {
319                 [AST_HTTP_GET] = ast_ari_device_states_list_cb,
320         },
321         .num_children = 1,
322         .children = { &deviceStates_deviceName, }
323 };
324
325 static int unload_module(void)
326 {
327         ast_ari_remove_handler(&deviceStates);
328         return 0;
329 }
330
331 static int load_module(void)
332 {
333         int res = 0;
334
335
336         res |= ast_ari_add_handler(&deviceStates);
337         if (res) {
338                 unload_module();
339                 return AST_MODULE_LOAD_DECLINE;
340         }
341
342         return AST_MODULE_LOAD_SUCCESS;
343 }
344
345 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - Device state resources",
346         .support_level = AST_MODULE_SUPPORT_CORE,
347         .load = load_module,
348         .unload = unload_module,
349         .requires = "res_ari,res_ari_model,res_stasis,res_stasis_device_state",
350 );