@kusinta/iot-schema 0.2.0-beta.5 → 0.2.0-beta.8

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.
@@ -236,6 +236,21 @@ export declare type HmMaintenanceProps = Message<"kusinta.iot.vendor.homematic.v
236
236
  * @generated from field: optional bool config_pending = 7;
237
237
  */
238
238
  configPending?: boolean | undefined;
239
+
240
+ /**
241
+ * True while the device has spent its share of the radio band's transmit budget and
242
+ * must wait before sending again. The 868 MHz band permits roughly one percent duty
243
+ * cycle, and it regenerates at about that rate per half minute.
244
+ *
245
+ * Worth carrying rather than leaving to the connector, because a spent budget is
246
+ * indistinguishable from a working device that simply has nothing to say: it stays
247
+ * reachable, reports no error, and silently drops what it was asked to do. Anything
248
+ * that writes on a schedule needs to be able to see this before it concludes a device
249
+ * is ignoring it.
250
+ *
251
+ * @generated from field: optional bool duty_cycle = 8;
252
+ */
253
+ dutyCycle?: boolean | undefined;
239
254
  };
240
255
 
241
256
  /**
@@ -9,7 +9,7 @@ import { file_kusinta_iot_vendor_v1_vendor_options } from "../../v1/vendor_optio
9
9
  * Describes the file kusinta/iot/vendor/homematic/v1/homematic.proto.
10
10
  */
11
11
  export const file_kusinta_iot_vendor_homematic_v1_homematic = /*@__PURE__*/
12
- fileDesc("Ci9rdXNpbnRhL2lvdC92ZW5kb3IvaG9tZW1hdGljL3YxL2hvbWVtYXRpYy5wcm90bxIfa3VzaW50YS5pb3QudmVuZG9yLmhvbWVtYXRpYy52MSI4ChdIb21lbWF0aWNEZXZpY2VJZGVudGl0eRIPCgdhZGRyZXNzGAEgASgJEgwKBHR5cGUYAiABKAki/wYKEUhtVGhlcm1vc3RhdFByb3BzEisKCmJvb3N0X21vZGUYASABKAhCEqK1GApCT09TVF9NT0RF0LUYBkgAiAEBEjUKFGJvb3N0X3RpbWVfcmVtYWluaW5nGAIgASgNQhKitRgKQk9PU1RfVElNRdC1GAVIAYgBARIvCgxjb250cm9sX21vZGUYAyABKA1CFKK1GAxDT05UUk9MX01PREXQtRgCSAKIAQESNwoQZnJvc3RfcHJvdGVjdGlvbhgEIAEoCEIYorUYEEZST1NUX1BST1RFQ1RJT07QtRgFSAOIAQESKwoKcGFydHlfbW9kZRgFIAEoCEISorUYClBBUlRZX01PREXQtRgFSASIAQESLwoMd2luZG93X3N0YXRlGAcgASgNQhSitRgMV0lORE9XX1NUQVRF0LUYB0gFiAEBEi0KC3ZhbHZlX3N0YXRlGAggASgNQhOitRgLVkFMVkVfU1RBVEXQtRgFSAaIAQESMwoOc2V0X3BvaW50X21vZGUYCSABKA1CFqK1GA5TRVRfUE9JTlRfTU9ERdC1GAdIB4gBARIzCg5hY3RpdmVfcHJvZmlsZRgKIAEoDUIWorUYDkFDVElWRV9QUk9GSUxF0LUYB0gIiAEBEkkKGWFjdHVhbF90ZW1wZXJhdHVyZV9zdGF0dXMYCyABKA1CIaK1GBlBQ1RVQUxfVEVNUEVSQVRVUkVfU1RBVFVT0LUYBUgJiAEBEjMKDnZhbHZlX2FkYXB0aW9uGAwgASgIQhaitRgOVkFMVkVfQURBUFRJT07QtRgHSAqIAQE6GKq1GBRob21lbWF0aWMudGhlcm1vc3RhdEINCgtfYm9vc3RfbW9kZUIXChVfYm9vc3RfdGltZV9yZW1haW5pbmdCDwoNX2NvbnRyb2xfbW9kZUITChFfZnJvc3RfcHJvdGVjdGlvbkINCgtfcGFydHlfbW9kZUIPCg1fd2luZG93X3N0YXRlQg4KDF92YWx2ZV9zdGF0ZUIRCg9fc2V0X3BvaW50X21vZGVCEQoPX2FjdGl2ZV9wcm9maWxlQhwKGl9hY3R1YWxfdGVtcGVyYXR1cmVfc3RhdHVzQhEKD192YWx2ZV9hZGFwdGlvbkoECAYQB1IFbGV2ZWxSFmN1cnJlbnRfcHJvZmlsZV9wZXJpb2RSEWJvb3N0X3RpbWVfcGVyaW9kIvoDChJIbU1haW50ZW5hbmNlUHJvcHMSKwoKZXJyb3JfY29kZRgBIAEoDUISorUYCkVSUk9SX0NPREXQtRgFSACIAQESJwoIc2Fib3RhZ2UYAiABKAhCEKK1GAhTQUJPVEFHRdC1GAVIAYgBARItCgtyc3NpX2RldmljZRgDIAEoEUITorUYC1JTU0lfREVWSUNF0LUYBUgCiAEBEikKCXJzc2lfcGVlchgEIAEoEUIRorUYCVJTU0lfUEVFUtC1GAVIA4gBARJHChhvcGVyYXRpbmdfdm9sdGFnZV9zdGF0dXMYBSABKA1CIKK1GBhPUEVSQVRJTkdfVk9MVEFHRV9TVEFUVVPQtRgFSASIAQESJQoHdW5yZWFjaBgGIAEoCEIPorUYB1VOUkVBQ0jQtRgFSAWIAQESMwoOY29uZmlnX3BlbmRpbmcYByABKAhCFqK1GA5DT05GSUdfUEVORElOR9C1GAVIBogBAToZqrUYFWhvbWVtYXRpYy5tYWludGVuYW5jZUINCgtfZXJyb3JfY29kZUILCglfc2Fib3RhZ2VCDgoMX3Jzc2lfZGV2aWNlQgwKCl9yc3NpX3BlZXJCGwoZX29wZXJhdGluZ192b2x0YWdlX3N0YXR1c0IKCghfdW5yZWFjaEIRCg9fY29uZmlnX3BlbmRpbmdCAkgBYgZwcm90bzM", [file_kusinta_iot_vendor_v1_vendor_options]);
12
+ fileDesc("Ci9rdXNpbnRhL2lvdC92ZW5kb3IvaG9tZW1hdGljL3YxL2hvbWVtYXRpYy5wcm90bxIfa3VzaW50YS5pb3QudmVuZG9yLmhvbWVtYXRpYy52MSI4ChdIb21lbWF0aWNEZXZpY2VJZGVudGl0eRIPCgdhZGRyZXNzGAEgASgJEgwKBHR5cGUYAiABKAki/wYKEUhtVGhlcm1vc3RhdFByb3BzEisKCmJvb3N0X21vZGUYASABKAhCEqK1GApCT09TVF9NT0RF0LUYBkgAiAEBEjUKFGJvb3N0X3RpbWVfcmVtYWluaW5nGAIgASgNQhKitRgKQk9PU1RfVElNRdC1GAVIAYgBARIvCgxjb250cm9sX21vZGUYAyABKA1CFKK1GAxDT05UUk9MX01PREXQtRgCSAKIAQESNwoQZnJvc3RfcHJvdGVjdGlvbhgEIAEoCEIYorUYEEZST1NUX1BST1RFQ1RJT07QtRgFSAOIAQESKwoKcGFydHlfbW9kZRgFIAEoCEISorUYClBBUlRZX01PREXQtRgFSASIAQESLwoMd2luZG93X3N0YXRlGAcgASgNQhSitRgMV0lORE9XX1NUQVRF0LUYB0gFiAEBEi0KC3ZhbHZlX3N0YXRlGAggASgNQhOitRgLVkFMVkVfU1RBVEXQtRgFSAaIAQESMwoOc2V0X3BvaW50X21vZGUYCSABKA1CFqK1GA5TRVRfUE9JTlRfTU9ERdC1GAdIB4gBARIzCg5hY3RpdmVfcHJvZmlsZRgKIAEoDUIWorUYDkFDVElWRV9QUk9GSUxF0LUYB0gIiAEBEkkKGWFjdHVhbF90ZW1wZXJhdHVyZV9zdGF0dXMYCyABKA1CIaK1GBlBQ1RVQUxfVEVNUEVSQVRVUkVfU1RBVFVT0LUYBUgJiAEBEjMKDnZhbHZlX2FkYXB0aW9uGAwgASgIQhaitRgOVkFMVkVfQURBUFRJT07QtRgHSAqIAQE6GKq1GBRob21lbWF0aWMudGhlcm1vc3RhdEINCgtfYm9vc3RfbW9kZUIXChVfYm9vc3RfdGltZV9yZW1haW5pbmdCDwoNX2NvbnRyb2xfbW9kZUITChFfZnJvc3RfcHJvdGVjdGlvbkINCgtfcGFydHlfbW9kZUIPCg1fd2luZG93X3N0YXRlQg4KDF92YWx2ZV9zdGF0ZUIRCg9fc2V0X3BvaW50X21vZGVCEQoPX2FjdGl2ZV9wcm9maWxlQhwKGl9hY3R1YWxfdGVtcGVyYXR1cmVfc3RhdHVzQhEKD192YWx2ZV9hZGFwdGlvbkoECAYQB1IFbGV2ZWxSFmN1cnJlbnRfcHJvZmlsZV9wZXJpb2RSEWJvb3N0X3RpbWVfcGVyaW9kIrYEChJIbU1haW50ZW5hbmNlUHJvcHMSKwoKZXJyb3JfY29kZRgBIAEoDUISorUYCkVSUk9SX0NPREXQtRgFSACIAQESJwoIc2Fib3RhZ2UYAiABKAhCEKK1GAhTQUJPVEFHRdC1GAVIAYgBARItCgtyc3NpX2RldmljZRgDIAEoEUITorUYC1JTU0lfREVWSUNF0LUYBUgCiAEBEikKCXJzc2lfcGVlchgEIAEoEUIRorUYCVJTU0lfUEVFUtC1GAVIA4gBARJHChhvcGVyYXRpbmdfdm9sdGFnZV9zdGF0dXMYBSABKA1CIKK1GBhPUEVSQVRJTkdfVk9MVEFHRV9TVEFUVVPQtRgFSASIAQESJQoHdW5yZWFjaBgGIAEoCEIPorUYB1VOUkVBQ0jQtRgFSAWIAQESMwoOY29uZmlnX3BlbmRpbmcYByABKAhCFqK1GA5DT05GSUdfUEVORElOR9C1GAVIBogBARIrCgpkdXR5X2N5Y2xlGAggASgIQhKitRgKRFVUWV9DWUNMRdC1GAVIB4gBAToZqrUYFWhvbWVtYXRpYy5tYWludGVuYW5jZUINCgtfZXJyb3JfY29kZUILCglfc2Fib3RhZ2VCDgoMX3Jzc2lfZGV2aWNlQgwKCl9yc3NpX3BlZXJCGwoZX29wZXJhdGluZ192b2x0YWdlX3N0YXR1c0IKCghfdW5yZWFjaEIRCg9fY29uZmlnX3BlbmRpbmdCDQoLX2R1dHlfY3ljbGVCAkgBYgZwcm90bzM", [file_kusinta_iot_vendor_v1_vendor_options]);
13
13
 
