From a1a34abaf77b8b54354ee64844ab8e2c078f0a00 Mon Sep 17 00:00:00 2001 From: Orne Brocaar Date: Wed, 14 Jun 2023 11:17:04 +0100 Subject: [PATCH] Refactor device enabled_class to enum + expose in API. --- api/proto/api/device.proto | 690 ++++++++++--------- api/rust/proto/chirpstack/api/device.proto | 690 ++++++++++--------- chirpstack/src/api/device.rs | 1 + chirpstack/src/api/helpers.rs | 12 +- chirpstack/src/downlink/data.rs | 12 +- chirpstack/src/downlink/tx_ack.rs | 7 +- chirpstack/src/maccommand/device_mode_ind.rs | 13 +- chirpstack/src/storage/device.rs | 70 +- chirpstack/src/test/assert.rs | 5 +- chirpstack/src/test/class_a_pr_test.rs | 6 +- chirpstack/src/test/class_a_test.rs | 37 +- chirpstack/src/test/class_b_test.rs | 13 +- chirpstack/src/test/class_c_test.rs | 7 +- chirpstack/src/test/otaa_pr_test.rs | 8 +- chirpstack/src/test/otaa_test.rs | 20 +- chirpstack/src/test/relay_class_a_test.rs | 8 +- chirpstack/src/test/relay_otaa_test.rs | 8 +- chirpstack/src/uplink/data.rs | 18 +- chirpstack/src/uplink/join.rs | 9 +- chirpstack/src/uplink/join_sns.rs | 11 +- 20 files changed, 893 insertions(+), 752 deletions(-) diff --git a/api/proto/api/device.proto b/api/proto/api/device.proto index efaf2ee9..f67eb016 100644 --- a/api/proto/api/device.proto +++ b/api/proto/api/device.proto @@ -16,520 +16,542 @@ import "google/protobuf/empty.proto"; // DeviceService is the service providing API methods for managing devices. service DeviceService { - // Create the given device. - rpc Create(CreateDeviceRequest) returns (google.protobuf.Empty) { - option(google.api.http) = { - post: "/api/devices" - body: "*" - }; - } + // Create the given device. + rpc Create(CreateDeviceRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + post : "/api/devices" + body : "*" + }; + } - // Get returns the device for the given DevEUI. - rpc Get(GetDeviceRequest) returns (GetDeviceResponse) { - option(google.api.http) = { - get: "/api/devices/{dev_eui}" - }; - } + // Get returns the device for the given DevEUI. + rpc Get(GetDeviceRequest) returns (GetDeviceResponse) { + option (google.api.http) = { + get : "/api/devices/{dev_eui}" + }; + } - // Update the given device. - rpc Update(UpdateDeviceRequest) returns (google.protobuf.Empty) { - option(google.api.http) = { - put: "/api/devices/{device.dev_eui}" - body: "*" - }; - } + // Update the given device. + rpc Update(UpdateDeviceRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + put : "/api/devices/{device.dev_eui}" + body : "*" + }; + } - // Delete the device with the given DevEUI. - rpc Delete(DeleteDeviceRequest) returns (google.protobuf.Empty) { - option(google.api.http) = { - delete: "/api/devices/{dev_eui}" - }; - } + // Delete the device with the given DevEUI. + rpc Delete(DeleteDeviceRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + delete : "/api/devices/{dev_eui}" + }; + } - // Get the list of devices. - rpc List(ListDevicesRequest) returns (ListDevicesResponse) { - option(google.api.http) = { - get: "/api/devices" - }; - } + // Get the list of devices. + rpc List(ListDevicesRequest) returns (ListDevicesResponse) { + option (google.api.http) = { + get : "/api/devices" + }; + } - // Create the given device-keys. - rpc CreateKeys(CreateDeviceKeysRequest) returns (google.protobuf.Empty) { - option(google.api.http) = { - post: "/api/devices/{device_keys.dev_eui}/keys" - body: "*" - }; - } + // Create the given device-keys. + rpc CreateKeys(CreateDeviceKeysRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + post : "/api/devices/{device_keys.dev_eui}/keys" + body : "*" + }; + } - // Get the device-keys for the given DevEUI. - rpc GetKeys(GetDeviceKeysRequest) returns (GetDeviceKeysResponse) { - option(google.api.http) = { - get: "/api/devices/{dev_eui}/keys" - }; - } + // Get the device-keys for the given DevEUI. + rpc GetKeys(GetDeviceKeysRequest) returns (GetDeviceKeysResponse) { + option (google.api.http) = { + get : "/api/devices/{dev_eui}/keys" + }; + } - // Update the given device-keys. - rpc UpdateKeys(UpdateDeviceKeysRequest) returns (google.protobuf.Empty) { - option(google.api.http) = { - put: "/api/devices/{device_keys.dev_eui}/keys" - body: "*" - }; - } + // Update the given device-keys. + rpc UpdateKeys(UpdateDeviceKeysRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + put : "/api/devices/{device_keys.dev_eui}/keys" + body : "*" + }; + } - // Delete the device-keys for the given DevEUI. - rpc DeleteKeys(DeleteDeviceKeysRequest) returns (google.protobuf.Empty) { - option(google.api.http) = { - delete: "/api/devices/{dev_eui}/keys" - }; - } + // Delete the device-keys for the given DevEUI. + rpc DeleteKeys(DeleteDeviceKeysRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + delete : "/api/devices/{dev_eui}/keys" + }; + } - // FlushDevNonces flushes the OTAA device nonces. - rpc FlushDevNonces(FlushDevNoncesRequest) returns (google.protobuf.Empty) { - option(google.api.http) = { - delete: "/api/devices/{dev_eui}/dev-nonces" - }; - } + // FlushDevNonces flushes the OTAA device nonces. + rpc FlushDevNonces(FlushDevNoncesRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + delete : "/api/devices/{dev_eui}/dev-nonces" + }; + } - // Activate (re)activates the device with the given parameters (for ABP or for importing OTAA activations). - rpc Activate(ActivateDeviceRequest) returns (google.protobuf.Empty) { - option(google.api.http) = { - post: "/api/devices/{device_activation.dev_eui}/activate" - body: "*" - }; - } + // Activate (re)activates the device with the given parameters (for ABP or for + // importing OTAA activations). + rpc Activate(ActivateDeviceRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + post : "/api/devices/{device_activation.dev_eui}/activate" + body : "*" + }; + } - // Deactivate de-activates the device. - rpc Deactivate(DeactivateDeviceRequest) returns (google.protobuf.Empty) { - option(google.api.http) = { - delete: "/api/devices/{dev_eui}/activation" - }; - } + // Deactivate de-activates the device. + rpc Deactivate(DeactivateDeviceRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + delete : "/api/devices/{dev_eui}/activation" + }; + } - // GetActivation returns the current activation details of the device (OTAA or ABP). - rpc GetActivation(GetDeviceActivationRequest) returns (GetDeviceActivationResponse) { - option(google.api.http) = { - get: "/api/devices/{dev_eui}/activation" - }; - } + // GetActivation returns the current activation details of the device (OTAA or + // ABP). + rpc GetActivation(GetDeviceActivationRequest) + returns (GetDeviceActivationResponse) { + option (google.api.http) = { + get : "/api/devices/{dev_eui}/activation" + }; + } - // GetRandomDevAddr returns a random DevAddr taking the NwkID prefix into account. - rpc GetRandomDevAddr(GetRandomDevAddrRequest) returns (GetRandomDevAddrResponse) { - option(google.api.http) = { - post: "/api/devices/{dev_eui}/get-random-dev-addr" - }; - } + // GetRandomDevAddr returns a random DevAddr taking the NwkID prefix into + // account. + rpc GetRandomDevAddr(GetRandomDevAddrRequest) + returns (GetRandomDevAddrResponse) { + option (google.api.http) = { + post : "/api/devices/{dev_eui}/get-random-dev-addr" + }; + } - // GetMetrics returns the device metrics. - // Note that this requires a device-profile with codec and measurements configured. - rpc GetMetrics(GetDeviceMetricsRequest) returns (GetDeviceMetricsResponse) { - option(google.api.http) = { - get: "/api/devices/{dev_eui}/metrics" - }; - } + // GetMetrics returns the device metrics. + // Note that this requires a device-profile with codec and measurements + // configured. + rpc GetMetrics(GetDeviceMetricsRequest) returns (GetDeviceMetricsResponse) { + option (google.api.http) = { + get : "/api/devices/{dev_eui}/metrics" + }; + } - // GetLinkMetrics returns the device link metrics. - // This includes uplinks, downlinks, RSSI, SNR, etc... - rpc GetLinkMetrics(GetDeviceLinkMetricsRequest) returns (GetDeviceLinkMetricsResponse) { - option(google.api.http) = { - get: "/api/devices/{dev_eui}/link-metrics" - }; - } + // GetLinkMetrics returns the device link metrics. + // This includes uplinks, downlinks, RSSI, SNR, etc... + rpc GetLinkMetrics(GetDeviceLinkMetricsRequest) + returns (GetDeviceLinkMetricsResponse) { + option (google.api.http) = { + get : "/api/devices/{dev_eui}/link-metrics" + }; + } - // Enqueue adds the given item to the downlink queue. - rpc Enqueue(EnqueueDeviceQueueItemRequest) returns (EnqueueDeviceQueueItemResponse) { - option(google.api.http) = { - post: "/api/devices/{queue_item.dev_eui}/queue" - body: "*" - }; - } + // Enqueue adds the given item to the downlink queue. + rpc Enqueue(EnqueueDeviceQueueItemRequest) + returns (EnqueueDeviceQueueItemResponse) { + option (google.api.http) = { + post : "/api/devices/{queue_item.dev_eui}/queue" + body : "*" + }; + } - // FlushQueue flushes the downlink device-queue. - rpc FlushQueue(FlushDeviceQueueRequest) returns (google.protobuf.Empty) { - option(google.api.http) = { - delete: "/api/devices/{dev_eui}/queue" - }; - } + // FlushQueue flushes the downlink device-queue. + rpc FlushQueue(FlushDeviceQueueRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + delete : "/api/devices/{dev_eui}/queue" + }; + } - // GetQueue returns the downlink device-queue. - rpc GetQueue(GetDeviceQueueItemsRequest) returns (GetDeviceQueueItemsResponse) { - option(google.api.http) = { - get: "/api/devices/{dev_eui}/queue" - }; - } + // GetQueue returns the downlink device-queue. + rpc GetQueue(GetDeviceQueueItemsRequest) + returns (GetDeviceQueueItemsResponse) { + option (google.api.http) = { + get : "/api/devices/{dev_eui}/queue" + }; + } +} + +enum DeviceClass { + // Class-A. + A = 0; + + // Class-B. + B = 1; + + // Class-C. + C = 2; } message Device { - // DevEUI (EUI64). - string dev_eui = 1; + // DevEUI (EUI64). + string dev_eui = 1; - // Name. - string name = 2; + // Name. + string name = 2; - // Description. - string description = 3; + // Description. + string description = 3; - // Application ID (UUID). - string application_id = 4; - - // Device-profile ID (UUID). - string device_profile_id = 5; + // Application ID (UUID). + string application_id = 4; - // Skip frame-counter checks (this is insecure, but could be helpful for debugging). - bool skip_fcnt_check = 6; + // Device-profile ID (UUID). + string device_profile_id = 5; - // Device is disabled. - bool is_disabled = 7; + // Skip frame-counter checks (this is insecure, but could be helpful for + // debugging). + bool skip_fcnt_check = 6; - // Variables (user defined). - // These variables can be used together with integrations to store tokens / - // secrets that must be configured per device. These variables are not - // exposed in the event payloads. - map variables = 8; + // Device is disabled. + bool is_disabled = 7; - // Tags (user defined). - // These tags are exposed in the event payloads or to integration. Tags are - // intended for aggregation and filtering. - map tags = 9; + // Variables (user defined). + // These variables can be used together with integrations to store tokens / + // secrets that must be configured per device. These variables are not + // exposed in the event payloads. + map variables = 8; - // JoinEUI (optional, EUI64). - // This field will be automatically set / updated on OTAA. However, in some - // cases it must be pre-configured. For example to allow OTAA using a Relay. - // In this case the Relay needs to know the JoinEUI + DevEUI combinations - // of the devices for which it needs to forward uplinks. - string join_eui = 10; + // Tags (user defined). + // These tags are exposed in the event payloads or to integration. Tags are + // intended for aggregation and filtering. + map tags = 9; + + // JoinEUI (optional, EUI64). + // This field will be automatically set / updated on OTAA. However, in some + // cases it must be pre-configured. For example to allow OTAA using a Relay. + // In this case the Relay needs to know the JoinEUI + DevEUI combinations + // of the devices for which it needs to forward uplinks. + string join_eui = 10; } message DeviceStatus { - // The device margin status - // -32..32: The demodulation SNR ration in dB - int32 margin = 1; + // The device margin status + // -32..32: The demodulation SNR ration in dB + int32 margin = 1; - // Device is connected to an external power source. - bool external_power_source = 2; + // Device is connected to an external power source. + bool external_power_source = 2; - // Device battery level as a percentage. - // -1 when the battery level is not available. - float battery_level = 3; + // Device battery level as a percentage. + // -1 when the battery level is not available. + float battery_level = 3; } message DeviceListItem { - // DevEUI (EUI64). - string dev_eui = 1; + // DevEUI (EUI64). + string dev_eui = 1; - // Created at timestamp. - google.protobuf.Timestamp created_at = 2; + // Created at timestamp. + google.protobuf.Timestamp created_at = 2; - // Last update timestamp. - google.protobuf.Timestamp updated_at = 3; + // Last update timestamp. + google.protobuf.Timestamp updated_at = 3; - // Last seen at timestamp. - google.protobuf.Timestamp last_seen_at = 4; + // Last seen at timestamp. + google.protobuf.Timestamp last_seen_at = 4; - // Name. - string name = 5; + // Name. + string name = 5; - // Description. - string description = 6; + // Description. + string description = 6; - // Device-profile ID (UUID). - string device_profile_id = 7; + // Device-profile ID (UUID). + string device_profile_id = 7; - // Device-profile name. - string device_profile_name = 8; + // Device-profile name. + string device_profile_name = 8; - // Device status. - DeviceStatus device_status = 9; + // Device status. + DeviceStatus device_status = 9; } message DeviceKeys { - // DevEUI (EUI64). - string dev_eui = 1; + // DevEUI (EUI64). + string dev_eui = 1; - // Network root key (128 bit). - // Note: For LoRaWAN 1.0.x, use this field for the LoRaWAN 1.0.x 'AppKey`! - string nwk_key = 2; + // Network root key (128 bit). + // Note: For LoRaWAN 1.0.x, use this field for the LoRaWAN 1.0.x 'AppKey`! + string nwk_key = 2; - // Application root key (128 bit). - // Note: This field only needs to be set for LoRaWAN 1.1.x devices! - string app_key = 3; + // Application root key (128 bit). + // Note: This field only needs to be set for LoRaWAN 1.1.x devices! + string app_key = 3; } message CreateDeviceRequest { - // Device object. - Device device = 1; + // Device object. + Device device = 1; } message GetDeviceRequest { - // DevEUI (EUI64). - string dev_eui = 1; + // DevEUI (EUI64). + string dev_eui = 1; } message GetDeviceResponse { - // Device object. - Device device = 1; + // Device object. + Device device = 1; - // Created at timestamp. - google.protobuf.Timestamp created_at = 2; + // Created at timestamp. + google.protobuf.Timestamp created_at = 2; - // Last update timestamp. - google.protobuf.Timestamp updated_at = 3; + // Last update timestamp. + google.protobuf.Timestamp updated_at = 3; - // Last seen at timestamp. - google.protobuf.Timestamp last_seen_at = 4; + // Last seen at timestamp. + google.protobuf.Timestamp last_seen_at = 4; - // Device status. - DeviceStatus device_status = 5; + // Device status. + DeviceStatus device_status = 5; + + // Enabled class. + DeviceClass enabled_class = 6; } message UpdateDeviceRequest { - // Device object. - Device device = 1; + // Device object. + Device device = 1; } message DeleteDeviceRequest { - // DevEUI (EUI64). - string dev_eui = 1; + // DevEUI (EUI64). + string dev_eui = 1; } message ListDevicesRequest { - // Max number of devices to return in the result-set. - uint32 limit = 1; + // Max number of devices to return in the result-set. + uint32 limit = 1; - // Offset in the result-set (for pagination). - uint32 offset = 2; + // Offset in the result-set (for pagination). + uint32 offset = 2; - // If set, the given string will be used to search on name (optional). - string search = 3; + // If set, the given string will be used to search on name (optional). + string search = 3; - // Application ID (UUID) to filter devices on. - string application_id = 4; + // Application ID (UUID) to filter devices on. + string application_id = 4; - // Multicst-group ID (UUID) to filter devices on. - string multicast_group_id = 5; + // Multicst-group ID (UUID) to filter devices on. + string multicast_group_id = 5; } message ListDevicesResponse { - // Total number of devices. - uint32 total_count = 1; + // Total number of devices. + uint32 total_count = 1; - // Result-set. - repeated DeviceListItem result = 2; + // Result-set. + repeated DeviceListItem result = 2; } message CreateDeviceKeysRequest { - // Device-keys object. - DeviceKeys device_keys = 1; + // Device-keys object. + DeviceKeys device_keys = 1; } message GetDeviceKeysRequest { - // DevEUI (EUI64). - string dev_eui = 1; + // DevEUI (EUI64). + string dev_eui = 1; } message GetDeviceKeysResponse { - // Device-keys object. - DeviceKeys device_keys = 1; + // Device-keys object. + DeviceKeys device_keys = 1; - // Created at timestamp. - google.protobuf.Timestamp created_at = 2; + // Created at timestamp. + google.protobuf.Timestamp created_at = 2; - // Last update timestamp. - google.protobuf.Timestamp updated_at = 3; + // Last update timestamp. + google.protobuf.Timestamp updated_at = 3; } message UpdateDeviceKeysRequest { - // Device-keys object. - DeviceKeys device_keys = 1; + // Device-keys object. + DeviceKeys device_keys = 1; } message DeleteDeviceKeysRequest { - // DevEUI (EUI64). - string dev_eui = 1; + // DevEUI (EUI64). + string dev_eui = 1; } message DeviceActivation { - // Device EUI (EUI64). - string dev_eui = 1; + // Device EUI (EUI64). + string dev_eui = 1; - // Device address (HEX encoded). - string dev_addr = 2; + // Device address (HEX encoded). + string dev_addr = 2; - // Application session key (HEX encoded). - string app_s_key = 3; + // Application session key (HEX encoded). + string app_s_key = 3; - // Network session encryption key (HEX encoded). - string nwk_s_enc_key = 4; + // Network session encryption key (HEX encoded). + string nwk_s_enc_key = 4; - // Serving network session integrity key (HEX encoded). - string s_nwk_s_int_key = 8; + // Serving network session integrity key (HEX encoded). + string s_nwk_s_int_key = 8; - // Forwarding network session integrity key (HEX encoded). - string f_nwk_s_int_key = 9; + // Forwarding network session integrity key (HEX encoded). + string f_nwk_s_int_key = 9; - // Uplink frame-counter. - uint32 f_cnt_up = 5; + // Uplink frame-counter. + uint32 f_cnt_up = 5; - // Downlink network frame-counter. - uint32 n_f_cnt_down = 6; + // Downlink network frame-counter. + uint32 n_f_cnt_down = 6; - // Downlink application frame-counter. - uint32 a_f_cnt_down = 10; + // Downlink application frame-counter. + uint32 a_f_cnt_down = 10; } message ActivateDeviceRequest { - // Device activation object. - DeviceActivation device_activation = 1; + // Device activation object. + DeviceActivation device_activation = 1; } message DeactivateDeviceRequest { - // DevEUI (EUI64). - string dev_eui = 1; + // DevEUI (EUI64). + string dev_eui = 1; } message GetDeviceActivationRequest { - // DevEUI (EUI64). - string dev_eui = 1; + // DevEUI (EUI64). + string dev_eui = 1; } message GetDeviceActivationResponse { - // Device activation object. - DeviceActivation device_activation = 1; + // Device activation object. + DeviceActivation device_activation = 1; } message GetRandomDevAddrRequest { - // DevEUI (EUI64). - string dev_eui = 1; + // DevEUI (EUI64). + string dev_eui = 1; } message GetRandomDevAddrResponse { - // DevAddr. - string dev_addr = 1; + // DevAddr. + string dev_addr = 1; } message GetDeviceMetricsRequest { - // DevEUI (EUI64). - string dev_eui = 1; + // DevEUI (EUI64). + string dev_eui = 1; - // Interval start timestamp. - google.protobuf.Timestamp start = 2; + // Interval start timestamp. + google.protobuf.Timestamp start = 2; - // Interval end timestamp. - google.protobuf.Timestamp end = 3; + // Interval end timestamp. + google.protobuf.Timestamp end = 3; - // Aggregation. - common.Aggregation aggregation = 4; + // Aggregation. + common.Aggregation aggregation = 4; } message GetDeviceMetricsResponse { - map metrics = 1; + map metrics = 1; - map states = 2; + map states = 2; } message DeviceState { - // Name. - string name = 2; + // Name. + string name = 2; - // Value. - string value = 3; + // Value. + string value = 3; } message GetDeviceLinkMetricsRequest { - // DevEUI (EUI64). - string dev_eui = 1; + // DevEUI (EUI64). + string dev_eui = 1; - // Interval start timestamp. - google.protobuf.Timestamp start = 2; + // Interval start timestamp. + google.protobuf.Timestamp start = 2; - // Interval end timestamp. - google.protobuf.Timestamp end = 3; + // Interval end timestamp. + google.protobuf.Timestamp end = 3; - // Aggregation. - common.Aggregation aggregation = 4; + // Aggregation. + common.Aggregation aggregation = 4; } message GetDeviceLinkMetricsResponse { - // Packets received from the device. - common.Metric rx_packets = 1; + // Packets received from the device. + common.Metric rx_packets = 1; - // RSSI (as reported by the gateway(s)). - common.Metric gw_rssi = 2; + // RSSI (as reported by the gateway(s)). + common.Metric gw_rssi = 2; - // SNR (as reported by the gateway(s)). - common.Metric gw_snr = 3; + // SNR (as reported by the gateway(s)). + common.Metric gw_snr = 3; - // Packets received by frequency. - common.Metric rx_packets_per_freq = 4; + // Packets received by frequency. + common.Metric rx_packets_per_freq = 4; - // Packets received by DR. - common.Metric rx_packets_per_dr = 5; + // Packets received by DR. + common.Metric rx_packets_per_dr = 5; - // Errors. - common.Metric errors = 6; + // Errors. + common.Metric errors = 6; } message DeviceQueueItem { - // ID (UUID). - // This is automatically generated on enqueue. - string id = 1; + // ID (UUID). + // This is automatically generated on enqueue. + string id = 1; - // Device EUI (EUI64). - string dev_eui = 2; + // Device EUI (EUI64). + string dev_eui = 2; - // Confirmed. - bool confirmed = 3; + // Confirmed. + bool confirmed = 3; - // FPort (must be > 0). - uint32 f_port = 4; + // FPort (must be > 0). + uint32 f_port = 4; - // Data. - // Or use the json_object field when a codec has been configured. - bytes data = 5; + // Data. + // Or use the json_object field when a codec has been configured. + bytes data = 5; - // Only use this when a codec has been configured that can encode this - // object to bytes. - google.protobuf.Struct object = 6; + // Only use this when a codec has been configured that can encode this + // object to bytes. + google.protobuf.Struct object = 6; - // Is pending. - // This is set to true when the downlink is pending. - bool is_pending = 7; + // Is pending. + // This is set to true when the downlink is pending. + bool is_pending = 7; - // Downlink frame-counter. - // This is set when the payload has been sent as downlink. - uint32 f_cnt_down = 8; + // Downlink frame-counter. + // This is set when the payload has been sent as downlink. + uint32 f_cnt_down = 8; } -message EnqueueDeviceQueueItemRequest { - DeviceQueueItem queue_item = 1; -} +message EnqueueDeviceQueueItemRequest { DeviceQueueItem queue_item = 1; } message EnqueueDeviceQueueItemResponse { - // ID (UUID). - string id = 1; + // ID (UUID). + string id = 1; } message FlushDeviceQueueRequest { - // Device EUI (EUI64). - string dev_eui = 1; + // Device EUI (EUI64). + string dev_eui = 1; } message GetDeviceQueueItemsRequest { - // Device EUI (EUI64). - string dev_eui = 1; + // Device EUI (EUI64). + string dev_eui = 1; - // Return only the count, not the result-set. - bool count_only = 2; + // Return only the count, not the result-set. + bool count_only = 2; } message GetDeviceQueueItemsResponse { - // Total number of queue items. - uint32 total_count = 1; + // Total number of queue items. + uint32 total_count = 1; - // Result-set. - repeated DeviceQueueItem result = 2; + // Result-set. + repeated DeviceQueueItem result = 2; } message FlushDevNoncesRequest { - // Device EUI (EUI64). - string dev_eui = 1; + // Device EUI (EUI64). + string dev_eui = 1; } diff --git a/api/rust/proto/chirpstack/api/device.proto b/api/rust/proto/chirpstack/api/device.proto index efaf2ee9..f67eb016 100644 --- a/api/rust/proto/chirpstack/api/device.proto +++ b/api/rust/proto/chirpstack/api/device.proto @@ -16,520 +16,542 @@ import "google/protobuf/empty.proto"; // DeviceService is the service providing API methods for managing devices. service DeviceService { - // Create the given device. - rpc Create(CreateDeviceRequest) returns (google.protobuf.Empty) { - option(google.api.http) = { - post: "/api/devices" - body: "*" - }; - } + // Create the given device. + rpc Create(CreateDeviceRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + post : "/api/devices" + body : "*" + }; + } - // Get returns the device for the given DevEUI. - rpc Get(GetDeviceRequest) returns (GetDeviceResponse) { - option(google.api.http) = { - get: "/api/devices/{dev_eui}" - }; - } + // Get returns the device for the given DevEUI. + rpc Get(GetDeviceRequest) returns (GetDeviceResponse) { + option (google.api.http) = { + get : "/api/devices/{dev_eui}" + }; + } - // Update the given device. - rpc Update(UpdateDeviceRequest) returns (google.protobuf.Empty) { - option(google.api.http) = { - put: "/api/devices/{device.dev_eui}" - body: "*" - }; - } + // Update the given device. + rpc Update(UpdateDeviceRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + put : "/api/devices/{device.dev_eui}" + body : "*" + }; + } - // Delete the device with the given DevEUI. - rpc Delete(DeleteDeviceRequest) returns (google.protobuf.Empty) { - option(google.api.http) = { - delete: "/api/devices/{dev_eui}" - }; - } + // Delete the device with the given DevEUI. + rpc Delete(DeleteDeviceRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + delete : "/api/devices/{dev_eui}" + }; + } - // Get the list of devices. - rpc List(ListDevicesRequest) returns (ListDevicesResponse) { - option(google.api.http) = { - get: "/api/devices" - }; - } + // Get the list of devices. + rpc List(ListDevicesRequest) returns (ListDevicesResponse) { + option (google.api.http) = { + get : "/api/devices" + }; + } - // Create the given device-keys. - rpc CreateKeys(CreateDeviceKeysRequest) returns (google.protobuf.Empty) { - option(google.api.http) = { - post: "/api/devices/{device_keys.dev_eui}/keys" - body: "*" - }; - } + // Create the given device-keys. + rpc CreateKeys(CreateDeviceKeysRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + post : "/api/devices/{device_keys.dev_eui}/keys" + body : "*" + }; + } - // Get the device-keys for the given DevEUI. - rpc GetKeys(GetDeviceKeysRequest) returns (GetDeviceKeysResponse) { - option(google.api.http) = { - get: "/api/devices/{dev_eui}/keys" - }; - } + // Get the device-keys for the given DevEUI. + rpc GetKeys(GetDeviceKeysRequest) returns (GetDeviceKeysResponse) { + option (google.api.http) = { + get : "/api/devices/{dev_eui}/keys" + }; + } - // Update the given device-keys. - rpc UpdateKeys(UpdateDeviceKeysRequest) returns (google.protobuf.Empty) { - option(google.api.http) = { - put: "/api/devices/{device_keys.dev_eui}/keys" - body: "*" - }; - } + // Update the given device-keys. + rpc UpdateKeys(UpdateDeviceKeysRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + put : "/api/devices/{device_keys.dev_eui}/keys" + body : "*" + }; + } - // Delete the device-keys for the given DevEUI. - rpc DeleteKeys(DeleteDeviceKeysRequest) returns (google.protobuf.Empty) { - option(google.api.http) = { - delete: "/api/devices/{dev_eui}/keys" - }; - } + // Delete the device-keys for the given DevEUI. + rpc DeleteKeys(DeleteDeviceKeysRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + delete : "/api/devices/{dev_eui}/keys" + }; + } - // FlushDevNonces flushes the OTAA device nonces. - rpc FlushDevNonces(FlushDevNoncesRequest) returns (google.protobuf.Empty) { - option(google.api.http) = { - delete: "/api/devices/{dev_eui}/dev-nonces" - }; - } + // FlushDevNonces flushes the OTAA device nonces. + rpc FlushDevNonces(FlushDevNoncesRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + delete : "/api/devices/{dev_eui}/dev-nonces" + }; + } - // Activate (re)activates the device with the given parameters (for ABP or for importing OTAA activations). - rpc Activate(ActivateDeviceRequest) returns (google.protobuf.Empty) { - option(google.api.http) = { - post: "/api/devices/{device_activation.dev_eui}/activate" - body: "*" - }; - } + // Activate (re)activates the device with the given parameters (for ABP or for + // importing OTAA activations). + rpc Activate(ActivateDeviceRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + post : "/api/devices/{device_activation.dev_eui}/activate" + body : "*" + }; + } - // Deactivate de-activates the device. - rpc Deactivate(DeactivateDeviceRequest) returns (google.protobuf.Empty) { - option(google.api.http) = { - delete: "/api/devices/{dev_eui}/activation" - }; - } + // Deactivate de-activates the device. + rpc Deactivate(DeactivateDeviceRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + delete : "/api/devices/{dev_eui}/activation" + }; + } - // GetActivation returns the current activation details of the device (OTAA or ABP). - rpc GetActivation(GetDeviceActivationRequest) returns (GetDeviceActivationResponse) { - option(google.api.http) = { - get: "/api/devices/{dev_eui}/activation" - }; - } + // GetActivation returns the current activation details of the device (OTAA or + // ABP). + rpc GetActivation(GetDeviceActivationRequest) + returns (GetDeviceActivationResponse) { + option (google.api.http) = { + get : "/api/devices/{dev_eui}/activation" + }; + } - // GetRandomDevAddr returns a random DevAddr taking the NwkID prefix into account. - rpc GetRandomDevAddr(GetRandomDevAddrRequest) returns (GetRandomDevAddrResponse) { - option(google.api.http) = { - post: "/api/devices/{dev_eui}/get-random-dev-addr" - }; - } + // GetRandomDevAddr returns a random DevAddr taking the NwkID prefix into + // account. + rpc GetRandomDevAddr(GetRandomDevAddrRequest) + returns (GetRandomDevAddrResponse) { + option (google.api.http) = { + post : "/api/devices/{dev_eui}/get-random-dev-addr" + }; + } - // GetMetrics returns the device metrics. - // Note that this requires a device-profile with codec and measurements configured. - rpc GetMetrics(GetDeviceMetricsRequest) returns (GetDeviceMetricsResponse) { - option(google.api.http) = { - get: "/api/devices/{dev_eui}/metrics" - }; - } + // GetMetrics returns the device metrics. + // Note that this requires a device-profile with codec and measurements + // configured. + rpc GetMetrics(GetDeviceMetricsRequest) returns (GetDeviceMetricsResponse) { + option (google.api.http) = { + get : "/api/devices/{dev_eui}/metrics" + }; + } - // GetLinkMetrics returns the device link metrics. - // This includes uplinks, downlinks, RSSI, SNR, etc... - rpc GetLinkMetrics(GetDeviceLinkMetricsRequest) returns (GetDeviceLinkMetricsResponse) { - option(google.api.http) = { - get: "/api/devices/{dev_eui}/link-metrics" - }; - } + // GetLinkMetrics returns the device link metrics. + // This includes uplinks, downlinks, RSSI, SNR, etc... + rpc GetLinkMetrics(GetDeviceLinkMetricsRequest) + returns (GetDeviceLinkMetricsResponse) { + option (google.api.http) = { + get : "/api/devices/{dev_eui}/link-metrics" + }; + } - // Enqueue adds the given item to the downlink queue. - rpc Enqueue(EnqueueDeviceQueueItemRequest) returns (EnqueueDeviceQueueItemResponse) { - option(google.api.http) = { - post: "/api/devices/{queue_item.dev_eui}/queue" - body: "*" - }; - } + // Enqueue adds the given item to the downlink queue. + rpc Enqueue(EnqueueDeviceQueueItemRequest) + returns (EnqueueDeviceQueueItemResponse) { + option (google.api.http) = { + post : "/api/devices/{queue_item.dev_eui}/queue" + body : "*" + }; + } - // FlushQueue flushes the downlink device-queue. - rpc FlushQueue(FlushDeviceQueueRequest) returns (google.protobuf.Empty) { - option(google.api.http) = { - delete: "/api/devices/{dev_eui}/queue" - }; - } + // FlushQueue flushes the downlink device-queue. + rpc FlushQueue(FlushDeviceQueueRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + delete : "/api/devices/{dev_eui}/queue" + }; + } - // GetQueue returns the downlink device-queue. - rpc GetQueue(GetDeviceQueueItemsRequest) returns (GetDeviceQueueItemsResponse) { - option(google.api.http) = { - get: "/api/devices/{dev_eui}/queue" - }; - } + // GetQueue returns the downlink device-queue. + rpc GetQueue(GetDeviceQueueItemsRequest) + returns (GetDeviceQueueItemsResponse) { + option (google.api.http) = { + get : "/api/devices/{dev_eui}/queue" + }; + } +} + +enum DeviceClass { + // Class-A. + A = 0; + + // Class-B. + B = 1; + + // Class-C. + C = 2; } message Device { - // DevEUI (EUI64). - string dev_eui = 1; + // DevEUI (EUI64). + string dev_eui = 1; - // Name. - string name = 2; + // Name. + string name = 2; - // Description. - string description = 3; + // Description. + string description = 3; - // Application ID (UUID). - string application_id = 4; - - // Device-profile ID (UUID). - string device_profile_id = 5; + // Application ID (UUID). + string application_id = 4; - // Skip frame-counter checks (this is insecure, but could be helpful for debugging). - bool skip_fcnt_check = 6; + // Device-profile ID (UUID). + string device_profile_id = 5; - // Device is disabled. - bool is_disabled = 7; + // Skip frame-counter checks (this is insecure, but could be helpful for + // debugging). + bool skip_fcnt_check = 6; - // Variables (user defined). - // These variables can be used together with integrations to store tokens / - // secrets that must be configured per device. These variables are not - // exposed in the event payloads. - map variables = 8; + // Device is disabled. + bool is_disabled = 7; - // Tags (user defined). - // These tags are exposed in the event payloads or to integration. Tags are - // intended for aggregation and filtering. - map tags = 9; + // Variables (user defined). + // These variables can be used together with integrations to store tokens / + // secrets that must be configured per device. These variables are not + // exposed in the event payloads. + map variables = 8; - // JoinEUI (optional, EUI64). - // This field will be automatically set / updated on OTAA. However, in some - // cases it must be pre-configured. For example to allow OTAA using a Relay. - // In this case the Relay needs to know the JoinEUI + DevEUI combinations - // of the devices for which it needs to forward uplinks. - string join_eui = 10; + // Tags (user defined). + // These tags are exposed in the event payloads or to integration. Tags are + // intended for aggregation and filtering. + map tags = 9; + + // JoinEUI (optional, EUI64). + // This field will be automatically set / updated on OTAA. However, in some + // cases it must be pre-configured. For example to allow OTAA using a Relay. + // In this case the Relay needs to know the JoinEUI + DevEUI combinations + // of the devices for which it needs to forward uplinks. + string join_eui = 10; } message DeviceStatus { - // The device margin status - // -32..32: The demodulation SNR ration in dB - int32 margin = 1; + // The device margin status + // -32..32: The demodulation SNR ration in dB + int32 margin = 1; - // Device is connected to an external power source. - bool external_power_source = 2; + // Device is connected to an external power source. + bool external_power_source = 2; - // Device battery level as a percentage. - // -1 when the battery level is not available. - float battery_level = 3; + // Device battery level as a percentage. + // -1 when the battery level is not available. + float battery_level = 3; } message DeviceListItem { - // DevEUI (EUI64). - string dev_eui = 1; + // DevEUI (EUI64). + string dev_eui = 1; - // Created at timestamp. - google.protobuf.Timestamp created_at = 2; + // Created at timestamp. + google.protobuf.Timestamp created_at = 2; - // Last update timestamp. - google.protobuf.Timestamp updated_at = 3; + // Last update timestamp. + google.protobuf.Timestamp updated_at = 3; - // Last seen at timestamp. - google.protobuf.Timestamp last_seen_at = 4; + // Last seen at timestamp. + google.protobuf.Timestamp last_seen_at = 4; - // Name. - string name = 5; + // Name. + string name = 5; - // Description. - string description = 6; + // Description. + string description = 6; - // Device-profile ID (UUID). - string device_profile_id = 7; + // Device-profile ID (UUID). + string device_profile_id = 7; - // Device-profile name. - string device_profile_name = 8; + // Device-profile name. + string device_profile_name = 8; - // Device status. - DeviceStatus device_status = 9; + // Device status. + DeviceStatus device_status = 9; } message DeviceKeys { - // DevEUI (EUI64). - string dev_eui = 1; + // DevEUI (EUI64). + string dev_eui = 1; - // Network root key (128 bit). - // Note: For LoRaWAN 1.0.x, use this field for the LoRaWAN 1.0.x 'AppKey`! - string nwk_key = 2; + // Network root key (128 bit). + // Note: For LoRaWAN 1.0.x, use this field for the LoRaWAN 1.0.x 'AppKey`! + string nwk_key = 2; - // Application root key (128 bit). - // Note: This field only needs to be set for LoRaWAN 1.1.x devices! - string app_key = 3; + // Application root key (128 bit). + // Note: This field only needs to be set for LoRaWAN 1.1.x devices! + string app_key = 3; } message CreateDeviceRequest { - // Device object. - Device device = 1; + // Device object. + Device device = 1; } message GetDeviceRequest { - // DevEUI (EUI64). - string dev_eui = 1; + // DevEUI (EUI64). + string dev_eui = 1; } message GetDeviceResponse { - // Device object. - Device device = 1; + // Device object. + Device device = 1; - // Created at timestamp. - google.protobuf.Timestamp created_at = 2; + // Created at timestamp. + google.protobuf.Timestamp created_at = 2; - // Last update timestamp. - google.protobuf.Timestamp updated_at = 3; + // Last update timestamp. + google.protobuf.Timestamp updated_at = 3; - // Last seen at timestamp. - google.protobuf.Timestamp last_seen_at = 4; + // Last seen at timestamp. + google.protobuf.Timestamp last_seen_at = 4; - // Device status. - DeviceStatus device_status = 5; + // Device status. + DeviceStatus device_status = 5; + + // Enabled class. + DeviceClass enabled_class = 6; } message UpdateDeviceRequest { - // Device object. - Device device = 1; + // Device object. + Device device = 1; } message DeleteDeviceRequest { - // DevEUI (EUI64). - string dev_eui = 1; + // DevEUI (EUI64). + string dev_eui = 1; } message ListDevicesRequest { - // Max number of devices to return in the result-set. - uint32 limit = 1; + // Max number of devices to return in the result-set. + uint32 limit = 1; - // Offset in the result-set (for pagination). - uint32 offset = 2; + // Offset in the result-set (for pagination). + uint32 offset = 2; - // If set, the given string will be used to search on name (optional). - string search = 3; + // If set, the given string will be used to search on name (optional). + string search = 3; - // Application ID (UUID) to filter devices on. - string application_id = 4; + // Application ID (UUID) to filter devices on. + string application_id = 4; - // Multicst-group ID (UUID) to filter devices on. - string multicast_group_id = 5; + // Multicst-group ID (UUID) to filter devices on. + string multicast_group_id = 5; } message ListDevicesResponse { - // Total number of devices. - uint32 total_count = 1; + // Total number of devices. + uint32 total_count = 1; - // Result-set. - repeated DeviceListItem result = 2; + // Result-set. + repeated DeviceListItem result = 2; } message CreateDeviceKeysRequest { - // Device-keys object. - DeviceKeys device_keys = 1; + // Device-keys object. + DeviceKeys device_keys = 1; } message GetDeviceKeysRequest { - // DevEUI (EUI64). - string dev_eui = 1; + // DevEUI (EUI64). + string dev_eui = 1; } message GetDeviceKeysResponse { - // Device-keys object. - DeviceKeys device_keys = 1; + // Device-keys object. + DeviceKeys device_keys = 1; - // Created at timestamp. - google.protobuf.Timestamp created_at = 2; + // Created at timestamp. + google.protobuf.Timestamp created_at = 2; - // Last update timestamp. - google.protobuf.Timestamp updated_at = 3; + // Last update timestamp. + google.protobuf.Timestamp updated_at = 3; } message UpdateDeviceKeysRequest { - // Device-keys object. - DeviceKeys device_keys = 1; + // Device-keys object. + DeviceKeys device_keys = 1; } message DeleteDeviceKeysRequest { - // DevEUI (EUI64). - string dev_eui = 1; + // DevEUI (EUI64). + string dev_eui = 1; } message DeviceActivation { - // Device EUI (EUI64). - string dev_eui = 1; + // Device EUI (EUI64). + string dev_eui = 1; - // Device address (HEX encoded). - string dev_addr = 2; + // Device address (HEX encoded). + string dev_addr = 2; - // Application session key (HEX encoded). - string app_s_key = 3; + // Application session key (HEX encoded). + string app_s_key = 3; - // Network session encryption key (HEX encoded). - string nwk_s_enc_key = 4; + // Network session encryption key (HEX encoded). + string nwk_s_enc_key = 4; - // Serving network session integrity key (HEX encoded). - string s_nwk_s_int_key = 8; + // Serving network session integrity key (HEX encoded). + string s_nwk_s_int_key = 8; - // Forwarding network session integrity key (HEX encoded). - string f_nwk_s_int_key = 9; + // Forwarding network session integrity key (HEX encoded). + string f_nwk_s_int_key = 9; - // Uplink frame-counter. - uint32 f_cnt_up = 5; + // Uplink frame-counter. + uint32 f_cnt_up = 5; - // Downlink network frame-counter. - uint32 n_f_cnt_down = 6; + // Downlink network frame-counter. + uint32 n_f_cnt_down = 6; - // Downlink application frame-counter. - uint32 a_f_cnt_down = 10; + // Downlink application frame-counter. + uint32 a_f_cnt_down = 10; } message ActivateDeviceRequest { - // Device activation object. - DeviceActivation device_activation = 1; + // Device activation object. + DeviceActivation device_activation = 1; } message DeactivateDeviceRequest { - // DevEUI (EUI64). - string dev_eui = 1; + // DevEUI (EUI64). + string dev_eui = 1; } message GetDeviceActivationRequest { - // DevEUI (EUI64). - string dev_eui = 1; + // DevEUI (EUI64). + string dev_eui = 1; } message GetDeviceActivationResponse { - // Device activation object. - DeviceActivation device_activation = 1; + // Device activation object. + DeviceActivation device_activation = 1; } message GetRandomDevAddrRequest { - // DevEUI (EUI64). - string dev_eui = 1; + // DevEUI (EUI64). + string dev_eui = 1; } message GetRandomDevAddrResponse { - // DevAddr. - string dev_addr = 1; + // DevAddr. + string dev_addr = 1; } message GetDeviceMetricsRequest { - // DevEUI (EUI64). - string dev_eui = 1; + // DevEUI (EUI64). + string dev_eui = 1; - // Interval start timestamp. - google.protobuf.Timestamp start = 2; + // Interval start timestamp. + google.protobuf.Timestamp start = 2; - // Interval end timestamp. - google.protobuf.Timestamp end = 3; + // Interval end timestamp. + google.protobuf.Timestamp end = 3; - // Aggregation. - common.Aggregation aggregation = 4; + // Aggregation. + common.Aggregation aggregation = 4; } message GetDeviceMetricsResponse { - map metrics = 1; + map metrics = 1; - map states = 2; + map states = 2; } message DeviceState { - // Name. - string name = 2; + // Name. + string name = 2; - // Value. - string value = 3; + // Value. + string value = 3; } message GetDeviceLinkMetricsRequest { - // DevEUI (EUI64). - string dev_eui = 1; + // DevEUI (EUI64). + string dev_eui = 1; - // Interval start timestamp. - google.protobuf.Timestamp start = 2; + // Interval start timestamp. + google.protobuf.Timestamp start = 2; - // Interval end timestamp. - google.protobuf.Timestamp end = 3; + // Interval end timestamp. + google.protobuf.Timestamp end = 3; - // Aggregation. - common.Aggregation aggregation = 4; + // Aggregation. + common.Aggregation aggregation = 4; } message GetDeviceLinkMetricsResponse { - // Packets received from the device. - common.Metric rx_packets = 1; + // Packets received from the device. + common.Metric rx_packets = 1; - // RSSI (as reported by the gateway(s)). - common.Metric gw_rssi = 2; + // RSSI (as reported by the gateway(s)). + common.Metric gw_rssi = 2; - // SNR (as reported by the gateway(s)). - common.Metric gw_snr = 3; + // SNR (as reported by the gateway(s)). + common.Metric gw_snr = 3; - // Packets received by frequency. - common.Metric rx_packets_per_freq = 4; + // Packets received by frequency. + common.Metric rx_packets_per_freq = 4; - // Packets received by DR. - common.Metric rx_packets_per_dr = 5; + // Packets received by DR. + common.Metric rx_packets_per_dr = 5; - // Errors. - common.Metric errors = 6; + // Errors. + common.Metric errors = 6; } message DeviceQueueItem { - // ID (UUID). - // This is automatically generated on enqueue. - string id = 1; + // ID (UUID). + // This is automatically generated on enqueue. + string id = 1; - // Device EUI (EUI64). - string dev_eui = 2; + // Device EUI (EUI64). + string dev_eui = 2; - // Confirmed. - bool confirmed = 3; + // Confirmed. + bool confirmed = 3; - // FPort (must be > 0). - uint32 f_port = 4; + // FPort (must be > 0). + uint32 f_port = 4; - // Data. - // Or use the json_object field when a codec has been configured. - bytes data = 5; + // Data. + // Or use the json_object field when a codec has been configured. + bytes data = 5; - // Only use this when a codec has been configured that can encode this - // object to bytes. - google.protobuf.Struct object = 6; + // Only use this when a codec has been configured that can encode this + // object to bytes. + google.protobuf.Struct object = 6; - // Is pending. - // This is set to true when the downlink is pending. - bool is_pending = 7; + // Is pending. + // This is set to true when the downlink is pending. + bool is_pending = 7; - // Downlink frame-counter. - // This is set when the payload has been sent as downlink. - uint32 f_cnt_down = 8; + // Downlink frame-counter. + // This is set when the payload has been sent as downlink. + uint32 f_cnt_down = 8; } -message EnqueueDeviceQueueItemRequest { - DeviceQueueItem queue_item = 1; -} +message EnqueueDeviceQueueItemRequest { DeviceQueueItem queue_item = 1; } message EnqueueDeviceQueueItemResponse { - // ID (UUID). - string id = 1; + // ID (UUID). + string id = 1; } message FlushDeviceQueueRequest { - // Device EUI (EUI64). - string dev_eui = 1; + // Device EUI (EUI64). + string dev_eui = 1; } message GetDeviceQueueItemsRequest { - // Device EUI (EUI64). - string dev_eui = 1; + // Device EUI (EUI64). + string dev_eui = 1; - // Return only the count, not the result-set. - bool count_only = 2; + // Return only the count, not the result-set. + bool count_only = 2; } message GetDeviceQueueItemsResponse { - // Total number of queue items. - uint32 total_count = 1; + // Total number of queue items. + uint32 total_count = 1; - // Result-set. - repeated DeviceQueueItem result = 2; + // Result-set. + repeated DeviceQueueItem result = 2; } message FlushDevNoncesRequest { - // Device EUI (EUI64). - string dev_eui = 1; + // Device EUI (EUI64). + string dev_eui = 1; } diff --git a/chirpstack/src/api/device.rs b/chirpstack/src/api/device.rs index 5fa9a5de..1eb8f996 100644 --- a/chirpstack/src/api/device.rs +++ b/chirpstack/src/api/device.rs @@ -132,6 +132,7 @@ impl DeviceService for Device { }), false => None, }, + enabled_class: d.enabled_class.to_proto().into(), }); resp.metadata_mut() .insert("x-log-dev_eui", req.dev_eui.parse().unwrap()); diff --git a/chirpstack/src/api/helpers.rs b/chirpstack/src/api/helpers.rs index 2a1903d3..7f2d93b8 100644 --- a/chirpstack/src/api/helpers.rs +++ b/chirpstack/src/api/helpers.rs @@ -2,7 +2,7 @@ use chrono::{DateTime, Utc}; use crate::codec::Codec; use crate::storage::fields::{MeasurementKind, MulticastGroupSchedulingType}; -use crate::storage::metrics::Aggregation; +use crate::storage::{device::DeviceClass, metrics::Aggregation}; use chirpstack_api::{api, common}; use lrwn::region::{CommonName, MacVersion, Revision}; @@ -249,6 +249,16 @@ impl FromProto for api::RelayModeActivation { } } +impl ToProto for DeviceClass { + fn to_proto(self) -> api::DeviceClass { + match self { + DeviceClass::A => api::DeviceClass::A, + DeviceClass::B => api::DeviceClass::B, + DeviceClass::C => api::DeviceClass::C, + } + } +} + pub fn datetime_to_prost_timestamp(dt: &DateTime) -> prost_types::Timestamp { let ts = dt.timestamp_nanos(); diff --git a/chirpstack/src/downlink/data.rs b/chirpstack/src/downlink/data.rs index d726139a..3cb867f0 100644 --- a/chirpstack/src/downlink/data.rs +++ b/chirpstack/src/downlink/data.rs @@ -14,8 +14,10 @@ use crate::downlink::{classb, helpers, tx_ack}; use crate::gpstime::{ToDateTime, ToGpsTime}; use crate::storage; use crate::storage::{ - application, device, device_gateway, device_profile, device_queue, device_session, - downlink_frame, mac_command, relay, tenant, + application, + device::{self, DeviceClass}, + device_gateway, device_profile, device_queue, device_session, downlink_frame, mac_command, + relay, tenant, }; use crate::uplink::{RelayContext, UplinkFrameSet}; use crate::{adr, config, gateway, integration, maccommand, region, sensitivity}; @@ -548,15 +550,15 @@ impl Data { } fn _is_class_a(&self) -> bool { - &self.device.enabled_class == "A" + self.device.enabled_class == DeviceClass::A } fn _is_class_b(&self) -> bool { - &self.device.enabled_class == "B" + self.device.enabled_class == DeviceClass::B } fn _is_class_c(&self) -> bool { - &self.device.enabled_class == "C" + self.device.enabled_class == DeviceClass::C } fn _is_roaming(&self) -> bool { diff --git a/chirpstack/src/downlink/tx_ack.rs b/chirpstack/src/downlink/tx_ack.rs index 95d3d6ba..61b1146b 100644 --- a/chirpstack/src/downlink/tx_ack.rs +++ b/chirpstack/src/downlink/tx_ack.rs @@ -8,8 +8,9 @@ use lrwn::{AES128Key, MType, Payload, PhyPayload, EUI64}; use crate::api::helpers::ToProto; use crate::storage::{ - application, device, device_profile, device_queue, device_session, downlink_frame, multicast, - tenant, + application, + device::{self, DeviceClass}, + device_profile, device_queue, device_session, downlink_frame, multicast, tenant, }; use crate::{framelog, integration, metalog}; use chirpstack_api::{api, common, gw, integration as integration_pb, internal, meta}; @@ -340,7 +341,7 @@ impl TxAck { qi.is_pending = true; - if &dev.enabled_class == "C" { + if dev.enabled_class == DeviceClass::C { let timeout = Utc::now() + Duration::seconds(dp.class_c_timeout as i64); qi.timeout_after = Some(timeout); } diff --git a/chirpstack/src/maccommand/device_mode_ind.rs b/chirpstack/src/maccommand/device_mode_ind.rs index 9fa57d81..9e0d6eb3 100644 --- a/chirpstack/src/maccommand/device_mode_ind.rs +++ b/chirpstack/src/maccommand/device_mode_ind.rs @@ -1,6 +1,6 @@ use anyhow::Result; -use crate::storage::device; +use crate::storage::device::{self, DeviceClass}; pub async fn handle( dev: &device::Device, @@ -10,7 +10,14 @@ pub async fn handle( .first() .ok_or_else(|| anyhow!("Expected DeviceModeInd"))?; if let lrwn::MACCommand::DeviceModeInd(pl) = mac { - device::set_enabled_class(&dev.dev_eui, &pl.class.to_string()).await?; + device::set_enabled_class( + &dev.dev_eui, + match pl.class { + lrwn::DeviceModeClass::ClassA => DeviceClass::A, + lrwn::DeviceModeClass::ClassC => DeviceClass::C, + }, + ) + .await?; return Ok(Some(lrwn::MACCommandSet::new(vec![ lrwn::MACCommand::DeviceModeConf(lrwn::DeviceModeConfPayload { class: pl.class }), @@ -81,6 +88,6 @@ pub mod test { ); let d = device::get(&dev.dev_eui).await.unwrap(); - assert_eq!("C".to_string(), d.enabled_class); + assert_eq!(DeviceClass::C, d.enabled_class); } } diff --git a/chirpstack/src/storage/device.rs b/chirpstack/src/storage/device.rs index 801486b9..072bd4e9 100644 --- a/chirpstack/src/storage/device.rs +++ b/chirpstack/src/storage/device.rs @@ -1,10 +1,11 @@ use std::collections::HashMap; +use std::fmt; +use std::str::FromStr; use anyhow::{Context, Result}; use bigdecimal::BigDecimal; use chrono::{DateTime, Duration, Utc}; -use diesel::dsl; -use diesel::prelude::*; +use diesel::{backend::Backend, deserialize, dsl, prelude::*, serialize, sql_types::Text}; use tokio::task; use tracing::info; use uuid::Uuid; @@ -15,6 +16,59 @@ use super::schema::{application, device, device_profile, multicast_group_device, use super::{error::Error, fields, get_db_conn, get_redis_conn, redis_key}; use crate::config; +#[derive(Debug, Clone, Copy, Eq, PartialEq, AsExpression, FromSqlRow)] +#[diesel(sql_type = Text)] +pub enum DeviceClass { + A, + B, + C, +} + +impl fmt::Display for DeviceClass { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?}", self) + } +} + +impl FromStr for DeviceClass { + type Err = anyhow::Error; + + fn from_str(s: &str) -> std::result::Result { + Ok(match s { + "A" => DeviceClass::A, + "B" => DeviceClass::B, + "C" => DeviceClass::C, + _ => return Err(anyhow!("Unexpected DeviceClass: {}", s)), + }) + } +} + +impl deserialize::FromSql for DeviceClass +where + DB: Backend, + *const str: deserialize::FromSql, +{ + fn from_sql(value: ::RawValue<'_>) -> deserialize::Result { + let string = String::from_sql(value)?; + Ok(DeviceClass::from_str(&string)?) + } +} + +impl serialize::ToSql for DeviceClass +where + str: serialize::ToSql, +{ + fn to_sql<'b>( + &'b self, + out: &mut serialize::Output<'b, '_, diesel::pg::Pg>, + ) -> serialize::Result { + >::to_sql( + &self.to_string(), + &mut out.reborrow(), + ) + } +} + #[derive(Queryable, QueryableByName, Insertable, PartialEq, Debug, Clone)] #[diesel(table_name = device)] pub struct Device { @@ -35,7 +89,7 @@ pub struct Device { pub longitude: Option, pub altitude: Option, pub dev_addr: Option, - pub enabled_class: String, + pub enabled_class: DeviceClass, pub skip_fcnt_check: bool, pub is_disabled: bool, pub tags: fields::KeyValue, @@ -74,7 +128,7 @@ impl Default for Device { longitude: None, altitude: None, dev_addr: None, - enabled_class: "A".into(), + enabled_class: DeviceClass::A, skip_fcnt_check: false, is_disabled: false, tags: fields::KeyValue::new(HashMap::new()), @@ -212,10 +266,10 @@ pub async fn update(d: Device) -> Result { Ok(d) } -pub async fn set_enabled_class(dev_eui: &EUI64, mode: &str) -> Result { +pub async fn set_enabled_class(dev_eui: &EUI64, mode: DeviceClass) -> Result { let d = task::spawn_blocking({ let dev_eui = *dev_eui; - let mode = mode.to_string(); + move || -> Result { let mut c = get_db_conn()?; diesel::update(device::dsl::device.find(&dev_eui)) @@ -746,13 +800,13 @@ pub mod test { assert_eq!(0, res.len()); // device in Class-B. - let d = set_enabled_class(&d.dev_eui, "B").await.unwrap(); + let d = set_enabled_class(&d.dev_eui, DeviceClass::B).await.unwrap(); let res = get_with_class_b_c_queue_items(10).await.unwrap(); let d = set_scheduler_run_after(&d.dev_eui, None).await.unwrap(); assert_eq!(1, res.len()); // device in Class-C - let d = set_enabled_class(&d.dev_eui, "C").await.unwrap(); + let d = set_enabled_class(&d.dev_eui, DeviceClass::C).await.unwrap(); let res = get_with_class_b_c_queue_items(10).await.unwrap(); assert_eq!(1, res.len()); diff --git a/chirpstack/src/test/assert.rs b/chirpstack/src/test/assert.rs index 14da23d3..43feaadf 100644 --- a/chirpstack/src/test/assert.rs +++ b/chirpstack/src/test/assert.rs @@ -11,7 +11,8 @@ use tokio::time::sleep; use crate::gateway::backend::mock as gateway_mock; use crate::integration::mock; use crate::storage::{ - device, device_queue, device_session, downlink_frame, get_redis_conn, redis_key, + device::{self, DeviceClass}, + device_queue, device_session, downlink_frame, get_redis_conn, redis_key, }; use chirpstack_api::{api, gw, integration as integration_pb, internal, meta}; use lrwn::EUI64; @@ -362,7 +363,7 @@ pub fn device_queue_items(dev_eui: EUI64, items: Vec Validator { +pub fn enabled_class(dev_eui: EUI64, c: DeviceClass) -> Validator { Box::new(move || { let c = c.clone(); let dev_eui = dev_eui.clone(); diff --git a/chirpstack/src/test/class_a_pr_test.rs b/chirpstack/src/test/class_a_pr_test.rs index ecd81c8f..9116da79 100644 --- a/chirpstack/src/test/class_a_pr_test.rs +++ b/chirpstack/src/test/class_a_pr_test.rs @@ -10,7 +10,9 @@ use crate::api::backend as backend_api; use crate::backend::{joinserver, roaming}; use crate::gateway::backend as gateway_backend; use crate::storage::{ - application, device, device_profile, device_queue, device_session, gateway, tenant, + application, + device::{self, DeviceClass}, + device_profile, device_queue, device_session, gateway, tenant, }; use crate::{config, test, uplink}; use chirpstack_api::{common, gw, internal}; @@ -222,7 +224,7 @@ async fn test_sns_uplink() { application_id: app.id.clone(), device_profile_id: dp.id.clone(), dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]), - enabled_class: "B".into(), + enabled_class: DeviceClass::B, ..Default::default() }) .await diff --git a/chirpstack/src/test/class_a_test.rs b/chirpstack/src/test/class_a_test.rs index 9b33bf43..2145c326 100644 --- a/chirpstack/src/test/class_a_test.rs +++ b/chirpstack/src/test/class_a_test.rs @@ -6,8 +6,9 @@ use uuid::Uuid; use super::assert; use crate::storage::{ - application, device, device_profile, device_queue, device_session, gateway, mac_command, - reset_redis, tenant, + application, + device::{self, DeviceClass}, + device_profile, device_queue, device_session, gateway, mac_command, reset_redis, tenant, }; use crate::{config, gateway::backend as gateway_backend, integration, region, test, uplink}; use chirpstack_api::{api, common, gw, integration as integration_pb, internal}; @@ -91,7 +92,7 @@ async fn test_gateway_filtering() { application_id: app.id.clone(), device_profile_id: dp.id.clone(), dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]), - enabled_class: "B".into(), + enabled_class: DeviceClass::B, ..Default::default() }) .await @@ -255,7 +256,7 @@ async fn test_region_config_id_filtering() { application_id: app.id.clone(), device_profile_id: dp.id.clone(), dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]), - enabled_class: "A".into(), + enabled_class: DeviceClass::A, ..Default::default() }) .await @@ -414,7 +415,7 @@ async fn test_lorawan_10_errors() { application_id: app.id.clone(), device_profile_id: dp.id.clone(), dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]), - enabled_class: "A".into(), + enabled_class: DeviceClass::A, ..Default::default() }) .await @@ -609,7 +610,7 @@ async fn test_lorawan_11_errors() { application_id: app.id.clone(), device_profile_id: dp.id.clone(), dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]), - enabled_class: "A".into(), + enabled_class: DeviceClass::A, ..Default::default() }) .await @@ -762,7 +763,7 @@ async fn test_lorawan_10_skip_f_cnt() { application_id: app.id.clone(), device_profile_id: dp.id.clone(), dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]), - enabled_class: "A".into(), + enabled_class: DeviceClass::A, skip_fcnt_check: true, ..Default::default() }) @@ -955,7 +956,7 @@ async fn test_lorawan_10_device_disabled() { application_id: app.id.clone(), device_profile_id: dp.id.clone(), dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]), - enabled_class: "A".into(), + enabled_class: DeviceClass::A, is_disabled: true, ..Default::default() }) @@ -1079,7 +1080,7 @@ async fn test_lorawan_10_uplink() { application_id: app.id.clone(), device_profile_id: dp.id.clone(), dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]), - enabled_class: "A".into(), + enabled_class: DeviceClass::A, ..Default::default() }) .await @@ -1698,7 +1699,7 @@ async fn test_lorawan_11_uplink() { application_id: app.id.clone(), device_profile_id: dp.id.clone(), dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]), - enabled_class: "A".into(), + enabled_class: DeviceClass::A, ..Default::default() }) .await @@ -1936,7 +1937,7 @@ async fn test_lorawan_10_rx_delay() { application_id: app.id.clone(), device_profile_id: dp.id.clone(), dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]), - enabled_class: "A".into(), + enabled_class: DeviceClass::A, ..Default::default() }) .await @@ -2149,7 +2150,7 @@ async fn test_lorawan_10_mac_commands() { application_id: app.id.clone(), device_profile_id: dp.id.clone(), dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]), - enabled_class: "A".into(), + enabled_class: DeviceClass::A, ..Default::default() }) .await @@ -2518,7 +2519,7 @@ async fn test_lorawan_11_mac_commands() { application_id: app.id.clone(), device_profile_id: dp.id.clone(), dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]), - enabled_class: "A".into(), + enabled_class: DeviceClass::A, ..Default::default() }) .await @@ -2712,7 +2713,7 @@ async fn test_lorawan_10_device_queue() { application_id: app.id.clone(), device_profile_id: dp.id.clone(), dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]), - enabled_class: "A".into(), + enabled_class: DeviceClass::A, ..Default::default() }) .await @@ -3185,7 +3186,7 @@ async fn test_lorawan_11_device_queue() { application_id: app.id.clone(), device_profile_id: dp.id.clone(), dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]), - enabled_class: "A".into(), + enabled_class: DeviceClass::A, ..Default::default() }) .await @@ -3662,7 +3663,7 @@ async fn test_lorawan_10_adr() { application_id: app.id.clone(), device_profile_id: dp.id.clone(), dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]), - enabled_class: "A".into(), + enabled_class: DeviceClass::A, ..Default::default() }) .await @@ -4505,7 +4506,7 @@ async fn test_lorawan_10_device_status_request() { application_id: app.id.clone(), device_profile_id: dp.id.clone(), dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]), - enabled_class: "A".into(), + enabled_class: DeviceClass::A, ..Default::default() }) .await @@ -4768,7 +4769,7 @@ async fn test_lorawan_11_receive_window_selection() { application_id: app.id.clone(), device_profile_id: dp.id.clone(), dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]), - enabled_class: "A".into(), + enabled_class: DeviceClass::A, ..Default::default() }) .await diff --git a/chirpstack/src/test/class_b_test.rs b/chirpstack/src/test/class_b_test.rs index 78f7f328..17b66b4a 100644 --- a/chirpstack/src/test/class_b_test.rs +++ b/chirpstack/src/test/class_b_test.rs @@ -3,8 +3,9 @@ use uuid::Uuid; use super::assert; use crate::gpstime::ToGpsTime; use crate::storage::{ - application, device, device_gateway, device_profile, device_queue, device_session, gateway, - reset_redis, tenant, + application, + device::{self, DeviceClass}, + device_gateway, device_profile, device_queue, device_session, gateway, reset_redis, tenant, }; use crate::{ config, downlink, downlink::classb, gateway::backend as gateway_backend, integration, test, @@ -78,7 +79,7 @@ async fn test_uplink() { application_id: app.id.clone(), device_profile_id: dp.id.clone(), dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]), - enabled_class: "A".into(), + enabled_class: DeviceClass::A, ..Default::default() }) .await @@ -155,7 +156,7 @@ async fn test_uplink() { }, assert: vec![ assert::f_cnt_up(dev.dev_eui.clone(), 9), - assert::enabled_class(dev.dev_eui.clone(), "B".into()), + assert::enabled_class(dev.dev_eui.clone(), DeviceClass::B), ], }) .await; @@ -189,7 +190,7 @@ async fn test_uplink() { }, assert: vec![ assert::f_cnt_up(dev.dev_eui.clone(), 9), - assert::enabled_class(dev.dev_eui.clone(), "A".into()), + assert::enabled_class(dev.dev_eui.clone(), DeviceClass::A), ], }) .await; @@ -242,7 +243,7 @@ async fn test_downlink_scheduler() { application_id: app.id.clone(), device_profile_id: dp.id.clone(), dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]), - enabled_class: "B".into(), + enabled_class: DeviceClass::B, ..Default::default() }) .await diff --git a/chirpstack/src/test/class_c_test.rs b/chirpstack/src/test/class_c_test.rs index 9f7357e7..9a530d72 100644 --- a/chirpstack/src/test/class_c_test.rs +++ b/chirpstack/src/test/class_c_test.rs @@ -2,8 +2,9 @@ use uuid::Uuid; use super::assert; use crate::storage::{ - application, device, device_gateway, device_profile, device_queue, device_session, gateway, - reset_redis, tenant, + application, + device::{self, DeviceClass}, + device_gateway, device_profile, device_queue, device_session, gateway, reset_redis, tenant, }; use crate::{downlink, gateway::backend as gateway_backend, integration, test}; use chirpstack_api::{common, gw, internal}; @@ -69,7 +70,7 @@ async fn test_downlink_scheduler() { application_id: app.id.clone(), device_profile_id: dp.id.clone(), dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]), - enabled_class: "C".into(), + enabled_class: DeviceClass::C, ..Default::default() }) .await diff --git a/chirpstack/src/test/otaa_pr_test.rs b/chirpstack/src/test/otaa_pr_test.rs index c999a000..ce7c7924 100644 --- a/chirpstack/src/test/otaa_pr_test.rs +++ b/chirpstack/src/test/otaa_pr_test.rs @@ -10,7 +10,11 @@ use super::assert; use crate::api::backend as backend_api; use crate::backend::{joinserver, roaming}; use crate::gateway::backend as gateway_backend; -use crate::storage::{application, device, device_keys, device_profile, gateway, tenant}; +use crate::storage::{ + application, + device::{self, DeviceClass}, + device_keys, device_profile, gateway, tenant, +}; use crate::{config, test, uplink}; use chirpstack_api::gw; use lrwn::{AES128Key, NetID, EUI64}; @@ -298,7 +302,7 @@ async fn test_sns() { application_id: app.id.clone(), device_profile_id: dp.id.clone(), dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]), - enabled_class: "B".into(), + enabled_class: DeviceClass::B, ..Default::default() }) .await diff --git a/chirpstack/src/test/otaa_test.rs b/chirpstack/src/test/otaa_test.rs index 59b1e27f..32ea5b87 100644 --- a/chirpstack/src/test/otaa_test.rs +++ b/chirpstack/src/test/otaa_test.rs @@ -6,7 +6,9 @@ use uuid::Uuid; use super::assert; use crate::storage::{ - application, device, device_keys, device_profile, gateway, reset_redis, tenant, + application, + device::{self, DeviceClass}, + device_keys, device_profile, gateway, reset_redis, tenant, }; use crate::{config, gateway::backend as gateway_backend, integration, region, test, uplink}; use chirpstack_api::{common, gw, internal, meta}; @@ -89,7 +91,7 @@ async fn test_gateway_filtering() { application_id: app.id.clone(), device_profile_id: dp.id.clone(), dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]), - enabled_class: "B".into(), + enabled_class: DeviceClass::B, ..Default::default() }) .await @@ -261,7 +263,7 @@ async fn test_lorawan_10() { application_id: app.id.clone(), device_profile_id: dp.id.clone(), dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]), - enabled_class: "B".into(), + enabled_class: DeviceClass::B, ..Default::default() }) .await @@ -560,7 +562,7 @@ async fn test_lorawan_10() { }), ..Default::default() }), - assert::enabled_class(dev.dev_eui.clone(), "A".into()), + assert::enabled_class(dev.dev_eui.clone(), DeviceClass::A), assert::device_queue_items(dev.dev_eui.clone(), vec![]), assert::uplink_meta_log(meta::UplinkMeta { dev_eui: dev.dev_eui.to_string(), @@ -807,7 +809,7 @@ async fn test_lorawan_10() { tx_info: tx_info.clone(), phy_payload: jr_pl.clone(), extra_uplink_channels: Vec::new(), - assert: vec![assert::enabled_class(dev.dev_eui.clone(), "A".to_string())], + assert: vec![assert::enabled_class(dev.dev_eui.clone(), DeviceClass::A)], }, Test { name: "join-request accepted + class-c supported".into(), @@ -834,7 +836,7 @@ async fn test_lorawan_10() { tx_info: tx_info.clone(), phy_payload: jr_pl.clone(), extra_uplink_channels: Vec::new(), - assert: vec![assert::enabled_class(dev.dev_eui.clone(), "C".to_string())], + assert: vec![assert::enabled_class(dev.dev_eui.clone(), DeviceClass::C)], }, Test { name: "device disabled".into(), @@ -915,7 +917,7 @@ async fn test_lorawan_11() { application_id: app.id.clone(), device_profile_id: dp.id.clone(), dev_eui: EUI64::from_be_bytes([2, 2, 3, 4, 5, 6, 7, 8]), - enabled_class: "B".into(), + enabled_class: DeviceClass::B, ..Default::default() }) .await @@ -1181,7 +1183,7 @@ async fn test_lorawan_11() { }), ..Default::default() }), - assert::enabled_class(dev.dev_eui.clone(), "A".into()), + assert::enabled_class(dev.dev_eui.clone(), DeviceClass::A), assert::device_queue_items(dev.dev_eui.clone(), vec![]), ], }, @@ -1210,7 +1212,7 @@ async fn test_lorawan_11() { tx_info: tx_info.clone(), phy_payload: jr_pl.clone(), extra_uplink_channels: Vec::new(), - assert: vec![assert::enabled_class(dev.dev_eui.clone(), "A".to_string())], + assert: vec![assert::enabled_class(dev.dev_eui.clone(), DeviceClass::A)], }, ]; diff --git a/chirpstack/src/test/relay_class_a_test.rs b/chirpstack/src/test/relay_class_a_test.rs index 560e50bf..ffeec542 100644 --- a/chirpstack/src/test/relay_class_a_test.rs +++ b/chirpstack/src/test/relay_class_a_test.rs @@ -4,7 +4,9 @@ use uuid::Uuid; use super::assert; use crate::storage::{ - application, device, device_profile, device_queue, device_session, gateway, reset_redis, tenant, + application, + device::{self, DeviceClass}, + device_profile, device_queue, device_session, gateway, reset_redis, tenant, }; use crate::{gateway::backend as gateway_backend, integration, test, uplink}; use chirpstack_api::{common, gw, integration as integration_pb, internal}; @@ -82,7 +84,7 @@ async fn test_lorawan_10() { application_id: app.id, device_profile_id: dp_relay.id, dev_eui: EUI64::from_be_bytes([1, 1, 1, 1, 1, 1, 1, 1]), - enabled_class: "A".into(), + enabled_class: DeviceClass::A, ..Default::default() }) .await @@ -93,7 +95,7 @@ async fn test_lorawan_10() { application_id: app.id, device_profile_id: dp_relay_ed.id, dev_eui: EUI64::from_be_bytes([2, 2, 2, 2, 2, 2, 2, 2]), - enabled_class: "A".into(), + enabled_class: DeviceClass::A, ..Default::default() }) .await diff --git a/chirpstack/src/test/relay_otaa_test.rs b/chirpstack/src/test/relay_otaa_test.rs index 05475e9c..4e93b2ea 100644 --- a/chirpstack/src/test/relay_otaa_test.rs +++ b/chirpstack/src/test/relay_otaa_test.rs @@ -4,7 +4,9 @@ use uuid::Uuid; use super::assert; use crate::storage::{ - application, device, device_keys, device_profile, device_session, gateway, tenant, + application, + device::{self, DeviceClass}, + device_keys, device_profile, device_session, gateway, tenant, }; use crate::{gateway::backend as gateway_backend, integration, test, uplink}; use chirpstack_api::{common, gw, internal}; @@ -82,7 +84,7 @@ async fn test_lorawan_10() { application_id: app.id.clone(), device_profile_id: dp.id.clone(), dev_eui: EUI64::from_be_bytes([1, 1, 1, 1, 1, 1, 1, 1]), - enabled_class: "A".into(), + enabled_class: DeviceClass::A, ..Default::default() }) .await @@ -101,7 +103,7 @@ async fn test_lorawan_10() { application_id: app.id.clone(), device_profile_id: dp_relay.id.clone(), dev_eui: EUI64::from_be_bytes([1, 1, 1, 1, 1, 1, 1, 2]), - enabled_class: "A".into(), + enabled_class: DeviceClass::A, ..Default::default() }) .await diff --git a/chirpstack/src/uplink/data.rs b/chirpstack/src/uplink/data.rs index 8cff45b7..d9fb27ff 100644 --- a/chirpstack/src/uplink/data.rs +++ b/chirpstack/src/uplink/data.rs @@ -14,8 +14,9 @@ use crate::api::helpers::ToProto; use crate::backend::roaming; use crate::storage::error::Error as StorageError; use crate::storage::{ - application, device, device_gateway, device_profile, device_queue, device_session, fields, - metrics, tenant, + application, + device::{self, DeviceClass}, + device_gateway, device_profile, device_queue, device_session, fields, metrics, tenant, }; use crate::{codec, config, downlink, framelog, integration, maccommand, metalog, region}; use chirpstack_api::{api, integration as integration_pb, internal, meta}; @@ -555,7 +556,7 @@ impl Data { let dev = self.device.as_mut().unwrap(); let conf = config::get(); - if &dev.enabled_class == "B" || &dev.enabled_class == "C" { + if dev.enabled_class == DeviceClass::B || dev.enabled_class == DeviceClass::C { trace!("Setting scheduler_run_after for device"); let scheduler_run_after = Utc::now() + Duration::from_std(conf.network.scheduler.class_a_lock_duration)?; @@ -708,22 +709,21 @@ impl Data { let dp = self.device_profile.as_ref().unwrap(); let mut mode = match dp.supports_class_c { - true => "C", - false => "A", - } - .to_string(); + true => DeviceClass::C, + false => DeviceClass::A, + }; if let lrwn::Payload::MACPayload(pl) = &self.phy_payload.payload { let locked = pl.fhdr.f_ctrl.class_b; mode = match locked { - true => "B".to_string(), + true => DeviceClass::B, false => mode, }; } // Update if the enabled class has changed. if dev.enabled_class != mode { - *dev = device::set_enabled_class(&dev.dev_eui, &mode).await?; + *dev = device::set_enabled_class(&dev.dev_eui, mode).await?; } Ok(()) diff --git a/chirpstack/src/uplink/join.rs b/chirpstack/src/uplink/join.rs index 9c3051d1..2e7ff8a5 100644 --- a/chirpstack/src/uplink/join.rs +++ b/chirpstack/src/uplink/join.rs @@ -20,7 +20,10 @@ use crate::api::backend::get_async_receiver; use crate::backend::{joinserver, keywrap, roaming}; use crate::storage::device_session; use crate::storage::{ - application, device, device_keys, device_profile, device_queue, error::Error as StorageError, + application, + device::{self, DeviceClass}, + device_keys, device_profile, device_queue, + error::Error as StorageError, metrics, tenant, }; use crate::{ @@ -843,9 +846,9 @@ impl JoinRequest { // LoRaWAN 1.1 devices send a mac-command when changing to Class-C. if dp.supports_class_c && dp.mac_version.to_string().starts_with("1.0") { - *device = device::set_enabled_class(&device.dev_eui, "C").await?; + *device = device::set_enabled_class(&device.dev_eui, DeviceClass::C).await?; } else { - *device = device::set_enabled_class(&device.dev_eui, "A").await?; + *device = device::set_enabled_class(&device.dev_eui, DeviceClass::A).await?; } Ok(()) } diff --git a/chirpstack/src/uplink/join_sns.rs b/chirpstack/src/uplink/join_sns.rs index 2a7f8fea..d46b2d01 100644 --- a/chirpstack/src/uplink/join_sns.rs +++ b/chirpstack/src/uplink/join_sns.rs @@ -7,8 +7,11 @@ use tracing::{span, trace, Instrument, Level}; use super::{helpers, UplinkFrameSet}; use crate::backend::{joinserver, keywrap, roaming}; use crate::storage::{ - application, device, device_keys, device_profile, device_queue, device_session, - error::Error as StorageError, metrics, tenant, + application, + device::{self, DeviceClass}, + device_keys, device_profile, device_queue, device_session, + error::Error as StorageError, + metrics, tenant, }; use crate::{config, devaddr::get_random_dev_addr, integration, metalog, region}; use backend::{PRStartAnsPayload, PRStartReqPayload}; @@ -647,9 +650,9 @@ impl JoinRequest { // LoRaWAN 1.1 devices send a mac-command when changing to Class-C. if dp.supports_class_c && dp.mac_version.to_string().starts_with("1.0") { - *device = device::set_enabled_class(&device.dev_eui, "C").await?; + *device = device::set_enabled_class(&device.dev_eui, DeviceClass::C).await?; } else { - *device = device::set_enabled_class(&device.dev_eui, "A").await?; + *device = device::set_enabled_class(&device.dev_eui, DeviceClass::A).await?; } Ok(()) }