@kusinta/iot-schema 0.1.0-beta.9 → 0.2.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +13 -2
- package/src/kusinta/iot/access/v1/acl_pb.d.ts +100 -11
- package/src/kusinta/iot/access/v1/acl_pb.js +11 -4
- package/src/kusinta/iot/access/v1/roles_pb.d.ts +27 -0
- package/src/kusinta/iot/access/v1/roles_pb.js +4 -0
- package/src/kusinta/iot/connector/v1/connector_pb.d.ts +60 -30
- package/src/kusinta/iot/connector/v1/connector_pb.js +12 -11
- package/src/kusinta/iot/connector/v1/connector_service_pb.d.ts +5 -5
- package/src/kusinta/iot/connector/v1/connector_service_pb.js +1 -1
- package/src/kusinta/iot/device/v1/cluster_state_pb.d.ts +238 -0
- package/src/kusinta/iot/device/v1/cluster_state_pb.js +54 -0
- package/src/kusinta/iot/device/v1/descriptor_pb.d.ts +37 -8
- package/src/kusinta/iot/device/v1/descriptor_pb.js +2 -1
- package/src/kusinta/iot/device/v1/device_event_pb.d.ts +162 -0
- package/src/kusinta/iot/device/v1/device_event_pb.js +45 -0
- package/src/kusinta/iot/device/v1/device_pb.d.ts +154 -28
- package/src/kusinta/iot/device/v1/device_pb.js +10 -2
- package/src/kusinta/iot/device/v1/matter_options_pb.d.ts +84 -0
- package/src/kusinta/iot/device/v1/matter_options_pb.js +91 -0
- package/src/kusinta/iot/device/v1/properties_pb.d.ts +228 -207
- package/src/kusinta/iot/device/v1/properties_pb.js +9 -1
- package/src/kusinta/iot/device/v1/property_update_pb.d.ts +197 -8
- package/src/kusinta/iot/device/v1/property_update_pb.js +20 -2
- package/src/kusinta/iot/registration/v1/registration_pb.d.ts +170 -0
- package/src/kusinta/iot/registration/v1/registration_pb.js +61 -0
- package/src/kusinta/iot/registration/v1/registration_service_pb.d.ts +34 -0
- package/src/kusinta/iot/registration/v1/registration_service_pb.js +19 -0
- package/src/kusinta/iot/signaling/v1/signaling_pb.d.ts +320 -0
- package/src/kusinta/iot/signaling/v1/signaling_pb.js +83 -0
- package/src/kusinta/iot/signaling/v1/signaling_service_pb.d.ts +34 -0
- package/src/kusinta/iot/signaling/v1/signaling_service_pb.js +19 -0
- package/src/kusinta/iot/vendor/homematic/v1/homematic_pb.d.ts +65 -47
- package/src/kusinta/iot/vendor/homematic/v1/homematic_pb.js +8 -7
- package/src/kusinta/iot/vendor/v1/vendor_options_pb.d.ts +50 -0
- package/src/kusinta/iot/vendor/v1/vendor_options_pb.js +53 -0
- package/src/kusinta/iot/webrtc/v1/app_token_pb.d.ts +152 -0
- package/src/kusinta/iot/webrtc/v1/app_token_pb.js +28 -0
- package/src/kusinta/iot/webrtc/v1/command_pb.d.ts +269 -39
- package/src/kusinta/iot/webrtc/v1/command_pb.js +28 -2
- package/src/kusinta/iot/webrtc/v1/device_state_pb.d.ts +65 -2
- package/src/kusinta/iot/webrtc/v1/device_state_pb.js +16 -1
- package/src/kusinta/iot/webrtc/v1/envelope_pb.d.ts +368 -21
- package/src/kusinta/iot/webrtc/v1/envelope_pb.js +68 -5
- package/src/kusinta/iot/webrtc/v1/management_pb.d.ts +451 -0
- package/src/kusinta/iot/webrtc/v1/management_pb.js +106 -0
- package/src/kusinta/iot/webrtc/v1/permission_push_pb.d.ts +7 -1
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// @generated by protoc-gen-es v2.12.0 with parameter "target=js+dts,import_extension=js"
|
|
2
|
+
// @generated from file kusinta/iot/vendor/v1/vendor_options.proto (package kusinta.iot.vendor.v1, syntax proto3)
|
|
3
|
+
/* eslint-disable */
|
|
4
|
+
|
|
5
|
+
import type { GenExtension, GenFile } from "@bufbuild/protobuf/codegenv2";
|
|
6
|
+
import type { FieldOptions, MessageOptions } from "@bufbuild/protobuf/wkt";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Describes the file kusinta/iot/vendor/v1/vendor_options.proto.
|
|
10
|
+
*/
|
|
11
|
+
export declare const file_kusinta_iot_vendor_v1_vendor_options: GenFile;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The vendor parameter this field carries, in the vendor's own spelling — e.g.
|
|
15
|
+
* "LEVEL", not "level". Matches device.v1.PropertyUpdate.attribute_name byte for byte
|
|
16
|
+
* when that update names a vendor extension.
|
|
17
|
+
*
|
|
18
|
+
* This and the Matter annotations are mutually exclusive: a field is either a Matter
|
|
19
|
+
* attribute or a vendor parameter. Which branch a PropertyUpdate takes is decided by
|
|
20
|
+
* whether it names a vendor extension, never by inspecting both.
|
|
21
|
+
*
|
|
22
|
+
* Must be unique within the message it appears in — the vendor branch matches one
|
|
23
|
+
* field of one message, so a repeat would make resolution ambiguous.
|
|
24
|
+
*
|
|
25
|
+
* @generated from extension: string vendor_attribute = 50004;
|
|
26
|
+
*/
|
|
27
|
+
export declare const vendor_attribute: GenExtension<FieldOptions, string>;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The stable key identifying a vendor extension message, e.g. "homematic.thermostat".
|
|
31
|
+
* Matches device.v1.PropertyUpdate.vendor_extension byte for byte, and is what selects
|
|
32
|
+
* the Endpoint.vendor_properties case.
|
|
33
|
+
*
|
|
34
|
+
* One key per message carried in Endpoint.vendor_properties, so the vendor branch of the
|
|
35
|
+
* resolution rule is the same shape as the Matter branch: pick a message by a message
|
|
36
|
+
* option, then one field by a field option. Nothing nests.
|
|
37
|
+
*
|
|
38
|
+
* Form: "<vendor>.<what the message models>", lower_snake_case on both sides —
|
|
39
|
+
* "homematic.thermostat", and a humidity one would be "homematic.humidity_sensor". The
|
|
40
|
+
* vendor half alone is NOT a key: a vendor has one message per device type it extends,
|
|
41
|
+
* and two sharing a key would make the branch non-deterministic. A test asserts they
|
|
42
|
+
* are distinct, but it cannot tell you which of two is wrong, so keep to the form.
|
|
43
|
+
*
|
|
44
|
+
* Not derived from the package or message name — this is the authoritative spelling,
|
|
45
|
+
* exactly as matter_attribute is on the Matter side.
|
|
46
|
+
*
|
|
47
|
+
* @generated from extension: string vendor_extension = 50005;
|
|
48
|
+
*/
|
|
49
|
+
export declare const vendor_extension: GenExtension<MessageOptions, string>;
|
|
50
|
+
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// @generated by protoc-gen-es v2.12.0 with parameter "target=js+dts,import_extension=js"
|
|
2
|
+
// @generated from file kusinta/iot/vendor/v1/vendor_options.proto (package kusinta.iot.vendor.v1, syntax proto3)
|
|
3
|
+
/* eslint-disable */
|
|
4
|
+
|
|
5
|
+
import { extDesc, fileDesc } from "@bufbuild/protobuf/codegenv2";
|
|
6
|
+
import { file_google_protobuf_descriptor } from "@bufbuild/protobuf/wkt";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Describes the file kusinta/iot/vendor/v1/vendor_options.proto.
|
|
10
|
+
*/
|
|
11
|
+
export const file_kusinta_iot_vendor_v1_vendor_options = /*@__PURE__*/
|
|
12
|
+
fileDesc("CiprdXNpbnRhL2lvdC92ZW5kb3IvdjEvdmVuZG9yX29wdGlvbnMucHJvdG8SFWt1c2ludGEuaW90LnZlbmRvci52MTpKChB2ZW5kb3JfYXR0cmlidXRlEh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucxjUhgMgASgJUg92ZW5kb3JBdHRyaWJ1dGU6TAoQdmVuZG9yX2V4dGVuc2lvbhIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxjVhgMgASgJUg92ZW5kb3JFeHRlbnNpb25iBnByb3RvMw", [file_google_protobuf_descriptor]);
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The vendor parameter this field carries, in the vendor's own spelling — e.g.
|
|
16
|
+
* "LEVEL", not "level". Matches device.v1.PropertyUpdate.attribute_name byte for byte
|
|
17
|
+
* when that update names a vendor extension.
|
|
18
|
+
*
|
|
19
|
+
* This and the Matter annotations are mutually exclusive: a field is either a Matter
|
|
20
|
+
* attribute or a vendor parameter. Which branch a PropertyUpdate takes is decided by
|
|
21
|
+
* whether it names a vendor extension, never by inspecting both.
|
|
22
|
+
*
|
|
23
|
+
* Must be unique within the message it appears in — the vendor branch matches one
|
|
24
|
+
* field of one message, so a repeat would make resolution ambiguous.
|
|
25
|
+
*
|
|
26
|
+
* @generated from extension: string vendor_attribute = 50004;
|
|
27
|
+
*/
|
|
28
|
+
export const vendor_attribute = /*@__PURE__*/
|
|
29
|
+
extDesc(file_kusinta_iot_vendor_v1_vendor_options, 0);
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The stable key identifying a vendor extension message, e.g. "homematic.thermostat".
|
|
33
|
+
* Matches device.v1.PropertyUpdate.vendor_extension byte for byte, and is what selects
|
|
34
|
+
* the Endpoint.vendor_properties case.
|
|
35
|
+
*
|
|
36
|
+
* One key per message carried in Endpoint.vendor_properties, so the vendor branch of the
|
|
37
|
+
* resolution rule is the same shape as the Matter branch: pick a message by a message
|
|
38
|
+
* option, then one field by a field option. Nothing nests.
|
|
39
|
+
*
|
|
40
|
+
* Form: "<vendor>.<what the message models>", lower_snake_case on both sides —
|
|
41
|
+
* "homematic.thermostat", and a humidity one would be "homematic.humidity_sensor". The
|
|
42
|
+
* vendor half alone is NOT a key: a vendor has one message per device type it extends,
|
|
43
|
+
* and two sharing a key would make the branch non-deterministic. A test asserts they
|
|
44
|
+
* are distinct, but it cannot tell you which of two is wrong, so keep to the form.
|
|
45
|
+
*
|
|
46
|
+
* Not derived from the package or message name — this is the authoritative spelling,
|
|
47
|
+
* exactly as matter_attribute is on the Matter side.
|
|
48
|
+
*
|
|
49
|
+
* @generated from extension: string vendor_extension = 50005;
|
|
50
|
+
*/
|
|
51
|
+
export const vendor_extension = /*@__PURE__*/
|
|
52
|
+
extDesc(file_kusinta_iot_vendor_v1_vendor_options, 1);
|
|
53
|
+
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
// @generated by protoc-gen-es v2.12.0 with parameter "target=js+dts,import_extension=js"
|
|
2
|
+
// @generated from file kusinta/iot/webrtc/v1/app_token.proto (package kusinta.iot.webrtc.v1, syntax proto3)
|
|
3
|
+
/* eslint-disable */
|
|
4
|
+
|
|
5
|
+
import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2";
|
|
6
|
+
import type { Message } from "@bufbuild/protobuf";
|
|
7
|
+
import type { Timestamp } from "@bufbuild/protobuf/wkt";
|
|
8
|
+
import type { Role } from "../../access/v1/roles_pb.js";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Describes the file kusinta/iot/webrtc/v1/app_token.proto.
|
|
12
|
+
*/
|
|
13
|
+
export declare const file_kusinta_iot_webrtc_v1_app_token: GenFile;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* AppTokenClaims is the contract for the payload of the JWT carried in
|
|
17
|
+
* AppHandshake.jwt. It is the single source of truth shared between the
|
|
18
|
+
* api-server (which mints the token) and the gateway (which validates it
|
|
19
|
+
* locally against the api-server's public key).
|
|
20
|
+
*
|
|
21
|
+
* This message is NOT sent on the wire — the wire value stays the signed,
|
|
22
|
+
* compact JWS string in AppHandshake.jwt. The fields here document the claim
|
|
23
|
+
* names and types each side must agree on. JWT libraries emit registered
|
|
24
|
+
* claims (iss/aud/sub) as flat strings and timestamps as NumericDate
|
|
25
|
+
* (seconds since the Unix epoch), so map to/from your native JWT library
|
|
26
|
+
* rather than serializing this message directly into the token.
|
|
27
|
+
*
|
|
28
|
+
* @generated from message kusinta.iot.webrtc.v1.AppTokenClaims
|
|
29
|
+
*/
|
|
30
|
+
export declare type AppTokenClaims = Message<"kusinta.iot.webrtc.v1.AppTokenClaims"> & {
|
|
31
|
+
/**
|
|
32
|
+
* Registered claims (RFC 7519).
|
|
33
|
+
* Issuer: the api-server's issuer identifier, agreed out of band. A fixed
|
|
34
|
+
* string both sides compare exactly — not derived from anything here.
|
|
35
|
+
*
|
|
36
|
+
* @generated from field: string iss = 1;
|
|
37
|
+
*/
|
|
38
|
+
iss: string;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* audience: the target GatewayId value
|
|
42
|
+
*
|
|
43
|
+
* @generated from field: string aud = 2;
|
|
44
|
+
*/
|
|
45
|
+
aud: string;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* subject: the UserId value
|
|
49
|
+
*
|
|
50
|
+
* @generated from field: string sub = 3;
|
|
51
|
+
*/
|
|
52
|
+
sub: string;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* issued-at (JWT NumericDate on the wire)
|
|
56
|
+
*
|
|
57
|
+
* @generated from field: google.protobuf.Timestamp iat = 4;
|
|
58
|
+
*/
|
|
59
|
+
iat?: Timestamp | undefined;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* expiry (JWT NumericDate on the wire)
|
|
63
|
+
*
|
|
64
|
+
* @generated from field: google.protobuf.Timestamp exp = 5;
|
|
65
|
+
*/
|
|
66
|
+
exp?: Timestamp | undefined;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Custom claims.
|
|
70
|
+
* A user may hold several roles at once (e.g. resident + gateway admin), so
|
|
71
|
+
* this is a list. Carried in the JWT as an array of enum NAME strings
|
|
72
|
+
* (e.g. ["ROLE_RESIDENT", "ROLE_GATEWAY_ADMIN"]), matching proto3 canonical
|
|
73
|
+
* JSON enum encoding — not integer values. This keeps the claim
|
|
74
|
+
* self-describing and aligns with text-typed role storage on the api-server.
|
|
75
|
+
*
|
|
76
|
+
* @generated from field: repeated kusinta.iot.access.v1.Role roles = 6;
|
|
77
|
+
*/
|
|
78
|
+
roles: Role[];
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* RFC 7800 confirmation claim. Binds the token to the DTLS certificate of the
|
|
82
|
+
* connection it may be presented on: the validator compares this against the
|
|
83
|
+
* fingerprint of the live peer and rejects on mismatch, so a token replayed on
|
|
84
|
+
* a different connection is not usable. Without it the token is a pure bearer
|
|
85
|
+
* credential — possession alone is the whole proof.
|
|
86
|
+
*
|
|
87
|
+
* Carried in the JWT as the nested object RFC 7800 specifies:
|
|
88
|
+
* "cnf": { "x5t#S256": "<base64url SHA-256 thumbprint of the peer's DER certificate>" }
|
|
89
|
+
*
|
|
90
|
+
* MANDATORY. The issuer MUST set it on every token, and the validator MUST
|
|
91
|
+
* reject a token that arrives without one. proto3 cannot express that, and
|
|
92
|
+
* the claim is a JSON object in a JWT rather than a field on this message on
|
|
93
|
+
* the wire, so nothing mechanical enforces it — it is a contract both sides
|
|
94
|
+
* implement or the binding is worthless. A validator that treats an absent
|
|
95
|
+
* cnf as "fall back to bearer" reopens the exact replay this claim closes,
|
|
96
|
+
* and gives any holder of a stolen token a way to opt out of the check by
|
|
97
|
+
* stripping it.
|
|
98
|
+
*
|
|
99
|
+
* Rollout order, since a mandatory claim cannot appear on both sides at once:
|
|
100
|
+
* the api-server must be issuing cnf on every token BEFORE the gateway begins
|
|
101
|
+
* rejecting tokens that lack it. Reverse that order and every live session is
|
|
102
|
+
* refused. Tokens are short-TTL, so the gap between the two deployments need
|
|
103
|
+
* only exceed one token lifetime.
|
|
104
|
+
*
|
|
105
|
+
* @generated from field: kusinta.iot.webrtc.v1.Confirmation cnf = 7;
|
|
106
|
+
*/
|
|
107
|
+
cnf?: Confirmation | undefined;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Describes the message kusinta.iot.webrtc.v1.AppTokenClaims.
|
|
112
|
+
* Use `create(AppTokenClaimsSchema)` to create a new message.
|
|
113
|
+
*/
|
|
114
|
+
export declare const AppTokenClaimsSchema: GenMessage<AppTokenClaims>;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* RFC 7800 confirmation, the value of the "cnf" claim. A separate message
|
|
118
|
+
* because the claim is a nested JSON object in the token, not a flat string.
|
|
119
|
+
*
|
|
120
|
+
* @generated from message kusinta.iot.webrtc.v1.Confirmation
|
|
121
|
+
*/
|
|
122
|
+
export declare type Confirmation = Message<"kusinta.iot.webrtc.v1.Confirmation"> & {
|
|
123
|
+
/**
|
|
124
|
+
* JWT claim name "x5t#S256" — the proto field cannot carry the "#", so the
|
|
125
|
+
* mapping to and from the JWT is by hand on both sides.
|
|
126
|
+
*
|
|
127
|
+
* ENCODING, pinned deliberately: base64url (unpadded) of the SHA-256 digest
|
|
128
|
+
* over the peer's DER-encoded certificate. WebRTC stacks hand you the same
|
|
129
|
+
* digest in the SDP `a=fingerprint:sha-256` attribute in a DIFFERENT form —
|
|
130
|
+
* uppercase, colon-separated hex — and the two will never compare equal.
|
|
131
|
+
* Issuer and validator must both normalise to the base64url form here; left
|
|
132
|
+
* unstated, each side can derive a correct value and never match.
|
|
133
|
+
*
|
|
134
|
+
* A DTLS fingerprint names a CERTIFICATE, not a connection: WebRTC permits
|
|
135
|
+
* reusing one certificate across several peer connections, and a new
|
|
136
|
+
* connection normally brings a new certificate. It is therefore neither
|
|
137
|
+
* unique per connection nor stable across reconnects, and must not be used as
|
|
138
|
+
* a session or connection key. It is a credential — it proves the peer holds
|
|
139
|
+
* the private key for the certificate the token was issued against, which is
|
|
140
|
+
* exactly and only what a confirmation claim needs.
|
|
141
|
+
*
|
|
142
|
+
* @generated from field: string x5t_s256 = 1;
|
|
143
|
+
*/
|
|
144
|
+
x5tS256: string;
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Describes the message kusinta.iot.webrtc.v1.Confirmation.
|
|
149
|
+
* Use `create(ConfirmationSchema)` to create a new message.
|
|
150
|
+
*/
|
|
151
|
+
export declare const ConfirmationSchema: GenMessage<Confirmation>;
|
|
152
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// @generated by protoc-gen-es v2.12.0 with parameter "target=js+dts,import_extension=js"
|
|
2
|
+
// @generated from file kusinta/iot/webrtc/v1/app_token.proto (package kusinta.iot.webrtc.v1, syntax proto3)
|
|
3
|
+
/* eslint-disable */
|
|
4
|
+
|
|
5
|
+
import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2";
|
|
6
|
+
import { file_google_protobuf_timestamp } from "@bufbuild/protobuf/wkt";
|
|
7
|
+
import { file_kusinta_iot_access_v1_roles } from "../../access/v1/roles_pb.js";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Describes the file kusinta/iot/webrtc/v1/app_token.proto.
|
|
11
|
+
*/
|
|
12
|
+
export const file_kusinta_iot_webrtc_v1_app_token = /*@__PURE__*/
|
|
13
|
+
fileDesc("CiVrdXNpbnRhL2lvdC93ZWJydGMvdjEvYXBwX3Rva2VuLnByb3RvEhVrdXNpbnRhLmlvdC53ZWJydGMudjEi5wEKDkFwcFRva2VuQ2xhaW1zEgsKA2lzcxgBIAEoCRILCgNhdWQYAiABKAkSCwoDc3ViGAMgASgJEicKA2lhdBgEIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASJwoDZXhwGAUgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIqCgVyb2xlcxgGIAMoDjIbLmt1c2ludGEuaW90LmFjY2Vzcy52MS5Sb2xlEjAKA2NuZhgHIAEoCzIjLmt1c2ludGEuaW90LndlYnJ0Yy52MS5Db25maXJtYXRpb24iIAoMQ29uZmlybWF0aW9uEhAKCHg1dF9zMjU2GAEgASgJQgJIAWIGcHJvdG8z", [file_google_protobuf_timestamp, file_kusinta_iot_access_v1_roles]);
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Describes the message kusinta.iot.webrtc.v1.AppTokenClaims.
|
|
17
|
+
* Use `create(AppTokenClaimsSchema)` to create a new message.
|
|
18
|
+
*/
|
|
19
|
+
export const AppTokenClaimsSchema = /*@__PURE__*/
|
|
20
|
+
messageDesc(file_kusinta_iot_webrtc_v1_app_token, 0);
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Describes the message kusinta.iot.webrtc.v1.Confirmation.
|
|
24
|
+
* Use `create(ConfirmationSchema)` to create a new message.
|
|
25
|
+
*/
|
|
26
|
+
export const ConfirmationSchema = /*@__PURE__*/
|
|
27
|
+
messageDesc(file_kusinta_iot_webrtc_v1_app_token, 1);
|
|
28
|
+
|