14
14
  /**
15
15
  * Describes the message kusinta.iot.vendor.homematic.v1.HomematicDeviceIdentity.
@@ -4,10 +4,13 @@
4
4
 
5
5
  import type { GenEnum, GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2";
6
6
  import type { Message } from "@bufbuild/protobuf";
7
- import type { DeviceId } from "../../identity/v1/identity_pb.js";
7
+ import type { ConnectorId, DeviceId, SpaceId } from "../../identity/v1/identity_pb.js";
8
8
  import type { AttributeRef } from "../../access/v1/acl_pb.js";
9
9
  import type { Space } from "../../space/v1/space_pb.js";
10
10
  import type { ManagementAck, ManagementRequest, SpaceTree } from "./management_pb.js";
11
+ import type { DeviceLinkList } from "../../link/v1/link_pb.js";
12
+ import type { PairingErrorDetail, PairingWindow } from "../../common/v1/pairing_pb.js";
13
+ import type { DeviceOwnershipType } from "../../common/v1/types_pb.js";
11
14
  import type { Timestamp } from "@bufbuild/protobuf/wkt";
12
15
  import type { DeviceAdded, DeviceRemoved, DeviceStateSnapshot, PropertyReport } from "./device_state_pb.js";
13
16
  import type { LivePermissionUpdate } from "./permission_push_pb.js";
@@ -316,6 +319,14 @@ export declare type ManagementResult = Message<"kusinta.iot.webrtc.v1.Management
316
319
  */
317
320
  value: ManagementAck;
318
321
  case: "ack";
322
+ } | {
323
+ /**
324
+ * list_device_links
325
+ *
326
+ * @generated from field: kusinta.iot.link.v1.DeviceLinkList links = 6;
327
+ */
328
+ value: DeviceLinkList;
329
+ case: "links";
319
330
  } | { case: undefined; value?: undefined };
320
331
  };
321
332
 
@@ -325,6 +336,157 @@ export declare type ManagementResult = Message<"kusinta.iot.webrtc.v1.Management
325
336
  */
326
337
  export declare const ManagementResultSchema: GenMessage<ManagementResult>;
327
338
 
339
+ /**
340
+ * Asks the gateway to put a connector into pairing mode, so a device joined during the
341
+ * window becomes the caller's rather than belonging to nobody.
342
+ *
343
+ * A payload case of its own rather than a ManagementRequest. Those are gated on a target —
344
+ * a space, a device — and that is the justification for keeping them behind one wrapper.
345
+ * This one names no target: connector_id is optional, and unset means every connector, so
346
+ * it is authorized against the caller's role and nothing else.
347
+ *
348
+ * Answered twice, and the two answers say different things at different times.
349
+ * PairingStarted reports whether the window opened; PairingFinished reports what came of
350
+ * it, seconds or minutes later, once someone has pressed a button on hardware that may be
351
+ * asleep or out of range.
352
+ *
353
+ * @generated from message kusinta.iot.webrtc.v1.StartPairing
354
+ */
355
+ export declare type StartPairing = Message<"kusinta.iot.webrtc.v1.StartPairing"> & {
356
+ /**
357
+ * Which connector to open. Unset means every connector the gateway holds, which is the
358
+ * sensible default: a device picks its hub by radio range, and asking a user to choose is
359
+ * asking them to guess at something they cannot observe.
360
+ *
361
+ * Name one where the answer is not a guess — a device that will be linked to devices on a
362
+ * particular hub has to join that hub, because links are held by the hub that brokered
363
+ * them.
364
+ *
365
+ * @generated from field: kusinta.iot.identity.v1.ConnectorId connector_id = 1;
366
+ */
367
+ connectorId?: ConnectorId | undefined;
368
+
369
+ /**
370
+ * How long, which device, how many. See PairingWindow.
371
+ *
372
+ * @generated from field: kusinta.iot.common.v1.PairingWindow window = 2;
373
+ */
374
+ window?: PairingWindow | undefined;
375
+
376
+ /**
377
+ * Where to file the device once it arrives.
378
+ *
379
+ * Optional, and the two cases differ. A caller pairing a device of their own must name a
380
+ * space they reach, so it is theirs and placed on arrival rather than sitting unfiled and
381
+ * invisible to them. A caller commissioning for a building may leave it unset: a building
382
+ * is commissioned before its spaces are recorded, and an unfiled device is visible to the
383
+ * administrator, who is the person doing the pairing.
384
+ *
385
+ * @generated from field: kusinta.iot.identity.v1.SpaceId initial_space_id = 3;
386
+ */
387
+ initialSpaceId?: SpaceId | undefined;
388
+
389
+ /**
390
+ * What the device should become. Unset lets the gateway decide from the caller's role,
391
+ * which is the reading that scales: someone commissioning fifty devices for a building
392
+ * should not come to own fifty devices because a field defaulted.
393
+ *
394
+ * The gateway refuses an ownership the caller may not confer, and never mints ownership
395
+ * for a third party — handing a device to someone else is a transfer, a separate operation
396
+ * with its own authority.
397
+ *
398
+ * @generated from field: kusinta.iot.common.v1.DeviceOwnershipType ownership = 4;
399
+ */
400
+ ownership: DeviceOwnershipType;
401
+ };
402
+
403
+ /**
404
+ * Describes the message kusinta.iot.webrtc.v1.StartPairing.
405
+ * Use `create(StartPairingSchema)` to create a new message.
406
+ */
407
+ export declare const StartPairingSchema: GenMessage<StartPairing>;
408
+
409
+ /**
410
+ * Whether the pairing window opened, gateway → app. The first of two answers to a
411
+ * StartPairing.
412
+ *
413
+ * @generated from message kusinta.iot.webrtc.v1.PairingStarted
414
+ */
415
+ export declare type PairingStarted = Message<"kusinta.iot.webrtc.v1.PairingStarted"> & {
416
+ /**
417
+ * AppMessage.message_id of the StartPairing
418
+ *
419
+ * @generated from field: string in_reply_to = 1;
420
+ */
421
+ inReplyTo: string;
422
+
423
+ /**
424
+ * When the window closes. Present when it opened, and this is the value to count down
425
+ * from — not the duration that was asked for, which both the gateway and the connector
426
+ * clamp. A countdown run on the request rather than on this one disagrees with the hub.
427
+ *
428
+ * @generated from field: google.protobuf.Timestamp expires_at = 2;
429
+ */
430
+ expiresAt?: Timestamp | undefined;
431
+
432
+ /**
433
+ * Why it did not open. Present instead of expires_at.
434
+ *
435
+ * @generated from field: kusinta.iot.common.v1.PairingErrorDetail error = 3;
436
+ */
437
+ error?: PairingErrorDetail | undefined;
438
+ };
439
+
440
+ /**
441
+ * Describes the message kusinta.iot.webrtc.v1.PairingStarted.
442
+ * Use `create(PairingStartedSchema)` to create a new message.
443
+ */
444
+ export declare const PairingStartedSchema: GenMessage<PairingStarted>;
445
+
446
+ /**
447
+ * What the pairing window produced, gateway → app. The second and last answer, sent once
448
+ * when the window closes.
449
+ *
450
+ * One message per request, not per device: a batch window attributes several, and a client
451
+ * given one message each has nothing telling it the window is over and no defined moment to
452
+ * stop waiting. The devices are listed here; each also arrives as an ordinary DeviceAdded
453
+ * as it appears, so a client may show them as they come and use this to finish.
454
+ *
455
+ * An error and a non-empty device list are not exclusive. A batch of five that attributed
456
+ * three and then expired reports both — three devices and NO_DEVICE_APPEARED — because
457
+ * "some worked" and "the window ran out" are both true and a user needs to be told both.
458
+ *
459
+ * @generated from message kusinta.iot.webrtc.v1.PairingFinished
460
+ */
461
+ export declare type PairingFinished = Message<"kusinta.iot.webrtc.v1.PairingFinished"> & {
462
+ /**
463
+ * AppMessage.message_id of the StartPairing
464
+ *
465
+ * @generated from field: string in_reply_to = 1;
466
+ */
467
+ inReplyTo: string;
468
+
469
+ /**
470
+ * @generated from field: repeated kusinta.iot.identity.v1.DeviceId device_ids = 2;
471
+ */
472
+ deviceIds: DeviceId[];
473
+
474
+ /**
475
+ * Why the window produced fewer devices than asked for, absent when it produced them all.
476
+ * Note this is not always a failure of the request: a window that simply expired unused
477
+ * ends here too, and is the ordinary result of a user changing their mind.
478
+ *
479
+ * @generated from field: kusinta.iot.common.v1.PairingErrorDetail error = 3;
480
+ */
481
+ error?: PairingErrorDetail | undefined;
482
+ };
483
+
484
+ /**
485
+ * Describes the message kusinta.iot.webrtc.v1.PairingFinished.
486
+ * Use `create(PairingFinishedSchema)` to create a new message.
487
+ */
488
+ export declare const PairingFinishedSchema: GenMessage<PairingFinished>;
489
+
328
490
  /**
329
491
  * GatewayMessage: gateway → app
330
492
  *
@@ -421,6 +583,18 @@ export declare type GatewayMessage = Message<"kusinta.iot.webrtc.v1.GatewayMessa
421
583
  */
