From 1590d32ab0a5b6797c96244a47f18f868574e970 Mon Sep 17 00:00:00 2001 From: Kinsey Moore <kmoore@digium.com> Date: Tue, 21 Jan 2014 14:27:21 +0000 Subject: [PATCH] ARI: Support channel variables in originate This adds back in support for specifying channel variables during an originate without compromising the ability to specify query parameters in the JSON body. This was accomplished by generating the body-parsing code in a separate function instead of being integrated with the URI query parameter parsing code such that it could be called by paths with body parameters. This is transparent to the user of the API and prevents manual duplication of code or data structures. (closes issue ASTERISK-23051) Review: https://reviewboard.asterisk.org/r/3122/ Reported by: Matt Jordan ........ Merged revisions 406003 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@406006 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- res/ari/resource_applications.h | 22 + res/ari/resource_asterisk.h | 33 ++ res/ari/resource_bridges.h | 66 +++ res/ari/resource_channels.c | 49 ++ res/ari/resource_channels.h | 134 +++++ res/ari/resource_device_states.h | 11 + res/ari/resource_mailboxes.h | 11 + res/ari/resource_playbacks.h | 11 + res/ari/resource_sounds.h | 11 + res/res_ari_applications.c | 146 +++--- res/res_ari_asterisk.c | 123 +++-- res/res_ari_bridges.c | 318 +++++++----- res/res_ari_channels.c | 459 +++++++++++------- res/res_ari_device_states.c | 21 +- res/res_ari_mailboxes.c | 29 +- res/res_ari_playbacks.c | 21 +- res/res_ari_sounds.c | 29 +- rest-api-templates/ari_resource.h.mustache | 13 + rest-api-templates/asterisk_processor.py | 2 + rest-api-templates/body_parsing.mustache | 71 +++ rest-api-templates/param_parsing.mustache | 41 +- .../res_ari_resource.c.mustache | 6 +- rest-api/api-docs/channels.json | 8 + 23 files changed, 1161 insertions(+), 474 deletions(-) create mode 100644 rest-api-templates/body_parsing.mustache diff --git a/res/ari/resource_applications.h b/res/ari/resource_applications.h index a4d12c9c07..3e57ad7164 100644 --- a/res/ari/resource_applications.h +++ b/res/ari/resource_applications.h @@ -74,6 +74,17 @@ struct ast_ari_applications_subscribe_args { /*! \brief Parsing context for event_source. */ char *event_source_parse; }; +/*! + * \brief Body parsing function for /applications/{applicationName}/subscription. + * \param body The JSON body from which to parse parameters. + * \param[out] args The args structure to parse into. + * \retval zero on success + * \retval non-zero on failure + */ +int ast_ari_applications_subscribe_parse_body( + struct ast_json *body, + struct ast_ari_applications_subscribe_args *args); + /*! * \brief Subscribe an application to a event source. * @@ -95,6 +106,17 @@ struct ast_ari_applications_unsubscribe_args { /*! \brief Parsing context for event_source. */ char *event_source_parse; }; +/*! + * \brief Body parsing function for /applications/{applicationName}/subscription. + * \param body The JSON body from which to parse parameters. + * \param[out] args The args structure to parse into. + * \retval zero on success + * \retval non-zero on failure + */ +int ast_ari_applications_unsubscribe_parse_body( + struct ast_json *body, + struct ast_ari_applications_unsubscribe_args *args); + /*! * \brief Unsubscribe an application from an event source. * diff --git a/res/ari/resource_asterisk.h b/res/ari/resource_asterisk.h index aff89c4454..93e161d3fc 100644 --- a/res/ari/resource_asterisk.h +++ b/res/ari/resource_asterisk.h @@ -48,6 +48,17 @@ struct ast_ari_asterisk_get_info_args { /*! \brief Parsing context for only. */ char *only_parse; }; +/*! + * \brief Body parsing function for /asterisk/info. + * \param body The JSON body from which to parse parameters. + * \param[out] args The args structure to parse into. + * \retval zero on success + * \retval non-zero on failure + */ +int ast_ari_asterisk_get_info_parse_body( + struct ast_json *body, + struct ast_ari_asterisk_get_info_args *args); + /*! * \brief Gets Asterisk system information. * @@ -61,6 +72,17 @@ struct ast_ari_asterisk_get_global_var_args { /*! \brief The variable to get */ const char *variable; }; +/*! + * \brief Body parsing function for /asterisk/variable. + * \param body The JSON body from which to parse parameters. + * \param[out] args The args structure to parse into. + * \retval zero on success + * \retval non-zero on failure + */ +int ast_ari_asterisk_get_global_var_parse_body( + struct ast_json *body, + struct ast_ari_asterisk_get_global_var_args *args); + /*! * \brief Get the value of a global variable. * @@ -76,6 +98,17 @@ struct ast_ari_asterisk_set_global_var_args { /*! \brief The value to set the variable to */ const char *value; }; +/*! + * \brief Body parsing function for /asterisk/variable. + * \param body The JSON body from which to parse parameters. + * \param[out] args The args structure to parse into. + * \retval zero on success + * \retval non-zero on failure + */ +int ast_ari_asterisk_set_global_var_parse_body( + struct ast_json *body, + struct ast_ari_asterisk_set_global_var_args *args); + /*! * \brief Set the value of a global variable. * diff --git a/res/ari/resource_bridges.h b/res/ari/resource_bridges.h index a7ccd31201..38ccb294bf 100644 --- a/res/ari/resource_bridges.h +++ b/res/ari/resource_bridges.h @@ -57,6 +57,17 @@ struct ast_ari_bridges_create_args { /*! \brief Name to give to the bridge being created. */ const char *name; }; +/*! + * \brief Body parsing function for /bridges. + * \param body The JSON body from which to parse parameters. + * \param[out] args The args structure to parse into. + * \retval zero on success + * \retval non-zero on failure + */ +int ast_ari_bridges_create_parse_body( + struct ast_json *body, + struct ast_ari_bridges_create_args *args); + /*! * \brief Create a new bridge. * @@ -108,6 +119,17 @@ struct ast_ari_bridges_add_channel_args { /*! \brief Channel's role in the bridge */ const char *role; }; +/*! + * \brief Body parsing function for /bridges/{bridgeId}/addChannel. + * \param body The JSON body from which to parse parameters. + * \param[out] args The args structure to parse into. + * \retval zero on success + * \retval non-zero on failure + */ +int ast_ari_bridges_add_channel_parse_body( + struct ast_json *body, + struct ast_ari_bridges_add_channel_args *args); + /*! * \brief Add a channel to a bridge. * @@ -127,6 +149,17 @@ struct ast_ari_bridges_remove_channel_args { /*! \brief Parsing context for channel. */ char *channel_parse; }; +/*! + * \brief Body parsing function for /bridges/{bridgeId}/removeChannel. + * \param body The JSON body from which to parse parameters. + * \param[out] args The args structure to parse into. + * \retval zero on success + * \retval non-zero on failure + */ +int ast_ari_bridges_remove_channel_parse_body( + struct ast_json *body, + struct ast_ari_bridges_remove_channel_args *args); + /*! * \brief Remove a channel from a bridge. * @@ -142,6 +175,17 @@ struct ast_ari_bridges_start_moh_args { /*! \brief Channel's id */ const char *moh_class; }; +/*! + * \brief Body parsing function for /bridges/{bridgeId}/moh. + * \param body The JSON body from which to parse parameters. + * \param[out] args The args structure to parse into. + * \retval zero on success + * \retval non-zero on failure + */ +int ast_ari_bridges_start_moh_parse_body( + struct ast_json *body, + struct ast_ari_bridges_start_moh_args *args); + /*! * \brief Play music on hold to a bridge or change the MOH class that is playing. * @@ -178,6 +222,17 @@ struct ast_ari_bridges_play_args { /*! \brief Number of milliseconds to skip for forward/reverse operations. */ int skipms; }; +/*! + * \brief Body parsing function for /bridges/{bridgeId}/play. + * \param body The JSON body from which to parse parameters. + * \param[out] args The args structure to parse into. + * \retval zero on success + * \retval non-zero on failure + */ +int ast_ari_bridges_play_parse_body( + struct ast_json *body, + struct ast_ari_bridges_play_args *args); + /*! * \brief Start playback of media on a bridge. * @@ -207,6 +262,17 @@ struct ast_ari_bridges_record_args { /*! \brief DTMF input to terminate recording. */ const char *terminate_on; }; +/*! + * \brief Body parsing function for /bridges/{bridgeId}/record. + * \param body The JSON body from which to parse parameters. + * \param[out] args The args structure to parse into. + * \retval zero on success + * \retval non-zero on failure + */ +int ast_ari_bridges_record_parse_body( + struct ast_json *body, + struct ast_ari_bridges_record_args *args); + /*! * \brief Start a recording. * diff --git a/res/ari/resource_channels.c b/res/ari/resource_channels.c index e6322a37c8..ab8f5b42b0 100644 --- a/res/ari/resource_channels.c +++ b/res/ari/resource_channels.c @@ -687,6 +687,43 @@ void ast_ari_channels_list(struct ast_variable *headers, ast_ari_response_ok(response, ast_json_ref(json)); } +static int ari_channels_set_channel_var(struct ast_channel *chan, + const char *variable, const char *value, struct ast_ari_response *response) +{ + if (pbx_builtin_setvar_helper(chan, variable, value)) { + ast_ari_response_error( + response, 400, "Bad Request", + "Unable to set channel variable %s=%s", variable, value); + return -1; + } + + return 0; +} + +static int ari_channels_set_channel_vars(struct ast_channel *chan, + struct ast_json *variables, struct ast_ari_response *response) +{ + struct ast_json_iter *i; + + if (!variables) { + /* nothing to do */ + return 0; + } + + for (i = ast_json_object_iter(variables); i; + i = ast_json_object_iter_next(variables, i)) { + if (ari_channels_set_channel_var( + chan, ast_json_object_iter_key(i), + ast_json_string_get(ast_json_object_iter_value(i)), + response)) { + /* response filled in by called function */ + return -1; + } + } + + return 0; +} + void ast_ari_channels_originate(struct ast_variable *headers, struct ast_ari_channels_originate_args *args, struct ast_ari_response *response) @@ -704,6 +741,7 @@ void ast_ari_channels_originate(struct ast_variable *headers, char *stuff; struct ast_channel *chan; RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup); + struct ast_json *variable_list = NULL; if (!cap) { ast_ari_response_alloc_failed(response); @@ -711,6 +749,12 @@ void ast_ari_channels_originate(struct ast_variable *headers, } ast_format_cap_add(cap, ast_format_set(&tmp_fmt, AST_FORMAT_SLINEAR, 0)); + /* Parse any query parameters out of the body parameter */ + if (args->variables) { + ast_ari_channels_originate_parse_body(args->variables, args); + variable_list = ast_json_object_get(args->variables, "variables"); + } + if (ast_strlen_zero(args->endpoint)) { ast_ari_response_error(response, 400, "Bad Request", "Endpoint must be specified"); @@ -776,6 +820,11 @@ void ast_ari_channels_originate(struct ast_variable *headers, return; } + if (ari_channels_set_channel_vars(chan, variable_list, response)) { + /* response filled in by called function */ + return; + } + snapshot = ast_channel_snapshot_create(chan); ast_channel_unlock(chan); diff --git a/res/ari/resource_channels.h b/res/ari/resource_channels.h index 49ab8eb342..7f740a67c5 100644 --- a/res/ari/resource_channels.h +++ b/res/ari/resource_channels.h @@ -68,7 +68,20 @@ struct ast_ari_channels_originate_args { const char *caller_id; /*! \brief Timeout (in seconds) before giving up dialing, or -1 for no timeout. */ int timeout; + /*! \brief The 'variables' key in the body object holds variable key/value pairs to set on the channel on creation. Other keys in the body object are interpreted as query parameters. Ex. { 'endpoint': 'SIP/Alice', 'variables': { 'CALLERID(name)': 'Alice' } } */ + struct ast_json *variables; }; +/*! + * \brief Body parsing function for /channels. + * \param body The JSON body from which to parse parameters. + * \param[out] args The args structure to parse into. + * \retval zero on success + * \retval non-zero on failure + */ +int ast_ari_channels_originate_parse_body( + struct ast_json *body, + struct ast_ari_channels_originate_args *args); + /*! * \brief Create a new channel (originate). * @@ -99,6 +112,17 @@ struct ast_ari_channels_hangup_args { /*! \brief Reason for hanging up the channel */ const char *reason; }; +/*! + * \brief Body parsing function for /channels/{channelId}. + * \param body The JSON body from which to parse parameters. + * \param[out] args The args structure to parse into. + * \retval zero on success + * \retval non-zero on failure + */ +int ast_ari_channels_hangup_parse_body( + struct ast_json *body, + struct ast_ari_channels_hangup_args *args); + /*! * \brief Delete (i.e. hangup) a channel. * @@ -118,6 +142,17 @@ struct ast_ari_channels_continue_in_dialplan_args { /*! \brief The priority to continue to. */ int priority; }; +/*! + * \brief Body parsing function for /channels/{channelId}/continue. + * \param body The JSON body from which to parse parameters. + * \param[out] args The args structure to parse into. + * \retval zero on success + * \retval non-zero on failure + */ +int ast_ari_channels_continue_in_dialplan_parse_body( + struct ast_json *body, + struct ast_ari_channels_continue_in_dialplan_args *args); + /*! * \brief Exit application; continue execution in the dialplan. * @@ -180,6 +215,17 @@ struct ast_ari_channels_send_dtmf_args { /*! \brief Amount of time to wait after DTMF digits (specified in milliseconds) end. */ int after; }; +/*! + * \brief Body parsing function for /channels/{channelId}/dtmf. + * \param body The JSON body from which to parse parameters. + * \param[out] args The args structure to parse into. + * \retval zero on success + * \retval non-zero on failure + */ +int ast_ari_channels_send_dtmf_parse_body( + struct ast_json *body, + struct ast_ari_channels_send_dtmf_args *args); + /*! * \brief Send provided DTMF to a given channel. * @@ -195,6 +241,17 @@ struct ast_ari_channels_mute_args { /*! \brief Direction in which to mute audio */ const char *direction; }; +/*! + * \brief Body parsing function for /channels/{channelId}/mute. + * \param body The JSON body from which to parse parameters. + * \param[out] args The args structure to parse into. + * \retval zero on success + * \retval non-zero on failure + */ +int ast_ari_channels_mute_parse_body( + struct ast_json *body, + struct ast_ari_channels_mute_args *args); + /*! * \brief Mute a channel. * @@ -210,6 +267,17 @@ struct ast_ari_channels_unmute_args { /*! \brief Direction in which to unmute audio */ const char *direction; }; +/*! + * \brief Body parsing function for /channels/{channelId}/mute. + * \param body The JSON body from which to parse parameters. + * \param[out] args The args structure to parse into. + * \retval zero on success + * \retval non-zero on failure + */ +int ast_ari_channels_unmute_parse_body( + struct ast_json *body, + struct ast_ari_channels_unmute_args *args); + /*! * \brief Unmute a channel. * @@ -251,6 +319,17 @@ struct ast_ari_channels_start_moh_args { /*! \brief Music on hold class to use */ const char *moh_class; }; +/*! + * \brief Body parsing function for /channels/{channelId}/moh. + * \param body The JSON body from which to parse parameters. + * \param[out] args The args structure to parse into. + * \retval zero on success + * \retval non-zero on failure + */ +int ast_ari_channels_start_moh_parse_body( + struct ast_json *body, + struct ast_ari_channels_start_moh_args *args); + /*! * \brief Play music on hold to a channel. * @@ -315,6 +394,17 @@ struct ast_ari_channels_play_args { /*! \brief Number of milliseconds to skip for forward/reverse operations. */ int skipms; }; +/*! + * \brief Body parsing function for /channels/{channelId}/play. + * \param body The JSON body from which to parse parameters. + * \param[out] args The args structure to parse into. + * \retval zero on success + * \retval non-zero on failure + */ +int ast_ari_channels_play_parse_body( + struct ast_json *body, + struct ast_ari_channels_play_args *args); + /*! * \brief Start playback of media. * @@ -344,6 +434,17 @@ struct ast_ari_channels_record_args { /*! \brief DTMF input to terminate recording */ const char *terminate_on; }; +/*! + * \brief Body parsing function for /channels/{channelId}/record. + * \param body The JSON body from which to parse parameters. + * \param[out] args The args structure to parse into. + * \retval zero on success + * \retval non-zero on failure + */ +int ast_ari_channels_record_parse_body( + struct ast_json *body, + struct ast_ari_channels_record_args *args); + /*! * \brief Start a recording. * @@ -361,6 +462,17 @@ struct ast_ari_channels_get_channel_var_args { /*! \brief The channel variable or function to get */ const char *variable; }; +/*! + * \brief Body parsing function for /channels/{channelId}/variable. + * \param body The JSON body from which to parse parameters. + * \param[out] args The args structure to parse into. + * \retval zero on success + * \retval non-zero on failure + */ +int ast_ari_channels_get_channel_var_parse_body( + struct ast_json *body, + struct ast_ari_channels_get_channel_var_args *args); + /*! * \brief Get the value of a channel variable or function. * @@ -378,6 +490,17 @@ struct ast_ari_channels_set_channel_var_args { /*! \brief The value to set the variable to */ const char *value; }; +/*! + * \brief Body parsing function for /channels/{channelId}/variable. + * \param body The JSON body from which to parse parameters. + * \param[out] args The args structure to parse into. + * \retval zero on success + * \retval non-zero on failure + */ +int ast_ari_channels_set_channel_var_parse_body( + struct ast_json *body, + struct ast_ari_channels_set_channel_var_args *args); + /*! * \brief Set the value of a channel variable or function. * @@ -399,6 +522,17 @@ struct ast_ari_channels_snoop_channel_args { /*! \brief The application arguments to pass to the Stasis application */ const char *app_args; }; +/*! + * \brief Body parsing function for /channels/{channelId}/snoop. + * \param body The JSON body from which to parse parameters. + * \param[out] args The args structure to parse into. + * \retval zero on success + * \retval non-zero on failure + */ +int ast_ari_channels_snoop_channel_parse_body( + struct ast_json *body, + struct ast_ari_channels_snoop_channel_args *args); + /*! * \brief Start snooping. * diff --git a/res/ari/resource_device_states.h b/res/ari/resource_device_states.h index a3bac999c1..7e2a38b4af 100644 --- a/res/ari/resource_device_states.h +++ b/res/ari/resource_device_states.h @@ -70,6 +70,17 @@ struct ast_ari_device_states_update_args { /*! \brief Device state value */ const char *device_state; }; +/*! + * \brief Body parsing function for /deviceStates/{deviceName}. + * \param body The JSON body from which to parse parameters. + * \param[out] args The args structure to parse into. + * \retval zero on success + * \retval non-zero on failure + */ +int ast_ari_device_states_update_parse_body( + struct ast_json *body, + struct ast_ari_device_states_update_args *args); + /*! * \brief Change the state of a device controlled by ARI. (Note - implicitly creates the device state). * diff --git a/res/ari/resource_mailboxes.h b/res/ari/resource_mailboxes.h index 33c69682dd..8627321db7 100644 --- a/res/ari/resource_mailboxes.h +++ b/res/ari/resource_mailboxes.h @@ -72,6 +72,17 @@ struct ast_ari_mailboxes_update_args { /*! \brief Count of new messages in the mailbox */ int new_messages; }; +/*! + * \brief Body parsing function for /mailboxes/{mailboxName}. + * \param body The JSON body from which to parse parameters. + * \param[out] args The args structure to parse into. + * \retval zero on success + * \retval non-zero on failure + */ +int ast_ari_mailboxes_update_parse_body( + struct ast_json *body, + struct ast_ari_mailboxes_update_args *args); + /*! * \brief Change the state of a mailbox. (Note - implicitly creates the mailbox). * diff --git a/res/ari/resource_playbacks.h b/res/ari/resource_playbacks.h index 9cd9f3cbd0..751be7504b 100644 --- a/res/ari/resource_playbacks.h +++ b/res/ari/resource_playbacks.h @@ -72,6 +72,17 @@ struct ast_ari_playbacks_control_args { /*! \brief Operation to perform on the playback. */ const char *operation; }; +/*! + * \brief Body parsing function for /playbacks/{playbackId}/control. + * \param body The JSON body from which to parse parameters. + * \param[out] args The args structure to parse into. + * \retval zero on success + * \retval non-zero on failure + */ +int ast_ari_playbacks_control_parse_body( + struct ast_json *body, + struct ast_ari_playbacks_control_args *args); + /*! * \brief Control a playback. * diff --git a/res/ari/resource_sounds.h b/res/ari/resource_sounds.h index 5e8ddd43df..d9588b1c01 100644 --- a/res/ari/resource_sounds.h +++ b/res/ari/resource_sounds.h @@ -46,6 +46,17 @@ struct ast_ari_sounds_list_args { /*! \brief Lookup sound in a specific format. */ const char *format; }; +/*! + * \brief Body parsing function for /sounds. + * \param body The JSON body from which to parse parameters. + * \param[out] args The args structure to parse into. + * \retval zero on success + * \retval non-zero on failure + */ +int ast_ari_sounds_list_parse_body( + struct ast_json *body, + struct ast_ari_sounds_list_args *args); + /*! * \brief List all sounds. * diff --git a/res/res_ari_applications.c b/res/res_ari_applications.c index 1f021c41d6..9195d4c83c 100644 --- a/res/res_ari_applications.c +++ b/res/res_ari_applications.c @@ -161,6 +161,44 @@ static void ast_ari_applications_get_cb( fin: __attribute__((unused)) return; } +int ast_ari_applications_subscribe_parse_body( + struct ast_json *body, + struct ast_ari_applications_subscribe_args *args) +{ + struct ast_json *field; + /* Parse query parameters out of it */ + field = ast_json_object_get(body, "eventSource"); + if (field) { + /* If they were silly enough to both pass in a query param and a + * JSON body, free up the query value. + */ + ast_free(args->event_source); + if (ast_json_typeof(field) == AST_JSON_ARRAY) { + /* Multiple param passed as array */ + size_t i; + args->event_source_count = ast_json_array_size(field); + args->event_source = ast_malloc(sizeof(*args->event_source) * args->event_source_count); + + if (!args->event_source) { + return -1; + } + + for (i = 0; i < args->event_source_count; ++i) { + args->event_source[i] = ast_json_string_get(ast_json_array_get(field, i)); + } + } else { + /* Multiple param passed as single value */ + args->event_source_count = 1; + args->event_source = ast_malloc(sizeof(*args->event_source) * args->event_source_count); + if (!args->event_source) { + return -1; + } + args->event_source[0] = ast_json_string_get(field); + } + } + return 0; +} + /*! * \brief Parameter parsing callback for /applications/{applicationName}/subscription. * \param get_params GET parameters in the HTTP request. @@ -176,7 +214,6 @@ static void ast_ari_applications_subscribe_cb( struct ast_ari_applications_subscribe_args args = {}; struct ast_variable *i; RAII_VAR(struct ast_json *, body, NULL, ast_json_unref); - struct ast_json *field; #if defined(AST_DEVMODE) int is_valid; int code; @@ -249,37 +286,9 @@ static void ast_ari_applications_subscribe_cb( goto fin; } } - /* Parse query parameters out of it */ - field = ast_json_object_get(body, "eventSource"); - if (field) { - /* If they were silly enough to both pass in a query param and a - * JSON body, free up the query value. - */ - ast_free(args.event_source); - if (ast_json_typeof(field) == AST_JSON_ARRAY) { - /* Multiple param passed as array */ - size_t i; - args.event_source_count = ast_json_array_size(field); - args.event_source = ast_malloc(sizeof(*args.event_source) * args.event_source_count); - - if (!args.event_source) { - ast_ari_response_alloc_failed(response); - goto fin; - } - - for (i = 0; i < args.event_source_count; ++i) { - args.event_source[i] = ast_json_string_get(ast_json_array_get(field, i)); - } - } else { - /* Multiple param passed as single value */ - args.event_source_count = 1; - args.event_source = ast_malloc(sizeof(*args.event_source) * args.event_source_count); - if (!args.event_source) { - ast_ari_response_alloc_failed(response); - goto fin; - } - args.event_source[0] = ast_json_string_get(field); - } + if (ast_ari_applications_subscribe_parse_body(body, &args)) { + ast_ari_response_alloc_failed(response); + goto fin; } ast_ari_applications_subscribe(headers, &args, response); #if defined(AST_DEVMODE) @@ -318,6 +327,44 @@ fin: __attribute__((unused)) ast_free(args.event_source); return; } +int ast_ari_applications_unsubscribe_parse_body( + struct ast_json *body, + struct ast_ari_applications_unsubscribe_args *args) +{ + struct ast_json *field; + /* Parse query parameters out of it */ + field = ast_json_object_get(body, "eventSource"); + if (field) { + /* If they were silly enough to both pass in a query param and a + * JSON body, free up the query value. + */ + ast_free(args->event_source); + if (ast_json_typeof(field) == AST_JSON_ARRAY) { + /* Multiple param passed as array */ + size_t i; + args->event_source_count = ast_json_array_size(field); + args->event_source = ast_malloc(sizeof(*args->event_source) * args->event_source_count); + + if (!args->event_source) { + return -1; + } + + for (i = 0; i < args->event_source_count; ++i) { + args->event_source[i] = ast_json_string_get(ast_json_array_get(field, i)); + } + } else { + /* Multiple param passed as single value */ + args->event_source_count = 1; + args->event_source = ast_malloc(sizeof(*args->event_source) * args->event_source_count); + if (!args->event_source) { + return -1; + } + args->event_source[0] = ast_json_string_get(field); + } + } + return 0; +} + /*! * \brief Parameter parsing callback for /applications/{applicationName}/subscription. * \param get_params GET parameters in the HTTP request. @@ -333,7 +380,6 @@ static void ast_ari_applications_unsubscribe_cb( struct ast_ari_applications_unsubscribe_args args = {}; struct ast_variable *i; RAII_VAR(struct ast_json *, body, NULL, ast_json_unref); - struct ast_json *field; #if defined(AST_DEVMODE) int is_valid; int code; @@ -406,37 +452,9 @@ static void ast_ari_applications_unsubscribe_cb( goto fin; } } - /* Parse query parameters out of it */ - field = ast_json_object_get(body, "eventSource"); - if (field) { - /* If they were silly enough to both pass in a query param and a - * JSON body, free up the query value. - */ - ast_free(args.event_source); - if (ast_json_typeof(field) == AST_JSON_ARRAY) { - /* Multiple param passed as array */ - size_t i; - args.event_source_count = ast_json_array_size(field); - args.event_source = ast_malloc(sizeof(*args.event_source) * args.event_source_count); - - if (!args.event_source) { - ast_ari_response_alloc_failed(response); - goto fin; - } - - for (i = 0; i < args.event_source_count; ++i) { - args.event_source[i] = ast_json_string_get(ast_json_array_get(field, i)); - } - } else { - /* Multiple param passed as single value */ - args.event_source_count = 1; - args.event_source = ast_malloc(sizeof(*args.event_source) * args.event_source_count); - if (!args.event_source) { - ast_ari_response_alloc_failed(response); - goto fin; - } - args.event_source[0] = ast_json_string_get(field); - } + if (ast_ari_applications_unsubscribe_parse_body(body, &args)) { + ast_ari_response_alloc_failed(response); + goto fin; } ast_ari_applications_unsubscribe(headers, &args, response); #if defined(AST_DEVMODE) diff --git a/res/res_ari_asterisk.c b/res/res_ari_asterisk.c index 6d561aca99..346c2c2f31 100644 --- a/res/res_ari_asterisk.c +++ b/res/res_ari_asterisk.c @@ -51,6 +51,44 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #define MAX_VALS 128 +int ast_ari_asterisk_get_info_parse_body( + struct ast_json *body, + struct ast_ari_asterisk_get_info_args *args) +{ + struct ast_json *field; + /* Parse query parameters out of it */ + field = ast_json_object_get(body, "only"); + if (field) { + /* If they were silly enough to both pass in a query param and a + * JSON body, free up the query value. + */ + ast_free(args->only); + if (ast_json_typeof(field) == AST_JSON_ARRAY) { + /* Multiple param passed as array */ + size_t i; + args->only_count = ast_json_array_size(field); + args->only = ast_malloc(sizeof(*args->only) * args->only_count); + + if (!args->only) { + return -1; + } + + for (i = 0; i < args->only_count; ++i) { + args->only[i] = ast_json_string_get(ast_json_array_get(field, i)); + } + } else { + /* Multiple param passed as single value */ + args->only_count = 1; + args->only = ast_malloc(sizeof(*args->only) * args->only_count); + if (!args->only) { + return -1; + } + args->only[0] = ast_json_string_get(field); + } + } + return 0; +} + /*! * \brief Parameter parsing callback for /asterisk/info. * \param get_params GET parameters in the HTTP request. @@ -66,7 +104,6 @@ static void ast_ari_asterisk_get_info_cb( struct ast_ari_asterisk_get_info_args args = {}; struct ast_variable *i; RAII_VAR(struct ast_json *, body, NULL, ast_json_unref); - struct ast_json *field; #if defined(AST_DEVMODE) int is_valid; int code; @@ -133,37 +170,9 @@ static void ast_ari_asterisk_get_info_cb( goto fin; } } - /* Parse query parameters out of it */ - field = ast_json_object_get(body, "only"); - if (field) { - /* If they were silly enough to both pass in a query param and a - * JSON body, free up the query value. - */ - ast_free(args.only); - if (ast_json_typeof(field) == AST_JSON_ARRAY) { - /* Multiple param passed as array */ - size_t i; - args.only_count = ast_json_array_size(field); - args.only = ast_malloc(sizeof(*args.only) * args.only_count); - - if (!args.only) { - ast_ari_response_alloc_failed(response); - goto fin; - } - - for (i = 0; i < args.only_count; ++i) { - args.only[i] = ast_json_string_get(ast_json_array_get(field, i)); - } - } else { - /* Multiple param passed as single value */ - args.only_count = 1; - args.only = ast_malloc(sizeof(*args.only) * args.only_count); - if (!args.only) { - ast_ari_response_alloc_failed(response); - goto fin; - } - args.only[0] = ast_json_string_get(field); - } + if (ast_ari_asterisk_get_info_parse_body(body, &args)) { + ast_ari_response_alloc_failed(response); + goto fin; } ast_ari_asterisk_get_info(headers, &args, response); #if defined(AST_DEVMODE) @@ -199,6 +208,19 @@ fin: __attribute__((unused)) ast_free(args.only); return; } +int ast_ari_asterisk_get_global_var_parse_body( + struct ast_json *body, + struct ast_ari_asterisk_get_global_var_args *args) +{ + struct ast_json *field; + /* Parse query parameters out of it */ + field = ast_json_object_get(body, "variable"); + if (field) { + args->variable = ast_json_string_get(field); + } + return 0; +} + /*! * \brief Parameter parsing callback for /asterisk/variable. * \param get_params GET parameters in the HTTP request. @@ -214,7 +236,6 @@ static void ast_ari_asterisk_get_global_var_cb( struct ast_ari_asterisk_get_global_var_args args = {}; struct ast_variable *i; RAII_VAR(struct ast_json *, body, NULL, ast_json_unref); - struct ast_json *field; #if defined(AST_DEVMODE) int is_valid; int code; @@ -241,10 +262,9 @@ static void ast_ari_asterisk_get_global_var_cb( goto fin; } } - /* Parse query parameters out of it */ - field = ast_json_object_get(body, "variable"); - if (field) { - args.variable = ast_json_string_get(field); + if (ast_ari_asterisk_get_global_var_parse_body(body, &args)) { + ast_ari_response_alloc_failed(response); + goto fin; } ast_ari_asterisk_get_global_var(headers, &args, response); #if defined(AST_DEVMODE) @@ -279,6 +299,23 @@ static void ast_ari_asterisk_get_global_var_cb( fin: __attribute__((unused)) return; } +int ast_ari_asterisk_set_global_var_parse_body( + struct ast_json *body, + struct ast_ari_asterisk_set_global_var_args *args) +{ + struct ast_json *field; + /* Parse query parameters out of it */ + field = ast_json_object_get(body, "variable"); + if (field) { + args->variable = ast_json_string_get(field); + } + field = ast_json_object_get(body, "value"); + if (field) { + args->value = ast_json_string_get(field); + } + return 0; +} + /*! * \brief Parameter parsing callback for /asterisk/variable. * \param get_params GET parameters in the HTTP request. @@ -294,7 +331,6 @@ static void ast_ari_asterisk_set_global_var_cb( struct ast_ari_asterisk_set_global_var_args args = {}; struct ast_variable *i; RAII_VAR(struct ast_json *, body, NULL, ast_json_unref); - struct ast_json *field; #if defined(AST_DEVMODE) int is_valid; int code; @@ -324,14 +360,9 @@ static void ast_ari_asterisk_set_global_var_cb( goto fin; } } - /* Parse query parameters out of it */ - field = ast_json_object_get(body, "variable"); - if (field) { - args.variable = ast_json_string_get(field); - } - field = ast_json_object_get(body, "value"); - if (field) { - args.value = ast_json_string_get(field); + if (ast_ari_asterisk_set_global_var_parse_body(body, &args)) { + ast_ari_response_alloc_failed(response); + goto fin; } ast_ari_asterisk_set_global_var(headers, &args, response); #if defined(AST_DEVMODE) diff --git a/res/res_ari_bridges.c b/res/res_ari_bridges.c index 242512d90a..e1c9fe672a 100644 --- a/res/res_ari_bridges.c +++ b/res/res_ari_bridges.c @@ -102,6 +102,23 @@ static void ast_ari_bridges_list_cb( fin: __attribute__((unused)) return; } +int ast_ari_bridges_create_parse_body( + struct ast_json *body, + struct ast_ari_bridges_create_args *args) +{ + struct ast_json *field; + /* Parse query parameters out of it */ + field = ast_json_object_get(body, "type"); + if (field) { + args->type = ast_json_string_get(field); + } + field = ast_json_object_get(body, "name"); + if (field) { + args->name = ast_json_string_get(field); + } + return 0; +} + /*! * \brief Parameter parsing callback for /bridges. * \param get_params GET parameters in the HTTP request. @@ -117,7 +134,6 @@ static void ast_ari_bridges_create_cb( struct ast_ari_bridges_create_args args = {}; struct ast_variable *i; RAII_VAR(struct ast_json *, body, NULL, ast_json_unref); - struct ast_json *field; #if defined(AST_DEVMODE) int is_valid; int code; @@ -147,14 +163,9 @@ static void ast_ari_bridges_create_cb( goto fin; } } - /* Parse query parameters out of it */ - field = ast_json_object_get(body, "type"); - if (field) { - args.type = ast_json_string_get(field); - } - field = ast_json_object_get(body, "name"); - if (field) { - args.name = ast_json_string_get(field); + if (ast_ari_bridges_create_parse_body(body, &args)) { + ast_ari_response_alloc_failed(response); + goto fin; } ast_ari_bridges_create(headers, &args, response); #if defined(AST_DEVMODE) @@ -306,6 +317,48 @@ static void ast_ari_bridges_destroy_cb( fin: __attribute__((unused)) return; } +int ast_ari_bridges_add_channel_parse_body( + struct ast_json *body, + struct ast_ari_bridges_add_channel_args *args) +{ + struct ast_json *field; + /* Parse query parameters out of it */ + field = ast_json_object_get(body, "channel"); + if (field) { + /* If they were silly enough to both pass in a query param and a + * JSON body, free up the query value. + */ + ast_free(args->channel); + if (ast_json_typeof(field) == AST_JSON_ARRAY) { + /* Multiple param passed as array */ + size_t i; + args->channel_count = ast_json_array_size(field); + args->channel = ast_malloc(sizeof(*args->channel) * args->channel_count); + + if (!args->channel) { + return -1; + } + + for (i = 0; i < args->channel_count; ++i) { + args->channel[i] = ast_json_string_get(ast_json_array_get(field, i)); + } + } else { + /* Multiple param passed as single value */ + args->channel_count = 1; + args->channel = ast_malloc(sizeof(*args->channel) * args->channel_count); + if (!args->channel) { + return -1; + } + args->channel[0] = ast_json_string_get(field); + } + } + field = ast_json_object_get(body, "role"); + if (field) { + args->role = ast_json_string_get(field); + } + return 0; +} + /*! * \brief Parameter parsing callback for /bridges/{bridgeId}/addChannel. * \param get_params GET parameters in the HTTP request. @@ -321,7 +374,6 @@ static void ast_ari_bridges_add_channel_cb( struct ast_ari_bridges_add_channel_args args = {}; struct ast_variable *i; RAII_VAR(struct ast_json *, body, NULL, ast_json_unref); - struct ast_json *field; #if defined(AST_DEVMODE) int is_valid; int code; @@ -397,41 +449,9 @@ static void ast_ari_bridges_add_channel_cb( goto fin; } } - /* Parse query parameters out of it */ - field = ast_json_object_get(body, "channel"); - if (field) { - /* If they were silly enough to both pass in a query param and a - * JSON body, free up the query value. - */ - ast_free(args.channel); - if (ast_json_typeof(field) == AST_JSON_ARRAY) { - /* Multiple param passed as array */ - size_t i; - args.channel_count = ast_json_array_size(field); - args.channel = ast_malloc(sizeof(*args.channel) * args.channel_count); - - if (!args.channel) { - ast_ari_response_alloc_failed(response); - goto fin; - } - - for (i = 0; i < args.channel_count; ++i) { - args.channel[i] = ast_json_string_get(ast_json_array_get(field, i)); - } - } else { - /* Multiple param passed as single value */ - args.channel_count = 1; - args.channel = ast_malloc(sizeof(*args.channel) * args.channel_count); - if (!args.channel) { - ast_ari_response_alloc_failed(response); - goto fin; - } - args.channel[0] = ast_json_string_get(field); - } - } - field = ast_json_object_get(body, "role"); - if (field) { - args.role = ast_json_string_get(field); + if (ast_ari_bridges_add_channel_parse_body(body, &args)) { + ast_ari_response_alloc_failed(response); + goto fin; } ast_ari_bridges_add_channel(headers, &args, response); #if defined(AST_DEVMODE) @@ -471,6 +491,44 @@ fin: __attribute__((unused)) ast_free(args.channel); return; } +int ast_ari_bridges_remove_channel_parse_body( + struct ast_json *body, + struct ast_ari_bridges_remove_channel_args *args) +{ + struct ast_json *field; + /* Parse query parameters out of it */ + field = ast_json_object_get(body, "channel"); + if (field) { + /* If they were silly enough to both pass in a query param and a + * JSON body, free up the query value. + */ + ast_free(args->channel); + if (ast_json_typeof(field) == AST_JSON_ARRAY) { + /* Multiple param passed as array */ + size_t i; + args->channel_count = ast_json_array_size(field); + args->channel = ast_malloc(sizeof(*args->channel) * args->channel_count); + + if (!args->channel) { + return -1; + } + + for (i = 0; i < args->channel_count; ++i) { + args->channel[i] = ast_json_string_get(ast_json_array_get(field, i)); + } + } else { + /* Multiple param passed as single value */ + args->channel_count = 1; + args->channel = ast_malloc(sizeof(*args->channel) * args->channel_count); + if (!args->channel) { + return -1; + } + args->channel[0] = ast_json_string_get(field); + } + } + return 0; +} + /*! * \brief Parameter parsing callback for /bridges/{bridgeId}/removeChannel. * \param get_params GET parameters in the HTTP request. @@ -486,7 +544,6 @@ static void ast_ari_bridges_remove_channel_cb( struct ast_ari_bridges_remove_channel_args args = {}; struct ast_variable *i; RAII_VAR(struct ast_json *, body, NULL, ast_json_unref); - struct ast_json *field; #if defined(AST_DEVMODE) int is_valid; int code; @@ -559,37 +616,9 @@ static void ast_ari_bridges_remove_channel_cb( goto fin; } } - /* Parse query parameters out of it */ - field = ast_json_object_get(body, "channel"); - if (field) { - /* If they were silly enough to both pass in a query param and a - * JSON body, free up the query value. - */ - ast_free(args.channel); - if (ast_json_typeof(field) == AST_JSON_ARRAY) { - /* Multiple param passed as array */ - size_t i; - args.channel_count = ast_json_array_size(field); - args.channel = ast_malloc(sizeof(*args.channel) * args.channel_count); - - if (!args.channel) { - ast_ari_response_alloc_failed(response); - goto fin; - } - - for (i = 0; i < args.channel_count; ++i) { - args.channel[i] = ast_json_string_get(ast_json_array_get(field, i)); - } - } else { - /* Multiple param passed as single value */ - args.channel_count = 1; - args.channel = ast_malloc(sizeof(*args.channel) * args.channel_count); - if (!args.channel) { - ast_ari_response_alloc_failed(response); - goto fin; - } - args.channel[0] = ast_json_string_get(field); - } + if (ast_ari_bridges_remove_channel_parse_body(body, &args)) { + ast_ari_response_alloc_failed(response); + goto fin; } ast_ari_bridges_remove_channel(headers, &args, response); #if defined(AST_DEVMODE) @@ -629,6 +658,19 @@ fin: __attribute__((unused)) ast_free(args.channel); return; } +int ast_ari_bridges_start_moh_parse_body( + struct ast_json *body, + struct ast_ari_bridges_start_moh_args *args) +{ + struct ast_json *field; + /* Parse query parameters out of it */ + field = ast_json_object_get(body, "mohClass"); + if (field) { + args->moh_class = ast_json_string_get(field); + } + return 0; +} + /*! * \brief Parameter parsing callback for /bridges/{bridgeId}/moh. * \param get_params GET parameters in the HTTP request. @@ -644,7 +686,6 @@ static void ast_ari_bridges_start_moh_cb( struct ast_ari_bridges_start_moh_args args = {}; struct ast_variable *i; RAII_VAR(struct ast_json *, body, NULL, ast_json_unref); - struct ast_json *field; #if defined(AST_DEVMODE) int is_valid; int code; @@ -677,10 +718,9 @@ static void ast_ari_bridges_start_moh_cb( goto fin; } } - /* Parse query parameters out of it */ - field = ast_json_object_get(body, "mohClass"); - if (field) { - args.moh_class = ast_json_string_get(field); + if (ast_ari_bridges_start_moh_parse_body(body, &args)) { + ast_ari_response_alloc_failed(response); + goto fin; } ast_ari_bridges_start_moh(headers, &args, response); #if defined(AST_DEVMODE) @@ -776,6 +816,31 @@ static void ast_ari_bridges_stop_moh_cb( fin: __attribute__((unused)) return; } +int ast_ari_bridges_play_parse_body( + struct ast_json *body, + struct ast_ari_bridges_play_args *args) +{ + struct ast_json *field; + /* Parse query parameters out of it */ + field = ast_json_object_get(body, "media"); + if (field) { + args->media = ast_json_string_get(field); + } + field = ast_json_object_get(body, "lang"); + if (field) { + args->lang = ast_json_string_get(field); + } + field = ast_json_object_get(body, "offsetms"); + if (field) { + args->offsetms = ast_json_integer_get(field); + } + field = ast_json_object_get(body, "skipms"); + if (field) { + args->skipms = ast_json_integer_get(field); + } + return 0; +} + /*! * \brief Parameter parsing callback for /bridges/{bridgeId}/play. * \param get_params GET parameters in the HTTP request. @@ -791,7 +856,6 @@ static void ast_ari_bridges_play_cb( struct ast_ari_bridges_play_args args = {}; struct ast_variable *i; RAII_VAR(struct ast_json *, body, NULL, ast_json_unref); - struct ast_json *field; #if defined(AST_DEVMODE) int is_valid; int code; @@ -833,22 +897,9 @@ static void ast_ari_bridges_play_cb( goto fin; } } - /* Parse query parameters out of it */ - field = ast_json_object_get(body, "media"); - if (field) { - args.media = ast_json_string_get(field); - } - field = ast_json_object_get(body, "lang"); - if (field) { - args.lang = ast_json_string_get(field); - } - field = ast_json_object_get(body, "offsetms"); - if (field) { - args.offsetms = ast_json_integer_get(field); - } - field = ast_json_object_get(body, "skipms"); - if (field) { - args.skipms = ast_json_integer_get(field); + if (ast_ari_bridges_play_parse_body(body, &args)) { + ast_ari_response_alloc_failed(response); + goto fin; } ast_ari_bridges_play(headers, &args, response); #if defined(AST_DEVMODE) @@ -884,6 +935,43 @@ static void ast_ari_bridges_play_cb( fin: __attribute__((unused)) return; } +int ast_ari_bridges_record_parse_body( + struct ast_json *body, + struct ast_ari_bridges_record_args *args) +{ + struct ast_json *field; + /* Parse query parameters out of it */ + field = ast_json_object_get(body, "name"); + if (field) { + args->name = ast_json_string_get(field); + } + field = ast_json_object_get(body, "format"); + if (field) { + args->format = ast_json_string_get(field); + } + field = ast_json_object_get(body, "maxDurationSeconds"); + if (field) { + args->max_duration_seconds = ast_json_integer_get(field); + } + field = ast_json_object_get(body, "maxSilenceSeconds"); + if (field) { + args->max_silence_seconds = ast_json_integer_get(field); + } + field = ast_json_object_get(body, "ifExists"); + if (field) { + args->if_exists = ast_json_string_get(field); + } + field = ast_json_object_get(body, "beep"); + if (field) { + args->beep = ast_json_is_true(field); + } + field = ast_json_object_get(body, "terminateOn"); + if (field) { + args->terminate_on = ast_json_string_get(field); + } + return 0; +} + /*! * \brief Parameter parsing callback for /bridges/{bridgeId}/record. * \param get_params GET parameters in the HTTP request. @@ -899,7 +987,6 @@ static void ast_ari_bridges_record_cb( struct ast_ari_bridges_record_args args = {}; struct ast_variable *i; RAII_VAR(struct ast_json *, body, NULL, ast_json_unref); - struct ast_json *field; #if defined(AST_DEVMODE) int is_valid; int code; @@ -950,34 +1037,9 @@ static void ast_ari_bridges_record_cb( goto fin; } } - /* Parse query parameters out of it */ - field = ast_json_object_get(body, "name"); - if (field) { - args.name = ast_json_string_get(field); - } - field = ast_json_object_get(body, "format"); - if (field) { - args.format = ast_json_string_get(field); - } - field = ast_json_object_get(body, "maxDurationSeconds"); - if (field) { - args.max_duration_seconds = ast_json_integer_get(field); - } - field = ast_json_object_get(body, "maxSilenceSeconds"); - if (field) { - args.max_silence_seconds = ast_json_integer_get(field); - } - field = ast_json_object_get(body, "ifExists"); - if (field) { - args.if_exists = ast_json_string_get(field); - } - field = ast_json_object_get(body, "beep"); - if (field) { - args.beep = ast_json_is_true(field); - } - field = ast_json_object_get(body, "terminateOn"); - if (field) { - args.terminate_on = ast_json_string_get(field); + if (ast_ari_bridges_record_parse_body(body, &args)) { + ast_ari_response_alloc_failed(response); + goto fin; } ast_ari_bridges_record(headers, &args, response); #if defined(AST_DEVMODE) diff --git a/res/res_ari_channels.c b/res/res_ari_channels.c index 40ad32b2b8..12ef16843b 100644 --- a/res/res_ari_channels.c +++ b/res/res_ari_channels.c @@ -102,6 +102,47 @@ static void ast_ari_channels_list_cb( fin: __attribute__((unused)) return; } +int ast_ari_channels_originate_parse_body( + struct ast_json *body, + struct ast_ari_channels_originate_args *args) +{ + struct ast_json *field; + /* Parse query parameters out of it */ + field = ast_json_object_get(body, "endpoint"); + if (field) { + args->endpoint = ast_json_string_get(field); + } + field = ast_json_object_get(body, "extension"); + if (field) { + args->extension = ast_json_string_get(field); + } + field = ast_json_object_get(body, "context"); + if (field) { + args->context = ast_json_string_get(field); + } + field = ast_json_object_get(body, "priority"); + if (field) { + args->priority = ast_json_integer_get(field); + } + field = ast_json_object_get(body, "app"); + if (field) { + args->app = ast_json_string_get(field); + } + field = ast_json_object_get(body, "appArgs"); + if (field) { + args->app_args = ast_json_string_get(field); + } + field = ast_json_object_get(body, "callerId"); + if (field) { + args->caller_id = ast_json_string_get(field); + } + field = ast_json_object_get(body, "timeout"); + if (field) { + args->timeout = ast_json_integer_get(field); + } + return 0; +} + /*! * \brief Parameter parsing callback for /channels. * \param get_params GET parameters in the HTTP request. @@ -117,7 +158,6 @@ static void ast_ari_channels_originate_cb( struct ast_ari_channels_originate_args args = {}; struct ast_variable *i; RAII_VAR(struct ast_json *, body, NULL, ast_json_unref); - struct ast_json *field; #if defined(AST_DEVMODE) int is_valid; int code; @@ -165,39 +205,7 @@ static void ast_ari_channels_originate_cb( goto fin; } } - /* Parse query parameters out of it */ - field = ast_json_object_get(body, "endpoint"); - if (field) { - args.endpoint = ast_json_string_get(field); - } - field = ast_json_object_get(body, "extension"); - if (field) { - args.extension = ast_json_string_get(field); - } - field = ast_json_object_get(body, "context"); - if (field) { - args.context = ast_json_string_get(field); - } - field = ast_json_object_get(body, "priority"); - if (field) { - args.priority = ast_json_integer_get(field); - } - field = ast_json_object_get(body, "app"); - if (field) { - args.app = ast_json_string_get(field); - } - field = ast_json_object_get(body, "appArgs"); - if (field) { - args.app_args = ast_json_string_get(field); - } - field = ast_json_object_get(body, "callerId"); - if (field) { - args.caller_id = ast_json_string_get(field); - } - field = ast_json_object_get(body, "timeout"); - if (field) { - args.timeout = ast_json_integer_get(field); - } + args.variables = ast_json_ref(body); ast_ari_channels_originate(headers, &args, response); #if defined(AST_DEVMODE) code = response->response_code; @@ -290,6 +298,19 @@ static void ast_ari_channels_get_cb( fin: __attribute__((unused)) return; } +int ast_ari_channels_hangup_parse_body( + struct ast_json *body, + struct ast_ari_channels_hangup_args *args) +{ + struct ast_json *field; + /* Parse query parameters out of it */ + field = ast_json_object_get(body, "reason"); + if (field) { + args->reason = ast_json_string_get(field); + } + return 0; +} + /*! * \brief Parameter parsing callback for /channels/{channelId}. * \param get_params GET parameters in the HTTP request. @@ -305,7 +326,6 @@ static void ast_ari_channels_hangup_cb( struct ast_ari_channels_hangup_args args = {}; struct ast_variable *i; RAII_VAR(struct ast_json *, body, NULL, ast_json_unref); - struct ast_json *field; #if defined(AST_DEVMODE) int is_valid; int code; @@ -338,10 +358,9 @@ static void ast_ari_channels_hangup_cb( goto fin; } } - /* Parse query parameters out of it */ - field = ast_json_object_get(body, "reason"); - if (field) { - args.reason = ast_json_string_get(field); + if (ast_ari_channels_hangup_parse_body(body, &args)) { + ast_ari_response_alloc_failed(response); + goto fin; } ast_ari_channels_hangup(headers, &args, response); #if defined(AST_DEVMODE) @@ -377,6 +396,27 @@ static void ast_ari_channels_hangup_cb( fin: __attribute__((unused)) return; } +int ast_ari_channels_continue_in_dialplan_parse_body( + struct ast_json *body, + struct ast_ari_channels_continue_in_dialplan_args *args) +{ + struct ast_json *field; + /* Parse query parameters out of it */ + field = ast_json_object_get(body, "context"); + if (field) { + args->context = ast_json_string_get(field); + } + field = ast_json_object_get(body, "extension"); + if (field) { + args->extension = ast_json_string_get(field); + } + field = ast_json_object_get(body, "priority"); + if (field) { + args->priority = ast_json_integer_get(field); + } + return 0; +} + /*! * \brief Parameter parsing callback for /channels/{channelId}/continue. * \param get_params GET parameters in the HTTP request. @@ -392,7 +432,6 @@ static void ast_ari_channels_continue_in_dialplan_cb( struct ast_ari_channels_continue_in_dialplan_args args = {}; struct ast_variable *i; RAII_VAR(struct ast_json *, body, NULL, ast_json_unref); - struct ast_json *field; #if defined(AST_DEVMODE) int is_valid; int code; @@ -431,18 +470,9 @@ static void ast_ari_channels_continue_in_dialplan_cb( goto fin; } } - /* Parse query parameters out of it */ - field = ast_json_object_get(body, "context"); - if (field) { - args.context = ast_json_string_get(field); - } - field = ast_json_object_get(body, "extension"); - if (field) { - args.extension = ast_json_string_get(field); - } - field = ast_json_object_get(body, "priority"); - if (field) { - args.priority = ast_json_integer_get(field); + if (ast_ari_channels_continue_in_dialplan_parse_body(body, &args)) { + ast_ari_response_alloc_failed(response); + goto fin; } ast_ari_channels_continue_in_dialplan(headers, &args, response); #if defined(AST_DEVMODE) @@ -658,6 +688,35 @@ static void ast_ari_channels_ring_stop_cb( fin: __attribute__((unused)) return; } +int ast_ari_channels_send_dtmf_parse_body( + struct ast_json *body, + struct ast_ari_channels_send_dtmf_args *args) +{ + struct ast_json *field; + /* Parse query parameters out of it */ + field = ast_json_object_get(body, "dtmf"); + if (field) { + args->dtmf = ast_json_string_get(field); + } + field = ast_json_object_get(body, "before"); + if (field) { + args->before = ast_json_integer_get(field); + } + field = ast_json_object_get(body, "between"); + if (field) { + args->between = ast_json_integer_get(field); + } + field = ast_json_object_get(body, "duration"); + if (field) { + args->duration = ast_json_integer_get(field); + } + field = ast_json_object_get(body, "after"); + if (field) { + args->after = ast_json_integer_get(field); + } + return 0; +} + /*! * \brief Parameter parsing callback for /channels/{channelId}/dtmf. * \param get_params GET parameters in the HTTP request. @@ -673,7 +732,6 @@ static void ast_ari_channels_send_dtmf_cb( struct ast_ari_channels_send_dtmf_args args = {}; struct ast_variable *i; RAII_VAR(struct ast_json *, body, NULL, ast_json_unref); - struct ast_json *field; #if defined(AST_DEVMODE) int is_valid; int code; @@ -718,26 +776,9 @@ static void ast_ari_channels_send_dtmf_cb( goto fin; } } - /* Parse query parameters out of it */ - field = ast_json_object_get(body, "dtmf"); - if (field) { - args.dtmf = ast_json_string_get(field); - } - field = ast_json_object_get(body, "before"); - if (field) { - args.before = ast_json_integer_get(field); - } - field = ast_json_object_get(body, "between"); - if (field) { - args.between = ast_json_integer_get(field); - } - field = ast_json_object_get(body, "duration"); - if (field) { - args.duration = ast_json_integer_get(field); - } - field = ast_json_object_get(body, "after"); - if (field) { - args.after = ast_json_integer_get(field); + if (ast_ari_channels_send_dtmf_parse_body(body, &args)) { + ast_ari_response_alloc_failed(response); + goto fin; } ast_ari_channels_send_dtmf(headers, &args, response); #if defined(AST_DEVMODE) @@ -774,6 +815,19 @@ static void ast_ari_channels_send_dtmf_cb( fin: __attribute__((unused)) return; } +int ast_ari_channels_mute_parse_body( + struct ast_json *body, + struct ast_ari_channels_mute_args *args) +{ + struct ast_json *field; + /* Parse query parameters out of it */ + field = ast_json_object_get(body, "direction"); + if (field) { + args->direction = ast_json_string_get(field); + } + return 0; +} + /*! * \brief Parameter parsing callback for /channels/{channelId}/mute. * \param get_params GET parameters in the HTTP request. @@ -789,7 +843,6 @@ static void ast_ari_channels_mute_cb( struct ast_ari_channels_mute_args args = {}; struct ast_variable *i; RAII_VAR(struct ast_json *, body, NULL, ast_json_unref); - struct ast_json *field; #if defined(AST_DEVMODE) int is_valid; int code; @@ -822,10 +875,9 @@ static void ast_ari_channels_mute_cb( goto fin; } } - /* Parse query parameters out of it */ - field = ast_json_object_get(body, "direction"); - if (field) { - args.direction = ast_json_string_get(field); + if (ast_ari_channels_mute_parse_body(body, &args)) { + ast_ari_response_alloc_failed(response); + goto fin; } ast_ari_channels_mute(headers, &args, response); #if defined(AST_DEVMODE) @@ -861,6 +913,19 @@ static void ast_ari_channels_mute_cb( fin: __attribute__((unused)) return; } +int ast_ari_channels_unmute_parse_body( + struct ast_json *body, + struct ast_ari_channels_unmute_args *args) +{ + struct ast_json *field; + /* Parse query parameters out of it */ + field = ast_json_object_get(body, "direction"); + if (field) { + args->direction = ast_json_string_get(field); + } + return 0; +} + /*! * \brief Parameter parsing callback for /channels/{channelId}/mute. * \param get_params GET parameters in the HTTP request. @@ -876,7 +941,6 @@ static void ast_ari_channels_unmute_cb( struct ast_ari_channels_unmute_args args = {}; struct ast_variable *i; RAII_VAR(struct ast_json *, body, NULL, ast_json_unref); - struct ast_json *field; #if defined(AST_DEVMODE) int is_valid; int code; @@ -909,10 +973,9 @@ static void ast_ari_channels_unmute_cb( goto fin; } } - /* Parse query parameters out of it */ - field = ast_json_object_get(body, "direction"); - if (field) { - args.direction = ast_json_string_get(field); + if (ast_ari_channels_unmute_parse_body(body, &args)) { + ast_ari_response_alloc_failed(response); + goto fin; } ast_ari_channels_unmute(headers, &args, response); #if defined(AST_DEVMODE) @@ -1068,6 +1131,19 @@ static void ast_ari_channels_unhold_cb( fin: __attribute__((unused)) return; } +int ast_ari_channels_start_moh_parse_body( + struct ast_json *body, + struct ast_ari_channels_start_moh_args *args) +{ + struct ast_json *field; + /* Parse query parameters out of it */ + field = ast_json_object_get(body, "mohClass"); + if (field) { + args->moh_class = ast_json_string_get(field); + } + return 0; +} + /*! * \brief Parameter parsing callback for /channels/{channelId}/moh. * \param get_params GET parameters in the HTTP request. @@ -1083,7 +1159,6 @@ static void ast_ari_channels_start_moh_cb( struct ast_ari_channels_start_moh_args args = {}; struct ast_variable *i; RAII_VAR(struct ast_json *, body, NULL, ast_json_unref); - struct ast_json *field; #if defined(AST_DEVMODE) int is_valid; int code; @@ -1116,10 +1191,9 @@ static void ast_ari_channels_start_moh_cb( goto fin; } } - /* Parse query parameters out of it */ - field = ast_json_object_get(body, "mohClass"); - if (field) { - args.moh_class = ast_json_string_get(field); + if (ast_ari_channels_start_moh_parse_body(body, &args)) { + ast_ari_response_alloc_failed(response); + goto fin; } ast_ari_channels_start_moh(headers, &args, response); #if defined(AST_DEVMODE) @@ -1335,6 +1409,31 @@ static void ast_ari_channels_stop_silence_cb( fin: __attribute__((unused)) return; } +int ast_ari_channels_play_parse_body( + struct ast_json *body, + struct ast_ari_channels_play_args *args) +{ + struct ast_json *field; + /* Parse query parameters out of it */ + field = ast_json_object_get(body, "media"); + if (field) { + args->media = ast_json_string_get(field); + } + field = ast_json_object_get(body, "lang"); + if (field) { + args->lang = ast_json_string_get(field); + } + field = ast_json_object_get(body, "offsetms"); + if (field) { + args->offsetms = ast_json_integer_get(field); + } + field = ast_json_object_get(body, "skipms"); + if (field) { + args->skipms = ast_json_integer_get(field); + } + return 0; +} + /*! * \brief Parameter parsing callback for /channels/{channelId}/play. * \param get_params GET parameters in the HTTP request. @@ -1350,7 +1449,6 @@ static void ast_ari_channels_play_cb( struct ast_ari_channels_play_args args = {}; struct ast_variable *i; RAII_VAR(struct ast_json *, body, NULL, ast_json_unref); - struct ast_json *field; #if defined(AST_DEVMODE) int is_valid; int code; @@ -1392,22 +1490,9 @@ static void ast_ari_channels_play_cb( goto fin; } } - /* Parse query parameters out of it */ - field = ast_json_object_get(body, "media"); - if (field) { - args.media = ast_json_string_get(field); - } - field = ast_json_object_get(body, "lang"); - if (field) { - args.lang = ast_json_string_get(field); - } - field = ast_json_object_get(body, "offsetms"); - if (field) { - args.offsetms = ast_json_integer_get(field); - } - field = ast_json_object_get(body, "skipms"); - if (field) { - args.skipms = ast_json_integer_get(field); + if (ast_ari_channels_play_parse_body(body, &args)) { + ast_ari_response_alloc_failed(response); + goto fin; } ast_ari_channels_play(headers, &args, response); #if defined(AST_DEVMODE) @@ -1443,6 +1528,43 @@ static void ast_ari_channels_play_cb( fin: __attribute__((unused)) return; } +int ast_ari_channels_record_parse_body( + struct ast_json *body, + struct ast_ari_channels_record_args *args) +{ + struct ast_json *field; + /* Parse query parameters out of it */ + field = ast_json_object_get(body, "name"); + if (field) { + args->name = ast_json_string_get(field); + } + field = ast_json_object_get(body, "format"); + if (field) { + args->format = ast_json_string_get(field); + } + field = ast_json_object_get(body, "maxDurationSeconds"); + if (field) { + args->max_duration_seconds = ast_json_integer_get(field); + } + field = ast_json_object_get(body, "maxSilenceSeconds"); + if (field) { + args->max_silence_seconds = ast_json_integer_get(field); + } + field = ast_json_object_get(body, "ifExists"); + if (field) { + args->if_exists = ast_json_string_get(field); + } + field = ast_json_object_get(body, "beep"); + if (field) { + args->beep = ast_json_is_true(field); + } + field = ast_json_object_get(body, "terminateOn"); + if (field) { + args->terminate_on = ast_json_string_get(field); + } + return 0; +} + /*! * \brief Parameter parsing callback for /channels/{channelId}/record. * \param get_params GET parameters in the HTTP request. @@ -1458,7 +1580,6 @@ static void ast_ari_channels_record_cb( struct ast_ari_channels_record_args args = {}; struct ast_variable *i; RAII_VAR(struct ast_json *, body, NULL, ast_json_unref); - struct ast_json *field; #if defined(AST_DEVMODE) int is_valid; int code; @@ -1509,34 +1630,9 @@ static void ast_ari_channels_record_cb( goto fin; } } - /* Parse query parameters out of it */ - field = ast_json_object_get(body, "name"); - if (field) { - args.name = ast_json_string_get(field); - } - field = ast_json_object_get(body, "format"); - if (field) { - args.format = ast_json_string_get(field); - } - field = ast_json_object_get(body, "maxDurationSeconds"); - if (field) { - args.max_duration_seconds = ast_json_integer_get(field); - } - field = ast_json_object_get(body, "maxSilenceSeconds"); - if (field) { - args.max_silence_seconds = ast_json_integer_get(field); - } - field = ast_json_object_get(body, "ifExists"); - if (field) { - args.if_exists = ast_json_string_get(field); - } - field = ast_json_object_get(body, "beep"); - if (field) { - args.beep = ast_json_is_true(field); - } - field = ast_json_object_get(body, "terminateOn"); - if (field) { - args.terminate_on = ast_json_string_get(field); + if (ast_ari_channels_record_parse_body(body, &args)) { + ast_ari_response_alloc_failed(response); + goto fin; } ast_ari_channels_record(headers, &args, response); #if defined(AST_DEVMODE) @@ -1574,6 +1670,19 @@ static void ast_ari_channels_record_cb( fin: __attribute__((unused)) return; } +int ast_ari_channels_get_channel_var_parse_body( + struct ast_json *body, + struct ast_ari_channels_get_channel_var_args *args) +{ + struct ast_json *field; + /* Parse query parameters out of it */ + field = ast_json_object_get(body, "variable"); + if (field) { + args->variable = ast_json_string_get(field); + } + return 0; +} + /*! * \brief Parameter parsing callback for /channels/{channelId}/variable. * \param get_params GET parameters in the HTTP request. @@ -1589,7 +1698,6 @@ static void ast_ari_channels_get_channel_var_cb( struct ast_ari_channels_get_channel_var_args args = {}; struct ast_variable *i; RAII_VAR(struct ast_json *, body, NULL, ast_json_unref); - struct ast_json *field; #if defined(AST_DEVMODE) int is_valid; int code; @@ -1622,10 +1730,9 @@ static void ast_ari_channels_get_channel_var_cb( goto fin; } } - /* Parse query parameters out of it */ - field = ast_json_object_get(body, "variable"); - if (field) { - args.variable = ast_json_string_get(field); + if (ast_ari_channels_get_channel_var_parse_body(body, &args)) { + ast_ari_response_alloc_failed(response); + goto fin; } ast_ari_channels_get_channel_var(headers, &args, response); #if defined(AST_DEVMODE) @@ -1662,6 +1769,23 @@ static void ast_ari_channels_get_channel_var_cb( fin: __attribute__((unused)) return; } +int ast_ari_channels_set_channel_var_parse_body( + struct ast_json *body, + struct ast_ari_channels_set_channel_var_args *args) +{ + struct ast_json *field; + /* Parse query parameters out of it */ + field = ast_json_object_get(body, "variable"); + if (field) { + args->variable = ast_json_string_get(field); + } + field = ast_json_object_get(body, "value"); + if (field) { + args->value = ast_json_string_get(field); + } + return 0; +} + /*! * \brief Parameter parsing callback for /channels/{channelId}/variable. * \param get_params GET parameters in the HTTP request. @@ -1677,7 +1801,6 @@ static void ast_ari_channels_set_channel_var_cb( struct ast_ari_channels_set_channel_var_args args = {}; struct ast_variable *i; RAII_VAR(struct ast_json *, body, NULL, ast_json_unref); - struct ast_json *field; #if defined(AST_DEVMODE) int is_valid; int code; @@ -1713,14 +1836,9 @@ static void ast_ari_channels_set_channel_var_cb( goto fin; } } - /* Parse query parameters out of it */ - field = ast_json_object_get(body, "variable"); - if (field) { - args.variable = ast_json_string_get(field); - } - field = ast_json_object_get(body, "value"); - if (field) { - args.value = ast_json_string_get(field); + if (ast_ari_channels_set_channel_var_parse_body(body, &args)) { + ast_ari_response_alloc_failed(response); + goto fin; } ast_ari_channels_set_channel_var(headers, &args, response); #if defined(AST_DEVMODE) @@ -1757,6 +1875,31 @@ static void ast_ari_channels_set_channel_var_cb( fin: __attribute__((unused)) return; } +int ast_ari_channels_snoop_channel_parse_body( + struct ast_json *body, + struct ast_ari_channels_snoop_channel_args *args) +{ + struct ast_json *field; + /* Parse query parameters out of it */ + field = ast_json_object_get(body, "spy"); + if (field) { + args->spy = ast_json_string_get(field); + } + field = ast_json_object_get(body, "whisper"); + if (field) { + args->whisper = ast_json_string_get(field); + } + field = ast_json_object_get(body, "app"); + if (field) { + args->app = ast_json_string_get(field); + } + field = ast_json_object_get(body, "appArgs"); + if (field) { + args->app_args = ast_json_string_get(field); + } + return 0; +} + /*! * \brief Parameter parsing callback for /channels/{channelId}/snoop. * \param get_params GET parameters in the HTTP request. @@ -1772,7 +1915,6 @@ static void ast_ari_channels_snoop_channel_cb( struct ast_ari_channels_snoop_channel_args args = {}; struct ast_variable *i; RAII_VAR(struct ast_json *, body, NULL, ast_json_unref); - struct ast_json *field; #if defined(AST_DEVMODE) int is_valid; int code; @@ -1814,22 +1956,9 @@ static void ast_ari_channels_snoop_channel_cb( goto fin; } } - /* Parse query parameters out of it */ - field = ast_json_object_get(body, "spy"); - if (field) { - args.spy = ast_json_string_get(field); - } - field = ast_json_object_get(body, "whisper"); - if (field) { - args.whisper = ast_json_string_get(field); - } - field = ast_json_object_get(body, "app"); - if (field) { - args.app = ast_json_string_get(field); - } - field = ast_json_object_get(body, "appArgs"); - if (field) { - args.app_args = ast_json_string_get(field); + if (ast_ari_channels_snoop_channel_parse_body(body, &args)) { + ast_ari_response_alloc_failed(response); + goto fin; } ast_ari_channels_snoop_channel(headers, &args, response); #if defined(AST_DEVMODE) diff --git a/res/res_ari_device_states.c b/res/res_ari_device_states.c index a8079f1391..5576a18594 100644 --- a/res/res_ari_device_states.c +++ b/res/res_ari_device_states.c @@ -160,6 +160,19 @@ static void ast_ari_device_states_get_cb( fin: __attribute__((unused)) return; } +int ast_ari_device_states_update_parse_body( + struct ast_json *body, + struct ast_ari_device_states_update_args *args) +{ + struct ast_json *field; + /* Parse query parameters out of it */ + field = ast_json_object_get(body, "deviceState"); + if (field) { + args->device_state = ast_json_string_get(field); + } + return 0; +} + /*! * \brief Parameter parsing callback for /deviceStates/{deviceName}. * \param get_params GET parameters in the HTTP request. @@ -175,7 +188,6 @@ static void ast_ari_device_states_update_cb( struct ast_ari_device_states_update_args args = {}; struct ast_variable *i; RAII_VAR(struct ast_json *, body, NULL, ast_json_unref); - struct ast_json *field; #if defined(AST_DEVMODE) int is_valid; int code; @@ -208,10 +220,9 @@ static void ast_ari_device_states_update_cb( goto fin; } } - /* Parse query parameters out of it */ - field = ast_json_object_get(body, "deviceState"); - if (field) { - args.device_state = ast_json_string_get(field); + if (ast_ari_device_states_update_parse_body(body, &args)) { + ast_ari_response_alloc_failed(response); + goto fin; } ast_ari_device_states_update(headers, &args, response); #if defined(AST_DEVMODE) diff --git a/res/res_ari_mailboxes.c b/res/res_ari_mailboxes.c index 842ff68134..40e132e3eb 100644 --- a/res/res_ari_mailboxes.c +++ b/res/res_ari_mailboxes.c @@ -161,6 +161,23 @@ static void ast_ari_mailboxes_get_cb( fin: __attribute__((unused)) return; } +int ast_ari_mailboxes_update_parse_body( + struct ast_json *body, + struct ast_ari_mailboxes_update_args *args) +{ + struct ast_json *field; + /* Parse query parameters out of it */ + field = ast_json_object_get(body, "oldMessages"); + if (field) { + args->old_messages = ast_json_integer_get(field); + } + field = ast_json_object_get(body, "newMessages"); + if (field) { + args->new_messages = ast_json_integer_get(field); + } + return 0; +} + /*! * \brief Parameter parsing callback for /mailboxes/{mailboxName}. * \param get_params GET parameters in the HTTP request. @@ -176,7 +193,6 @@ static void ast_ari_mailboxes_update_cb( struct ast_ari_mailboxes_update_args args = {}; struct ast_variable *i; RAII_VAR(struct ast_json *, body, NULL, ast_json_unref); - struct ast_json *field; #if defined(AST_DEVMODE) int is_valid; int code; @@ -212,14 +228,9 @@ static void ast_ari_mailboxes_update_cb( goto fin; } } - /* Parse query parameters out of it */ - field = ast_json_object_get(body, "oldMessages"); - if (field) { - args.old_messages = ast_json_integer_get(field); - } - field = ast_json_object_get(body, "newMessages"); - if (field) { - args.new_messages = ast_json_integer_get(field); + if (ast_ari_mailboxes_update_parse_body(body, &args)) { + ast_ari_response_alloc_failed(response); + goto fin; } ast_ari_mailboxes_update(headers, &args, response); #if defined(AST_DEVMODE) diff --git a/res/res_ari_playbacks.c b/res/res_ari_playbacks.c index 429f00dc21..fee22c38b0 100644 --- a/res/res_ari_playbacks.c +++ b/res/res_ari_playbacks.c @@ -169,6 +169,19 @@ static void ast_ari_playbacks_stop_cb( fin: __attribute__((unused)) return; } +int ast_ari_playbacks_control_parse_body( + struct ast_json *body, + struct ast_ari_playbacks_control_args *args) +{ + struct ast_json *field; + /* Parse query parameters out of it */ + field = ast_json_object_get(body, "operation"); + if (field) { + args->operation = ast_json_string_get(field); + } + return 0; +} + /*! * \brief Parameter parsing callback for /playbacks/{playbackId}/control. * \param get_params GET parameters in the HTTP request. @@ -184,7 +197,6 @@ static void ast_ari_playbacks_control_cb( struct ast_ari_playbacks_control_args args = {}; struct ast_variable *i; RAII_VAR(struct ast_json *, body, NULL, ast_json_unref); - struct ast_json *field; #if defined(AST_DEVMODE) int is_valid; int code; @@ -217,10 +229,9 @@ static void ast_ari_playbacks_control_cb( goto fin; } } - /* Parse query parameters out of it */ - field = ast_json_object_get(body, "operation"); - if (field) { - args.operation = ast_json_string_get(field); + if (ast_ari_playbacks_control_parse_body(body, &args)) { + ast_ari_response_alloc_failed(response); + goto fin; } ast_ari_playbacks_control(headers, &args, response); #if defined(AST_DEVMODE) diff --git a/res/res_ari_sounds.c b/res/res_ari_sounds.c index a3657d13ba..69c7d163e9 100644 --- a/res/res_ari_sounds.c +++ b/res/res_ari_sounds.c @@ -51,6 +51,23 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #define MAX_VALS 128 +int ast_ari_sounds_list_parse_body( + struct ast_json *body, + struct ast_ari_sounds_list_args *args) +{ + struct ast_json *field; + /* Parse query parameters out of it */ + field = ast_json_object_get(body, "lang"); + if (field) { + args->lang = ast_json_string_get(field); + } + field = ast_json_object_get(body, "format"); + if (field) { + args->format = ast_json_string_get(field); + } + return 0; +} + /*! * \brief Parameter parsing callback for /sounds. * \param get_params GET parameters in the HTTP request. @@ -66,7 +83,6 @@ static void ast_ari_sounds_list_cb( struct ast_ari_sounds_list_args args = {}; struct ast_variable *i; RAII_VAR(struct ast_json *, body, NULL, ast_json_unref); - struct ast_json *field; #if defined(AST_DEVMODE) int is_valid; int code; @@ -96,14 +112,9 @@ static void ast_ari_sounds_list_cb( goto fin; } } - /* Parse query parameters out of it */ - field = ast_json_object_get(body, "lang"); - if (field) { - args.lang = ast_json_string_get(field); - } - field = ast_json_object_get(body, "format"); - if (field) { - args.format = ast_json_string_get(field); + if (ast_ari_sounds_list_parse_body(body, &args)) { + ast_ari_response_alloc_failed(response); + goto fin; } ast_ari_sounds_list(headers, &args, response); #if defined(AST_DEVMODE) diff --git a/rest-api-templates/ari_resource.h.mustache b/rest-api-templates/ari_resource.h.mustache index e389eb5d7b..e66d9b6042 100644 --- a/rest-api-templates/ari_resource.h.mustache +++ b/rest-api-templates/ari_resource.h.mustache @@ -62,6 +62,19 @@ struct ast_ari_{{c_name}}_{{c_nickname}}_args { {{/parameters}} }; {{#is_req}} +{{#parse_body}} +/*! + * \brief Body parsing function for {{path}}. + * \param body The JSON body from which to parse parameters. + * \param[out] args The args structure to parse into. + * \retval zero on success + * \retval non-zero on failure + */ +int ast_ari_{{c_name}}_{{c_nickname}}_parse_body( + struct ast_json *body, + struct ast_ari_{{c_name}}_{{c_nickname}}_args *args); + +{{/parse_body}} /*! * \brief {{summary}} {{#notes}} diff --git a/rest-api-templates/asterisk_processor.py b/rest-api-templates/asterisk_processor.py index 7eb5bff6fa..ef0f1673a2 100644 --- a/rest-api-templates/asterisk_processor.py +++ b/rest-api-templates/asterisk_processor.py @@ -203,8 +203,10 @@ class AsteriskProcessor(SwaggerPostProcessor): def process_parameter(self, parameter, context): if parameter.param_type == 'body': + parameter.is_body_parameter = True; parameter.c_data_type = 'struct ast_json *' else: + parameter.is_body_parameter = False; if not parameter.data_type in self.type_mapping: raise SwaggerError( "Invalid parameter type %s" % parameter.data_type, context) diff --git a/rest-api-templates/body_parsing.mustache b/rest-api-templates/body_parsing.mustache new file mode 100644 index 0000000000..63cce0de8d --- /dev/null +++ b/rest-api-templates/body_parsing.mustache @@ -0,0 +1,71 @@ +{{! + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2014, Digium, Inc. + * + * William Kinsey Moore, III <kmoore@digium.com> + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. +}} +{{! + * Snippet for decoding parameters into an _args struct. +}} +{{#parse_body}} +int ast_ari_{{c_name}}_{{c_nickname}}_parse_body( + struct ast_json *body, + struct ast_ari_{{c_name}}_{{c_nickname}}_args *args) +{ +{{#has_query_parameters}} + struct ast_json *field; +{{/has_query_parameters}} + /* Parse query parameters out of it */ +{{#query_parameters}} +{{^is_body_parameter}} + field = ast_json_object_get(body, "{{name}}"); + if (field) { +{{^allow_multiple}} + args->{{c_name}} = {{json_convert}}(field); +{{/allow_multiple}} +{{#allow_multiple}} + /* If they were silly enough to both pass in a query param and a + * JSON body, free up the query value. + */ + ast_free(args->{{c_name}}); + if (ast_json_typeof(field) == AST_JSON_ARRAY) { + /* Multiple param passed as array */ + size_t i; + args->{{c_name}}_count = ast_json_array_size(field); + args->{{c_name}} = ast_malloc(sizeof(*args->{{c_name}}) * args->{{c_name}}_count); + + if (!args->{{c_name}}) { + return -1; + } + + for (i = 0; i < args->{{c_name}}_count; ++i) { + args->{{c_name}}[i] = {{json_convert}}(ast_json_array_get(field, i)); + } + } else { + /* Multiple param passed as single value */ + args->{{c_name}}_count = 1; + args->{{c_name}} = ast_malloc(sizeof(*args->{{c_name}}) * args->{{c_name}}_count); + if (!args->{{c_name}}) { + return -1; + } + args->{{c_name}}[0] = {{json_convert}}(field); + } +{{/allow_multiple}} + } +{{/is_body_parameter}} +{{/query_parameters}} + return 0; +} + +{{/parse_body}} diff --git a/rest-api-templates/param_parsing.mustache b/rest-api-templates/param_parsing.mustache index 9d20738693..2dde4b33fa 100644 --- a/rest-api-templates/param_parsing.mustache +++ b/rest-api-templates/param_parsing.mustache @@ -104,45 +104,10 @@ args.{{c_name}} = ast_json_ref(body); {{/body_parameter}} {{^body_parameter}} - /* Parse query parameters out of it */ -{{#query_parameters}} - field = ast_json_object_get(body, "{{name}}"); - if (field) { -{{^allow_multiple}} - args.{{c_name}} = {{json_convert}}(field); -{{/allow_multiple}} -{{#allow_multiple}} - /* If they were silly enough to both pass in a query param and a - * JSON body, free up the query value. - */ - ast_free(args.{{c_name}}); - if (ast_json_typeof(field) == AST_JSON_ARRAY) { - /* Multiple param passed as array */ - size_t i; - args.{{c_name}}_count = ast_json_array_size(field); - args.{{c_name}} = ast_malloc(sizeof(*args.{{c_name}}) * args.{{c_name}}_count); - - if (!args.{{c_name}}) { - ast_ari_response_alloc_failed(response); - goto fin; - } - - for (i = 0; i < args.{{c_name}}_count; ++i) { - args.{{c_name}}[i] = {{json_convert}}(ast_json_array_get(field, i)); - } - } else { - /* Multiple param passed as single value */ - args.{{c_name}}_count = 1; - args.{{c_name}} = ast_malloc(sizeof(*args.{{c_name}}) * args.{{c_name}}_count); - if (!args.{{c_name}}) { - ast_ari_response_alloc_failed(response); - goto fin; - } - args.{{c_name}}[0] = {{json_convert}}(field); - } -{{/allow_multiple}} + if (ast_ari_{{c_name}}_{{c_nickname}}_parse_body(body, &args)) { + ast_ari_response_alloc_failed(response); + goto fin; } -{{/query_parameters}} {{/body_parameter}} {{/parse_body}} {{/is_websocket}} diff --git a/rest-api-templates/res_ari_resource.c.mustache b/rest-api-templates/res_ari_resource.c.mustache index d2823a8776..74681fc298 100644 --- a/rest-api-templates/res_ari_resource.c.mustache +++ b/rest-api-templates/res_ari_resource.c.mustache @@ -66,6 +66,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") {{#apis}} {{#operations}} {{#is_req}} +{{> body_parsing}} /*! * \brief Parameter parsing callback for {{path}}. * \param get_params GET parameters in the HTTP request. @@ -83,11 +84,6 @@ static void ast_ari_{{c_name}}_{{c_nickname}}_cb( struct ast_variable *i; {{/has_parameters}} RAII_VAR(struct ast_json *, body, NULL, ast_json_unref); -{{^body_parameter}} -{{#has_query_parameters}} - struct ast_json *field; -{{/has_query_parameters}} -{{/body_parameter}} #if defined(AST_DEVMODE) int is_valid; int code; diff --git a/rest-api/api-docs/channels.json b/rest-api/api-docs/channels.json index 3b14c8fbb3..3ab6080cb4 100644 --- a/rest-api/api-docs/channels.json +++ b/rest-api/api-docs/channels.json @@ -88,6 +88,14 @@ "allowMultiple": false, "dataType": "int", "defaultValue": 30 + }, + { + "name": "variables", + "description": "The 'variables' key in the body object holds variable key/value pairs to set on the channel on creation. Other keys in the body object are interpreted as query parameters. Ex. { 'endpoint': 'SIP/Alice', 'variables': { 'CALLERID(name)': 'Alice' } }", + "paramType": "body", + "required": false, + "dataType": "containers", + "allowMultiple": false } ], "errorResponses": [ -- GitLab