]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
ari: expose channel driver's unique id to ARI channel resource
authorMoritz Fain <moritz@fain.io>
Mon, 25 Apr 2022 22:40:49 +0000 (00:40 +0200)
committerFriendly Automation <jenkins2@gerrit.asterisk.org>
Fri, 20 May 2022 02:34:59 +0000 (21:34 -0500)
This change exposes the channel driver's unique id (i.e. the Call-ID
for chan_sip/chan_pjsip based channels) to ARI channel resources
as `protocol_id`.

ASTERISK-30027
Reported by: Moritz Fain
Tested by: Moritz Fain

Change-Id: I7cc6e7a9d29efe74bc27811d788dac20fe559b87

channels/chan_pjsip.c
doc/CHANGES-staging/ari_add_pvt_id_to_channel_resource.txt [new file with mode: 0644]
include/asterisk/stasis_channels.h
main/channel_internal_api.c
main/stasis_channels.c
res/ari/ari_model_validators.c
res/ari/ari_model_validators.h
rest-api/api-docs/channels.json
tests/test_stasis_channels.c

index b70b210cec8654dccb977eda5bd7d9ede7a0e5b5..7c6b301080e1f4675cbcf4654cbf4914200d4bb1 100644 (file)
@@ -1273,7 +1273,7 @@ static const char *chan_pjsip_get_uniqueid(struct ast_channel *ast)
        struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
        char *uniqueid = ast_threadstorage_get(&uniqueid_threadbuf, UNIQUEID_BUFSIZE);
 
-       if (!uniqueid) {
+       if (!channel || !uniqueid) {
                return "";
        }
 
diff --git a/doc/CHANGES-staging/ari_add_pvt_id_to_channel_resource.txt b/doc/CHANGES-staging/ari_add_pvt_id_to_channel_resource.txt
new file mode 100644 (file)
index 0000000..a4f008f
--- /dev/null
@@ -0,0 +1,7 @@
+Subject: ari
+Subject: stasis_channels
+
+Expose channel driver's unique id (which is the Call-ID for SIP/PJSIP)
+to ARI channel resources as 'protocol_id'.
+
+ASTERISK-30027
index 80c79ebd2ef24d858b1b8d56b1ca049675ca2e8f..73771864a6ea7449c4a5191d0c537d8c864ebdca 100644 (file)
@@ -112,6 +112,7 @@ struct ast_channel_snapshot_base {
        );
        struct timeval creationtime; /*!< The time of channel creation */
        int tech_properties;         /*!< Properties of the channel's technology */
+       AST_STRING_FIELD_EXTENDED(protocol_id); /*!< Channel driver protocol id (i.e. Call-ID for chan_sip/chan_pjsip) */
 };
 
 /*!
index 131faae452494d69c440ca5ce338351839c7c937..123f61aebd248861d2c3217e5c7f08d2f2313954 100644 (file)
@@ -587,6 +587,9 @@ void *ast_channel_tech_pvt(const struct ast_channel *chan)
 void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)
 {
        chan->tech_pvt = value;
+       if (value != NULL) {
+               ast_channel_snapshot_invalidate_segment(chan, AST_CHANNEL_SNAPSHOT_INVALIDATE_BASE);
+       }
 }
 void *ast_channel_timingdata(const struct ast_channel *chan)
 {
index 8becf96f898292dbd4033beb00ac400360ae76fc..d373f6a5ef649092d8632b0f2b400c3be3eecb72 100644 (file)
@@ -273,7 +273,7 @@ static struct ast_channel_snapshot_base *channel_snapshot_base_create(struct ast
                return NULL;
        }
 
-       if (ast_string_field_init(snapshot, 256)) {
+       if (ast_string_field_init(snapshot, 256) || ast_string_field_init_extended(snapshot, protocol_id)) {
                ao2_ref(snapshot, -1);
                return NULL;
        }
@@ -288,6 +288,10 @@ static struct ast_channel_snapshot_base *channel_snapshot_base_create(struct ast
        snapshot->creationtime = ast_channel_creationtime(chan);
        snapshot->tech_properties = ast_channel_tech(chan)->properties;
 
+       if (ast_channel_tech(chan)->get_pvt_uniqueid) {
+               ast_string_field_set(snapshot, protocol_id, ast_channel_tech(chan)->get_pvt_uniqueid(chan));
+       }
+
        return snapshot;
 }
 
@@ -1266,14 +1270,15 @@ struct ast_json *ast_channel_snapshot_to_json(
        }
 
        json_chan = ast_json_pack(
-               /* Broken up into groups of three for readability */
-               "{ s: s, s: s, s: s,"
+               /* Broken up into groups for readability */
+               "{ s: s, s: s, s: s, s: s,"
                "  s: o, s: o, s: s,"
                "  s: o, s: o, s: s }",
                /* First line */
                "id", snapshot->base->uniqueid,
                "name", snapshot->base->name,
                "state", ast_state2str(snapshot->state),