422
584
  value: DeviceEventBatch;
423
585
  case: "deviceEvents";
586
+ } | {
587
+ /**
588
+ * @generated from field: kusinta.iot.webrtc.v1.PairingStarted pairing_started = 17;
589
+ */
590
+ value: PairingStarted;
591
+ case: "pairingStarted";
592
+ } | {
593
+ /**
594
+ * @generated from field: kusinta.iot.webrtc.v1.PairingFinished pairing_finished = 18;
595
+ */
596
+ value: PairingFinished;
597
+ case: "pairingFinished";
424
598
  } | { case: undefined; value?: undefined };
425
599
  };
426
600
 
@@ -497,6 +671,12 @@ export declare type AppMessage = Message<"kusinta.iot.webrtc.v1.AppMessage"> & {
497
671
  */
498
672
  value: AttributeWriteRequest;
499
673
  case: "attributeWrite";
674
+ } | {
675
+ /**
676
+ * @generated from field: kusinta.iot.webrtc.v1.StartPairing start_pairing = 11;
677
+ */
678
+ value: StartPairing;
679
+ case: "startPairing";
500
680
  } | { case: undefined; value?: undefined };
501
681
  };
502
682
 
@@ -5,8 +5,11 @@
5
5
  import { enumDesc, fileDesc, messageDesc, tsEnum } from "@bufbuild/protobuf/codegenv2";
6
6
  import { file_google_protobuf_timestamp } from "@bufbuild/protobuf/wkt";
7
7
  import { file_kusinta_iot_access_v1_acl } from "../../access/v1/acl_pb.js";
8
+ import { file_kusinta_iot_common_v1_pairing } from "../../common/v1/pairing_pb.js";
9
+ import { file_kusinta_iot_common_v1_types } from "../../common/v1/types_pb.js";
8
10
  import { file_kusinta_iot_device_v1_device_event } from "../../device/v1/device_event_pb.js";
9
11
  import { file_kusinta_iot_identity_v1_identity } from "../../identity/v1/identity_pb.js";
12
+ import { file_kusinta_iot_link_v1_link } from "../../link/v1/link_pb.js";
10
13
  import { file_kusinta_iot_space_v1_space } from "../../space/v1/space_pb.js";
11
14
  import { file_kusinta_iot_webrtc_v1_command } from "./command_pb.js";
12
15
  import { file_kusinta_iot_webrtc_v1_device_state } from "./device_state_pb.js";
@@ -17,7 +20,7 @@ import { file_kusinta_iot_webrtc_v1_permission_push } from "./permission_push_pb
17
20
  * Describes the file kusinta/iot/webrtc/v1/envelope.proto.
18
21
  */
19
22
  export const file_kusinta_iot_webrtc_v1_envelope = /*@__PURE__*/
