res_ari_channels.c 78 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2012 - 2013, Digium, Inc.
  5. *
  6. * David M. Lee, II <dlee@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. * !!!!! DO NOT EDIT !!!!!
  21. * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  22. * This file is generated by a mustache template. Please see the original
  23. * template in rest-api-templates/res_ari_resource.c.mustache
  24. */
  25. /*! \file
  26. *
  27. * \brief Channel resources
  28. *
  29. * \author David M. Lee, II <dlee@digium.com>
  30. */
  31. /*** MODULEINFO
  32. <depend type="module">res_ari</depend>
  33. <depend type="module">res_stasis</depend>
  34. <support_level>core</support_level>
  35. ***/
  36. #include "asterisk.h"
  37. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  38. #include "asterisk/app.h"
  39. #include "asterisk/module.h"
  40. #include "asterisk/stasis_app.h"
  41. #include "ari/resource_channels.h"
  42. #if defined(AST_DEVMODE)
  43. #include "ari/ari_model_validators.h"
  44. #endif
  45. #define MAX_VALS 128
  46. /*!
  47. * \brief Parameter parsing callback for /channels.
  48. * \param get_params GET parameters in the HTTP request.
  49. * \param path_vars Path variables extracted from the request.
  50. * \param headers HTTP headers.
  51. * \param[out] response Response to the HTTP request.
  52. */
  53. static void ast_ari_channels_list_cb(
  54. struct ast_tcptls_session_instance *ser,
  55. struct ast_variable *get_params, struct ast_variable *path_vars,
  56. struct ast_variable *headers, struct ast_ari_response *response)
  57. {
  58. struct ast_ari_channels_list_args args = {};
  59. RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
  60. #if defined(AST_DEVMODE)
  61. int is_valid;
  62. int code;
  63. #endif /* AST_DEVMODE */
  64. ast_ari_channels_list(headers, &args, response);
  65. #if defined(AST_DEVMODE)
  66. code = response->response_code;
  67. switch (code) {
  68. case 0: /* Implementation is still a stub, or the code wasn't set */
  69. is_valid = response->message == NULL;
  70. break;
  71. case 500: /* Internal Server Error */
  72. case 501: /* Not Implemented */
  73. is_valid = 1;
  74. break;
  75. default:
  76. if (200 <= code && code <= 299) {
  77. is_valid = ast_ari_validate_list(response->message,
  78. ast_ari_validate_channel_fn());
  79. } else {
  80. ast_log(LOG_ERROR, "Invalid error response %d for /channels\n", code);
  81. is_valid = 0;
  82. }
  83. }
  84. if (!is_valid) {
  85. ast_log(LOG_ERROR, "Response validation failed for /channels\n");
  86. ast_ari_response_error(response, 500,
  87. "Internal Server Error", "Response validation failed");
  88. }
  89. #endif /* AST_DEVMODE */
  90. fin: __attribute__((unused))
  91. return;
  92. }
  93. int ast_ari_channels_originate_parse_body(
  94. struct ast_json *body,
  95. struct ast_ari_channels_originate_args *args)
  96. {
  97. struct ast_json *field;
  98. /* Parse query parameters out of it */
  99. field = ast_json_object_get(body, "endpoint");
  100. if (field) {
  101. args->endpoint = ast_json_string_get(field);
  102. }
  103. field = ast_json_object_get(body, "extension");
  104. if (field) {
  105. args->extension = ast_json_string_get(field);
  106. }
  107. field = ast_json_object_get(body, "context");
  108. if (field) {
  109. args->context = ast_json_string_get(field);
  110. }
  111. field = ast_json_object_get(body, "priority");
  112. if (field) {
  113. args->priority = ast_json_integer_get(field);
  114. }
  115. field = ast_json_object_get(body, "label");
  116. if (field) {
  117. args->label = ast_json_string_get(field);
  118. }
  119. field = ast_json_object_get(body, "app");
  120. if (field) {
  121. args->app = ast_json_string_get(field);
  122. }
  123. field = ast_json_object_get(body, "appArgs");
  124. if (field) {
  125. args->app_args = ast_json_string_get(field);
  126. }
  127. field = ast_json_object_get(body, "callerId");
  128. if (field) {
  129. args->caller_id = ast_json_string_get(field);
  130. }
  131. field = ast_json_object_get(body, "timeout");
  132. if (field) {
  133. args->timeout = ast_json_integer_get(field);
  134. }
  135. field = ast_json_object_get(body, "channelId");
  136. if (field) {
  137. args->channel_id = ast_json_string_get(field);
  138. }
  139. field = ast_json_object_get(body, "otherChannelId");
  140. if (field) {
  141. args->other_channel_id = ast_json_string_get(field);
  142. }
  143. field = ast_json_object_get(body, "originator");
  144. if (field) {
  145. args->originator = ast_json_string_get(field);
  146. }
  147. return 0;
  148. }
  149. /*!
  150. * \brief Parameter parsing callback for /channels.
  151. * \param get_params GET parameters in the HTTP request.
  152. * \param path_vars Path variables extracted from the request.
  153. * \param headers HTTP headers.
  154. * \param[out] response Response to the HTTP request.
  155. */
  156. static void ast_ari_channels_originate_cb(
  157. struct ast_tcptls_session_instance *ser,
  158. struct ast_variable *get_params, struct ast_variable *path_vars,
  159. struct ast_variable *headers, struct ast_ari_response *response)
  160. {
  161. struct ast_ari_channels_originate_args args = {};
  162. struct ast_variable *i;
  163. RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
  164. #if defined(AST_DEVMODE)
  165. int is_valid;
  166. int code;
  167. #endif /* AST_DEVMODE */
  168. for (i = get_params; i; i = i->next) {
  169. if (strcmp(i->name, "endpoint") == 0) {
  170. args.endpoint = (i->value);
  171. } else
  172. if (strcmp(i->name, "extension") == 0) {
  173. args.extension = (i->value);
  174. } else
  175. if (strcmp(i->name, "context") == 0) {
  176. args.context = (i->value);
  177. } else
  178. if (strcmp(i->name, "priority") == 0) {
  179. args.priority = atol(i->value);
  180. } else
  181. if (strcmp(i->name, "label") == 0) {
  182. args.label = (i->value);
  183. } else
  184. if (strcmp(i->name, "app") == 0) {
  185. args.app = (i->value);
  186. } else
  187. if (strcmp(i->name, "appArgs") == 0) {
  188. args.app_args = (i->value);
  189. } else
  190. if (strcmp(i->name, "callerId") == 0) {
  191. args.caller_id = (i->value);
  192. } else
  193. if (strcmp(i->name, "timeout") == 0) {
  194. args.timeout = atoi(i->value);
  195. } else
  196. if (strcmp(i->name, "channelId") == 0) {
  197. args.channel_id = (i->value);
  198. } else
  199. if (strcmp(i->name, "otherChannelId") == 0) {
  200. args.other_channel_id = (i->value);
  201. } else
  202. if (strcmp(i->name, "originator") == 0) {
  203. args.originator = (i->value);
  204. } else
  205. {}
  206. }
  207. /* Look for a JSON request entity */
  208. body = ast_http_get_json(ser, headers);
  209. if (!body) {
  210. switch (errno) {
  211. case EFBIG:
  212. ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
  213. goto fin;
  214. case ENOMEM:
  215. ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
  216. goto fin;
  217. case EIO:
  218. ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
  219. goto fin;
  220. }
  221. }
  222. args.variables = body;
  223. ast_ari_channels_originate(headers, &args, response);
  224. #if defined(AST_DEVMODE)
  225. code = response->response_code;
  226. switch (code) {
  227. case 0: /* Implementation is still a stub, or the code wasn't set */
  228. is_valid = response->message == NULL;
  229. break;
  230. case 500: /* Internal Server Error */
  231. case 501: /* Not Implemented */
  232. case 400: /* Invalid parameters for originating a channel. */
  233. is_valid = 1;
  234. break;
  235. default:
  236. if (200 <= code && code <= 299) {
  237. is_valid = ast_ari_validate_channel(
  238. response->message);
  239. } else {
  240. ast_log(LOG_ERROR, "Invalid error response %d for /channels\n", code);
  241. is_valid = 0;
  242. }
  243. }
  244. if (!is_valid) {
  245. ast_log(LOG_ERROR, "Response validation failed for /channels\n");
  246. ast_ari_response_error(response, 500,
  247. "Internal Server Error", "Response validation failed");
  248. }
  249. #endif /* AST_DEVMODE */
  250. fin: __attribute__((unused))
  251. return;
  252. }
  253. /*!
  254. * \brief Parameter parsing callback for /channels/{channelId}.
  255. * \param get_params GET parameters in the HTTP request.
  256. * \param path_vars Path variables extracted from the request.
  257. * \param headers HTTP headers.
  258. * \param[out] response Response to the HTTP request.
  259. */
  260. static void ast_ari_channels_get_cb(
  261. struct ast_tcptls_session_instance *ser,
  262. struct ast_variable *get_params, struct ast_variable *path_vars,
  263. struct ast_variable *headers, struct ast_ari_response *response)
  264. {
  265. struct ast_ari_channels_get_args args = {};
  266. struct ast_variable *i;
  267. RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
  268. #if defined(AST_DEVMODE)
  269. int is_valid;
  270. int code;
  271. #endif /* AST_DEVMODE */
  272. for (i = path_vars; i; i = i->next) {
  273. if (strcmp(i->name, "channelId") == 0) {
  274. args.channel_id = (i->value);
  275. } else
  276. {}
  277. }
  278. ast_ari_channels_get(headers, &args, response);
  279. #if defined(AST_DEVMODE)
  280. code = response->response_code;
  281. switch (code) {
  282. case 0: /* Implementation is still a stub, or the code wasn't set */
  283. is_valid = response->message == NULL;
  284. break;
  285. case 500: /* Internal Server Error */
  286. case 501: /* Not Implemented */
  287. case 404: /* Channel not found */
  288. is_valid = 1;
  289. break;
  290. default:
  291. if (200 <= code && code <= 299) {
  292. is_valid = ast_ari_validate_channel(
  293. response->message);
  294. } else {
  295. ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}\n", code);
  296. is_valid = 0;
  297. }
  298. }
  299. if (!is_valid) {
  300. ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}\n");
  301. ast_ari_response_error(response, 500,
  302. "Internal Server Error", "Response validation failed");
  303. }
  304. #endif /* AST_DEVMODE */
  305. fin: __attribute__((unused))
  306. return;
  307. }
  308. int ast_ari_channels_originate_with_id_parse_body(
  309. struct ast_json *body,
  310. struct ast_ari_channels_originate_with_id_args *args)
  311. {
  312. struct ast_json *field;
  313. /* Parse query parameters out of it */
  314. field = ast_json_object_get(body, "endpoint");
  315. if (field) {
  316. args->endpoint = ast_json_string_get(field);
  317. }
  318. field = ast_json_object_get(body, "extension");
  319. if (field) {
  320. args->extension = ast_json_string_get(field);
  321. }
  322. field = ast_json_object_get(body, "context");
  323. if (field) {
  324. args->context = ast_json_string_get(field);
  325. }
  326. field = ast_json_object_get(body, "priority");
  327. if (field) {
  328. args->priority = ast_json_integer_get(field);
  329. }
  330. field = ast_json_object_get(body, "label");
  331. if (field) {
  332. args->label = ast_json_string_get(field);
  333. }
  334. field = ast_json_object_get(body, "app");
  335. if (field) {
  336. args->app = ast_json_string_get(field);
  337. }
  338. field = ast_json_object_get(body, "appArgs");
  339. if (field) {
  340. args->app_args = ast_json_string_get(field);
  341. }
  342. field = ast_json_object_get(body, "callerId");
  343. if (field) {
  344. args->caller_id = ast_json_string_get(field);
  345. }
  346. field = ast_json_object_get(body, "timeout");
  347. if (field) {
  348. args->timeout = ast_json_integer_get(field);
  349. }
  350. field = ast_json_object_get(body, "otherChannelId");
  351. if (field) {
  352. args->other_channel_id = ast_json_string_get(field);
  353. }
  354. field = ast_json_object_get(body, "originator");
  355. if (field) {
  356. args->originator = ast_json_string_get(field);
  357. }
  358. return 0;
  359. }
  360. /*!
  361. * \brief Parameter parsing callback for /channels/{channelId}.
  362. * \param get_params GET parameters in the HTTP request.
  363. * \param path_vars Path variables extracted from the request.
  364. * \param headers HTTP headers.
  365. * \param[out] response Response to the HTTP request.
  366. */
  367. static void ast_ari_channels_originate_with_id_cb(
  368. struct ast_tcptls_session_instance *ser,
  369. struct ast_variable *get_params, struct ast_variable *path_vars,
  370. struct ast_variable *headers, struct ast_ari_response *response)
  371. {
  372. struct ast_ari_channels_originate_with_id_args args = {};
  373. struct ast_variable *i;
  374. RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
  375. #if defined(AST_DEVMODE)
  376. int is_valid;
  377. int code;
  378. #endif /* AST_DEVMODE */
  379. for (i = get_params; i; i = i->next) {
  380. if (strcmp(i->name, "endpoint") == 0) {
  381. args.endpoint = (i->value);
  382. } else
  383. if (strcmp(i->name, "extension") == 0) {
  384. args.extension = (i->value);
  385. } else
  386. if (strcmp(i->name, "context") == 0) {
  387. args.context = (i->value);
  388. } else
  389. if (strcmp(i->name, "priority") == 0) {
  390. args.priority = atol(i->value);
  391. } else
  392. if (strcmp(i->name, "label") == 0) {
  393. args.label = (i->value);
  394. } else
  395. if (strcmp(i->name, "app") == 0) {
  396. args.app = (i->value);
  397. } else
  398. if (strcmp(i->name, "appArgs") == 0) {
  399. args.app_args = (i->value);
  400. } else
  401. if (strcmp(i->name, "callerId") == 0) {
  402. args.caller_id = (i->value);
  403. } else
  404. if (strcmp(i->name, "timeout") == 0) {
  405. args.timeout = atoi(i->value);
  406. } else
  407. if (strcmp(i->name, "otherChannelId") == 0) {
  408. args.other_channel_id = (i->value);
  409. } else
  410. if (strcmp(i->name, "originator") == 0) {
  411. args.originator = (i->value);
  412. } else
  413. {}
  414. }
  415. for (i = path_vars; i; i = i->next) {
  416. if (strcmp(i->name, "channelId") == 0) {
  417. args.channel_id = (i->value);
  418. } else
  419. {}
  420. }
  421. /* Look for a JSON request entity */
  422. body = ast_http_get_json(ser, headers);
  423. if (!body) {
  424. switch (errno) {
  425. case EFBIG:
  426. ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
  427. goto fin;
  428. case ENOMEM:
  429. ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
  430. goto fin;
  431. case EIO:
  432. ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
  433. goto fin;
  434. }
  435. }
  436. args.variables = body;
  437. ast_ari_channels_originate_with_id(headers, &args, response);
  438. #if defined(AST_DEVMODE)
  439. code = response->response_code;
  440. switch (code) {
  441. case 0: /* Implementation is still a stub, or the code wasn't set */
  442. is_valid = response->message == NULL;
  443. break;
  444. case 500: /* Internal Server Error */
  445. case 501: /* Not Implemented */
  446. case 400: /* Invalid parameters for originating a channel. */
  447. is_valid = 1;
  448. break;
  449. default:
  450. if (200 <= code && code <= 299) {
  451. is_valid = ast_ari_validate_channel(
  452. response->message);
  453. } else {
  454. ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}\n", code);
  455. is_valid = 0;
  456. }
  457. }
  458. if (!is_valid) {
  459. ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}\n");
  460. ast_ari_response_error(response, 500,
  461. "Internal Server Error", "Response validation failed");
  462. }
  463. #endif /* AST_DEVMODE */
  464. fin: __attribute__((unused))
  465. return;
  466. }
  467. int ast_ari_channels_hangup_parse_body(
  468. struct ast_json *body,
  469. struct ast_ari_channels_hangup_args *args)
  470. {
  471. struct ast_json *field;
  472. /* Parse query parameters out of it */
  473. field = ast_json_object_get(body, "reason");
  474. if (field) {
  475. args->reason = ast_json_string_get(field);
  476. }
  477. return 0;
  478. }
  479. /*!
  480. * \brief Parameter parsing callback for /channels/{channelId}.
  481. * \param get_params GET parameters in the HTTP request.
  482. * \param path_vars Path variables extracted from the request.
  483. * \param headers HTTP headers.
  484. * \param[out] response Response to the HTTP request.
  485. */
  486. static void ast_ari_channels_hangup_cb(
  487. struct ast_tcptls_session_instance *ser,
  488. struct ast_variable *get_params, struct ast_variable *path_vars,
  489. struct ast_variable *headers, struct ast_ari_response *response)
  490. {
  491. struct ast_ari_channels_hangup_args args = {};
  492. struct ast_variable *i;
  493. RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
  494. #if defined(AST_DEVMODE)
  495. int is_valid;
  496. int code;
  497. #endif /* AST_DEVMODE */
  498. for (i = get_params; i; i = i->next) {
  499. if (strcmp(i->name, "reason") == 0) {
  500. args.reason = (i->value);
  501. } else
  502. {}
  503. }
  504. for (i = path_vars; i; i = i->next) {
  505. if (strcmp(i->name, "channelId") == 0) {
  506. args.channel_id = (i->value);
  507. } else
  508. {}
  509. }
  510. /* Look for a JSON request entity */
  511. body = ast_http_get_json(ser, headers);
  512. if (!body) {
  513. switch (errno) {
  514. case EFBIG:
  515. ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
  516. goto fin;
  517. case ENOMEM:
  518. ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
  519. goto fin;
  520. case EIO:
  521. ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
  522. goto fin;
  523. }
  524. }
  525. if (ast_ari_channels_hangup_parse_body(body, &args)) {
  526. ast_ari_response_alloc_failed(response);
  527. goto fin;
  528. }
  529. ast_ari_channels_hangup(headers, &args, response);
  530. #if defined(AST_DEVMODE)
  531. code = response->response_code;
  532. switch (code) {
  533. case 0: /* Implementation is still a stub, or the code wasn't set */
  534. is_valid = response->message == NULL;
  535. break;
  536. case 500: /* Internal Server Error */
  537. case 501: /* Not Implemented */
  538. case 400: /* Invalid reason for hangup provided */
  539. case 404: /* Channel not found */
  540. is_valid = 1;
  541. break;
  542. default:
  543. if (200 <= code && code <= 299) {
  544. is_valid = ast_ari_validate_void(
  545. response->message);
  546. } else {
  547. ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}\n", code);
  548. is_valid = 0;
  549. }
  550. }
  551. if (!is_valid) {
  552. ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}\n");
  553. ast_ari_response_error(response, 500,
  554. "Internal Server Error", "Response validation failed");
  555. }
  556. #endif /* AST_DEVMODE */
  557. fin: __attribute__((unused))
  558. return;
  559. }
  560. int ast_ari_channels_continue_in_dialplan_parse_body(
  561. struct ast_json *body,
  562. struct ast_ari_channels_continue_in_dialplan_args *args)
  563. {
  564. struct ast_json *field;
  565. /* Parse query parameters out of it */
  566. field = ast_json_object_get(body, "context");
  567. if (field) {
  568. args->context = ast_json_string_get(field);
  569. }
  570. field = ast_json_object_get(body, "extension");
  571. if (field) {
  572. args->extension = ast_json_string_get(field);
  573. }
  574. field = ast_json_object_get(body, "priority");
  575. if (field) {
  576. args->priority = ast_json_integer_get(field);
  577. }
  578. field = ast_json_object_get(body, "label");
  579. if (field) {
  580. args->label = ast_json_string_get(field);
  581. }
  582. return 0;
  583. }
  584. /*!
  585. * \brief Parameter parsing callback for /channels/{channelId}/continue.
  586. * \param get_params GET parameters in the HTTP request.
  587. * \param path_vars Path variables extracted from the request.
  588. * \param headers HTTP headers.
  589. * \param[out] response Response to the HTTP request.
  590. */
  591. static void ast_ari_channels_continue_in_dialplan_cb(
  592. struct ast_tcptls_session_instance *ser,
  593. struct ast_variable *get_params, struct ast_variable *path_vars,
  594. struct ast_variable *headers, struct ast_ari_response *response)
  595. {
  596. struct ast_ari_channels_continue_in_dialplan_args args = {};
  597. struct ast_variable *i;
  598. RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
  599. #if defined(AST_DEVMODE)
  600. int is_valid;
  601. int code;
  602. #endif /* AST_DEVMODE */
  603. for (i = get_params; i; i = i->next) {
  604. if (strcmp(i->name, "context") == 0) {
  605. args.context = (i->value);
  606. } else
  607. if (strcmp(i->name, "extension") == 0) {
  608. args.extension = (i->value);
  609. } else
  610. if (strcmp(i->name, "priority") == 0) {
  611. args.priority = atoi(i->value);
  612. } else
  613. if (strcmp(i->name, "label") == 0) {
  614. args.label = (i->value);
  615. } else
  616. {}
  617. }
  618. for (i = path_vars; i; i = i->next) {
  619. if (strcmp(i->name, "channelId") == 0) {
  620. args.channel_id = (i->value);
  621. } else
  622. {}
  623. }
  624. /* Look for a JSON request entity */
  625. body = ast_http_get_json(ser, headers);
  626. if (!body) {
  627. switch (errno) {
  628. case EFBIG:
  629. ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
  630. goto fin;
  631. case ENOMEM:
  632. ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
  633. goto fin;
  634. case EIO:
  635. ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
  636. goto fin;
  637. }
  638. }
  639. if (ast_ari_channels_continue_in_dialplan_parse_body(body, &args)) {
  640. ast_ari_response_alloc_failed(response);
  641. goto fin;
  642. }
  643. ast_ari_channels_continue_in_dialplan(headers, &args, response);
  644. #if defined(AST_DEVMODE)
  645. code = response->response_code;
  646. switch (code) {
  647. case 0: /* Implementation is still a stub, or the code wasn't set */
  648. is_valid = response->message == NULL;
  649. break;
  650. case 500: /* Internal Server Error */
  651. case 501: /* Not Implemented */
  652. case 404: /* Channel not found */
  653. case 409: /* Channel not in a Stasis application */
  654. is_valid = 1;
  655. break;
  656. default:
  657. if (200 <= code && code <= 299) {
  658. is_valid = ast_ari_validate_void(
  659. response->message);
  660. } else {
  661. ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/continue\n", code);
  662. is_valid = 0;
  663. }
  664. }
  665. if (!is_valid) {
  666. ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/continue\n");
  667. ast_ari_response_error(response, 500,
  668. "Internal Server Error", "Response validation failed");
  669. }
  670. #endif /* AST_DEVMODE */
  671. fin: __attribute__((unused))
  672. return;
  673. }
  674. int ast_ari_channels_redirect_parse_body(
  675. struct ast_json *body,
  676. struct ast_ari_channels_redirect_args *args)
  677. {
  678. struct ast_json *field;
  679. /* Parse query parameters out of it */
  680. field = ast_json_object_get(body, "endpoint");
  681. if (field) {
  682. args->endpoint = ast_json_string_get(field);
  683. }
  684. return 0;
  685. }
  686. /*!
  687. * \brief Parameter parsing callback for /channels/{channelId}/redirect.
  688. * \param get_params GET parameters in the HTTP request.
  689. * \param path_vars Path variables extracted from the request.
  690. * \param headers HTTP headers.
  691. * \param[out] response Response to the HTTP request.
  692. */
  693. static void ast_ari_channels_redirect_cb(
  694. struct ast_tcptls_session_instance *ser,
  695. struct ast_variable *get_params, struct ast_variable *path_vars,
  696. struct ast_variable *headers, struct ast_ari_response *response)
  697. {
  698. struct ast_ari_channels_redirect_args args = {};
  699. struct ast_variable *i;
  700. RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
  701. #if defined(AST_DEVMODE)
  702. int is_valid;
  703. int code;
  704. #endif /* AST_DEVMODE */
  705. for (i = get_params; i; i = i->next) {
  706. if (strcmp(i->name, "endpoint") == 0) {
  707. args.endpoint = (i->value);
  708. } else
  709. {}
  710. }
  711. for (i = path_vars; i; i = i->next) {
  712. if (strcmp(i->name, "channelId") == 0) {
  713. args.channel_id = (i->value);
  714. } else
  715. {}
  716. }
  717. /* Look for a JSON request entity */
  718. body = ast_http_get_json(ser, headers);
  719. if (!body) {
  720. switch (errno) {
  721. case EFBIG:
  722. ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
  723. goto fin;
  724. case ENOMEM:
  725. ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
  726. goto fin;
  727. case EIO:
  728. ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
  729. goto fin;
  730. }
  731. }
  732. if (ast_ari_channels_redirect_parse_body(body, &args)) {
  733. ast_ari_response_alloc_failed(response);
  734. goto fin;
  735. }
  736. ast_ari_channels_redirect(headers, &args, response);
  737. #if defined(AST_DEVMODE)
  738. code = response->response_code;
  739. switch (code) {
  740. case 0: /* Implementation is still a stub, or the code wasn't set */
  741. is_valid = response->message == NULL;
  742. break;
  743. case 500: /* Internal Server Error */
  744. case 501: /* Not Implemented */
  745. case 400: /* Endpoint parameter not provided */
  746. case 404: /* Channel or endpoint not found */
  747. case 409: /* Channel not in a Stasis application */
  748. case 422: /* Endpoint is not the same type as the channel */
  749. is_valid = 1;
  750. break;
  751. default:
  752. if (200 <= code && code <= 299) {
  753. is_valid = ast_ari_validate_void(
  754. response->message);
  755. } else {
  756. ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/redirect\n", code);
  757. is_valid = 0;
  758. }
  759. }
  760. if (!is_valid) {
  761. ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/redirect\n");
  762. ast_ari_response_error(response, 500,
  763. "Internal Server Error", "Response validation failed");
  764. }
  765. #endif /* AST_DEVMODE */
  766. fin: __attribute__((unused))
  767. return;
  768. }
  769. /*!
  770. * \brief Parameter parsing callback for /channels/{channelId}/answer.
  771. * \param get_params GET parameters in the HTTP request.
  772. * \param path_vars Path variables extracted from the request.
  773. * \param headers HTTP headers.
  774. * \param[out] response Response to the HTTP request.
  775. */
  776. static void ast_ari_channels_answer_cb(
  777. struct ast_tcptls_session_instance *ser,
  778. struct ast_variable *get_params, struct ast_variable *path_vars,
  779. struct ast_variable *headers, struct ast_ari_response *response)
  780. {
  781. struct ast_ari_channels_answer_args args = {};
  782. struct ast_variable *i;
  783. RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
  784. #if defined(AST_DEVMODE)
  785. int is_valid;
  786. int code;
  787. #endif /* AST_DEVMODE */
  788. for (i = path_vars; i; i = i->next) {
  789. if (strcmp(i->name, "channelId") == 0) {
  790. args.channel_id = (i->value);
  791. } else
  792. {}
  793. }
  794. ast_ari_channels_answer(headers, &args, response);
  795. #if defined(AST_DEVMODE)
  796. code = response->response_code;
  797. switch (code) {
  798. case 0: /* Implementation is still a stub, or the code wasn't set */
  799. is_valid = response->message == NULL;
  800. break;
  801. case 500: /* Internal Server Error */
  802. case 501: /* Not Implemented */
  803. case 404: /* Channel not found */
  804. case 409: /* Channel not in a Stasis application */
  805. is_valid = 1;
  806. break;
  807. default:
  808. if (200 <= code && code <= 299) {
  809. is_valid = ast_ari_validate_void(
  810. response->message);
  811. } else {
  812. ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/answer\n", code);
  813. is_valid = 0;
  814. }
  815. }
  816. if (!is_valid) {
  817. ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/answer\n");
  818. ast_ari_response_error(response, 500,
  819. "Internal Server Error", "Response validation failed");
  820. }
  821. #endif /* AST_DEVMODE */
  822. fin: __attribute__((unused))
  823. return;
  824. }
  825. /*!
  826. * \brief Parameter parsing callback for /channels/{channelId}/ring.
  827. * \param get_params GET parameters in the HTTP request.
  828. * \param path_vars Path variables extracted from the request.
  829. * \param headers HTTP headers.
  830. * \param[out] response Response to the HTTP request.
  831. */
  832. static void ast_ari_channels_ring_cb(
  833. struct ast_tcptls_session_instance *ser,
  834. struct ast_variable *get_params, struct ast_variable *path_vars,
  835. struct ast_variable *headers, struct ast_ari_response *response)
  836. {
  837. struct ast_ari_channels_ring_args args = {};
  838. struct ast_variable *i;
  839. RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
  840. #if defined(AST_DEVMODE)
  841. int is_valid;
  842. int code;
  843. #endif /* AST_DEVMODE */
  844. for (i = path_vars; i; i = i->next) {
  845. if (strcmp(i->name, "channelId") == 0) {
  846. args.channel_id = (i->value);
  847. } else
  848. {}
  849. }
  850. ast_ari_channels_ring(headers, &args, response);
  851. #if defined(AST_DEVMODE)
  852. code = response->response_code;
  853. switch (code) {
  854. case 0: /* Implementation is still a stub, or the code wasn't set */
  855. is_valid = response->message == NULL;
  856. break;
  857. case 500: /* Internal Server Error */
  858. case 501: /* Not Implemented */
  859. case 404: /* Channel not found */
  860. case 409: /* Channel not in a Stasis application */
  861. is_valid = 1;
  862. break;
  863. default:
  864. if (200 <= code && code <= 299) {
  865. is_valid = ast_ari_validate_void(
  866. response->message);
  867. } else {
  868. ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/ring\n", code);
  869. is_valid = 0;
  870. }
  871. }
  872. if (!is_valid) {
  873. ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/ring\n");
  874. ast_ari_response_error(response, 500,
  875. "Internal Server Error", "Response validation failed");
  876. }
  877. #endif /* AST_DEVMODE */
  878. fin: __attribute__((unused))
  879. return;
  880. }
  881. /*!
  882. * \brief Parameter parsing callback for /channels/{channelId}/ring.
  883. * \param get_params GET parameters in the HTTP request.
  884. * \param path_vars Path variables extracted from the request.
  885. * \param headers HTTP headers.
  886. * \param[out] response Response to the HTTP request.
  887. */
  888. static void ast_ari_channels_ring_stop_cb(
  889. struct ast_tcptls_session_instance *ser,
  890. struct ast_variable *get_params, struct ast_variable *path_vars,
  891. struct ast_variable *headers, struct ast_ari_response *response)
  892. {
  893. struct ast_ari_channels_ring_stop_args args = {};
  894. struct ast_variable *i;
  895. RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
  896. #if defined(AST_DEVMODE)
  897. int is_valid;
  898. int code;
  899. #endif /* AST_DEVMODE */
  900. for (i = path_vars; i; i = i->next) {
  901. if (strcmp(i->name, "channelId") == 0) {
  902. args.channel_id = (i->value);
  903. } else
  904. {}
  905. }
  906. ast_ari_channels_ring_stop(headers, &args, response);
  907. #if defined(AST_DEVMODE)
  908. code = response->response_code;
  909. switch (code) {
  910. case 0: /* Implementation is still a stub, or the code wasn't set */
  911. is_valid = response->message == NULL;
  912. break;
  913. case 500: /* Internal Server Error */
  914. case 501: /* Not Implemented */
  915. case 404: /* Channel not found */
  916. case 409: /* Channel not in a Stasis application */
  917. is_valid = 1;
  918. break;
  919. default:
  920. if (200 <= code && code <= 299) {
  921. is_valid = ast_ari_validate_void(
  922. response->message);
  923. } else {
  924. ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/ring\n", code);
  925. is_valid = 0;
  926. }
  927. }
  928. if (!is_valid) {
  929. ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/ring\n");
  930. ast_ari_response_error(response, 500,
  931. "Internal Server Error", "Response validation failed");
  932. }
  933. #endif /* AST_DEVMODE */
  934. fin: __attribute__((unused))
  935. return;
  936. }
  937. int ast_ari_channels_send_dtmf_parse_body(
  938. struct ast_json *body,
  939. struct ast_ari_channels_send_dtmf_args *args)
  940. {
  941. struct ast_json *field;
  942. /* Parse query parameters out of it */
  943. field = ast_json_object_get(body, "dtmf");
  944. if (field) {
  945. args->dtmf = ast_json_string_get(field);
  946. }
  947. field = ast_json_object_get(body, "before");
  948. if (field) {
  949. args->before = ast_json_integer_get(field);
  950. }
  951. field = ast_json_object_get(body, "between");
  952. if (field) {
  953. args->between = ast_json_integer_get(field);
  954. }
  955. field = ast_json_object_get(body, "duration");
  956. if (field) {
  957. args->duration = ast_json_integer_get(field);
  958. }
  959. field = ast_json_object_get(body, "after");
  960. if (field) {
  961. args->after = ast_json_integer_get(field);
  962. }
  963. return 0;
  964. }
  965. /*!
  966. * \brief Parameter parsing callback for /channels/{channelId}/dtmf.
  967. * \param get_params GET parameters in the HTTP request.
  968. * \param path_vars Path variables extracted from the request.
  969. * \param headers HTTP headers.
  970. * \param[out] response Response to the HTTP request.
  971. */
  972. static void ast_ari_channels_send_dtmf_cb(
  973. struct ast_tcptls_session_instance *ser,
  974. struct ast_variable *get_params, struct ast_variable *path_vars,
  975. struct ast_variable *headers, struct ast_ari_response *response)
  976. {
  977. struct ast_ari_channels_send_dtmf_args args = {};
  978. struct ast_variable *i;
  979. RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
  980. #if defined(AST_DEVMODE)
  981. int is_valid;
  982. int code;
  983. #endif /* AST_DEVMODE */
  984. for (i = get_params; i; i = i->next) {
  985. if (strcmp(i->name, "dtmf") == 0) {
  986. args.dtmf = (i->value);
  987. } else
  988. if (strcmp(i->name, "before") == 0) {
  989. args.before = atoi(i->value);
  990. } else
  991. if (strcmp(i->name, "between") == 0) {
  992. args.between = atoi(i->value);
  993. } else
  994. if (strcmp(i->name, "duration") == 0) {
  995. args.duration = atoi(i->value);
  996. } else
  997. if (strcmp(i->name, "after") == 0) {
  998. args.after = atoi(i->value);
  999. } else
  1000. {}
  1001. }
  1002. for (i = path_vars; i; i = i->next) {
  1003. if (strcmp(i->name, "channelId") == 0) {
  1004. args.channel_id = (i->value);
  1005. } else
  1006. {}
  1007. }
  1008. /* Look for a JSON request entity */
  1009. body = ast_http_get_json(ser, headers);
  1010. if (!body) {
  1011. switch (errno) {
  1012. case EFBIG:
  1013. ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
  1014. goto fin;
  1015. case ENOMEM:
  1016. ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
  1017. goto fin;
  1018. case EIO:
  1019. ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
  1020. goto fin;
  1021. }
  1022. }
  1023. if (ast_ari_channels_send_dtmf_parse_body(body, &args)) {
  1024. ast_ari_response_alloc_failed(response);
  1025. goto fin;
  1026. }
  1027. ast_ari_channels_send_dtmf(headers, &args, response);
  1028. #if defined(AST_DEVMODE)
  1029. code = response->response_code;
  1030. switch (code) {
  1031. case 0: /* Implementation is still a stub, or the code wasn't set */
  1032. is_valid = response->message == NULL;
  1033. break;
  1034. case 500: /* Internal Server Error */
  1035. case 501: /* Not Implemented */
  1036. case 400: /* DTMF is required */
  1037. case 404: /* Channel not found */
  1038. case 409: /* Channel not in a Stasis application */
  1039. is_valid = 1;
  1040. break;
  1041. default:
  1042. if (200 <= code && code <= 299) {
  1043. is_valid = ast_ari_validate_void(
  1044. response->message);
  1045. } else {
  1046. ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/dtmf\n", code);
  1047. is_valid = 0;
  1048. }
  1049. }
  1050. if (!is_valid) {
  1051. ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/dtmf\n");
  1052. ast_ari_response_error(response, 500,
  1053. "Internal Server Error", "Response validation failed");
  1054. }
  1055. #endif /* AST_DEVMODE */
  1056. fin: __attribute__((unused))
  1057. return;
  1058. }
  1059. int ast_ari_channels_mute_parse_body(
  1060. struct ast_json *body,
  1061. struct ast_ari_channels_mute_args *args)
  1062. {
  1063. struct ast_json *field;
  1064. /* Parse query parameters out of it */
  1065. field = ast_json_object_get(body, "direction");
  1066. if (field) {
  1067. args->direction = ast_json_string_get(field);
  1068. }
  1069. return 0;
  1070. }
  1071. /*!
  1072. * \brief Parameter parsing callback for /channels/{channelId}/mute.
  1073. * \param get_params GET parameters in the HTTP request.
  1074. * \param path_vars Path variables extracted from the request.
  1075. * \param headers HTTP headers.
  1076. * \param[out] response Response to the HTTP request.
  1077. */
  1078. static void ast_ari_channels_mute_cb(
  1079. struct ast_tcptls_session_instance *ser,
  1080. struct ast_variable *get_params, struct ast_variable *path_vars,
  1081. struct ast_variable *headers, struct ast_ari_response *response)
  1082. {
  1083. struct ast_ari_channels_mute_args args = {};
  1084. struct ast_variable *i;
  1085. RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
  1086. #if defined(AST_DEVMODE)
  1087. int is_valid;
  1088. int code;
  1089. #endif /* AST_DEVMODE */
  1090. for (i = get_params; i; i = i->next) {
  1091. if (strcmp(i->name, "direction") == 0) {
  1092. args.direction = (i->value);
  1093. } else
  1094. {}
  1095. }
  1096. for (i = path_vars; i; i = i->next) {
  1097. if (strcmp(i->name, "channelId") == 0) {
  1098. args.channel_id = (i->value);
  1099. } else
  1100. {}
  1101. }
  1102. /* Look for a JSON request entity */
  1103. body = ast_http_get_json(ser, headers);
  1104. if (!body) {
  1105. switch (errno) {
  1106. case EFBIG:
  1107. ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
  1108. goto fin;
  1109. case ENOMEM:
  1110. ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
  1111. goto fin;
  1112. case EIO:
  1113. ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
  1114. goto fin;
  1115. }
  1116. }
  1117. if (ast_ari_channels_mute_parse_body(body, &args)) {
  1118. ast_ari_response_alloc_failed(response);
  1119. goto fin;
  1120. }
  1121. ast_ari_channels_mute(headers, &args, response);
  1122. #if defined(AST_DEVMODE)
  1123. code = response->response_code;
  1124. switch (code) {
  1125. case 0: /* Implementation is still a stub, or the code wasn't set */
  1126. is_valid = response->message == NULL;
  1127. break;
  1128. case 500: /* Internal Server Error */
  1129. case 501: /* Not Implemented */
  1130. case 404: /* Channel not found */
  1131. case 409: /* Channel not in a Stasis application */
  1132. is_valid = 1;
  1133. break;
  1134. default:
  1135. if (200 <= code && code <= 299) {
  1136. is_valid = ast_ari_validate_void(
  1137. response->message);
  1138. } else {
  1139. ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/mute\n", code);
  1140. is_valid = 0;
  1141. }
  1142. }
  1143. if (!is_valid) {
  1144. ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/mute\n");
  1145. ast_ari_response_error(response, 500,
  1146. "Internal Server Error", "Response validation failed");
  1147. }
  1148. #endif /* AST_DEVMODE */
  1149. fin: __attribute__((unused))
  1150. return;
  1151. }
  1152. int ast_ari_channels_unmute_parse_body(
  1153. struct ast_json *body,
  1154. struct ast_ari_channels_unmute_args *args)
  1155. {
  1156. struct ast_json *field;
  1157. /* Parse query parameters out of it */
  1158. field = ast_json_object_get(body, "direction");
  1159. if (field) {
  1160. args->direction = ast_json_string_get(field);
  1161. }
  1162. return 0;
  1163. }
  1164. /*!
  1165. * \brief Parameter parsing callback for /channels/{channelId}/mute.
  1166. * \param get_params GET parameters in the HTTP request.
  1167. * \param path_vars Path variables extracted from the request.
  1168. * \param headers HTTP headers.
  1169. * \param[out] response Response to the HTTP request.
  1170. */
  1171. static void ast_ari_channels_unmute_cb(
  1172. struct ast_tcptls_session_instance *ser,
  1173. struct ast_variable *get_params, struct ast_variable *path_vars,
  1174. struct ast_variable *headers, struct ast_ari_response *response)
  1175. {
  1176. struct ast_ari_channels_unmute_args args = {};
  1177. struct ast_variable *i;
  1178. RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
  1179. #if defined(AST_DEVMODE)
  1180. int is_valid;
  1181. int code;
  1182. #endif /* AST_DEVMODE */
  1183. for (i = get_params; i; i = i->next) {
  1184. if (strcmp(i->name, "direction") == 0) {
  1185. args.direction = (i->value);
  1186. } else
  1187. {}
  1188. }
  1189. for (i = path_vars; i; i = i->next) {
  1190. if (strcmp(i->name, "channelId") == 0) {
  1191. args.channel_id = (i->value);
  1192. } else
  1193. {}
  1194. }
  1195. /* Look for a JSON request entity */
  1196. body = ast_http_get_json(ser, headers);
  1197. if (!body) {
  1198. switch (errno) {
  1199. case EFBIG:
  1200. ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
  1201. goto fin;
  1202. case ENOMEM:
  1203. ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
  1204. goto fin;
  1205. case EIO:
  1206. ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
  1207. goto fin;
  1208. }
  1209. }
  1210. if (ast_ari_channels_unmute_parse_body(body, &args)) {
  1211. ast_ari_response_alloc_failed(response);
  1212. goto fin;
  1213. }
  1214. ast_ari_channels_unmute(headers, &args, response);
  1215. #if defined(AST_DEVMODE)
  1216. code = response->response_code;
  1217. switch (code) {
  1218. case 0: /* Implementation is still a stub, or the code wasn't set */
  1219. is_valid = response->message == NULL;
  1220. break;
  1221. case 500: /* Internal Server Error */
  1222. case 501: /* Not Implemented */
  1223. case 404: /* Channel not found */
  1224. case 409: /* Channel not in a Stasis application */
  1225. is_valid = 1;
  1226. break;
  1227. default:
  1228. if (200 <= code && code <= 299) {
  1229. is_valid = ast_ari_validate_void(
  1230. response->message);
  1231. } else {
  1232. ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/mute\n", code);
  1233. is_valid = 0;
  1234. }
  1235. }
  1236. if (!is_valid) {
  1237. ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/mute\n");
  1238. ast_ari_response_error(response, 500,
  1239. "Internal Server Error", "Response validation failed");
  1240. }
  1241. #endif /* AST_DEVMODE */
  1242. fin: __attribute__((unused))
  1243. return;
  1244. }
  1245. /*!
  1246. * \brief Parameter parsing callback for /channels/{channelId}/hold.
  1247. * \param get_params GET parameters in the HTTP request.
  1248. * \param path_vars Path variables extracted from the request.
  1249. * \param headers HTTP headers.
  1250. * \param[out] response Response to the HTTP request.
  1251. */
  1252. static void ast_ari_channels_hold_cb(
  1253. struct ast_tcptls_session_instance *ser,
  1254. struct ast_variable *get_params, struct ast_variable *path_vars,
  1255. struct ast_variable *headers, struct ast_ari_response *response)
  1256. {
  1257. struct ast_ari_channels_hold_args args = {};
  1258. struct ast_variable *i;
  1259. RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
  1260. #if defined(AST_DEVMODE)
  1261. int is_valid;
  1262. int code;
  1263. #endif /* AST_DEVMODE */
  1264. for (i = path_vars; i; i = i->next) {
  1265. if (strcmp(i->name, "channelId") == 0) {
  1266. args.channel_id = (i->value);
  1267. } else
  1268. {}
  1269. }
  1270. ast_ari_channels_hold(headers, &args, response);
  1271. #if defined(AST_DEVMODE)
  1272. code = response->response_code;
  1273. switch (code) {
  1274. case 0: /* Implementation is still a stub, or the code wasn't set */
  1275. is_valid = response->message == NULL;
  1276. break;
  1277. case 500: /* Internal Server Error */
  1278. case 501: /* Not Implemented */
  1279. case 404: /* Channel not found */
  1280. case 409: /* Channel not in a Stasis application */
  1281. is_valid = 1;
  1282. break;
  1283. default:
  1284. if (200 <= code && code <= 299) {
  1285. is_valid = ast_ari_validate_void(
  1286. response->message);
  1287. } else {
  1288. ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/hold\n", code);
  1289. is_valid = 0;
  1290. }
  1291. }
  1292. if (!is_valid) {
  1293. ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/hold\n");
  1294. ast_ari_response_error(response, 500,
  1295. "Internal Server Error", "Response validation failed");
  1296. }
  1297. #endif /* AST_DEVMODE */
  1298. fin: __attribute__((unused))
  1299. return;
  1300. }
  1301. /*!
  1302. * \brief Parameter parsing callback for /channels/{channelId}/hold.
  1303. * \param get_params GET parameters in the HTTP request.
  1304. * \param path_vars Path variables extracted from the request.
  1305. * \param headers HTTP headers.
  1306. * \param[out] response Response to the HTTP request.
  1307. */
  1308. static void ast_ari_channels_unhold_cb(
  1309. struct ast_tcptls_session_instance *ser,
  1310. struct ast_variable *get_params, struct ast_variable *path_vars,
  1311. struct ast_variable *headers, struct ast_ari_response *response)
  1312. {
  1313. struct ast_ari_channels_unhold_args args = {};
  1314. struct ast_variable *i;
  1315. RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
  1316. #if defined(AST_DEVMODE)
  1317. int is_valid;
  1318. int code;
  1319. #endif /* AST_DEVMODE */
  1320. for (i = path_vars; i; i = i->next) {
  1321. if (strcmp(i->name, "channelId") == 0) {
  1322. args.channel_id = (i->value);
  1323. } else
  1324. {}
  1325. }
  1326. ast_ari_channels_unhold(headers, &args, response);
  1327. #if defined(AST_DEVMODE)
  1328. code = response->response_code;
  1329. switch (code) {
  1330. case 0: /* Implementation is still a stub, or the code wasn't set */
  1331. is_valid = response->message == NULL;
  1332. break;
  1333. case 500: /* Internal Server Error */
  1334. case 501: /* Not Implemented */
  1335. case 404: /* Channel not found */
  1336. case 409: /* Channel not in a Stasis application */
  1337. is_valid = 1;
  1338. break;
  1339. default:
  1340. if (200 <= code && code <= 299) {
  1341. is_valid = ast_ari_validate_void(
  1342. response->message);
  1343. } else {
  1344. ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/hold\n", code);
  1345. is_valid = 0;
  1346. }
  1347. }
  1348. if (!is_valid) {
  1349. ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/hold\n");
  1350. ast_ari_response_error(response, 500,
  1351. "Internal Server Error", "Response validation failed");
  1352. }
  1353. #endif /* AST_DEVMODE */
  1354. fin: __attribute__((unused))
  1355. return;
  1356. }
  1357. int ast_ari_channels_start_moh_parse_body(
  1358. struct ast_json *body,
  1359. struct ast_ari_channels_start_moh_args *args)
  1360. {
  1361. struct ast_json *field;
  1362. /* Parse query parameters out of it */
  1363. field = ast_json_object_get(body, "mohClass");
  1364. if (field) {
  1365. args->moh_class = ast_json_string_get(field);
  1366. }
  1367. return 0;
  1368. }
  1369. /*!
  1370. * \brief Parameter parsing callback for /channels/{channelId}/moh.
  1371. * \param get_params GET parameters in the HTTP request.
  1372. * \param path_vars Path variables extracted from the request.
  1373. * \param headers HTTP headers.
  1374. * \param[out] response Response to the HTTP request.
  1375. */
  1376. static void ast_ari_channels_start_moh_cb(
  1377. struct ast_tcptls_session_instance *ser,
  1378. struct ast_variable *get_params, struct ast_variable *path_vars,
  1379. struct ast_variable *headers, struct ast_ari_response *response)
  1380. {
  1381. struct ast_ari_channels_start_moh_args args = {};
  1382. struct ast_variable *i;
  1383. RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
  1384. #if defined(AST_DEVMODE)
  1385. int is_valid;
  1386. int code;
  1387. #endif /* AST_DEVMODE */
  1388. for (i = get_params; i; i = i->next) {
  1389. if (strcmp(i->name, "mohClass") == 0) {
  1390. args.moh_class = (i->value);
  1391. } else
  1392. {}
  1393. }
  1394. for (i = path_vars; i; i = i->next) {
  1395. if (strcmp(i->name, "channelId") == 0) {
  1396. args.channel_id = (i->value);
  1397. } else
  1398. {}
  1399. }
  1400. /* Look for a JSON request entity */
  1401. body = ast_http_get_json(ser, headers);
  1402. if (!body) {
  1403. switch (errno) {
  1404. case EFBIG:
  1405. ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
  1406. goto fin;
  1407. case ENOMEM:
  1408. ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
  1409. goto fin;
  1410. case EIO:
  1411. ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
  1412. goto fin;
  1413. }
  1414. }
  1415. if (ast_ari_channels_start_moh_parse_body(body, &args)) {
  1416. ast_ari_response_alloc_failed(response);
  1417. goto fin;
  1418. }
  1419. ast_ari_channels_start_moh(headers, &args, response);
  1420. #if defined(AST_DEVMODE)
  1421. code = response->response_code;
  1422. switch (code) {
  1423. case 0: /* Implementation is still a stub, or the code wasn't set */
  1424. is_valid = response->message == NULL;
  1425. break;
  1426. case 500: /* Internal Server Error */
  1427. case 501: /* Not Implemented */
  1428. case 404: /* Channel not found */
  1429. case 409: /* Channel not in a Stasis application */
  1430. is_valid = 1;
  1431. break;
  1432. default:
  1433. if (200 <= code && code <= 299) {
  1434. is_valid = ast_ari_validate_void(
  1435. response->message);
  1436. } else {
  1437. ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/moh\n", code);
  1438. is_valid = 0;
  1439. }
  1440. }
  1441. if (!is_valid) {
  1442. ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/moh\n");
  1443. ast_ari_response_error(response, 500,
  1444. "Internal Server Error", "Response validation failed");
  1445. }
  1446. #endif /* AST_DEVMODE */
  1447. fin: __attribute__((unused))
  1448. return;
  1449. }
  1450. /*!
  1451. * \brief Parameter parsing callback for /channels/{channelId}/moh.
  1452. * \param get_params GET parameters in the HTTP request.
  1453. * \param path_vars Path variables extracted from the request.
  1454. * \param headers HTTP headers.
  1455. * \param[out] response Response to the HTTP request.
  1456. */
  1457. static void ast_ari_channels_stop_moh_cb(
  1458. struct ast_tcptls_session_instance *ser,
  1459. struct ast_variable *get_params, struct ast_variable *path_vars,
  1460. struct ast_variable *headers, struct ast_ari_response *response)
  1461. {
  1462. struct ast_ari_channels_stop_moh_args args = {};
  1463. struct ast_variable *i;
  1464. RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
  1465. #if defined(AST_DEVMODE)
  1466. int is_valid;
  1467. int code;
  1468. #endif /* AST_DEVMODE */
  1469. for (i = path_vars; i; i = i->next) {
  1470. if (strcmp(i->name, "channelId") == 0) {
  1471. args.channel_id = (i->value);
  1472. } else
  1473. {}
  1474. }
  1475. ast_ari_channels_stop_moh(headers, &args, response);
  1476. #if defined(AST_DEVMODE)
  1477. code = response->response_code;
  1478. switch (code) {
  1479. case 0: /* Implementation is still a stub, or the code wasn't set */
  1480. is_valid = response->message == NULL;
  1481. break;
  1482. case 500: /* Internal Server Error */
  1483. case 501: /* Not Implemented */
  1484. case 404: /* Channel not found */
  1485. case 409: /* Channel not in a Stasis application */
  1486. is_valid = 1;
  1487. break;
  1488. default:
  1489. if (200 <= code && code <= 299) {
  1490. is_valid = ast_ari_validate_void(
  1491. response->message);
  1492. } else {
  1493. ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/moh\n", code);
  1494. is_valid = 0;
  1495. }
  1496. }
  1497. if (!is_valid) {
  1498. ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/moh\n");
  1499. ast_ari_response_error(response, 500,
  1500. "Internal Server Error", "Response validation failed");
  1501. }
  1502. #endif /* AST_DEVMODE */
  1503. fin: __attribute__((unused))
  1504. return;
  1505. }
  1506. /*!
  1507. * \brief Parameter parsing callback for /channels/{channelId}/silence.
  1508. * \param get_params GET parameters in the HTTP request.
  1509. * \param path_vars Path variables extracted from the request.
  1510. * \param headers HTTP headers.
  1511. * \param[out] response Response to the HTTP request.
  1512. */
  1513. static void ast_ari_channels_start_silence_cb(
  1514. struct ast_tcptls_session_instance *ser,
  1515. struct ast_variable *get_params, struct ast_variable *path_vars,
  1516. struct ast_variable *headers, struct ast_ari_response *response)
  1517. {
  1518. struct ast_ari_channels_start_silence_args args = {};
  1519. struct ast_variable *i;
  1520. RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
  1521. #if defined(AST_DEVMODE)
  1522. int is_valid;
  1523. int code;
  1524. #endif /* AST_DEVMODE */
  1525. for (i = path_vars; i; i = i->next) {
  1526. if (strcmp(i->name, "channelId") == 0) {
  1527. args.channel_id = (i->value);
  1528. } else
  1529. {}
  1530. }
  1531. ast_ari_channels_start_silence(headers, &args, response);
  1532. #if defined(AST_DEVMODE)
  1533. code = response->response_code;
  1534. switch (code) {
  1535. case 0: /* Implementation is still a stub, or the code wasn't set */
  1536. is_valid = response->message == NULL;
  1537. break;
  1538. case 500: /* Internal Server Error */
  1539. case 501: /* Not Implemented */
  1540. case 404: /* Channel not found */
  1541. case 409: /* Channel not in a Stasis application */
  1542. is_valid = 1;
  1543. break;
  1544. default:
  1545. if (200 <= code && code <= 299) {
  1546. is_valid = ast_ari_validate_void(
  1547. response->message);
  1548. } else {
  1549. ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/silence\n", code);
  1550. is_valid = 0;
  1551. }
  1552. }
  1553. if (!is_valid) {
  1554. ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/silence\n");
  1555. ast_ari_response_error(response, 500,
  1556. "Internal Server Error", "Response validation failed");
  1557. }
  1558. #endif /* AST_DEVMODE */
  1559. fin: __attribute__((unused))
  1560. return;
  1561. }
  1562. /*!
  1563. * \brief Parameter parsing callback for /channels/{channelId}/silence.
  1564. * \param get_params GET parameters in the HTTP request.
  1565. * \param path_vars Path variables extracted from the request.
  1566. * \param headers HTTP headers.
  1567. * \param[out] response Response to the HTTP request.
  1568. */
  1569. static void ast_ari_channels_stop_silence_cb(
  1570. struct ast_tcptls_session_instance *ser,
  1571. struct ast_variable *get_params, struct ast_variable *path_vars,
  1572. struct ast_variable *headers, struct ast_ari_response *response)
  1573. {
  1574. struct ast_ari_channels_stop_silence_args args = {};
  1575. struct ast_variable *i;
  1576. RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
  1577. #if defined(AST_DEVMODE)
  1578. int is_valid;
  1579. int code;
  1580. #endif /* AST_DEVMODE */
  1581. for (i = path_vars; i; i = i->next) {
  1582. if (strcmp(i->name, "channelId") == 0) {
  1583. args.channel_id = (i->value);
  1584. } else
  1585. {}
  1586. }
  1587. ast_ari_channels_stop_silence(headers, &args, response);
  1588. #if defined(AST_DEVMODE)
  1589. code = response->response_code;
  1590. switch (code) {
  1591. case 0: /* Implementation is still a stub, or the code wasn't set */
  1592. is_valid = response->message == NULL;
  1593. break;
  1594. case 500: /* Internal Server Error */
  1595. case 501: /* Not Implemented */
  1596. case 404: /* Channel not found */
  1597. case 409: /* Channel not in a Stasis application */
  1598. is_valid = 1;
  1599. break;
  1600. default:
  1601. if (200 <= code && code <= 299) {
  1602. is_valid = ast_ari_validate_void(
  1603. response->message);
  1604. } else {
  1605. ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/silence\n", code);
  1606. is_valid = 0;
  1607. }
  1608. }
  1609. if (!is_valid) {
  1610. ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/silence\n");
  1611. ast_ari_response_error(response, 500,
  1612. "Internal Server Error", "Response validation failed");
  1613. }
  1614. #endif /* AST_DEVMODE */
  1615. fin: __attribute__((unused))
  1616. return;
  1617. }
  1618. int ast_ari_channels_play_parse_body(
  1619. struct ast_json *body,
  1620. struct ast_ari_channels_play_args *args)
  1621. {
  1622. struct ast_json *field;
  1623. /* Parse query parameters out of it */
  1624. field = ast_json_object_get(body, "media");
  1625. if (field) {
  1626. args->media = ast_json_string_get(field);
  1627. }
  1628. field = ast_json_object_get(body, "lang");
  1629. if (field) {
  1630. args->lang = ast_json_string_get(field);
  1631. }
  1632. field = ast_json_object_get(body, "offsetms");
  1633. if (field) {
  1634. args->offsetms = ast_json_integer_get(field);
  1635. }
  1636. field = ast_json_object_get(body, "skipms");
  1637. if (field) {
  1638. args->skipms = ast_json_integer_get(field);
  1639. }
  1640. field = ast_json_object_get(body, "playbackId");
  1641. if (field) {
  1642. args->playback_id = ast_json_string_get(field);
  1643. }
  1644. return 0;
  1645. }
  1646. /*!
  1647. * \brief Parameter parsing callback for /channels/{channelId}/play.
  1648. * \param get_params GET parameters in the HTTP request.
  1649. * \param path_vars Path variables extracted from the request.
  1650. * \param headers HTTP headers.
  1651. * \param[out] response Response to the HTTP request.
  1652. */
  1653. static void ast_ari_channels_play_cb(
  1654. struct ast_tcptls_session_instance *ser,
  1655. struct ast_variable *get_params, struct ast_variable *path_vars,
  1656. struct ast_variable *headers, struct ast_ari_response *response)
  1657. {
  1658. struct ast_ari_channels_play_args args = {};
  1659. struct ast_variable *i;
  1660. RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
  1661. #if defined(AST_DEVMODE)
  1662. int is_valid;
  1663. int code;
  1664. #endif /* AST_DEVMODE */
  1665. for (i = get_params; i; i = i->next) {
  1666. if (strcmp(i->name, "media") == 0) {
  1667. args.media = (i->value);
  1668. } else
  1669. if (strcmp(i->name, "lang") == 0) {
  1670. args.lang = (i->value);
  1671. } else
  1672. if (strcmp(i->name, "offsetms") == 0) {
  1673. args.offsetms = atoi(i->value);
  1674. } else
  1675. if (strcmp(i->name, "skipms") == 0) {
  1676. args.skipms = atoi(i->value);
  1677. } else
  1678. if (strcmp(i->name, "playbackId") == 0) {
  1679. args.playback_id = (i->value);
  1680. } else
  1681. {}
  1682. }
  1683. for (i = path_vars; i; i = i->next) {
  1684. if (strcmp(i->name, "channelId") == 0) {
  1685. args.channel_id = (i->value);
  1686. } else
  1687. {}
  1688. }
  1689. /* Look for a JSON request entity */
  1690. body = ast_http_get_json(ser, headers);
  1691. if (!body) {
  1692. switch (errno) {
  1693. case EFBIG:
  1694. ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
  1695. goto fin;
  1696. case ENOMEM:
  1697. ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
  1698. goto fin;
  1699. case EIO:
  1700. ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
  1701. goto fin;
  1702. }
  1703. }
  1704. if (ast_ari_channels_play_parse_body(body, &args)) {
  1705. ast_ari_response_alloc_failed(response);
  1706. goto fin;
  1707. }
  1708. ast_ari_channels_play(headers, &args, response);
  1709. #if defined(AST_DEVMODE)
  1710. code = response->response_code;
  1711. switch (code) {
  1712. case 0: /* Implementation is still a stub, or the code wasn't set */
  1713. is_valid = response->message == NULL;
  1714. break;
  1715. case 500: /* Internal Server Error */
  1716. case 501: /* Not Implemented */
  1717. case 404: /* Channel not found */
  1718. case 409: /* Channel not in a Stasis application */
  1719. is_valid = 1;
  1720. break;
  1721. default:
  1722. if (200 <= code && code <= 299) {
  1723. is_valid = ast_ari_validate_playback(
  1724. response->message);
  1725. } else {
  1726. ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/play\n", code);
  1727. is_valid = 0;
  1728. }
  1729. }
  1730. if (!is_valid) {
  1731. ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/play\n");
  1732. ast_ari_response_error(response, 500,
  1733. "Internal Server Error", "Response validation failed");
  1734. }
  1735. #endif /* AST_DEVMODE */
  1736. fin: __attribute__((unused))
  1737. return;
  1738. }
  1739. int ast_ari_channels_play_with_id_parse_body(
  1740. struct ast_json *body,
  1741. struct ast_ari_channels_play_with_id_args *args)
  1742. {
  1743. struct ast_json *field;
  1744. /* Parse query parameters out of it */
  1745. field = ast_json_object_get(body, "media");
  1746. if (field) {
  1747. args->media = ast_json_string_get(field);
  1748. }
  1749. field = ast_json_object_get(body, "lang");
  1750. if (field) {
  1751. args->lang = ast_json_string_get(field);
  1752. }
  1753. field = ast_json_object_get(body, "offsetms");
  1754. if (field) {
  1755. args->offsetms = ast_json_integer_get(field);
  1756. }
  1757. field = ast_json_object_get(body, "skipms");
  1758. if (field) {
  1759. args->skipms = ast_json_integer_get(field);
  1760. }
  1761. return 0;
  1762. }
  1763. /*!
  1764. * \brief Parameter parsing callback for /channels/{channelId}/play/{playbackId}.
  1765. * \param get_params GET parameters in the HTTP request.
  1766. * \param path_vars Path variables extracted from the request.
  1767. * \param headers HTTP headers.
  1768. * \param[out] response Response to the HTTP request.
  1769. */
  1770. static void ast_ari_channels_play_with_id_cb(
  1771. struct ast_tcptls_session_instance *ser,
  1772. struct ast_variable *get_params, struct ast_variable *path_vars,
  1773. struct ast_variable *headers, struct ast_ari_response *response)
  1774. {
  1775. struct ast_ari_channels_play_with_id_args args = {};
  1776. struct ast_variable *i;
  1777. RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
  1778. #if defined(AST_DEVMODE)
  1779. int is_valid;
  1780. int code;
  1781. #endif /* AST_DEVMODE */
  1782. for (i = get_params; i; i = i->next) {
  1783. if (strcmp(i->name, "media") == 0) {
  1784. args.media = (i->value);
  1785. } else
  1786. if (strcmp(i->name, "lang") == 0) {
  1787. args.lang = (i->value);
  1788. } else
  1789. if (strcmp(i->name, "offsetms") == 0) {
  1790. args.offsetms = atoi(i->value);
  1791. } else
  1792. if (strcmp(i->name, "skipms") == 0) {
  1793. args.skipms = atoi(i->value);
  1794. } else
  1795. {}
  1796. }
  1797. for (i = path_vars; i; i = i->next) {
  1798. if (strcmp(i->name, "channelId") == 0) {
  1799. args.channel_id = (i->value);
  1800. } else
  1801. if (strcmp(i->name, "playbackId") == 0) {
  1802. args.playback_id = (i->value);
  1803. } else
  1804. {}
  1805. }
  1806. /* Look for a JSON request entity */
  1807. body = ast_http_get_json(ser, headers);
  1808. if (!body) {
  1809. switch (errno) {
  1810. case EFBIG:
  1811. ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
  1812. goto fin;
  1813. case ENOMEM:
  1814. ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
  1815. goto fin;
  1816. case EIO:
  1817. ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
  1818. goto fin;
  1819. }
  1820. }
  1821. if (ast_ari_channels_play_with_id_parse_body(body, &args)) {
  1822. ast_ari_response_alloc_failed(response);
  1823. goto fin;
  1824. }
  1825. ast_ari_channels_play_with_id(headers, &args, response);
  1826. #if defined(AST_DEVMODE)
  1827. code = response->response_code;
  1828. switch (code) {
  1829. case 0: /* Implementation is still a stub, or the code wasn't set */
  1830. is_valid = response->message == NULL;
  1831. break;
  1832. case 500: /* Internal Server Error */
  1833. case 501: /* Not Implemented */
  1834. case 404: /* Channel not found */
  1835. case 409: /* Channel not in a Stasis application */
  1836. is_valid = 1;
  1837. break;
  1838. default:
  1839. if (200 <= code && code <= 299) {
  1840. is_valid = ast_ari_validate_playback(
  1841. response->message);
  1842. } else {
  1843. ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/play/{playbackId}\n", code);
  1844. is_valid = 0;
  1845. }
  1846. }
  1847. if (!is_valid) {
  1848. ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/play/{playbackId}\n");
  1849. ast_ari_response_error(response, 500,
  1850. "Internal Server Error", "Response validation failed");
  1851. }
  1852. #endif /* AST_DEVMODE */
  1853. fin: __attribute__((unused))
  1854. return;
  1855. }
  1856. int ast_ari_channels_record_parse_body(
  1857. struct ast_json *body,
  1858. struct ast_ari_channels_record_args *args)
  1859. {
  1860. struct ast_json *field;
  1861. /* Parse query parameters out of it */
  1862. field = ast_json_object_get(body, "name");
  1863. if (field) {
  1864. args->name = ast_json_string_get(field);
  1865. }
  1866. field = ast_json_object_get(body, "format");
  1867. if (field) {
  1868. args->format = ast_json_string_get(field);
  1869. }
  1870. field = ast_json_object_get(body, "maxDurationSeconds");
  1871. if (field) {
  1872. args->max_duration_seconds = ast_json_integer_get(field);
  1873. }
  1874. field = ast_json_object_get(body, "maxSilenceSeconds");
  1875. if (field) {
  1876. args->max_silence_seconds = ast_json_integer_get(field);
  1877. }
  1878. field = ast_json_object_get(body, "ifExists");
  1879. if (field) {
  1880. args->if_exists = ast_json_string_get(field);
  1881. }
  1882. field = ast_json_object_get(body, "beep");
  1883. if (field) {
  1884. args->beep = ast_json_is_true(field);
  1885. }
  1886. field = ast_json_object_get(body, "terminateOn");
  1887. if (field) {
  1888. args->terminate_on = ast_json_string_get(field);
  1889. }
  1890. return 0;
  1891. }
  1892. /*!
  1893. * \brief Parameter parsing callback for /channels/{channelId}/record.
  1894. * \param get_params GET parameters in the HTTP request.
  1895. * \param path_vars Path variables extracted from the request.
  1896. * \param headers HTTP headers.
  1897. * \param[out] response Response to the HTTP request.
  1898. */
  1899. static void ast_ari_channels_record_cb(
  1900. struct ast_tcptls_session_instance *ser,
  1901. struct ast_variable *get_params, struct ast_variable *path_vars,
  1902. struct ast_variable *headers, struct ast_ari_response *response)
  1903. {
  1904. struct ast_ari_channels_record_args args = {};
  1905. struct ast_variable *i;
  1906. RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
  1907. #if defined(AST_DEVMODE)
  1908. int is_valid;
  1909. int code;
  1910. #endif /* AST_DEVMODE */
  1911. for (i = get_params; i; i = i->next) {
  1912. if (strcmp(i->name, "name") == 0) {
  1913. args.name = (i->value);
  1914. } else
  1915. if (strcmp(i->name, "format") == 0) {
  1916. args.format = (i->value);
  1917. } else
  1918. if (strcmp(i->name, "maxDurationSeconds") == 0) {
  1919. args.max_duration_seconds = atoi(i->value);
  1920. } else
  1921. if (strcmp(i->name, "maxSilenceSeconds") == 0) {
  1922. args.max_silence_seconds = atoi(i->value);
  1923. } else
  1924. if (strcmp(i->name, "ifExists") == 0) {
  1925. args.if_exists = (i->value);
  1926. } else
  1927. if (strcmp(i->name, "beep") == 0) {
  1928. args.beep = ast_true(i->value);
  1929. } else
  1930. if (strcmp(i->name, "terminateOn") == 0) {
  1931. args.terminate_on = (i->value);
  1932. } else
  1933. {}
  1934. }
  1935. for (i = path_vars; i; i = i->next) {
  1936. if (strcmp(i->name, "channelId") == 0) {
  1937. args.channel_id = (i->value);
  1938. } else
  1939. {}
  1940. }
  1941. /* Look for a JSON request entity */
  1942. body = ast_http_get_json(ser, headers);
  1943. if (!body) {
  1944. switch (errno) {
  1945. case EFBIG:
  1946. ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
  1947. goto fin;
  1948. case ENOMEM:
  1949. ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
  1950. goto fin;
  1951. case EIO:
  1952. ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
  1953. goto fin;
  1954. }
  1955. }
  1956. if (ast_ari_channels_record_parse_body(body, &args)) {
  1957. ast_ari_response_alloc_failed(response);
  1958. goto fin;
  1959. }
  1960. ast_ari_channels_record(headers, &args, response);
  1961. #if defined(AST_DEVMODE)
  1962. code = response->response_code;
  1963. switch (code) {
  1964. case 0: /* Implementation is still a stub, or the code wasn't set */
  1965. is_valid = response->message == NULL;
  1966. break;
  1967. case 500: /* Internal Server Error */
  1968. case 501: /* Not Implemented */
  1969. case 400: /* Invalid parameters */
  1970. case 404: /* Channel not found */
  1971. case 409: /* Channel is not in a Stasis application; the channel is currently bridged with other hcannels; A recording with the same name already exists on the system and can not be overwritten because it is in progress or ifExists=fail */
  1972. case 422: /* The format specified is unknown on this system */
  1973. is_valid = 1;
  1974. break;
  1975. default:
  1976. if (200 <= code && code <= 299) {
  1977. is_valid = ast_ari_validate_live_recording(
  1978. response->message);
  1979. } else {
  1980. ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/record\n", code);
  1981. is_valid = 0;
  1982. }
  1983. }
  1984. if (!is_valid) {
  1985. ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/record\n");
  1986. ast_ari_response_error(response, 500,
  1987. "Internal Server Error", "Response validation failed");
  1988. }
  1989. #endif /* AST_DEVMODE */
  1990. fin: __attribute__((unused))
  1991. return;
  1992. }
  1993. int ast_ari_channels_get_channel_var_parse_body(
  1994. struct ast_json *body,
  1995. struct ast_ari_channels_get_channel_var_args *args)
  1996. {
  1997. struct ast_json *field;
  1998. /* Parse query parameters out of it */
  1999. field = ast_json_object_get(body, "variable");
  2000. if (field) {
  2001. args->variable = ast_json_string_get(field);
  2002. }
  2003. return 0;
  2004. }
  2005. /*!
  2006. * \brief Parameter parsing callback for /channels/{channelId}/variable.
  2007. * \param get_params GET parameters in the HTTP request.
  2008. * \param path_vars Path variables extracted from the request.
  2009. * \param headers HTTP headers.
  2010. * \param[out] response Response to the HTTP request.
  2011. */
  2012. static void ast_ari_channels_get_channel_var_cb(
  2013. struct ast_tcptls_session_instance *ser,
  2014. struct ast_variable *get_params, struct ast_variable *path_vars,
  2015. struct ast_variable *headers, struct ast_ari_response *response)
  2016. {
  2017. struct ast_ari_channels_get_channel_var_args args = {};
  2018. struct ast_variable *i;
  2019. RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
  2020. #if defined(AST_DEVMODE)
  2021. int is_valid;
  2022. int code;
  2023. #endif /* AST_DEVMODE */
  2024. for (i = get_params; i; i = i->next) {
  2025. if (strcmp(i->name, "variable") == 0) {
  2026. args.variable = (i->value);
  2027. } else
  2028. {}
  2029. }
  2030. for (i = path_vars; i; i = i->next) {
  2031. if (strcmp(i->name, "channelId") == 0) {
  2032. args.channel_id = (i->value);
  2033. } else
  2034. {}
  2035. }
  2036. /* Look for a JSON request entity */
  2037. body = ast_http_get_json(ser, headers);
  2038. if (!body) {
  2039. switch (errno) {
  2040. case EFBIG:
  2041. ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
  2042. goto fin;
  2043. case ENOMEM:
  2044. ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
  2045. goto fin;
  2046. case EIO:
  2047. ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
  2048. goto fin;
  2049. }
  2050. }
  2051. if (ast_ari_channels_get_channel_var_parse_body(body, &args)) {
  2052. ast_ari_response_alloc_failed(response);
  2053. goto fin;
  2054. }
  2055. ast_ari_channels_get_channel_var(headers, &args, response);
  2056. #if defined(AST_DEVMODE)
  2057. code = response->response_code;
  2058. switch (code) {
  2059. case 0: /* Implementation is still a stub, or the code wasn't set */
  2060. is_valid = response->message == NULL;
  2061. break;
  2062. case 500: /* Internal Server Error */
  2063. case 501: /* Not Implemented */
  2064. case 400: /* Missing variable parameter. */
  2065. case 404: /* Channel or variable not found */
  2066. case 409: /* Channel not in a Stasis application */
  2067. is_valid = 1;
  2068. break;
  2069. default:
  2070. if (200 <= code && code <= 299) {
  2071. is_valid = ast_ari_validate_variable(
  2072. response->message);
  2073. } else {
  2074. ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/variable\n", code);
  2075. is_valid = 0;
  2076. }
  2077. }
  2078. if (!is_valid) {
  2079. ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/variable\n");
  2080. ast_ari_response_error(response, 500,
  2081. "Internal Server Error", "Response validation failed");
  2082. }
  2083. #endif /* AST_DEVMODE */
  2084. fin: __attribute__((unused))
  2085. return;
  2086. }
  2087. int ast_ari_channels_set_channel_var_parse_body(
  2088. struct ast_json *body,
  2089. struct ast_ari_channels_set_channel_var_args *args)
  2090. {
  2091. struct ast_json *field;
  2092. /* Parse query parameters out of it */
  2093. field = ast_json_object_get(body, "variable");
  2094. if (field) {
  2095. args->variable = ast_json_string_get(field);
  2096. }
  2097. field = ast_json_object_get(body, "value");
  2098. if (field) {
  2099. args->value = ast_json_string_get(field);
  2100. }
  2101. return 0;
  2102. }
  2103. /*!
  2104. * \brief Parameter parsing callback for /channels/{channelId}/variable.
  2105. * \param get_params GET parameters in the HTTP request.
  2106. * \param path_vars Path variables extracted from the request.
  2107. * \param headers HTTP headers.
  2108. * \param[out] response Response to the HTTP request.
  2109. */
  2110. static void ast_ari_channels_set_channel_var_cb(
  2111. struct ast_tcptls_session_instance *ser,
  2112. struct ast_variable *get_params, struct ast_variable *path_vars,
  2113. struct ast_variable *headers, struct ast_ari_response *response)
  2114. {
  2115. struct ast_ari_channels_set_channel_var_args args = {};
  2116. struct ast_variable *i;
  2117. RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
  2118. #if defined(AST_DEVMODE)
  2119. int is_valid;
  2120. int code;
  2121. #endif /* AST_DEVMODE */
  2122. for (i = get_params; i; i = i->next) {
  2123. if (strcmp(i->name, "variable") == 0) {
  2124. args.variable = (i->value);
  2125. } else
  2126. if (strcmp(i->name, "value") == 0) {
  2127. args.value = (i->value);
  2128. } else
  2129. {}
  2130. }
  2131. for (i = path_vars; i; i = i->next) {
  2132. if (strcmp(i->name, "channelId") == 0) {
  2133. args.channel_id = (i->value);
  2134. } else
  2135. {}
  2136. }
  2137. /* Look for a JSON request entity */
  2138. body = ast_http_get_json(ser, headers);
  2139. if (!body) {
  2140. switch (errno) {
  2141. case EFBIG:
  2142. ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
  2143. goto fin;
  2144. case ENOMEM:
  2145. ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
  2146. goto fin;
  2147. case EIO:
  2148. ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
  2149. goto fin;
  2150. }
  2151. }
  2152. if (ast_ari_channels_set_channel_var_parse_body(body, &args)) {
  2153. ast_ari_response_alloc_failed(response);
  2154. goto fin;
  2155. }
  2156. ast_ari_channels_set_channel_var(headers, &args, response);
  2157. #if defined(AST_DEVMODE)
  2158. code = response->response_code;
  2159. switch (code) {
  2160. case 0: /* Implementation is still a stub, or the code wasn't set */
  2161. is_valid = response->message == NULL;
  2162. break;
  2163. case 500: /* Internal Server Error */
  2164. case 501: /* Not Implemented */
  2165. case 400: /* Missing variable parameter. */
  2166. case 404: /* Channel not found */
  2167. case 409: /* Channel not in a Stasis application */
  2168. is_valid = 1;
  2169. break;
  2170. default:
  2171. if (200 <= code && code <= 299) {
  2172. is_valid = ast_ari_validate_void(
  2173. response->message);
  2174. } else {
  2175. ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/variable\n", code);
  2176. is_valid = 0;
  2177. }
  2178. }
  2179. if (!is_valid) {
  2180. ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/variable\n");
  2181. ast_ari_response_error(response, 500,
  2182. "Internal Server Error", "Response validation failed");
  2183. }
  2184. #endif /* AST_DEVMODE */
  2185. fin: __attribute__((unused))
  2186. return;
  2187. }
  2188. int ast_ari_channels_snoop_channel_parse_body(
  2189. struct ast_json *body,
  2190. struct ast_ari_channels_snoop_channel_args *args)
  2191. {
  2192. struct ast_json *field;
  2193. /* Parse query parameters out of it */
  2194. field = ast_json_object_get(body, "spy");
  2195. if (field) {
  2196. args->spy = ast_json_string_get(field);
  2197. }
  2198. field = ast_json_object_get(body, "whisper");
  2199. if (field) {
  2200. args->whisper = ast_json_string_get(field);
  2201. }
  2202. field = ast_json_object_get(body, "app");
  2203. if (field) {
  2204. args->app = ast_json_string_get(field);
  2205. }
  2206. field = ast_json_object_get(body, "appArgs");
  2207. if (field) {
  2208. args->app_args = ast_json_string_get(field);
  2209. }
  2210. field = ast_json_object_get(body, "snoopId");
  2211. if (field) {
  2212. args->snoop_id = ast_json_string_get(field);
  2213. }
  2214. return 0;
  2215. }
  2216. /*!
  2217. * \brief Parameter parsing callback for /channels/{channelId}/snoop.
  2218. * \param get_params GET parameters in the HTTP request.
  2219. * \param path_vars Path variables extracted from the request.
  2220. * \param headers HTTP headers.
  2221. * \param[out] response Response to the HTTP request.
  2222. */
  2223. static void ast_ari_channels_snoop_channel_cb(
  2224. struct ast_tcptls_session_instance *ser,
  2225. struct ast_variable *get_params, struct ast_variable *path_vars,
  2226. struct ast_variable *headers, struct ast_ari_response *response)
  2227. {
  2228. struct ast_ari_channels_snoop_channel_args args = {};
  2229. struct ast_variable *i;
  2230. RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
  2231. #if defined(AST_DEVMODE)
  2232. int is_valid;
  2233. int code;
  2234. #endif /* AST_DEVMODE */
  2235. for (i = get_params; i; i = i->next) {
  2236. if (strcmp(i->name, "spy") == 0) {
  2237. args.spy = (i->value);
  2238. } else
  2239. if (strcmp(i->name, "whisper") == 0) {
  2240. args.whisper = (i->value);
  2241. } else
  2242. if (strcmp(i->name, "app") == 0) {
  2243. args.app = (i->value);
  2244. } else
  2245. if (strcmp(i->name, "appArgs") == 0) {
  2246. args.app_args = (i->value);
  2247. } else
  2248. if (strcmp(i->name, "snoopId") == 0) {
  2249. args.snoop_id = (i->value);
  2250. } else
  2251. {}
  2252. }
  2253. for (i = path_vars; i; i = i->next) {
  2254. if (strcmp(i->name, "channelId") == 0) {
  2255. args.channel_id = (i->value);
  2256. } else
  2257. {}
  2258. }
  2259. /* Look for a JSON request entity */
  2260. body = ast_http_get_json(ser, headers);
  2261. if (!body) {
  2262. switch (errno) {
  2263. case EFBIG:
  2264. ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
  2265. goto fin;
  2266. case ENOMEM:
  2267. ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
  2268. goto fin;
  2269. case EIO:
  2270. ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
  2271. goto fin;
  2272. }
  2273. }
  2274. if (ast_ari_channels_snoop_channel_parse_body(body, &args)) {
  2275. ast_ari_response_alloc_failed(response);
  2276. goto fin;
  2277. }
  2278. ast_ari_channels_snoop_channel(headers, &args, response);
  2279. #if defined(AST_DEVMODE)
  2280. code = response->response_code;
  2281. switch (code) {
  2282. case 0: /* Implementation is still a stub, or the code wasn't set */
  2283. is_valid = response->message == NULL;
  2284. break;
  2285. case 500: /* Internal Server Error */
  2286. case 501: /* Not Implemented */
  2287. case 400: /* Invalid parameters */
  2288. case 404: /* Channel not found */
  2289. is_valid = 1;
  2290. break;
  2291. default:
  2292. if (200 <= code && code <= 299) {
  2293. is_valid = ast_ari_validate_channel(
  2294. response->message);
  2295. } else {
  2296. ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/snoop\n", code);
  2297. is_valid = 0;
  2298. }
  2299. }
  2300. if (!is_valid) {
  2301. ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/snoop\n");
  2302. ast_ari_response_error(response, 500,
  2303. "Internal Server Error", "Response validation failed");
  2304. }
  2305. #endif /* AST_DEVMODE */
  2306. fin: __attribute__((unused))
  2307. return;
  2308. }
  2309. int ast_ari_channels_snoop_channel_with_id_parse_body(
  2310. struct ast_json *body,
  2311. struct ast_ari_channels_snoop_channel_with_id_args *args)
  2312. {
  2313. struct ast_json *field;
  2314. /* Parse query parameters out of it */
  2315. field = ast_json_object_get(body, "spy");
  2316. if (field) {
  2317. args->spy = ast_json_string_get(field);
  2318. }
  2319. field = ast_json_object_get(body, "whisper");
  2320. if (field) {
  2321. args->whisper = ast_json_string_get(field);
  2322. }
  2323. field = ast_json_object_get(body, "app");
  2324. if (field) {
  2325. args->app = ast_json_string_get(field);
  2326. }
  2327. field = ast_json_object_get(body, "appArgs");
  2328. if (field) {
  2329. args->app_args = ast_json_string_get(field);
  2330. }
  2331. return 0;
  2332. }
  2333. /*!
  2334. * \brief Parameter parsing callback for /channels/{channelId}/snoop/{snoopId}.
  2335. * \param get_params GET parameters in the HTTP request.
  2336. * \param path_vars Path variables extracted from the request.
  2337. * \param headers HTTP headers.
  2338. * \param[out] response Response to the HTTP request.
  2339. */
  2340. static void ast_ari_channels_snoop_channel_with_id_cb(
  2341. struct ast_tcptls_session_instance *ser,
  2342. struct ast_variable *get_params, struct ast_variable *path_vars,
  2343. struct ast_variable *headers, struct ast_ari_response *response)
  2344. {
  2345. struct ast_ari_channels_snoop_channel_with_id_args args = {};
  2346. struct ast_variable *i;
  2347. RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
  2348. #if defined(AST_DEVMODE)
  2349. int is_valid;
  2350. int code;
  2351. #endif /* AST_DEVMODE */
  2352. for (i = get_params; i; i = i->next) {
  2353. if (strcmp(i->name, "spy") == 0) {
  2354. args.spy = (i->value);
  2355. } else
  2356. if (strcmp(i->name, "whisper") == 0) {
  2357. args.whisper = (i->value);
  2358. } else
  2359. if (strcmp(i->name, "app") == 0) {
  2360. args.app = (i->value);
  2361. } else
  2362. if (strcmp(i->name, "appArgs") == 0) {
  2363. args.app_args = (i->value);
  2364. } else
  2365. {}
  2366. }
  2367. for (i = path_vars; i; i = i->next) {
  2368. if (strcmp(i->name, "channelId") == 0) {
  2369. args.channel_id = (i->value);
  2370. } else
  2371. if (strcmp(i->name, "snoopId") == 0) {
  2372. args.snoop_id = (i->value);
  2373. } else
  2374. {}
  2375. }
  2376. /* Look for a JSON request entity */
  2377. body = ast_http_get_json(ser, headers);
  2378. if (!body) {
  2379. switch (errno) {
  2380. case EFBIG:
  2381. ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
  2382. goto fin;
  2383. case ENOMEM:
  2384. ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
  2385. goto fin;
  2386. case EIO:
  2387. ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
  2388. goto fin;
  2389. }
  2390. }
  2391. if (ast_ari_channels_snoop_channel_with_id_parse_body(body, &args)) {
  2392. ast_ari_response_alloc_failed(response);
  2393. goto fin;
  2394. }
  2395. ast_ari_channels_snoop_channel_with_id(headers, &args, response);
  2396. #if defined(AST_DEVMODE)
  2397. code = response->response_code;
  2398. switch (code) {
  2399. case 0: /* Implementation is still a stub, or the code wasn't set */
  2400. is_valid = response->message == NULL;
  2401. break;
  2402. case 500: /* Internal Server Error */
  2403. case 501: /* Not Implemented */
  2404. case 400: /* Invalid parameters */
  2405. case 404: /* Channel not found */
  2406. is_valid = 1;
  2407. break;
  2408. default:
  2409. if (200 <= code && code <= 299) {
  2410. is_valid = ast_ari_validate_channel(
  2411. response->message);
  2412. } else {
  2413. ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/snoop/{snoopId}\n", code);
  2414. is_valid = 0;
  2415. }
  2416. }
  2417. if (!is_valid) {
  2418. ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/snoop/{snoopId}\n");
  2419. ast_ari_response_error(response, 500,
  2420. "Internal Server Error", "Response validation failed");
  2421. }
  2422. #endif /* AST_DEVMODE */
  2423. fin: __attribute__((unused))
  2424. return;
  2425. }
  2426. /*! \brief REST handler for /api-docs/channels.{format} */
  2427. static struct stasis_rest_handlers channels_channelId_continue = {
  2428. .path_segment = "continue",
  2429. .callbacks = {
  2430. [AST_HTTP_POST] = ast_ari_channels_continue_in_dialplan_cb,
  2431. },
  2432. .num_children = 0,
  2433. .children = { }
  2434. };
  2435. /*! \brief REST handler for /api-docs/channels.{format} */
  2436. static struct stasis_rest_handlers channels_channelId_redirect = {
  2437. .path_segment = "redirect",
  2438. .callbacks = {
  2439. [AST_HTTP_POST] = ast_ari_channels_redirect_cb,
  2440. },
  2441. .num_children = 0,
  2442. .children = { }
  2443. };
  2444. /*! \brief REST handler for /api-docs/channels.{format} */
  2445. static struct stasis_rest_handlers channels_channelId_answer = {
  2446. .path_segment = "answer",
  2447. .callbacks = {
  2448. [AST_HTTP_POST] = ast_ari_channels_answer_cb,
  2449. },
  2450. .num_children = 0,
  2451. .children = { }
  2452. };
  2453. /*! \brief REST handler for /api-docs/channels.{format} */
  2454. static struct stasis_rest_handlers channels_channelId_ring = {
  2455. .path_segment = "ring",
  2456. .callbacks = {
  2457. [AST_HTTP_POST] = ast_ari_channels_ring_cb,
  2458. [AST_HTTP_DELETE] = ast_ari_channels_ring_stop_cb,
  2459. },
  2460. .num_children = 0,
  2461. .children = { }
  2462. };
  2463. /*! \brief REST handler for /api-docs/channels.{format} */
  2464. static struct stasis_rest_handlers channels_channelId_dtmf = {
  2465. .path_segment = "dtmf",
  2466. .callbacks = {
  2467. [AST_HTTP_POST] = ast_ari_channels_send_dtmf_cb,
  2468. },
  2469. .num_children = 0,
  2470. .children = { }
  2471. };
  2472. /*! \brief REST handler for /api-docs/channels.{format} */
  2473. static struct stasis_rest_handlers channels_channelId_mute = {
  2474. .path_segment = "mute",
  2475. .callbacks = {
  2476. [AST_HTTP_POST] = ast_ari_channels_mute_cb,
  2477. [AST_HTTP_DELETE] = ast_ari_channels_unmute_cb,
  2478. },
  2479. .num_children = 0,
  2480. .children = { }
  2481. };
  2482. /*! \brief REST handler for /api-docs/channels.{format} */
  2483. static struct stasis_rest_handlers channels_channelId_hold = {
  2484. .path_segment = "hold",
  2485. .callbacks = {
  2486. [AST_HTTP_POST] = ast_ari_channels_hold_cb,
  2487. [AST_HTTP_DELETE] = ast_ari_channels_unhold_cb,
  2488. },
  2489. .num_children = 0,
  2490. .children = { }
  2491. };
  2492. /*! \brief REST handler for /api-docs/channels.{format} */
  2493. static struct stasis_rest_handlers channels_channelId_moh = {
  2494. .path_segment = "moh",
  2495. .callbacks = {
  2496. [AST_HTTP_POST] = ast_ari_channels_start_moh_cb,
  2497. [AST_HTTP_DELETE] = ast_ari_channels_stop_moh_cb,
  2498. },
  2499. .num_children = 0,
  2500. .children = { }
  2501. };
  2502. /*! \brief REST handler for /api-docs/channels.{format} */
  2503. static struct stasis_rest_handlers channels_channelId_silence = {
  2504. .path_segment = "silence",
  2505. .callbacks = {
  2506. [AST_HTTP_POST] = ast_ari_channels_start_silence_cb,
  2507. [AST_HTTP_DELETE] = ast_ari_channels_stop_silence_cb,
  2508. },
  2509. .num_children = 0,
  2510. .children = { }
  2511. };
  2512. /*! \brief REST handler for /api-docs/channels.{format} */
  2513. static struct stasis_rest_handlers channels_channelId_play_playbackId = {
  2514. .path_segment = "playbackId",
  2515. .is_wildcard = 1,
  2516. .callbacks = {
  2517. [AST_HTTP_POST] = ast_ari_channels_play_with_id_cb,
  2518. },
  2519. .num_children = 0,
  2520. .children = { }
  2521. };
  2522. /*! \brief REST handler for /api-docs/channels.{format} */
  2523. static struct stasis_rest_handlers channels_channelId_play = {
  2524. .path_segment = "play",
  2525. .callbacks = {
  2526. [AST_HTTP_POST] = ast_ari_channels_play_cb,
  2527. },
  2528. .num_children = 1,
  2529. .children = { &channels_channelId_play_playbackId, }
  2530. };
  2531. /*! \brief REST handler for /api-docs/channels.{format} */
  2532. static struct stasis_rest_handlers channels_channelId_record = {
  2533. .path_segment = "record",
  2534. .callbacks = {
  2535. [AST_HTTP_POST] = ast_ari_channels_record_cb,
  2536. },
  2537. .num_children = 0,
  2538. .children = { }
  2539. };
  2540. /*! \brief REST handler for /api-docs/channels.{format} */
  2541. static struct stasis_rest_handlers channels_channelId_variable = {
  2542. .path_segment = "variable",
  2543. .callbacks = {
  2544. [AST_HTTP_GET] = ast_ari_channels_get_channel_var_cb,
  2545. [AST_HTTP_POST] = ast_ari_channels_set_channel_var_cb,
  2546. },
  2547. .num_children = 0,
  2548. .children = { }
  2549. };
  2550. /*! \brief REST handler for /api-docs/channels.{format} */
  2551. static struct stasis_rest_handlers channels_channelId_snoop_snoopId = {
  2552. .path_segment = "snoopId",
  2553. .is_wildcard = 1,
  2554. .callbacks = {
  2555. [AST_HTTP_POST] = ast_ari_channels_snoop_channel_with_id_cb,
  2556. },
  2557. .num_children = 0,
  2558. .children = { }
  2559. };
  2560. /*! \brief REST handler for /api-docs/channels.{format} */
  2561. static struct stasis_rest_handlers channels_channelId_snoop = {
  2562. .path_segment = "snoop",
  2563. .callbacks = {
  2564. [AST_HTTP_POST] = ast_ari_channels_snoop_channel_cb,
  2565. },
  2566. .num_children = 1,
  2567. .children = { &channels_channelId_snoop_snoopId, }
  2568. };
  2569. /*! \brief REST handler for /api-docs/channels.{format} */
  2570. static struct stasis_rest_handlers channels_channelId = {
  2571. .path_segment = "channelId",
  2572. .is_wildcard = 1,
  2573. .callbacks = {
  2574. [AST_HTTP_GET] = ast_ari_channels_get_cb,
  2575. [AST_HTTP_POST] = ast_ari_channels_originate_with_id_cb,
  2576. [AST_HTTP_DELETE] = ast_ari_channels_hangup_cb,
  2577. },
  2578. .num_children = 13,
  2579. .children = { &channels_channelId_continue,&channels_channelId_redirect,&channels_channelId_answer,&channels_channelId_ring,&channels_channelId_dtmf,&channels_channelId_mute,&channels_channelId_hold,&channels_channelId_moh,&channels_channelId_silence,&channels_channelId_play,&channels_channelId_record,&channels_channelId_variable,&channels_channelId_snoop, }
  2580. };
  2581. /*! \brief REST handler for /api-docs/channels.{format} */
  2582. static struct stasis_rest_handlers channels = {
  2583. .path_segment = "channels",
  2584. .callbacks = {
  2585. [AST_HTTP_GET] = ast_ari_channels_list_cb,
  2586. [AST_HTTP_POST] = ast_ari_channels_originate_cb,
  2587. },
  2588. .num_children = 1,
  2589. .children = { &channels_channelId, }
  2590. };
  2591. static int load_module(void)
  2592. {
  2593. int res = 0;
  2594. stasis_app_ref();
  2595. res |= ast_ari_add_handler(&channels);
  2596. return res;
  2597. }
  2598. static int unload_module(void)
  2599. {
  2600. ast_ari_remove_handler(&channels);
  2601. stasis_app_unref();
  2602. return 0;
  2603. }
  2604. AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - Channel resources",
  2605. .support_level = AST_MODULE_SUPPORT_CORE,
  2606. .load = load_module,
  2607. .unload = unload_module,
  2608. .nonoptreq = "res_ari,res_stasis",
  2609. );