diff --git a/include/asterisk/json.h b/include/asterisk/json.h index 665380c760897459719f7c4a05a55c6c69064fdc..ce0baa452740d94b7f8e2f68daa512fbbc65a0bb 100644 --- a/include/asterisk/json.h +++ b/include/asterisk/json.h @@ -992,6 +992,22 @@ struct ast_json *ast_json_timeval(const struct timeval tv, const char *zone); */ struct ast_json *ast_json_ipaddr(const struct ast_sockaddr *addr, enum ast_transport transport_type); +/*! + * \brief Construct a context/exten/priority/application/application_data as JSON. + * + * If a \c NULL is passed for \c context or \c exten or \c app_name or \c app_data, + * or -1 for \c priority, the fields is set to ast_json_null(). + * + * \param context Context name. + * \param exten Extension. + * \param priority Dialplan priority. + * \param app_name Application name. + * \param app_data Application argument. + * \return JSON object with \c context, \c exten and \c priority \c app_name \c app_data fields + */ +struct ast_json *ast_json_dialplan_cep_app( + const char *context, const char *exten, int priority, const char *app_name, const char *app_data); + /*! * \brief Construct a context/exten/priority as JSON. * diff --git a/main/json.c b/main/json.c index f72de41020660b772ab15057987b73a03c2f4482..09101aa61edd0f3721e86e31013e00ed5c2142f8 100644 --- a/main/json.c +++ b/main/json.c @@ -629,12 +629,21 @@ struct ast_json *ast_json_name_number(const char *name, const char *number) "number", AST_JSON_UTF8_VALIDATE(number)); } +struct ast_json *ast_json_dialplan_cep_app( + const char *context, const char *exten, int priority, const char *app_name, const char *app_data) +{ + return ast_json_pack("{s: s?, s: s?, s: o, s: s?, s: s?}", + "context", context, + "exten", exten, + "priority", priority != -1 ? ast_json_integer_create(priority) : ast_json_null(), + "app_name", app_name, + "app_data", app_data + ); +} + struct ast_json *ast_json_dialplan_cep(const char *context, const char *exten, int priority) { - return ast_json_pack("{s: o, s: o, s: o}", - "context", context ? ast_json_string_create(context) : ast_json_null(), - "exten", exten ? ast_json_string_create(exten) : ast_json_null(), - "priority", priority != -1 ? ast_json_integer_create(priority) : ast_json_null()); + return ast_json_dialplan_cep_app(context, exten, priority, "", ""); } struct ast_json *ast_json_timeval(const struct timeval tv, const char *zone) diff --git a/main/stasis_channels.c b/main/stasis_channels.c index e8842c1bfe6926db63e2429f1477c88994b64271..be77cb92857ac510830ca590ef7819abdbbf6d78 100644 --- a/main/stasis_channels.c +++ b/main/stasis_channels.c @@ -1281,8 +1281,9 @@ struct ast_json *ast_channel_snapshot_to_json( snapshot->connected->name, snapshot->connected->number), "accountcode", snapshot->base->accountcode, /* Third line */ - "dialplan", ast_json_dialplan_cep( - snapshot->dialplan->context, snapshot->dialplan->exten, snapshot->dialplan->priority), + "dialplan", ast_json_dialplan_cep_app( + snapshot->dialplan->context, snapshot->dialplan->exten, snapshot->dialplan->priority, + snapshot->dialplan->appl, snapshot->dialplan->data), "creationtime", ast_json_timeval(snapshot->base->creationtime, NULL), "language", snapshot->base->language); diff --git a/res/ari/ari_model_validators.c b/res/ari/ari_model_validators.c index bc7ac6b2fa0f5f10868cead578dc7569b7421917..1194a464b97bf46b4e5940839fb40f883516673c 100644 --- a/res/ari/ari_model_validators.c +++ b/res/ari/ari_model_validators.c @@ -1287,11 +1287,33 @@ int ast_ari_validate_dialplan_cep(struct ast_json *json) { int res = 1; struct ast_json_iter *iter; + int has_app_data = 0; + int has_app_name = 0; int has_context = 0; int has_exten = 0; int has_priority = 0; for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) { + if (strcmp("app_data", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_app_data = 1; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI DialplanCEP field app_data failed validation\n"); + res = 0; + } + } else + if (strcmp("app_name", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + has_app_name = 1; + prop_is_valid = ast_ari_validate_string( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI DialplanCEP field app_name failed validation\n"); + res = 0; + } + } else if (strcmp("context", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_context = 1; @@ -1330,6 +1352,16 @@ int ast_ari_validate_dialplan_cep(struct ast_json *json) } } + if (!has_app_data) { + ast_log(LOG_ERROR, "ARI DialplanCEP missing required field app_data\n"); + res = 0; + } + + if (!has_app_name) { + ast_log(LOG_ERROR, "ARI DialplanCEP missing required field app_name\n"); + res = 0; + } + if (!has_context) { ast_log(LOG_ERROR, "ARI DialplanCEP missing required field context\n"); res = 0; diff --git a/res/ari/ari_model_validators.h b/res/ari/ari_model_validators.h index 8fa28bc9ebb50013982802824b4d61c4d4a7a71a..133747d9ba944e49f845c405c54b0b525eb8324e 100644 --- a/res/ari/ari_model_validators.h +++ b/res/ari/ari_model_validators.h @@ -1499,6 +1499,8 @@ ari_validator ast_ari_validate_application_fn(void); * - state: string (required) * Dialed * DialplanCEP + * - app_data: string (required) + * - app_name: string (required) * - context: string (required) * - exten: string (required) * - priority: long (required) diff --git a/rest-api/api-docs/channels.json b/rest-api/api-docs/channels.json index 616193421efba295186241af23bcbfbc2cde9d06..53a362eac037e6743e47ab6657acfce63b1d97ca 100644 --- a/rest-api/api-docs/channels.json +++ b/rest-api/api-docs/channels.json @@ -1746,6 +1746,16 @@ "required": true, "type": "long", "description": "Priority in the dialplan" + }, + "app_name": { + "required": true, + "type": "string", + "description": "Name of current dialplan application" + }, + "app_data": { + "required": true, + "type": "string", + "description": "Parameter of current dialplan application" } } }, diff --git a/tests/test_json.c b/tests/test_json.c index 2f710868ec4c90c092d3c9d36570119b1aeaa7ce..8dbb8727923f9f456c266fd78b386242b87d79c4 100644 --- a/tests/test_json.c +++ b/tests/test_json.c @@ -1680,20 +1680,26 @@ AST_TEST_DEFINE(json_test_cep) break; } - expected = ast_json_pack("{s: o, s: o, s: o}", + expected = ast_json_pack("{s: o, s: o, s: o, s: o, s: o}", "context", ast_json_null(), "exten", ast_json_null(), - "priority", ast_json_null()); - uut = ast_json_dialplan_cep(NULL, NULL, -1); + "priority", ast_json_null(), + "app_name", ast_json_null(), + "app_data", ast_json_null() + ); + uut = ast_json_dialplan_cep_app(NULL, NULL, -1, NULL, NULL); ast_test_validate(test, ast_json_equal(expected, uut)); ast_json_unref(expected); ast_json_unref(uut); - expected = ast_json_pack("{s: s, s: s, s: i}", + expected = ast_json_pack("{s: s, s: s, s: i, s: s, s: s}", "context", "main", "exten", "4321", - "priority", 7); - uut = ast_json_dialplan_cep("main", "4321", 7); + "priority", 7, + "app_name", "", + "app_data", "" + ); + uut = ast_json_dialplan_cep_app("main", "4321", 7, "", ""); ast_test_validate(test, ast_json_equal(expected, uut)); return AST_TEST_PASS; diff --git a/tests/test_stasis_channels.c b/tests/test_stasis_channels.c index f8d2a03f818495150f1c04eea0e1bd950f107edd..d4a05b206f98ff625d100c71fe0f66e5aed09148 100644 --- a/tests/test_stasis_channels.c +++ b/tests/test_stasis_channels.c @@ -274,7 +274,7 @@ AST_TEST_DEFINE(channel_snapshot_json) actual = ast_channel_snapshot_to_json(snapshot, NULL); expected = ast_json_pack("{ s: s, s: s, s: s, s: s," - " s: { s: s, s: s, s: i }," + " s: { s: s, s: s, s: i, s: s, s: s }," " s: { s: s, s: s }," " s: { s: s, s: s }," " s: s" @@ -288,6 +288,8 @@ AST_TEST_DEFINE(channel_snapshot_json) "context", "context", "exten", "exten", "priority", 1, + "app_name", "", + "app_data", "", "caller", "name", "cid_name", "number", "cid_num",