20
- fileDesc("CiRrdXNpbnRhL2lvdC93ZWJydGMvdjEvZW52ZWxvcGUucHJvdG8SFWt1c2ludGEuaW90LndlYnJ0Yy52MSIGCgRQaW5nIgYKBFBvbmciIwoRSGFuZHNoYWtlUmVqZWN0ZWQSDgoGcmVhc29uGAEgASgJIlwKDEFwcEhhbmRzaGFrZRILCgNqd3QYASABKAkSPwoUc3Vic2NyaWJlX2RldmljZV9pZHMYAiADKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZCJJChBTdWJzY3JpYmVEZXZpY2VzEjUKCmRldmljZV9pZHMYASADKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZCJLChJVbnN1YnNjcmliZURldmljZXMSNQoKZGV2aWNlX2lkcxgBIAMoCzIhLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLkRldmljZUlkIpMBChNSZWZ1c2VkU3Vic2NyaXB0aW9uEjQKCWRldmljZV9pZBgBIAEoCzIhLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLkRldmljZUlkEjUKBGNvZGUYAiABKA4yJy5rdXNpbnRhLmlvdC53ZWJydGMudjEuR2F0ZXdheUVycm9yQ29kZRIPCgdtZXNzYWdlGAMgASgJIpoBCg9TdWJzY3JpcHRpb25BY2sSEwoLaW5fcmVwbHlfdG8YASABKAkSNQoKc3Vic2NyaWJlZBgCIAMoCzIhLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLkRldmljZUlkEjsKB3JlZnVzZWQYAyADKAsyKi5rdXNpbnRhLmlvdC53ZWJydGMudjEuUmVmdXNlZFN1YnNjcmlwdGlvbiLRAQoTUHJvcGVydHlSZWFkUmVxdWVzdBI0CglkZXZpY2VfaWQYASABKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZBIzCgZ0YXJnZXQYByABKAsyIy5rdXNpbnRhLmlvdC5hY2Nlc3MudjEuQXR0cmlidXRlUmVmSgQIAhAHUg5hdHRyaWJ1dGVfbmFtZVIOY2x1c3Rlcl9pZF9oZXhSCmNsdXN0ZXJfaWRSC2VuZHBvaW50X2lkUhB2ZW5kb3JfZXh0ZW5zaW9uIswBCgxHYXRld2F5RXJyb3ISNQoEY29kZRgBIAEoDjInLmt1c2ludGEuaW90LndlYnJ0Yy52MS5HYXRld2F5RXJyb3JDb2RlEg8KB21lc3NhZ2UYAiABKAkSQwoIbWV0YWRhdGEYAyADKAsyMS5rdXNpbnRhLmlvdC53ZWJydGMudjEuR2F0ZXdheUVycm9yLk1ldGFkYXRhRW50cnkaLwoNTWV0YWRhdGFFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBIoICChBNYW5hZ2VtZW50UmVzdWx0EhMKC2luX3JlcGx5X3RvGAEgASgJEjQKBWVycm9yGAIgASgLMiMua3VzaW50YS5pb3Qud2VicnRjLnYxLkdhdGV3YXlFcnJvckgAEiwKBXNwYWNlGAMgASgLMhsua3VzaW50YS5pb3Quc3BhY2UudjEuU3BhY2VIABI2CgpzcGFjZV90cmVlGAQgASgLMiAua3VzaW50YS5pb3Qud2VicnRjLnYxLlNwYWNlVHJlZUgAEjMKA2FjaxgFIAEoCzIkLmt1c2ludGEuaW90LndlYnJ0Yy52MS5NYW5hZ2VtZW50QWNrSABCCAoGcmVzdWx0IpUHCg5HYXRld2F5TWVzc2FnZRISCgptZXNzYWdlX2lkGAEgASgJEisKB3NlbnRfYXQYAiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEkQKDnN0YXRlX3NuYXBzaG90GAMgASgLMioua3VzaW50YS5pb3Qud2VicnRjLnYxLkRldmljZVN0YXRlU25hcHNob3RIABJACg9wcm9wZXJ0eV9yZXBvcnQYBCABKAsyJS5rdXNpbnRhLmlvdC53ZWJydGMudjEuUHJvcGVydHlSZXBvcnRIABJIChFwZXJtaXNzaW9uX3VwZGF0ZRgFIAEoCzIrLmt1c2ludGEuaW90LndlYnJ0Yy52MS5MaXZlUGVybWlzc2lvblVwZGF0ZUgAEj4KDmNvbW1hbmRfcmVzdWx0GAYgASgLMiQua3VzaW50YS5pb3Qud2VicnRjLnYxLkNvbW1hbmRSZXN1bHRIABIrCgRwb25nGAggASgLMhsua3VzaW50YS5pb3Qud2VicnRjLnYxLlBvbmdIABJGChJoYW5kc2hha2VfcmVqZWN0ZWQYCSABKAsyKC5rdXNpbnRhLmlvdC53ZWJydGMudjEuSGFuZHNoYWtlUmVqZWN0ZWRIABI0CgVlcnJvchgKIAEoCzIjLmt1c2ludGEuaW90LndlYnJ0Yy52MS5HYXRld2F5RXJyb3JIABJCChBzdWJzY3JpcHRpb25fYWNrGAsgASgLMiYua3VzaW50YS5pb3Qud2VicnRjLnYxLlN1YnNjcmlwdGlvbkFja0gAEjoKDGRldmljZV9hZGRlZBgMIAEoCzIiLmt1c2ludGEuaW90LndlYnJ0Yy52MS5EZXZpY2VBZGRlZEgAEj4KDmRldmljZV9yZW1vdmVkGA0gASgLMiQua3VzaW50YS5pb3Qud2VicnRjLnYxLkRldmljZVJlbW92ZWRIABJEChFtYW5hZ2VtZW50X3Jlc3VsdBgOIAEoCzInLmt1c2ludGEuaW90LndlYnJ0Yy52MS5NYW5hZ2VtZW50UmVzdWx0SAASQAoNZGV2aWNlX2V2ZW50cxgQIAEoCzInLmt1c2ludGEuaW90LmRldmljZS52MS5EZXZpY2VFdmVudEJhdGNoSABCCQoHcGF5bG9hZEoECA8QEEoECAcQCFIWYXR0cmlidXRlX3dyaXRlX3Jlc3VsdFIOcHJvcGVydHlfZXZlbnQixQQKCkFwcE1lc3NhZ2USEgoKbWVzc2FnZV9pZBgBIAEoCRIrCgdzZW50X2F0GAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBI4CgloYW5kc2hha2UYAyABKAsyIy5rdXNpbnRhLmlvdC53ZWJydGMudjEuQXBwSGFuZHNoYWtlSAASNwoHY29tbWFuZBgEIAEoCzIkLmt1c2ludGEuaW90LndlYnJ0Yy52MS5EZXZpY2VDb21tYW5kSAASQgoMcmVhZF9yZXF1ZXN0GAUgASgLMioua3VzaW50YS5pb3Qud2VicnRjLnYxLlByb3BlcnR5UmVhZFJlcXVlc3RIABIrCgRwaW5nGAYgASgLMhsua3VzaW50YS5pb3Qud2VicnRjLnYxLlBpbmdIABI8CglzdWJzY3JpYmUYByABKAsyJy5rdXNpbnRhLmlvdC53ZWJydGMudjEuU3Vic2NyaWJlRGV2aWNlc0gAEkAKC3Vuc3Vic2NyaWJlGAggASgLMikua3VzaW50YS5pb3Qud2VicnRjLnYxLlVuc3Vic2NyaWJlRGV2aWNlc0gAEj4KCm1hbmFnZW1lbnQYCSABKAsyKC5rdXNpbnRhLmlvdC53ZWJydGMudjEuTWFuYWdlbWVudFJlcXVlc3RIABJHCg9hdHRyaWJ1dGVfd3JpdGUYCiABKAsyLC5rdXNpbnRhLmlvdC53ZWJydGMudjEuQXR0cmlidXRlV3JpdGVSZXF1ZXN0SABCCQoHcGF5bG9hZCr2AQoQR2F0ZXdheUVycm9yQ29kZRIiCh5HQVRFV0FZX0VSUk9SX0NPREVfVU5TUEVDSUZJRUQQABIjCh9HQVRFV0FZX0VSUk9SX0NPREVfTk9UX0VOVElUTEVEEAESJgoiR0FURVdBWV9FUlJPUl9DT0RFX0lOVkFMSURfUkVRVUVTVBACEiIKHkdBVEVXQVlfRVJST1JfQ09ERV9VTkFWQUlMQUJMRRADEh8KG0dBVEVXQVlfRVJST1JfQ09ERV9JTlRFUk5BTBAEEiwKKEdBVEVXQVlfRVJST1JfQ09ERV9TRVNTSU9OX0xJTUlUX1JFQUNIRUQQBUICSAFiBnByb3RvMw", [file_google_protobuf_timestamp, file_kusinta_iot_access_v1_acl, file_kusinta_iot_device_v1_device_event, file_kusinta_iot_identity_v1_identity, file_kusinta_iot_space_v1_space, file_kusinta_iot_webrtc_v1_command, file_kusinta_iot_webrtc_v1_device_state, file_kusinta_iot_webrtc_v1_management, file_kusinta_iot_webrtc_v1_permission_push]);
23
+ fileDesc("CiRrdXNpbnRhL2lvdC93ZWJydGMvdjEvZW52ZWxvcGUucHJvdG8SFWt1c2ludGEuaW90LndlYnJ0Yy52MSIGCgRQaW5nIgYKBFBvbmciIwoRSGFuZHNoYWtlUmVqZWN0ZWQSDgoGcmVhc29uGAEgASgJIlwKDEFwcEhhbmRzaGFrZRILCgNqd3QYASABKAkSPwoUc3Vic2NyaWJlX2RldmljZV9pZHMYAiADKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZCJJChBTdWJzY3JpYmVEZXZpY2VzEjUKCmRldmljZV9pZHMYASADKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZCJLChJVbnN1YnNjcmliZURldmljZXMSNQoKZGV2aWNlX2lkcxgBIAMoCzIhLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLkRldmljZUlkIpMBChNSZWZ1c2VkU3Vic2NyaXB0aW9uEjQKCWRldmljZV9pZBgBIAEoCzIhLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLkRldmljZUlkEjUKBGNvZGUYAiABKA4yJy5rdXNpbnRhLmlvdC53ZWJydGMudjEuR2F0ZXdheUVycm9yQ29kZRIPCgdtZXNzYWdlGAMgASgJIpoBCg9TdWJzY3JpcHRpb25BY2sSEwoLaW5fcmVwbHlfdG8YASABKAkSNQoKc3Vic2NyaWJlZBgCIAMoCzIhLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLkRldmljZUlkEjsKB3JlZnVzZWQYAyADKAsyKi5rdXNpbnRhLmlvdC53ZWJydGMudjEuUmVmdXNlZFN1YnNjcmlwdGlvbiLRAQoTUHJvcGVydHlSZWFkUmVxdWVzdBI0CglkZXZpY2VfaWQYASABKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZBIzCgZ0YXJnZXQYByABKAsyIy5rdXNpbnRhLmlvdC5hY2Nlc3MudjEuQXR0cmlidXRlUmVmSgQIAhAHUg5hdHRyaWJ1dGVfbmFtZVIOY2x1c3Rlcl9pZF9oZXhSCmNsdXN0ZXJfaWRSC2VuZHBvaW50X2lkUhB2ZW5kb3JfZXh0ZW5zaW9uIswBCgxHYXRld2F5RXJyb3ISNQoEY29kZRgBIAEoDjInLmt1c2ludGEuaW90LndlYnJ0Yy52MS5HYXRld2F5RXJyb3JDb2RlEg8KB21lc3NhZ2UYAiABKAkSQwoIbWV0YWRhdGEYAyADKAsyMS5rdXNpbnRhLmlvdC53ZWJydGMudjEuR2F0ZXdheUVycm9yLk1ldGFkYXRhRW50cnkaLwoNTWV0YWRhdGFFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBIrgCChBNYW5hZ2VtZW50UmVzdWx0EhMKC2luX3JlcGx5X3RvGAEgASgJEjQKBWVycm9yGAIgASgLMiMua3VzaW50YS5pb3Qud2VicnRjLnYxLkdhdGV3YXlFcnJvckgAEiwKBXNwYWNlGAMgASgLMhsua3VzaW50YS5pb3Quc3BhY2UudjEuU3BhY2VIABI2CgpzcGFjZV90cmVlGAQgASgLMiAua3VzaW50YS5pb3Qud2VicnRjLnYxLlNwYWNlVHJlZUgAEjMKA2FjaxgFIAEoCzIkLmt1c2ludGEuaW90LndlYnJ0Yy52MS5NYW5hZ2VtZW50QWNrSAASNAoFbGlua3MYBiABKAsyIy5rdXNpbnRhLmlvdC5saW5rLnYxLkRldmljZUxpbmtMaXN0SABCCAoGcmVzdWx0IvsBCgxTdGFydFBhaXJpbmcSOgoMY29ubmVjdG9yX2lkGAEgASgLMiQua3VzaW50YS5pb3QuaWRlbnRpdHkudjEuQ29ubmVjdG9ySWQSNAoGd2luZG93GAIgASgLMiQua3VzaW50YS5pb3QuY29tbW9uLnYxLlBhaXJpbmdXaW5kb3cSOgoQaW5pdGlhbF9zcGFjZV9pZBgDIAEoCzIgLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLlNwYWNlSWQSPQoJb3duZXJzaGlwGAQgASgOMioua3VzaW50YS5pb3QuY29tbW9uLnYxLkRldmljZU93bmVyc2hpcFR5cGUijwEKDlBhaXJpbmdTdGFydGVkEhMKC2luX3JlcGx5X3RvGAEgASgJEi4KCmV4cGlyZXNfYXQYAiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEjgKBWVycm9yGAMgASgLMikua3VzaW50YS5pb3QuY29tbW9uLnYxLlBhaXJpbmdFcnJvckRldGFpbCKXAQoPUGFpcmluZ0ZpbmlzaGVkEhMKC2luX3JlcGx5X3RvGAEgASgJEjUKCmRldmljZV9pZHMYAiADKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZBI4CgVlcnJvchgDIAEoCzIpLmt1c2ludGEuaW90LmNvbW1vbi52MS5QYWlyaW5nRXJyb3JEZXRhaWwimwgKDkdhdGV3YXlNZXNzYWdlEhIKCm1lc3NhZ2VfaWQYASABKAkSKwoHc2VudF9hdBgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASRAoOc3RhdGVfc25hcHNob3QYAyABKAsyKi5rdXNpbnRhLmlvdC53ZWJydGMudjEuRGV2aWNlU3RhdGVTbmFwc2hvdEgAEkAKD3Byb3BlcnR5X3JlcG9ydBgEIAEoCzIlLmt1c2ludGEuaW90LndlYnJ0Yy52MS5Qcm9wZXJ0eVJlcG9ydEgAEkgKEXBlcm1pc3Npb25fdXBkYXRlGAUgASgLMisua3VzaW50YS5pb3Qud2VicnRjLnYxLkxpdmVQZXJtaXNzaW9uVXBkYXRlSAASPgoOY29tbWFuZF9yZXN1bHQYBiABKAsyJC5rdXNpbnRhLmlvdC53ZWJydGMudjEuQ29tbWFuZFJlc3VsdEgAEisKBHBvbmcYCCABKAsyGy5rdXNpbnRhLmlvdC53ZWJydGMudjEuUG9uZ0gAEkYKEmhhbmRzaGFrZV9yZWplY3RlZBgJIAEoCzIoLmt1c2ludGEuaW90LndlYnJ0Yy52MS5IYW5kc2hha2VSZWplY3RlZEgAEjQKBWVycm9yGAogASgLMiMua3VzaW50YS5pb3Qud2VicnRjLnYxLkdhdGV3YXlFcnJvckgAEkIKEHN1YnNjcmlwdGlvbl9hY2sYCyABKAsyJi5rdXNpbnRhLmlvdC53ZWJydGMudjEuU3Vic2NyaXB0aW9uQWNrSAASOgoMZGV2aWNlX2FkZGVkGAwgASgLMiIua3VzaW50YS5pb3Qud2VicnRjLnYxLkRldmljZUFkZGVkSAASPgoOZGV2aWNlX3JlbW92ZWQYDSABKAsyJC5rdXNpbnRhLmlvdC53ZWJydGMudjEuRGV2aWNlUmVtb3ZlZEgAEkQKEW1hbmFnZW1lbnRfcmVzdWx0GA4gASgLMicua3VzaW50YS5pb3Qud2VicnRjLnYxLk1hbmFnZW1lbnRSZXN1bHRIABJACg1kZXZpY2VfZXZlbnRzGBAgASgLMicua3VzaW50YS5pb3QuZGV2aWNlLnYxLkRldmljZUV2ZW50QmF0Y2hIABJACg9wYWlyaW5nX3N0YXJ0ZWQYESABKAsyJS5rdXNpbnRhLmlvdC53ZWJydGMudjEuUGFpcmluZ1N0YXJ0ZWRIABJCChBwYWlyaW5nX2ZpbmlzaGVkGBIgASgLMiYua3VzaW50YS5pb3Qud2VicnRjLnYxLlBhaXJpbmdGaW5pc2hlZEgAQgkKB3BheWxvYWRKBAgPEBBKBAgHEAhSFmF0dHJpYnV0ZV93cml0ZV9yZXN1bHRSDnByb3BlcnR5X2V2ZW50IoMFCgpBcHBNZXNzYWdlEhIKCm1lc3NhZ2VfaWQYASABKAkSKwoHc2VudF9hdBgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASOAoJaGFuZHNoYWtlGAMgASgLMiMua3VzaW50YS5pb3Qud2VicnRjLnYxLkFwcEhhbmRzaGFrZUgAEjcKB2NvbW1hbmQYBCABKAsyJC5rdXNpbnRhLmlvdC53ZWJydGMudjEuRGV2aWNlQ29tbWFuZEgAEkIKDHJlYWRfcmVxdWVzdBgFIAEoCzIqLmt1c2ludGEuaW90LndlYnJ0Yy52MS5Qcm9wZXJ0eVJlYWRSZXF1ZXN0SAASKwoEcGluZxgGIAEoCzIbLmt1c2ludGEuaW90LndlYnJ0Yy52MS5QaW5nSAASPAoJc3Vic2NyaWJlGAcgASgLMicua3VzaW50YS5pb3Qud2VicnRjLnYxLlN1YnNjcmliZURldmljZXNIABJACgt1bnN1YnNjcmliZRgIIAEoCzIpLmt1c2ludGEuaW90LndlYnJ0Yy52MS5VbnN1YnNjcmliZURldmljZXNIABI+CgptYW5hZ2VtZW50GAkgASgLMigua3VzaW50YS5pb3Qud2VicnRjLnYxLk1hbmFnZW1lbnRSZXF1ZXN0SAASRwoPYXR0cmlidXRlX3dyaXRlGAogASgLMiwua3VzaW50YS5pb3Qud2VicnRjLnYxLkF0dHJpYnV0ZVdyaXRlUmVxdWVzdEgAEjwKDXN0YXJ0X3BhaXJpbmcYCyABKAsyIy5rdXNpbnRhLmlvdC53ZWJydGMudjEuU3RhcnRQYWlyaW5nSABCCQoHcGF5bG9hZCr2AQoQR2F0ZXdheUVycm9yQ29kZRIiCh5HQVRFV0FZX0VSUk9SX0NPREVfVU5TUEVDSUZJRUQQABIjCh9HQVRFV0FZX0VSUk9SX0NPREVfTk9UX0VOVElUTEVEEAESJgoiR0FURVdBWV9FUlJPUl9DT0RFX0lOVkFMSURfUkVRVUVTVBACEiIKHkdBVEVXQVlfRVJST1JfQ09ERV9VTkFWQUlMQUJMRRADEh8KG0dBVEVXQVlfRVJST1JfQ09ERV9JTlRFUk5BTBAEEiwKKEdBVEVXQVlfRVJST1JfQ09ERV9TRVNTSU9OX0xJTUlUX1JFQUNIRUQQBUICSAFiBnByb3RvMw", [file_google_protobuf_timestamp, file_kusinta_iot_access_v1_acl, file_kusinta_iot_common_v1_pairing, file_kusinta_iot_common_v1_types, file_kusinta_iot_device_v1_device_event, file_kusinta_iot_identity_v1_identity, file_kusinta_iot_link_v1_link, file_kusinta_iot_space_v1_space, file_kusinta_iot_webrtc_v1_command, file_kusinta_iot_webrtc_v1_device_state, file_kusinta_iot_webrtc_v1_management, file_kusinta_iot_webrtc_v1_permission_push]);
21
24
 