+               "protocol_id", snapshot->base->protocol_id,
                /* Second line */
                "caller", ast_json_name_number(
                        snapshot->caller->name, snapshot->caller->number),
index 0bbbb195e2be4d8212f9d451acb1e0c58a7e0272..fffb87a1624f047c3afe8c71414d44a0c04a73b4 100644 (file)
@@ -1043,6 +1043,7 @@ int ast_ari_validate_channel(struct ast_json *json)
        int has_id = 0;
        int has_language = 0;
        int has_name = 0;
+       int has_protocol_id = 0;
        int has_state = 0;
 
        for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
@@ -1135,6 +1136,16 @@ int ast_ari_validate_channel(struct ast_json *json)
                                res = 0;
                        }
                } else
+               if (strcmp("protocol_id", ast_json_object_iter_key(iter)) == 0) {
+                       int prop_is_valid;
+                       has_protocol_id = 1;
+                       prop_is_valid = ast_ari_validate_string(
+                               ast_json_object_iter_value(iter));
+                       if (!prop_is_valid) {
+                               ast_log(LOG_ERROR, "ARI Channel field protocol_id failed validation\n");
+                               res = 0;
+                       }
+               } else
                if (strcmp("state", ast_json_object_iter_key(iter)) == 0) {
                        int prop_is_valid;
                        has_state = 1;
@@ -1193,6 +1204,11 @@ int ast_ari_validate_channel(struct ast_json *json)
                res = 0;
        }
 
+       if (!has_protocol_id) {
+               ast_log(LOG_ERROR, "ARI Channel missing required field protocol_id\n");
+               res = 0;
+       }
+
        if (!has_state) {
                ast_log(LOG_ERROR, "ARI Channel missing required field state\n");
                res = 0;
index 583cba33a4e7cfb34e0c5a708a32c491c86eb0af..64f167c07cdc1dd20994636980ba16fd055c2a36 100644 (file)
@@ -1353,6 +1353,7 @@ ari_validator ast_ari_validate_application_fn(void);
  * - id: string (required)
  * - language: string (required)
  * - name: string (required)
+ * - protocol_id: string (required)
  * - state: string (required)
  * Dialed
  * DialplanCEP
index 04d1577337f3213efd9e4ff82ff9d73e39566ec8..269976dfa4bc20b54b00691c77b5786d8a5b3b46 100644 (file)
                                        "type": "string",
                                        "description": "Unique identifier of the channel.\n\nThis is the same as the Uniqueid field in AMI."
                                },
+                               "protocol_id": {
+                                       "required": true,
+                                       "type": "string",
+                                       "description": "Protocol id from underlying channel driver (i.e. Call-ID for chan_sip/chan_pjsip; will be empty if not applicable or not implemented by driver)."
+                               },
                                "name": {
                                        "required": true,
                                        "type": "string",
index d4a05b206f98ff625d100c71fe0f66e5aed09148..5ea9dd807c3e8b8b7d6dd8b5b5c63fd207374370 100644 (file)
@@ -273,7 +273,7 @@ AST_TEST_DEFINE(channel_snapshot_json)
        ast_test_validate(test, NULL != snapshot);
 
        actual = ast_channel_snapshot_to_json(snapshot, NULL);
-       expected = ast_json_pack("{ s: s, s: s, s: s, s: s,"
+       expected = ast_json_pack("{ s: s, s: s, s: s, s: s, s: s,"
                                 "  s: { s: s, s: s, s: i, s: s, s: s },"
                                 "  s: { s: s, s: s },"
                                 "  s: { s: s, s: s },"
@@ -284,6 +284,7 @@ AST_TEST_DEFINE(channel_snapshot_json)
                                 "state", "Down",
                                 "accountcode", "acctcode",
                                 "id", ast_channel_uniqueid(chan),
+                                "protocol_id", "",
                                 "dialplan",
                                 "context", "context",
                                 "exten", "exten",