diff --git a/include/asterisk/json.h b/include/asterisk/json.h index 02b617e80db5a524a67afea2454053bf993127e9..94c30d5fa10acbe5d239453f5499416481a0c3a3 100644 --- a/include/asterisk/json.h +++ b/include/asterisk/json.h @@ -1021,6 +1021,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 50dd601ff8400ea100f85d4806b09f837a634cbb..16137e0c2085257fc6e863f250c0e1e2c4980d73 100644 --- a/main/json.c +++ b/main/json.c @@ -892,12 +892,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 d0f502666adebc9654d684af72d8b41283ee87c5..cc7ab7d8c47eeb300ab02ac9c22f648783694d41 100644 --- a/main/stasis_channels.c +++ b/main/stasis_channels.c @@ -988,8 +988,9 @@ struct ast_json *ast_channel_snapshot_to_json( snapshot->connected_name, snapshot->connected_number), "accountcode", snapshot->accountcode, /* Third line */ - "dialplan", ast_json_dialplan_cep( - snapshot->context, snapshot->exten, snapshot->priority), + "dialplan", ast_json_dialplan_cep_app( + snapshot->context, snapshot->exten, snapshot->priority, + snapshot->appl, snapshot->data), "creationtime", ast_json_timeval(snapshot->creationtime, NULL), "language", snapshot->language); diff --git a/res/ari/ari_model_validators.c b/res/ari/ari_model_validators.c index 0b75f2b078bb262bf07b04b45796a85ad7ea9372..8e23d6bff618c2ef84e6f7054b30fade2cf0f597 100644 --- a/res/ari/ari_model_validators.c +++ b/res/ari/ari_model_validators.c @@ -1280,11 +1280,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; @@ -1323,6 +1345,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 e5c803ab8eff3e082dff26b7b180467a71251e52..64e11c0498a1d6c0b1dfaf2db84afd1462b6d47d 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 4d26b54a0a8219cf44f7a764c5ea446dbcd4ff08..fdeb0b8359d255a667c3b1cc313e3caed5b415d6 100644 --- a/rest-api/api-docs/channels.json +++ b/rest-api/api-docs/channels.json @@ -1565,6 +1565,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 12c56d43b82316229392c0baff6e3f0ded66327c..15c05fc509cee620376f23887efac8d5627a55be 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 ed6292b8c4d0bebc6224cbe7ee5f7c38e11bad4e..f64b364015f2e9e24aa3af4aaea5287fcfcafb62 100644 --- a/tests/test_stasis_channels.c +++ b/tests/test_stasis_channels.c @@ -275,7 +275,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" @@ -289,6 +289,8 @@ AST_TEST_DEFINE(channel_snapshot_json) "context", "context", "exten", "exten", "priority", 1, + "app_name", "", + "app_data", "", "caller", "name", "cid_name", "number", "cid_num",