22
25
  /**
23
26
  * Describes the message kusinta.iot.webrtc.v1.Ping.
@@ -96,19 +99,40 @@ export const GatewayErrorSchema = /*@__PURE__*/
96
99
  export const ManagementResultSchema = /*@__PURE__*/
97
100
  messageDesc(file_kusinta_iot_webrtc_v1_envelope, 10);
98
101
 
102
+ /**
103
+ * Describes the message kusinta.iot.webrtc.v1.StartPairing.
104
+ * Use `create(StartPairingSchema)` to create a new message.
105
+ */
106
+ export const StartPairingSchema = /*@__PURE__*/
107
+ messageDesc(file_kusinta_iot_webrtc_v1_envelope, 11);
108
+
109
+ /**
110
+ * Describes the message kusinta.iot.webrtc.v1.PairingStarted.
111
+ * Use `create(PairingStartedSchema)` to create a new message.
112
+ */
113
+ export const PairingStartedSchema = /*@__PURE__*/
114
+ messageDesc(file_kusinta_iot_webrtc_v1_envelope, 12);
115
+
116
+ /**
117
+ * Describes the message kusinta.iot.webrtc.v1.PairingFinished.
118
+ * Use `create(PairingFinishedSchema)` to create a new message.
119
+ */
120
+ export const PairingFinishedSchema = /*@__PURE__*/
121
+ messageDesc(file_kusinta_iot_webrtc_v1_envelope, 13);
122
+
99
123
  /**
100
124
  * Describes the message kusinta.iot.webrtc.v1.GatewayMessage.
101
125
  * Use `create(GatewayMessageSchema)` to create a new message.
102
126
  */
