*/
struct ast_json *ast_json_party_id(struct ast_party_id *party);
+enum ast_json_to_ast_vars_code {
+ /*! \brief Conversion successful */
+ AST_JSON_TO_AST_VARS_CODE_SUCCESS,
+ /*!
+ * \brief Conversion failed because invalid value type supplied.
+ * \note Only string values allowed.
+ */
+ AST_JSON_TO_AST_VARS_CODE_INVALID_TYPE,
+ /*! \brief Conversion failed because of allocation failure. (Out Of Memory) */
+ AST_JSON_TO_AST_VARS_CODE_OOM,
+};
+
/*!
* \brief Convert a \c ast_json list of key/value pair tuples into a \c ast_variable list
* \since 12.5.0
*
* \param json_variables The JSON blob containing the variable
* \param variables An out reference to the variables to populate.
- * The pointer to the variables should be NULL when calling this.
*
* \code
* struct ast_json *json_variables = ast_json_pack("[ { s: s } ]", "foo", "bar");
* res = ast_json_to_ast_variables(json_variables, &variables);
* \endcode
*
- * \retval 0 success
- * \retval -1 error
+ * \return Conversion enum ast_json_to_ast_vars_code status
*/
-int ast_json_to_ast_variables(struct ast_json *json_variables, struct ast_variable **variables);
+enum ast_json_to_ast_vars_code ast_json_to_ast_variables(struct ast_json *json_variables, struct ast_variable **variables);
/*!@}*/
return ast_json_ref(json_party_id);
}
-int ast_json_to_ast_variables(struct ast_json *json_variables, struct ast_variable **variables)
+enum ast_json_to_ast_vars_code ast_json_to_ast_variables(struct ast_json *json_variables, struct ast_variable **variables)
{
struct ast_json_iter *it_json_var;
*variables = NULL;
for (it_json_var = ast_json_object_iter(json_variables); it_json_var;
- it_json_var = ast_json_object_iter_next(json_variables, it_json_var)) {
+ it_json_var = ast_json_object_iter_next(json_variables, it_json_var)) {
struct ast_variable *new_var;
const char *key = ast_json_object_iter_key(it_json_var);
+ const char *value;
+ struct ast_json *json_value;
if (ast_strlen_zero(key)) {
continue;
}
- new_var = ast_variable_new(key,
- ast_json_string_get(ast_json_object_iter_value(it_json_var)),
- "");
+ json_value = ast_json_object_iter_value(it_json_var);
+ if (ast_json_typeof(json_value) != AST_JSON_STRING) {
+ /* Error: Only strings allowed */
+ ast_variables_destroy(*variables);
+ *variables = NULL;
+ return AST_JSON_TO_AST_VARS_CODE_INVALID_TYPE;
+ }
+ value = ast_json_string_get(json_value);
+ /* Should never be NULL. Otherwise, how could it be a string type? */
+ ast_assert(value != NULL);
+ if (!value) {
+ /* To be safe. */
+ continue;
+ }
+ new_var = ast_variable_new(key, value, "");
if (!new_var) {
+ /* Error: OOM */
ast_variables_destroy(*variables);
*variables = NULL;
- return -1;
+ return AST_JSON_TO_AST_VARS_CODE_OOM;
}
ast_variable_list_append(variables, new_var);
}
- return 0;
+ return AST_JSON_TO_AST_VARS_CODE_SUCCESS;
}
return;
}
+/*!
+ * \internal
+ * \brief Convert a \c ast_json list of key/value pair tuples into a \c ast_variable list
+ * \since 13.3.0
+ *
+ * \param[out] response HTTP response if error
+ * \param json_variables The JSON blob containing the variable
+ * \param[out] variables An out reference to the variables to populate.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+static int json_to_ast_variables(struct ast_ari_response *response, struct ast_json *json_variables, struct ast_variable **variables)
+{
+ enum ast_json_to_ast_vars_code res;
+
+ res = ast_json_to_ast_variables(json_variables, variables);
+ switch (res) {
+ case AST_JSON_TO_AST_VARS_CODE_SUCCESS:
+ return 0;
+ case AST_JSON_TO_AST_VARS_CODE_INVALID_TYPE:
+ ast_ari_response_error(response, 400, "Bad Request",
+ "Only string values in the 'variables' object allowed");
+ break;
+ case AST_JSON_TO_AST_VARS_CODE_OOM:
+ ast_ari_response_alloc_failed(response);
+ break;
+ }
+ ast_log(AST_LOG_ERROR, "Unable to convert 'variables' in JSON body to channel variables\n");
+
+ return -1;
+}
+
void ast_ari_channels_originate_with_id(struct ast_variable *headers,
struct ast_ari_channels_originate_with_id_args *args,
struct ast_ari_response *response)
{
- RAII_VAR(struct ast_variable *, variables, NULL, ast_variables_destroy);
+ struct ast_variable *variables = NULL;
/* Parse any query parameters out of the body parameter */
if (args->variables) {
ast_ari_channels_originate_with_id_parse_body(args->variables, args);
json_variables = ast_json_object_get(args->variables, "variables");
- if (json_variables) {
- if (ast_json_to_ast_variables(json_variables, &variables)) {
- ast_log(AST_LOG_ERROR, "Unable to convert 'variables' in JSON body to channel variables\n");
- ast_ari_response_alloc_failed(response);
- return;
- }
+ if (json_variables
+ && json_to_ast_variables(response, json_variables, &variables)) {
+ return;
}
}
args->other_channel_id,
args->originator,
response);
+ ast_variables_destroy(variables);
}
void ast_ari_channels_originate(struct ast_variable *headers,
struct ast_ari_channels_originate_args *args,
struct ast_ari_response *response)
{
- RAII_VAR(struct ast_variable *, variables, NULL, ast_variables_destroy);
+ struct ast_variable *variables = NULL;
/* Parse any query parameters out of the body parameter */
if (args->variables) {
ast_ari_channels_originate_parse_body(args->variables, args);
json_variables = ast_json_object_get(args->variables, "variables");
- if (json_variables) {
- if (ast_json_to_ast_variables(json_variables, &variables)) {
- ast_log(AST_LOG_ERROR, "Unable to convert 'variables' in JSON body to channel variables\n");
- ast_ari_response_alloc_failed(response);
- return;
- }
+ if (json_variables
+ && json_to_ast_variables(response, json_variables, &variables)) {
+ return;
}
}
args->other_channel_id,
args->originator,
response);
+ ast_variables_destroy(variables);
}
void ast_ari_channels_get_channel_var(struct ast_variable *headers,
response->response_text = "Accepted";
}
+/*!
+ * \internal
+ * \brief Convert a \c ast_json list of key/value pair tuples into a \c ast_variable list
+ * \since 13.3.0
+ *
+ * \param[out] response HTTP response if error
+ * \param json_variables The JSON blob containing the variable
+ * \param[out] variables An out reference to the variables to populate.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+static int json_to_ast_variables(struct ast_ari_response *response, struct ast_json *json_variables, struct ast_variable **variables)
+{
+ enum ast_json_to_ast_vars_code res;
+
+ res = ast_json_to_ast_variables(json_variables, variables);
+ switch (res) {
+ case AST_JSON_TO_AST_VARS_CODE_SUCCESS:
+ return 0;
+ case AST_JSON_TO_AST_VARS_CODE_INVALID_TYPE:
+ ast_ari_response_error(response, 400, "Bad Request",
+ "Only string values in the 'variables' object allowed");
+ break;
+ case AST_JSON_TO_AST_VARS_CODE_OOM:
+ ast_ari_response_alloc_failed(response);
+ break;
+ }
+ ast_log(AST_LOG_ERROR, "Unable to convert 'variables' in JSON body to Asterisk variables\n");
+
+ return -1;
+}
+
void ast_ari_endpoints_send_message(struct ast_variable *headers,
struct ast_ari_endpoints_send_message_args *args,
struct ast_ari_response *response)
{
- RAII_VAR(struct ast_variable *, variables, NULL, ast_variables_destroy);
+ struct ast_variable *variables = NULL;
if (args->variables) {
struct ast_json *json_variables;
ast_ari_endpoints_send_message_parse_body(args->variables, args);
json_variables = ast_json_object_get(args->variables, "variables");
- if (json_variables) {
- if (ast_json_to_ast_variables(json_variables, &variables)) {
- ast_log(AST_LOG_ERROR, "Unable to convert 'variables' in JSON body to Asterisk variables\n");
- ast_ari_response_alloc_failed(response);
- return;
- }
+ if (json_variables
+ && json_to_ast_variables(response, json_variables, &variables)) {
+ return;
}
}
send_message(args->to, args->from, args->body, variables, response);
+ ast_variables_destroy(variables);
}
void ast_ari_endpoints_send_message_to_endpoint(struct ast_variable *headers,
struct ast_ari_endpoints_send_message_to_endpoint_args *args,
struct ast_ari_response *response)
{
- RAII_VAR(struct ast_variable *, variables, NULL, ast_variables_destroy);
- RAII_VAR(struct ast_endpoint_snapshot *, snapshot, NULL, ao2_cleanup);
+ struct ast_variable *variables = NULL;
+ struct ast_endpoint_snapshot *snapshot;
char msg_to[128];
char *tech = ast_strdupa(args->tech);
"Endpoint not found");
return;
}
+ ao2_ref(snapshot, -1);
if (args->variables) {
struct ast_json *json_variables;
ast_ari_endpoints_send_message_to_endpoint_parse_body(args->variables, args);
json_variables = ast_json_object_get(args->variables, "variables");
-
- if (json_variables) {
- if (ast_json_to_ast_variables(json_variables, &variables)) {
- ast_log(AST_LOG_ERROR, "Unable to convert 'variables' in JSON body to Asterisk variables\n");
- ast_ari_response_alloc_failed(response);
- return;
- }
+ if (json_variables
+ && json_to_ast_variables(response, json_variables, &variables)) {
+ return;
}
}
snprintf(msg_to, sizeof(msg_to), "%s:%s", ast_str_to_lower(tech), args->resource);
send_message(msg_to, args->from, args->body, variables, response);
+ ast_variables_destroy(variables);
}
break;
case 500: /* Internal Server Error */
case 501: /* Not Implemented */
+ case 400: /* Invalid parameters for sending a message. */
case 404: /* Endpoint not found */
is_valid = 1;
break;
],
"errorResponses": [
{
+ "code": 400,
+ "reason": "Invalid parameters for sending a message."
+ },
+ {
"code": 404,
"reason": "Endpoint not found"
}