103
127
  export const GatewayMessageSchema = /*@__PURE__*/
104
- messageDesc(file_kusinta_iot_webrtc_v1_envelope, 11);
128
+ messageDesc(file_kusinta_iot_webrtc_v1_envelope, 14);
105
129
 
106
130
  /**
107
131
  * Describes the message kusinta.iot.webrtc.v1.AppMessage.
108
132
  * Use `create(AppMessageSchema)` to create a new message.
109
133
  */
110
134
  export const AppMessageSchema = /*@__PURE__*/
111
- messageDesc(file_kusinta_iot_webrtc_v1_envelope, 12);
135
+ messageDesc(file_kusinta_iot_webrtc_v1_envelope, 15);
112
136
 
113
137
  /**
114
138
  * Describes the enum kusinta.iot.webrtc.v1.GatewayErrorCode.
@@ -7,6 +7,7 @@ import type { Message } from "@bufbuild/protobuf";
7
7
  import type { DeviceOwnershipType, SpaceType } from "../../common/v1/types_pb.js";
8
8
  import type { DeviceId, SpaceId, UserId } from "../../identity/v1/identity_pb.js";
9
9
  import type { Space } from "../../space/v1/space_pb.js";
10
+ import type { LinkFunction, LinkMode } from "../../link/v1/link_pb.js";
10
11
 
11
12
  /**
12
13
  * Describes the file kusinta/iot/webrtc/v1/management.proto.
@@ -265,8 +266,18 @@ export declare type ClaimDevice = Message<"kusinta.iot.webrtc.v1.ClaimDevice"> &
265
266
  initialSpaceId?: SpaceId | undefined;
266
267
 
267
268
  /**
268
- * Evidence the claimant is standing at the device: the serial printed on it,
269
- * matched against DeviceDescriptor.serial_number. Required precisely when the
269
+ * Evidence the claimant is standing at the device: the identifier printed on it,
270
+ * matched against DeviceDescriptor.serial_number.
271
+ *
272
+ * The match is by SUFFIX, because what a connector announces is not always the whole
273
+ * of what is printed and the announced value is commonly the tail of the printed one.
274
+ * Both sides are normalised first — lowercased, with whitespace and ASCII hyphens
275
+ * removed, since a label prints the value in groups and a scan does not — and the proof
276
+ * is accepted when what remains ends with the announced serial. Spelled out because two
277
+ * gateways normalising differently would accept different proofs for the same device.
278
+ *
279
+ * A serial shorter than eight characters cannot be proved at all: under a suffix rule a
280
+ * short one is proved by almost anything ending with it. Required precisely when the
270
281
  * caller cannot already reach the device, which is the ordinary case for a
271
282
  * resident claiming something they just bought — an unfiled device is invisible
272
283
  * to them, so possession is the only thing left that can distinguish them from
@@ -373,7 +384,91 @@ export declare const ManagementAckSchema: GenMessage<ManagementAck>;
373
384
  * message kind, so these can never be gated by a table keyed on the envelope case
374
385
  * the way device messages are. Keeping them behind one case means one place that
375
386
  * must authorize, and one refusal path that must not leak whether a target exists.
387
+ * Links one device to another, so the sender leads the receiver. The gateway
388
+ * resolves which underlying connections that needs and asks the connector for
389
+ * them; a caller names two devices and what the link is for.
376
390
  *
391
+ * Authorized against both ends, and not symmetrically. Leading a device is a
392
+ * standing grant of control over it, so the receiver requires ownership or a
393
+ * servicing role. The sender's requirement depends on the mode: a gateway-kept
394
+ * link only reads what the caller can already see, while a device-to-device one
395
+ * writes configuration to the sender and spends its battery, which is a change
396
+ * to someone else's hardware.
397
+ *
398
+ * @generated from message kusinta.iot.webrtc.v1.CreateDeviceLink
399
+ */
400
+ export declare type CreateDeviceLink = Message<"kusinta.iot.webrtc.v1.CreateDeviceLink"> & {
401
+ /**
402
+ * @generated from field: kusinta.iot.identity.v1.DeviceId sender = 1;
403
+ */
404
+ sender?: DeviceId | undefined;
405
+
406
+ /**
407
+ * @generated from field: kusinta.iot.identity.v1.DeviceId receiver = 2;
408
+ */
409
+ receiver?: DeviceId | undefined;
410
+
411
+ /**
412
+ * @generated from field: kusinta.iot.link.v1.LinkFunction function = 3;
413
+ */
414
+ function: LinkFunction;
415
+
416
+ /**
417
+ * Unset lets the gateway choose, which prefers a device-to-device link where
418
+ * one can be brokered: it survives a gateway outage and runs at the devices'
419
+ * own rate. Name one to override that.
420
+ *
421
+ * @generated from field: kusinta.iot.link.v1.LinkMode mode = 4;
422
+ */
423
+ mode: LinkMode;
424
+ };
425
+
426
+ /**
427
+ * Describes the message kusinta.iot.webrtc.v1.CreateDeviceLink.
428
+ * Use `create(CreateDeviceLinkSchema)` to create a new message.
429
+ */
430
+ export declare const CreateDeviceLinkSchema: GenMessage<CreateDeviceLink>;
431
+
432
+ /**
433
+ * Removes a link. Note that on at least one vendor, removing a link disturbs the
434
+ * receiver's own settings and the connector must repair them, so this is not the
435
+ * no-op it appears to be.
436
+ *
437
+ * @generated from message kusinta.iot.webrtc.v1.RemoveDeviceLink
438
+ */
439
+ export declare type RemoveDeviceLink = Message<"kusinta.iot.webrtc.v1.RemoveDeviceLink"> & {
440
+ /**
441
+ * @generated from field: string link_id = 1;
442
+ */
443
+ linkId: string;
444
+ };
445
+
446
+ /**
447
+ * Describes the message kusinta.iot.webrtc.v1.RemoveDeviceLink.
448
+ * Use `create(RemoveDeviceLinkSchema)` to create a new message.
449
+ */
450
+ export declare const RemoveDeviceLinkSchema: GenMessage<RemoveDeviceLink>;
451
+
452
+ /**
453
+ * Lists links. Unset device_id lists every link among devices the caller can
454
+ * reach; naming one narrows it to that device's own, in either direction.
455
+ *
456
+ * @generated from message kusinta.iot.webrtc.v1.ListDeviceLinks
457
+ */
458
+ export declare type ListDeviceLinks = Message<"kusinta.iot.webrtc.v1.ListDeviceLinks"> & {
459
+ /**
460
+ * @generated from field: kusinta.iot.identity.v1.DeviceId device_id = 1;
461
+ */
462
+ deviceId?: DeviceId | undefined;
463
+ };
464
+
465
+ /**
466
+ * Describes the message kusinta.iot.webrtc.v1.ListDeviceLinks.
467
+ * Use `create(ListDeviceLinksSchema)` to create a new message.
468
+ */
469
+ export declare const ListDeviceLinksSchema: GenMessage<ListDeviceLinks>;
470
+
471
+ /**
377
472
  * @generated from message kusinta.iot.webrtc.v1.ManagementRequest
378
473
  */
379
474
  export declare type ManagementRequest = Message<"kusinta.iot.webrtc.v1.ManagementRequest"> & {
@@ -440,6 +535,24 @@ export declare type ManagementRequest = Message<"kusinta.iot.webrtc.v1.Managemen
440
535
  */
441
536
  value: ListSpaces;
442
537
  case: "listSpaces";
538
+ } | {
539
+ /**
540
+ * @generated from field: kusinta.iot.webrtc.v1.CreateDeviceLink create_device_link = 11;
541
+ */
542
+ value: CreateDeviceLink;
543
+ case: "createDeviceLink";
544
+ } | {
545
+ /**
546
+ * @generated from field: kusinta.iot.webrtc.v1.RemoveDeviceLink remove_device_link = 12;
547
+ */
548
+ value: RemoveDeviceLink;
549
+ case: "removeDeviceLink";
550
+ } | {
551
+ /**
552
+ * @generated from field: kusinta.iot.webrtc.v1.ListDeviceLinks list_device_links = 13;
553
+ */
554
+ value: ListDeviceLinks;
555
+ case: "listDeviceLinks";
443
556
  } | { case: undefined; value?: undefined };
444
557
  };
445
558
 
@@ -5,13 +5,14 @@
5
5
  import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2";
6
6
  import { file_kusinta_iot_common_v1_types } from "../../common/v1/types_pb.js";
7
7
  import { file_kusinta_iot_identity_v1_identity } from "../../identity/v1/identity_pb.js";
8
+ import { file_kusinta_iot_link_v1_link } from "../../link/v1/link_pb.js";
8
9
  import { file_kusinta_iot_space_v1_space } from "../../space/v1/space_pb.js";
9
10
 
10
11
  /**
11
12
  * Describes the file kusinta/iot/webrtc/v1/management.proto.
12
13
  */
13
14
  export const file_kusinta_iot_webrtc_v1_management = /*@__PURE__*/
14
- fileDesc("CiZrdXNpbnRhL2lvdC93ZWJydGMvdjEvbWFuYWdlbWVudC5wcm90bxIVa3VzaW50YS5pb3Qud2VicnRjLnYxIrABCgtDcmVhdGVTcGFjZRI0CgpzcGFjZV90eXBlGAEgASgOMiAua3VzaW50YS5pb3QuY29tbW9uLnYxLlNwYWNlVHlwZRIMCgRuYW1lGAIgASgJEhMKC2Rlc2NyaXB0aW9uGAMgASgJEg0KBWZsb29yGAQgASgFEjkKD3BhcmVudF9zcGFjZV9pZBgFIAEoCzIgLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLlNwYWNlSWQizwIKC1VwZGF0ZVNwYWNlEjIKCHNwYWNlX2lkGAEgASgLMiAua3VzaW50YS5pb3QuaWRlbnRpdHkudjEuU3BhY2VJZBI5CgpzcGFjZV90eXBlGAIgASgOMiAua3VzaW50YS5pb3QuY29tbW9uLnYxLlNwYWNlVHlwZUgBiAEBEhEKBG5hbWUYAyABKAlIAogBARIYCgtkZXNjcmlwdGlvbhgEIAEoCUgDiAEBEhIKBWZsb29yGAUgASgFSASIAQESOwoPcGFyZW50X3NwYWNlX2lkGAYgASgLMiAua3VzaW50YS5pb3QuaWRlbnRpdHkudjEuU3BhY2VJZEgAEhAKBmRldGFjaBgHIAEoCEgAQg8KDXBhcmVudF9jaGFuZ2VCDQoLX3NwYWNlX3R5cGVCBwoFX25hbWVCDgoMX2Rlc2NyaXB0aW9uQggKBl9mbG9vciJSCgtEZWxldGVTcGFjZRIyCghzcGFjZV9pZBgBIAEoCzIgLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLlNwYWNlSWQSDwoHY2FzY2FkZRgCIAEoCCJ/ChFBc3NpZ25Vc2VyVG9TcGFjZRIyCghzcGFjZV9pZBgBIAEoCzIgLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLlNwYWNlSWQSMAoHdXNlcl9pZBgCIAEoCzIfLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLlVzZXJJZEoECAMQBCJ7ChNSZW1vdmVVc2VyRnJvbVNwYWNlEjIKCHNwYWNlX2lkGAEgASgLMiAua3VzaW50YS5pb3QuaWRlbnRpdHkudjEuU3BhY2VJZBIwCgd1c2VyX2lkGAIgASgLMh8ua3VzaW50YS5pb3QuaWRlbnRpdHkudjEuVXNlcklkIn4KElBsYWNlRGV2aWNlSW5TcGFjZRI0CglkZXZpY2VfaWQYASABKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZBIyCghzcGFjZV9pZBgCIAEoCzIgLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLlNwYWNlSWQigQEKFVJlbW92ZURldmljZUZyb21TcGFjZRI0CglkZXZpY2VfaWQYASABKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZBIyCghzcGFjZV9pZBgCIAEoCzIgLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLlNwYWNlSWQi2AEKC0NsYWltRGV2aWNlEjQKCWRldmljZV9pZBgBIAEoCzIhLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLkRldmljZUlkEj0KCW93bmVyc2hpcBgCIAEoDjIqLmt1c2ludGEuaW90LmNvbW1vbi52MS5EZXZpY2VPd25lcnNoaXBUeXBlEjoKEGluaXRpYWxfc3BhY2VfaWQYAyABKAsyIC5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5TcGFjZUlkEhgKEHBvc3Nlc3Npb25fcHJvb2YYBCABKAkiRQoNUmVsZWFzZURldmljZRI0CglkZXZpY2VfaWQYASABKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZCJFCgpMaXN0U3BhY2VzEjcKDXJvb3Rfc3BhY2VfaWQYASABKAsyIC5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5TcGFjZUlkIjgKCVNwYWNlVHJlZRIrCgZzcGFjZXMYASADKAsyGy5rdXNpbnRhLmlvdC5zcGFjZS52MS5TcGFjZSIPCg1NYW5hZ2VtZW50QWNrIr4FChFNYW5hZ2VtZW50UmVxdWVzdBI6CgxjcmVhdGVfc3BhY2UYASABKAsyIi5rdXNpbnRhLmlvdC53ZWJydGMudjEuQ3JlYXRlU3BhY2VIABI6Cgx1cGRhdGVfc3BhY2UYAiABKAsyIi5rdXNpbnRhLmlvdC53ZWJydGMudjEuVXBkYXRlU3BhY2VIABI6CgxkZWxldGVfc3BhY2UYAyABKAsyIi5rdXNpbnRhLmlvdC53ZWJydGMudjEuRGVsZXRlU3BhY2VIABJIChRhc3NpZ25fdXNlcl90b19zcGFjZRgEIAEoCzIoLmt1c2ludGEuaW90LndlYnJ0Yy52MS5Bc3NpZ25Vc2VyVG9TcGFjZUgAEkwKFnJlbW92ZV91c2VyX2Zyb21fc3BhY2UYBSABKAsyKi5rdXNpbnRhLmlvdC53ZWJydGMudjEuUmVtb3ZlVXNlckZyb21TcGFjZUgAEkoKFXBsYWNlX2RldmljZV9pbl9zcGFjZRgGIAEoCzIpLmt1c2ludGEuaW90LndlYnJ0Yy52MS5QbGFjZURldmljZUluU3BhY2VIABJQChhyZW1vdmVfZGV2aWNlX2Zyb21fc3BhY2UYByABKAsyLC5rdXNpbnRhLmlvdC53ZWJydGMudjEuUmVtb3ZlRGV2aWNlRnJvbVNwYWNlSAASOgoMY2xhaW1fZGV2aWNlGAggASgLMiIua3VzaW50YS5pb3Qud2VicnRjLnYxLkNsYWltRGV2aWNlSAASPgoOcmVsZWFzZV9kZXZpY2UYCSABKAsyJC5rdXNpbnRhLmlvdC53ZWJydGMudjEuUmVsZWFzZURldmljZUgAEjgKC2xpc3Rfc3BhY2VzGAogASgLMiEua3VzaW50YS5pb3Qud2VicnRjLnYxLkxpc3RTcGFjZXNIAEIJCgdyZXF1ZXN0QgJIAWIGcHJvdG8z", [file_kusinta_iot_common_v1_types, file_kusinta_iot_identity_v1_identity, file_kusinta_iot_space_v1_space]);
15
+ fileDesc("CiZrdXNpbnRhL2lvdC93ZWJydGMvdjEvbWFuYWdlbWVudC5wcm90bxIVa3VzaW50YS5pb3Qud2VicnRjLnYxIrABCgtDcmVhdGVTcGFjZRI0CgpzcGFjZV90eXBlGAEgASgOMiAua3VzaW50YS5pb3QuY29tbW9uLnYxLlNwYWNlVHlwZRIMCgRuYW1lGAIgASgJEhMKC2Rlc2NyaXB0aW9uGAMgASgJEg0KBWZsb29yGAQgASgFEjkKD3BhcmVudF9zcGFjZV9pZBgFIAEoCzIgLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLlNwYWNlSWQizwIKC1VwZGF0ZVNwYWNlEjIKCHNwYWNlX2lkGAEgASgLMiAua3VzaW50YS5pb3QuaWRlbnRpdHkudjEuU3BhY2VJZBI5CgpzcGFjZV90eXBlGAIgASgOMiAua3VzaW50YS5pb3QuY29tbW9uLnYxLlNwYWNlVHlwZUgBiAEBEhEKBG5hbWUYAyABKAlIAogBARIYCgtkZXNjcmlwdGlvbhgEIAEoCUgDiAEBEhIKBWZsb29yGAUgASgFSASIAQESOwoPcGFyZW50X3NwYWNlX2lkGAYgASgLMiAua3VzaW50YS5pb3QuaWRlbnRpdHkudjEuU3BhY2VJZEgAEhAKBmRldGFjaBgHIAEoCEgAQg8KDXBhcmVudF9jaGFuZ2VCDQoLX3NwYWNlX3R5cGVCBwoFX25hbWVCDgoMX2Rlc2NyaXB0aW9uQggKBl9mbG9vciJSCgtEZWxldGVTcGFjZRIyCghzcGFjZV9pZBgBIAEoCzIgLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLlNwYWNlSWQSDwoHY2FzY2FkZRgCIAEoCCJ/ChFBc3NpZ25Vc2VyVG9TcGFjZRIyCghzcGFjZV9pZBgBIAEoCzIgLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLlNwYWNlSWQSMAoHdXNlcl9pZBgCIAEoCzIfLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLlVzZXJJZEoECAMQBCJ7ChNSZW1vdmVVc2VyRnJvbVNwYWNlEjIKCHNwYWNlX2lkGAEgASgLMiAua3VzaW50YS5pb3QuaWRlbnRpdHkudjEuU3BhY2VJZBIwCgd1c2VyX2lkGAIgASgLMh8ua3VzaW50YS5pb3QuaWRlbnRpdHkudjEuVXNlcklkIn4KElBsYWNlRGV2aWNlSW5TcGFjZRI0CglkZXZpY2VfaWQYASABKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZBIyCghzcGFjZV9pZBgCIAEoCzIgLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLlNwYWNlSWQigQEKFVJlbW92ZURldmljZUZyb21TcGFjZRI0CglkZXZpY2VfaWQYASABKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZBIyCghzcGFjZV9pZBgCIAEoCzIgLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLlNwYWNlSWQi2AEKC0NsYWltRGV2aWNlEjQKCWRldmljZV9pZBgBIAEoCzIhLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLkRldmljZUlkEj0KCW93bmVyc2hpcBgCIAEoDjIqLmt1c2ludGEuaW90LmNvbW1vbi52MS5EZXZpY2VPd25lcnNoaXBUeXBlEjoKEGluaXRpYWxfc3BhY2VfaWQYAyABKAsyIC5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5TcGFjZUlkEhgKEHBvc3Nlc3Npb25fcHJvb2YYBCABKAkiRQoNUmVsZWFzZURldmljZRI0CglkZXZpY2VfaWQYASABKAsyIS5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5EZXZpY2VJZCJFCgpMaXN0U3BhY2VzEjcKDXJvb3Rfc3BhY2VfaWQYASABKAsyIC5rdXNpbnRhLmlvdC5pZGVudGl0eS52MS5TcGFjZUlkIjgKCVNwYWNlVHJlZRIrCgZzcGFjZXMYASADKAsyGy5rdXNpbnRhLmlvdC5zcGFjZS52MS5TcGFjZSIPCg1NYW5hZ2VtZW50QWNrItwBChBDcmVhdGVEZXZpY2VMaW5rEjEKBnNlbmRlchgBIAEoCzIhLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLkRldmljZUlkEjMKCHJlY2VpdmVyGAIgASgLMiEua3VzaW50YS5pb3QuaWRlbnRpdHkudjEuRGV2aWNlSWQSMwoIZnVuY3Rpb24YAyABKA4yIS5rdXNpbnRhLmlvdC5saW5rLnYxLkxpbmtGdW5jdGlvbhIrCgRtb2RlGAQgASgOMh0ua3VzaW50YS5pb3QubGluay52MS5MaW5rTW9kZSIjChBSZW1vdmVEZXZpY2VMaW5rEg8KB2xpbmtfaWQYASABKAkiRwoPTGlzdERldmljZUxpbmtzEjQKCWRldmljZV9pZBgBIAEoCzIhLmt1c2ludGEuaW90LmlkZW50aXR5LnYxLkRldmljZUlkIpcHChFNYW5hZ2VtZW50UmVxdWVzdBI6CgxjcmVhdGVfc3BhY2UYASABKAsyIi5rdXNpbnRhLmlvdC53ZWJydGMudjEuQ3JlYXRlU3BhY2VIABI6Cgx1cGRhdGVfc3BhY2UYAiABKAsyIi5rdXNpbnRhLmlvdC53ZWJydGMudjEuVXBkYXRlU3BhY2VIABI6CgxkZWxldGVfc3BhY2UYAyABKAsyIi5rdXNpbnRhLmlvdC53ZWJydGMudjEuRGVsZXRlU3BhY2VIABJIChRhc3NpZ25fdXNlcl90b19zcGFjZRgEIAEoCzIoLmt1c2ludGEuaW90LndlYnJ0Yy52MS5Bc3NpZ25Vc2VyVG9TcGFjZUgAEkwKFnJlbW92ZV91c2VyX2Zyb21fc3BhY2UYBSABKAsyKi5rdXNpbnRhLmlvdC53ZWJydGMudjEuUmVtb3ZlVXNlckZyb21TcGFjZUgAEkoKFXBsYWNlX2RldmljZV9pbl9zcGFjZRgGIAEoCzIpLmt1c2ludGEuaW90LndlYnJ0Yy52MS5QbGFjZURldmljZUluU3BhY2VIABJQChhyZW1vdmVfZGV2aWNlX2Zyb21fc3BhY2UYByABKAsyLC5rdXNpbnRhLmlvdC53ZWJydGMudjEuUmVtb3ZlRGV2aWNlRnJvbVNwYWNlSAASOgoMY2xhaW1fZGV2aWNlGAggASgLMiIua3VzaW50YS5pb3Qud2VicnRjLnYxLkNsYWltRGV2aWNlSAASPgoOcmVsZWFzZV9kZXZpY2UYCSABKAsyJC5rdXNpbnRhLmlvdC53ZWJydGMudjEuUmVsZWFzZURldmljZUgAEjgKC2xpc3Rfc3BhY2VzGAogASgLMiEua3VzaW50YS5pb3Qud2VicnRjLnYxLkxpc3RTcGFjZXNIABJFChJjcmVhdGVfZGV2aWNlX2xpbmsYCyABKAsyJy5rdXNpbnRhLmlvdC53ZWJydGMudjEuQ3JlYXRlRGV2aWNlTGlua0gAEkUKEnJlbW92ZV9kZXZpY2VfbGluaxgMIAEoCzInLmt1c2ludGEuaW90LndlYnJ0Yy52MS5SZW1vdmVEZXZpY2VMaW5rSAASQwoRbGlzdF9kZXZpY2VfbGlua3MYDSABKAsyJi5rdXNpbnRhLmlvdC53ZWJydGMudjEuTGlzdERldmljZUxpbmtzSABCCQoHcmVxdWVzdEoECA4QD0ICSAFiBnByb3RvMw", [file_kusinta_iot_common_v1_types, file_kusinta_iot_identity_v1_identity, file_kusinta_iot_link_v1_link, file_kusinta_iot_space_v1_space]);
15
16
 
16
17
  /**
17
18
  * Describes the message kusinta.iot.webrtc.v1.CreateSpace.
@@ -97,10 +98,31 @@ export const SpaceTreeSchema = /*@__PURE__*/
97
98
  export const ManagementAckSchema = /*@__PURE__*/
98
99
  messageDesc(file_kusinta_iot_webrtc_v1_management, 11);
99
100
 
101
+ /**
102
+ * Describes the message kusinta.iot.webrtc.v1.CreateDeviceLink.
103
+ * Use `create(CreateDeviceLinkSchema)` to create a new message.
104
+ */
105
+ export const CreateDeviceLinkSchema = /*@__PURE__*/
106
+ messageDesc(file_kusinta_iot_webrtc_v1_management, 12);
107
+
108
+ /**
109
+ * Describes the message kusinta.iot.webrtc.v1.RemoveDeviceLink.
110
+ * Use `create(RemoveDeviceLinkSchema)` to create a new message.
111
+ */
112
+ export const RemoveDeviceLinkSchema = /*@__PURE__*/
113
+ messageDesc(file_kusinta_iot_webrtc_v1_management, 13);
114
+
115
+ /**
116
+ * Describes the message kusinta.iot.webrtc.v1.ListDeviceLinks.
117
+ * Use `create(ListDeviceLinksSchema)` to create a new message.
118
+ */
119
+ export const ListDeviceLinksSchema = /*@__PURE__*/
120
+ messageDesc(file_kusinta_iot_webrtc_v1_management, 14);
121
+
100
122
  /**
101
123
  * Describes the message kusinta.iot.webrtc.v1.ManagementRequest.
102
124
  * Use `create(ManagementRequestSchema)` to create a new message.
103
125
  */
104
126
  export const ManagementRequestSchema = /*@__PURE__*/
105
- messageDesc(file_kusinta_iot_webrtc_v1_management, 12);
127
+ messageDesc(file_kusinta_iot_webrtc_v1_management, 15);
106
128