1 // Copyright 2022, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 //! Provide the conversion between the uwb_core's elements and protobuf bindings.
16
17 use std::convert::{TryFrom, TryInto};
18
19 use protobuf::RepeatedField;
20 use zeroize::Zeroize;
21
22 use crate::error::{Error, Result};
23 use crate::params::fira_app_config_params::{
24 AoaResultRequest, BprfPhrDataRate, DeviceRole, DeviceType, FiraAppConfigParams,
25 FiraAppConfigParamsBuilder, HoppingMode, KeyRotation, MacAddressMode, MacFcsType,
26 MultiNodeMode, PreambleDuration, PrfMode, PsduDataRate, RangeDataNtfConfig,
27 RangingRoundControl, RangingRoundUsage, RangingTimeStruct, ResultReportConfig, RframeConfig,
28 ScheduledMode, StsConfig, StsLength, TxAdaptivePayloadPower, UwbAddress, UwbChannel,
29 };
30 use crate::params::uci_packets::{
31 Controlee, DeviceState, ExtendedAddressDlTdoaRangingMeasurement,
32 ExtendedAddressOwrAoaRangingMeasurement, ExtendedAddressTwoWayRangingMeasurement, PowerStats,
33 RangingMeasurementType, ReasonCode, SessionState, SessionType,
34 ShortAddressDlTdoaRangingMeasurement, ShortAddressOwrAoaRangingMeasurement,
35 ShortAddressTwoWayRangingMeasurement, StatusCode, UpdateMulticastListAction,
36 };
37 use crate::params::AppConfigParams;
38 use crate::proto::bindings::{
39 AoaResultRequest as ProtoAoaResultRequest, BprfPhrDataRate as ProtoBprfPhrDataRate,
40 Controlee as ProtoControlee, DeviceRole as ProtoDeviceRole, DeviceState as ProtoDeviceState,
41 DeviceType as ProtoDeviceType, DlTDoARangingMeasurement as ProtoDlTDoARangingMeasurement,
42 FiraAppConfigParams as ProtoFiraAppConfigParams, HoppingMode as ProtoHoppingMode,
43 KeyRotation as ProtoKeyRotation, MacAddressMode as ProtoMacAddressMode,
44 MacFcsType as ProtoMacFcsType, MultiNodeMode as ProtoMultiNodeMode,
45 OwrAoaRangingMeasurement as ProtoOwrAoaRangingMeasurement, PowerStats as ProtoPowerStats,
46 PreambleDuration as ProtoPreambleDuration, PrfMode as ProtoPrfMode,
47 PsduDataRate as ProtoPsduDataRate, RangeDataNtfConfig as ProtoRangeDataNtfConfig,
48 RangingMeasurementType as ProtoRangingMeasurementType,
49 RangingRoundControl as ProtoRangingRoundControl, RangingRoundUsage as ProtoRangingRoundUsage,
50 RangingTimeStruct as ProtoRangingTimeStruct, ReasonCode as ProtoReasonCode,
51 ResultReportConfig as ProtoResultReportConfig, RframeConfig as ProtoRframeConfig,
52 ScheduledMode as ProtoScheduledMode, SessionRangeData as ProtoSessionRangeData,
53 SessionState as ProtoSessionState, SessionType as ProtoSessionType, Status as ProtoStatus,
54 StatusCode as ProtoStatusCode, StsConfig as ProtoStsConfig, StsLength as ProtoStsLength,
55 TwoWayRangingMeasurement as ProtoTwoWayRangingMeasurement,
56 TxAdaptivePayloadPower as ProtoTxAdaptivePayloadPower, UciLoggerMode as ProtoUciLoggerMode,
57 UpdateMulticastListAction as ProtoUpdateMulticastListAction, UwbChannel as ProtoUwbChannel,
58 };
59 use crate::uci::notification::{RangingMeasurements, SessionRangeData};
60 use crate::uci::uci_logger::UciLoggerMode;
61
62 /// Generate the conversion functions between 2 enum types, which field is 1-to-1 mapping.
63 ///
64 /// Example:
65 /// ```
66 /// enum EnumA {
67 /// Value1,
68 /// Value2,
69 /// }
70 /// enum EnumB {
71 /// Foo,
72 /// Bar,
73 /// }
74 /// // This macro generates `From<EnumA> for EnumB` and `From<EnumB> for EnumA`.
75 /// uwb_core::enum_mapping! {
76 /// EnumA => EnumB,
77 /// Value1 => Foo,
78 /// Value2 => Bar,
79 /// }
80 /// ```
81 #[macro_export]
82 macro_rules! enum_mapping {
83 ( $enum_a:ty => $enum_b:ty, $( $field_a:ident => $field_b:ident, )+ ) => {
84 impl From<$enum_a> for $enum_b {
85 fn from(item: $enum_a) -> $enum_b {
86 match item {
87 $(
88 <$enum_a>::$field_a => <$enum_b>::$field_b,
89 )*
90 }
91 }
92 }
93 impl From<$enum_b> for $enum_a {
94 fn from(item: $enum_b) -> $enum_a {
95 match item {
96 $(
97 <$enum_b>::$field_b => <$enum_a>::$field_a,
98 )*
99 }
100 }
101 }
102 };
103 }
104
105 impl From<ProtoStatusCode> for StatusCode {
from(item: ProtoStatusCode) -> Self106 fn from(item: ProtoStatusCode) -> Self {
107 match item {
108 ProtoStatusCode::UCI_STATUS_OK => StatusCode::UciStatusOk,
109 ProtoStatusCode::UCI_STATUS_REJECTED => StatusCode::UciStatusRejected,
110 ProtoStatusCode::UCI_STATUS_FAILED => StatusCode::UciStatusFailed,
111 ProtoStatusCode::UCI_STATUS_SYNTAX_ERROR => StatusCode::UciStatusSyntaxError,
112 ProtoStatusCode::UCI_STATUS_INVALID_PARAM => StatusCode::UciStatusInvalidParam,
113 ProtoStatusCode::UCI_STATUS_INVALID_RANGE => StatusCode::UciStatusInvalidRange,
114 ProtoStatusCode::UCI_STATUS_INVALID_MSG_SIZE => StatusCode::UciStatusInvalidMsgSize,
115 ProtoStatusCode::UCI_STATUS_UNKNOWN_GID => StatusCode::UciStatusUnknownGid,
116 ProtoStatusCode::UCI_STATUS_UNKNOWN_OID => StatusCode::UciStatusUnknownOid,
117 ProtoStatusCode::UCI_STATUS_READ_ONLY => StatusCode::UciStatusReadOnly,
118 ProtoStatusCode::UCI_STATUS_COMMAND_RETRY => StatusCode::UciStatusCommandRetry,
119 ProtoStatusCode::UCI_STATUS_SESSION_NOT_EXIST => StatusCode::UciStatusSessionNotExist,
120 ProtoStatusCode::UCI_STATUS_SESSION_DUPLICATE => StatusCode::UciStatusSessionDuplicate,
121 ProtoStatusCode::UCI_STATUS_SESSION_ACTIVE => StatusCode::UciStatusSessionActive,
122 ProtoStatusCode::UCI_STATUS_MAX_SESSIONS_EXCEEDED => {
123 StatusCode::UciStatusMaxSessionsExceeded
124 }
125 ProtoStatusCode::UCI_STATUS_SESSION_NOT_CONFIGURED => {
126 StatusCode::UciStatusSessionNotConfigured
127 }
128 ProtoStatusCode::UCI_STATUS_ACTIVE_SESSIONS_ONGOING => {
129 StatusCode::UciStatusActiveSessionsOngoing
130 }
131 ProtoStatusCode::UCI_STATUS_MULTICAST_LIST_FULL => {
132 StatusCode::UciStatusMulticastListFull
133 }
134 ProtoStatusCode::UCI_STATUS_ADDRESS_NOT_FOUND => StatusCode::UciStatusAddressNotFound,
135 ProtoStatusCode::UCI_STATUS_ADDRESS_ALREADY_PRESENT => {
136 StatusCode::UciStatusAddressAlreadyPresent
137 }
138 ProtoStatusCode::UCI_STATUS_OK_NEGATIVE_DISTANCE_REPORT => {
139 StatusCode::UciStatusOkNegativeDistanceReport
140 }
141 ProtoStatusCode::UCI_STATUS_RANGING_TX_FAILED => StatusCode::UciStatusRangingTxFailed,
142 ProtoStatusCode::UCI_STATUS_RANGING_RX_TIMEOUT => {
143 StatusCode::UciStatusRangingRxTimeout
144 }
145 ProtoStatusCode::UCI_STATUS_RANGING_RX_PHY_DEC_FAILED => {
146 StatusCode::UciStatusRangingRxPhyDecFailed
147 }
148 ProtoStatusCode::UCI_STATUS_RANGING_RX_PHY_TOA_FAILED => {
149 StatusCode::UciStatusRangingRxPhyToaFailed
150 }
151 ProtoStatusCode::UCI_STATUS_RANGING_RX_PHY_STS_FAILED => {
152 StatusCode::UciStatusRangingRxPhyStsFailed
153 }
154 ProtoStatusCode::UCI_STATUS_RANGING_RX_MAC_DEC_FAILED => {
155 StatusCode::UciStatusRangingRxMacDecFailed
156 }
157 ProtoStatusCode::UCI_STATUS_RANGING_RX_MAC_IE_DEC_FAILED => {
158 StatusCode::UciStatusRangingRxMacIeDecFailed
159 }
160 ProtoStatusCode::UCI_STATUS_RANGING_RX_MAC_IE_MISSING => {
161 StatusCode::UciStatusRangingRxMacIeMissing
162 }
163 ProtoStatusCode::UCI_STATUS_ERROR_ROUND_INDEX_NOT_ACTIVATED => {
164 StatusCode::UciStatusErrorRoundIndexNotActivated
165 }
166 ProtoStatusCode::UCI_STATUS_ERROR_NUMBER_OF_ACTIVE_RANGING_ROUNDS_EXCEEDED => {
167 StatusCode::UciStatusErrorNumberOfActiveRangingRoundsExceeded
168 }
169 ProtoStatusCode::UCI_STATUS_ERROR_DL_TDOA_DEVICE_ADDRESS_NOT_MATCHING_IN_REPLY_TIME_LIST =>
170 StatusCode::UciStatusErrorDlTdoaDeviceAddressNotMatchingInReplyTimeList,
171 ProtoStatusCode::UCI_STATUS_DATA_MAX_TX_PSDU_SIZE_EXCEEDED => {
172 StatusCode::UciStatusDataMaxTxPsduSizeExceeded
173 }
174 ProtoStatusCode::UCI_STATUS_DATA_RX_CRC_ERROR => StatusCode::UciStatusDataRxCrcError,
175 ProtoStatusCode::UCI_STATUS_ERROR_CCC_SE_BUSY => StatusCode::UciStatusErrorCccSeBusy,
176 ProtoStatusCode::UCI_STATUS_ERROR_CCC_LIFECYCLE => {
177 StatusCode::UciStatusErrorCccLifecycle
178 }
179 ProtoStatusCode::UCI_STATUS_ERROR_STOPPED_DUE_TO_OTHER_SESSION_CONFLICT => {
180 StatusCode::UciStatusErrorStoppedDueToOtherSessionConflict
181 }
182 _ => StatusCode::VendorSpecificStatusCode2,
183 }
184 }
185 }
186
187 impl From<StatusCode> for ProtoStatusCode {
from(item: StatusCode) -> Self188 fn from(item: StatusCode) -> Self {
189 match item {
190 StatusCode::UciStatusOk => ProtoStatusCode::UCI_STATUS_OK,
191 StatusCode::UciStatusRejected => ProtoStatusCode::UCI_STATUS_REJECTED,
192 StatusCode::UciStatusFailed => ProtoStatusCode::UCI_STATUS_FAILED,
193 StatusCode::UciStatusSyntaxError => ProtoStatusCode::UCI_STATUS_SYNTAX_ERROR,
194 StatusCode::UciStatusInvalidParam => ProtoStatusCode::UCI_STATUS_INVALID_PARAM,
195 StatusCode::UciStatusInvalidRange => ProtoStatusCode::UCI_STATUS_INVALID_RANGE,
196 StatusCode::UciStatusInvalidMsgSize => ProtoStatusCode::UCI_STATUS_INVALID_MSG_SIZE,
197 StatusCode::UciStatusUnknownGid => ProtoStatusCode::UCI_STATUS_UNKNOWN_GID,
198 StatusCode::UciStatusUnknownOid => ProtoStatusCode::UCI_STATUS_UNKNOWN_OID,
199 StatusCode::UciStatusReadOnly => ProtoStatusCode::UCI_STATUS_READ_ONLY,
200 StatusCode::UciStatusCommandRetry => ProtoStatusCode::UCI_STATUS_COMMAND_RETRY,
201 StatusCode::UciStatusSessionNotExist => ProtoStatusCode::UCI_STATUS_SESSION_NOT_EXIST,
202 StatusCode::UciStatusSessionDuplicate => ProtoStatusCode::UCI_STATUS_SESSION_DUPLICATE,
203 StatusCode::UciStatusSessionActive => ProtoStatusCode::UCI_STATUS_SESSION_ACTIVE,
204 StatusCode::UciStatusMaxSessionsExceeded => {
205 ProtoStatusCode::UCI_STATUS_MAX_SESSIONS_EXCEEDED
206 }
207 StatusCode::UciStatusSessionNotConfigured => {
208 ProtoStatusCode::UCI_STATUS_SESSION_NOT_CONFIGURED
209 }
210 StatusCode::UciStatusActiveSessionsOngoing => {
211 ProtoStatusCode::UCI_STATUS_ACTIVE_SESSIONS_ONGOING
212 }
213 StatusCode::UciStatusMulticastListFull => {
214 ProtoStatusCode::UCI_STATUS_MULTICAST_LIST_FULL
215 }
216 StatusCode::UciStatusAddressNotFound => {
217 ProtoStatusCode::UCI_STATUS_ADDRESS_NOT_FOUND
218 }
219 StatusCode::UciStatusAddressAlreadyPresent => {
220 ProtoStatusCode::UCI_STATUS_ADDRESS_ALREADY_PRESENT
221 }
222 StatusCode::UciStatusOkNegativeDistanceReport => {
223 ProtoStatusCode::UCI_STATUS_OK_NEGATIVE_DISTANCE_REPORT
224 }
225 StatusCode::UciStatusRangingTxFailed => {
226 ProtoStatusCode::UCI_STATUS_RANGING_TX_FAILED
227 }
228 StatusCode::UciStatusRangingRxTimeout => {
229 ProtoStatusCode::UCI_STATUS_RANGING_RX_TIMEOUT
230 }
231 StatusCode::UciStatusRangingRxPhyDecFailed => {
232 ProtoStatusCode::UCI_STATUS_RANGING_RX_PHY_DEC_FAILED
233 }
234 StatusCode::UciStatusRangingRxPhyToaFailed => {
235 ProtoStatusCode::UCI_STATUS_RANGING_RX_PHY_TOA_FAILED
236 }
237 StatusCode::UciStatusRangingRxPhyStsFailed => {
238 ProtoStatusCode::UCI_STATUS_RANGING_RX_PHY_STS_FAILED
239 }
240 StatusCode::UciStatusRangingRxMacDecFailed => {
241 ProtoStatusCode::UCI_STATUS_RANGING_RX_MAC_DEC_FAILED
242 }
243 StatusCode::UciStatusRangingRxMacIeDecFailed => {
244 ProtoStatusCode::UCI_STATUS_RANGING_RX_MAC_IE_DEC_FAILED
245 }
246 StatusCode::UciStatusRangingRxMacIeMissing => {
247 ProtoStatusCode::UCI_STATUS_RANGING_RX_MAC_IE_MISSING
248 }
249 StatusCode::UciStatusErrorRoundIndexNotActivated => {
250 ProtoStatusCode::UCI_STATUS_ERROR_ROUND_INDEX_NOT_ACTIVATED
251 }
252 StatusCode::UciStatusErrorNumberOfActiveRangingRoundsExceeded => {
253 ProtoStatusCode::UCI_STATUS_ERROR_NUMBER_OF_ACTIVE_RANGING_ROUNDS_EXCEEDED
254 }
255 StatusCode::UciStatusErrorDlTdoaDeviceAddressNotMatchingInReplyTimeList => {
256 ProtoStatusCode::UCI_STATUS_ERROR_DL_TDOA_DEVICE_ADDRESS_NOT_MATCHING_IN_REPLY_TIME_LIST
257 }
258 StatusCode::UciStatusDataMaxTxPsduSizeExceeded => {
259 ProtoStatusCode::UCI_STATUS_DATA_MAX_TX_PSDU_SIZE_EXCEEDED
260 }
261 StatusCode::UciStatusDataRxCrcError => {
262 ProtoStatusCode::UCI_STATUS_DATA_RX_CRC_ERROR
263 }
264 StatusCode::UciStatusErrorCccSeBusy => {
265 ProtoStatusCode::UCI_STATUS_ERROR_CCC_SE_BUSY
266 }
267 StatusCode::UciStatusErrorCccLifecycle => {
268 ProtoStatusCode::UCI_STATUS_ERROR_CCC_LIFECYCLE
269 }
270 StatusCode::UciStatusErrorStoppedDueToOtherSessionConflict => {
271 ProtoStatusCode::UCI_STATUS_ERROR_STOPPED_DUE_TO_OTHER_SESSION_CONFLICT
272 }
273 _ => ProtoStatusCode::UCI_STATUS_RFU_OR_VENDOR_SPECIFIC,
274 }
275 }
276 }
277
278 enum_mapping! {
279 ProtoDeviceState => DeviceState,
280 DEVICE_STATE_READY => DeviceStateReady,
281 DEVICE_STATE_ACTIVE => DeviceStateActive,
282 DEVICE_STATE_ERROR => DeviceStateError,
283 }
284
285 enum_mapping! {
286 ProtoSessionState => SessionState,
287 INIT => SessionStateInit,
288 DEINIT => SessionStateDeinit,
289 ACTIVE => SessionStateActive,
290 IDLE => SessionStateIdle,
291 }
292
293 impl From<ProtoReasonCode> for ReasonCode {
from(item: ProtoReasonCode) -> Self294 fn from(item: ProtoReasonCode) -> Self {
295 match item {
296 ProtoReasonCode::STATE_CHANGE_WITH_SESSION_MANAGEMENT_COMMANDS => {
297 ReasonCode::StateChangeWithSessionManagementCommands
298 }
299 ProtoReasonCode::MAX_RANGING_ROUND_RETRY_COUNT_REACHED => {
300 ReasonCode::MaxRangingRoundRetryCountReached
301 }
302 ProtoReasonCode::MAX_NUMBER_OF_MEASUREMENTS_REACHED => {
303 ReasonCode::MaxNumberOfMeasurementsReached
304 }
305 ProtoReasonCode::SESSION_SUSPENDED_DUE_TO_INBAND_SIGNAL => {
306 ReasonCode::SessionSuspendedDueToInbandSignal
307 }
308 ProtoReasonCode::SESSION_RESUMED_DUE_TO_INBAND_SIGNAL => {
309 ReasonCode::SessionResumedDueToInbandSignal
310 }
311 ProtoReasonCode::SESSION_STOPPED_DUE_TO_INBAND_SIGNAL => {
312 ReasonCode::SessionStoppedDueToInbandSignal
313 }
314 ProtoReasonCode::ERROR_INVALID_UL_TDOA_RANDOM_WINDOW => {
315 ReasonCode::ErrorInvalidUlTdoaRandomWindow
316 }
317 ProtoReasonCode::ERROR_MIN_RFRAMES_PER_RR_NOT_SUPPORTED => {
318 ReasonCode::ErrorMinRframesPerRrNotSupported
319 }
320 ProtoReasonCode::ERROR_TX_DELAY_NOT_SUPPORTED => ReasonCode::ErrorTxDelayNotSupported,
321 ProtoReasonCode::ERROR_SLOT_LENGTH_NOT_SUPPORTED => {
322 ReasonCode::ErrorSlotLengthNotSupported
323 }
324 ProtoReasonCode::ERROR_INSUFFICIENT_SLOTS_PER_RR => {
325 ReasonCode::ErrorInsufficientSlotsPerRr
326 }
327 ProtoReasonCode::ERROR_MAC_ADDRESS_MODE_NOT_SUPPORTED => {
328 ReasonCode::ErrorMacAddressModeNotSupported
329 }
330 ProtoReasonCode::ERROR_INVALID_RANGING_DURATION => {
331 ReasonCode::ErrorInvalidRangingDuration
332 }
333 ProtoReasonCode::ERROR_INVALID_STS_CONFIG => ReasonCode::ErrorInvalidStsConfig,
334 ProtoReasonCode::ERROR_INVALID_RFRAME_CONFIG => ReasonCode::ErrorInvalidRframeConfig,
335 ProtoReasonCode::ERROR_HUS_NOT_ENOUGH_SLOTS => ReasonCode::ErrorHusNotEnoughSlots,
336 ProtoReasonCode::ERROR_HUS_CFP_PHASE_TOO_SHORT => ReasonCode::ErrorHusCfpPhaseTooShort,
337 ProtoReasonCode::ERROR_HUS_CAP_PHASE_TOO_SHORT => ReasonCode::ErrorHusCapPhaseTooShort,
338 ProtoReasonCode::ERROR_HUS_OTHERS => ReasonCode::ErrorHusOthers,
339 ProtoReasonCode::ERROR_STATUS_SESSION_KEY_NOT_FOUND => {
340 ReasonCode::ErrorStatusSessionKeyNotFound
341 }
342 ProtoReasonCode::ERROR_STATUS_SUB_SESSION_KEY_NOT_FOUND => {
343 ReasonCode::ErrorStatusSubSessionKeyNotFound
344 }
345 ProtoReasonCode::ERROR_INVALID_PREAMBLE_CODE_INDEX => {
346 ReasonCode::ErrorInvalidPreambleCodeIndex
347 }
348 ProtoReasonCode::ERROR_INVALID_SFD_ID => ReasonCode::ErrorInvalidSfdId,
349 ProtoReasonCode::ERROR_INVALID_PSDU_DATA_RATE => ReasonCode::ErrorInvalidPsduDataRate,
350 ProtoReasonCode::ERROR_INVALID_PHR_DATA_RATE => ReasonCode::ErrorInvalidPhrDataRate,
351 ProtoReasonCode::ERROR_INVALID_PREAMBLE_DURATION => {
352 ReasonCode::ErrorInvalidPreambleDuration
353 }
354 ProtoReasonCode::ERROR_INVALID_STS_LENGTH => ReasonCode::ErrorInvalidStsLength,
355 ProtoReasonCode::ERROR_INVALID_NUM_OF_STS_SEGMENTS => {
356 ReasonCode::ErrorInvalidNumOfStsSegments
357 }
358 ProtoReasonCode::ERROR_INVALID_NUM_OF_CONTROLEES => {
359 ReasonCode::ErrorInvalidNumOfControlees
360 }
361 ProtoReasonCode::ERROR_MAX_RANGING_REPLY_TIME_EXCEEDED => {
362 ReasonCode::ErrorMaxRangingReplyTimeExceeded
363 }
364 ProtoReasonCode::ERROR_INVALID_DST_ADDRESS_LIST => {
365 ReasonCode::ErrorInvalidDstAddressList
366 }
367 ProtoReasonCode::ERROR_INVALID_OR_NOT_FOUND_SUB_SESSION_ID => {
368 ReasonCode::ErrorInvalidOrNotFoundSubSessionId
369 }
370 ProtoReasonCode::ERROR_INVALID_RESULT_REPORT_CONFIG => {
371 ReasonCode::ErrorInvalidResultReportConfig
372 }
373 ProtoReasonCode::ERROR_INVALID_RANGING_ROUND_USAGE => {
374 ReasonCode::ErrorInvalidRangingRoundUsage
375 }
376 ProtoReasonCode::ERROR_INVALID_MULTI_NODE_MODE => ReasonCode::ErrorInvalidMultiNodeMode,
377 ProtoReasonCode::ERROR_RDS_FETCH_FAILURE => ReasonCode::ErrorRdsFetchFailure,
378 ProtoReasonCode::ERROR_REF_UWB_SESSION_DOES_NOT_EXIST => {
379 ReasonCode::ErrorRefUwbSessionDoesNotExist
380 }
381 ProtoReasonCode::ERROR_REF_UWB_SESSION_RANGING_DURATION_MISMATCH => {
382 ReasonCode::ErrorRefUwbSessionRangingDurationMismatch
383 }
384 ProtoReasonCode::ERROR_REF_UWB_SESSION_INVALID_OFFSET_TIME => {
385 ReasonCode::ErrorRefUwbSessionInvalidOffsetTime
386 }
387 ProtoReasonCode::ERROR_REF_UWB_SESSION_LOST => ReasonCode::ErrorRefUwbSessionLost,
388 ProtoReasonCode::ERROR_INVALID_CHANNEL_WITH_AOA => {
389 ReasonCode::ErrorInvalidChannelWithAoa
390 }
391 ProtoReasonCode::ERROR_STOPPED_DUE_TO_OTHER_SESSION_CONFLICT => {
392 ReasonCode::ErrorStoppedDueToOtherSessionConflict
393 }
394 _ => ReasonCode::VendorSpecificReasonCode2,
395 }
396 }
397 }
398
399 impl From<ReasonCode> for ProtoReasonCode {
from(item: ReasonCode) -> Self400 fn from(item: ReasonCode) -> Self {
401 match item {
402 ReasonCode::StateChangeWithSessionManagementCommands => {
403 ProtoReasonCode::STATE_CHANGE_WITH_SESSION_MANAGEMENT_COMMANDS
404 }
405 ReasonCode::MaxRangingRoundRetryCountReached => {
406 ProtoReasonCode::MAX_RANGING_ROUND_RETRY_COUNT_REACHED
407 }
408 ReasonCode::MaxNumberOfMeasurementsReached => {
409 ProtoReasonCode::MAX_NUMBER_OF_MEASUREMENTS_REACHED
410 }
411 ReasonCode::SessionSuspendedDueToInbandSignal => {
412 ProtoReasonCode::SESSION_SUSPENDED_DUE_TO_INBAND_SIGNAL
413 }
414 ReasonCode::SessionResumedDueToInbandSignal => {
415 ProtoReasonCode::SESSION_RESUMED_DUE_TO_INBAND_SIGNAL
416 }
417 ReasonCode::SessionStoppedDueToInbandSignal => {
418 ProtoReasonCode::SESSION_STOPPED_DUE_TO_INBAND_SIGNAL
419 }
420 ReasonCode::ErrorInvalidUlTdoaRandomWindow => {
421 ProtoReasonCode::ERROR_INVALID_UL_TDOA_RANDOM_WINDOW
422 }
423 ReasonCode::ErrorMinRframesPerRrNotSupported => {
424 ProtoReasonCode::ERROR_MIN_RFRAMES_PER_RR_NOT_SUPPORTED
425 }
426 ReasonCode::ErrorTxDelayNotSupported => ProtoReasonCode::ERROR_TX_DELAY_NOT_SUPPORTED,
427 ReasonCode::ErrorSlotLengthNotSupported => {
428 ProtoReasonCode::ERROR_SLOT_LENGTH_NOT_SUPPORTED
429 }
430 ReasonCode::ErrorInsufficientSlotsPerRr => {
431 ProtoReasonCode::ERROR_INSUFFICIENT_SLOTS_PER_RR
432 }
433 ReasonCode::ErrorMacAddressModeNotSupported => {
434 ProtoReasonCode::ERROR_MAC_ADDRESS_MODE_NOT_SUPPORTED
435 }
436 ReasonCode::ErrorInvalidRangingDuration => {
437 ProtoReasonCode::ERROR_INVALID_RANGING_DURATION
438 }
439 ReasonCode::ErrorInvalidStsConfig => ProtoReasonCode::ERROR_INVALID_STS_CONFIG,
440 ReasonCode::ErrorInvalidRframeConfig => ProtoReasonCode::ERROR_INVALID_RFRAME_CONFIG,
441 ReasonCode::ErrorHusNotEnoughSlots => ProtoReasonCode::ERROR_HUS_NOT_ENOUGH_SLOTS,
442 ReasonCode::ErrorHusCfpPhaseTooShort => ProtoReasonCode::ERROR_HUS_CFP_PHASE_TOO_SHORT,
443 ReasonCode::ErrorHusCapPhaseTooShort => ProtoReasonCode::ERROR_HUS_CAP_PHASE_TOO_SHORT,
444 ReasonCode::ErrorHusOthers => ProtoReasonCode::ERROR_HUS_OTHERS,
445 ReasonCode::ErrorStatusSessionKeyNotFound => {
446 ProtoReasonCode::ERROR_STATUS_SESSION_KEY_NOT_FOUND
447 }
448 ReasonCode::ErrorStatusSubSessionKeyNotFound => {
449 ProtoReasonCode::ERROR_STATUS_SUB_SESSION_KEY_NOT_FOUND
450 }
451 ReasonCode::ErrorInvalidPreambleCodeIndex => {
452 ProtoReasonCode::ERROR_INVALID_PREAMBLE_CODE_INDEX
453 }
454 ReasonCode::ErrorInvalidSfdId => ProtoReasonCode::ERROR_INVALID_SFD_ID,
455 ReasonCode::ErrorInvalidPsduDataRate => ProtoReasonCode::ERROR_INVALID_PSDU_DATA_RATE,
456 ReasonCode::ErrorInvalidPhrDataRate => ProtoReasonCode::ERROR_INVALID_PHR_DATA_RATE,
457 ReasonCode::ErrorInvalidPreambleDuration => {
458 ProtoReasonCode::ERROR_INVALID_PREAMBLE_DURATION
459 }
460 ReasonCode::ErrorInvalidStsLength => ProtoReasonCode::ERROR_INVALID_STS_LENGTH,
461 ReasonCode::ErrorInvalidNumOfStsSegments => {
462 ProtoReasonCode::ERROR_INVALID_NUM_OF_STS_SEGMENTS
463 }
464 ReasonCode::ErrorInvalidNumOfControlees => {
465 ProtoReasonCode::ERROR_INVALID_NUM_OF_CONTROLEES
466 }
467 ReasonCode::ErrorMaxRangingReplyTimeExceeded => {
468 ProtoReasonCode::ERROR_MAX_RANGING_REPLY_TIME_EXCEEDED
469 }
470 ReasonCode::ErrorInvalidDstAddressList => {
471 ProtoReasonCode::ERROR_INVALID_DST_ADDRESS_LIST
472 }
473 ReasonCode::ErrorInvalidOrNotFoundSubSessionId => {
474 ProtoReasonCode::ERROR_INVALID_OR_NOT_FOUND_SUB_SESSION_ID
475 }
476 ReasonCode::ErrorInvalidResultReportConfig => {
477 ProtoReasonCode::ERROR_INVALID_RESULT_REPORT_CONFIG
478 }
479 ReasonCode::ErrorInvalidRangingRoundUsage => {
480 ProtoReasonCode::ERROR_INVALID_RANGING_ROUND_USAGE
481 }
482 ReasonCode::ErrorInvalidMultiNodeMode => ProtoReasonCode::ERROR_INVALID_MULTI_NODE_MODE,
483 ReasonCode::ErrorRdsFetchFailure => ProtoReasonCode::ERROR_RDS_FETCH_FAILURE,
484 ReasonCode::ErrorRefUwbSessionDoesNotExist => {
485 ProtoReasonCode::ERROR_REF_UWB_SESSION_DOES_NOT_EXIST
486 }
487 ReasonCode::ErrorRefUwbSessionRangingDurationMismatch => {
488 ProtoReasonCode::ERROR_REF_UWB_SESSION_RANGING_DURATION_MISMATCH
489 }
490 ReasonCode::ErrorRefUwbSessionInvalidOffsetTime => {
491 ProtoReasonCode::ERROR_REF_UWB_SESSION_INVALID_OFFSET_TIME
492 }
493 ReasonCode::ErrorRefUwbSessionLost => ProtoReasonCode::ERROR_REF_UWB_SESSION_LOST,
494 ReasonCode::ErrorInvalidChannelWithAoa => {
495 ProtoReasonCode::ERROR_INVALID_CHANNEL_WITH_AOA
496 }
497 ReasonCode::ErrorStoppedDueToOtherSessionConflict => {
498 ProtoReasonCode::ERROR_STOPPED_DUE_TO_OTHER_SESSION_CONFLICT
499 }
500 ReasonCode::ErrorDtAnchorRangingRoundsNotConfigured => {
501 ProtoReasonCode::ERROR_DT_ANCHOR_RANGING_ROUNDS_NOT_CONFIGURED
502 }
503 ReasonCode::ErrorDtTagRangingRoundsNotConfigured => {
504 ProtoReasonCode::ERROR_DT_TAG_RANGING_ROUNDS_NOT_CONFIGURED
505 }
506 _ => ProtoReasonCode::ERROR_RFU_OR_VENDOR_SPECIFIC,
507 }
508 }
509 }
510
511 enum_mapping! {
512 ProtoUciLoggerMode => UciLoggerMode,
513 UCI_LOGGER_MODE_DISABLED => Disabled,
514 UCI_LOGGER_MODE_UNFILTERED => Unfiltered,
515 UCI_LOGGER_MODE_FILTERED => Filtered,
516 }
517
518 enum_mapping! {
519 ProtoRangingMeasurementType => RangingMeasurementType,
520 ONE_WAY => OneWay,
521 TWO_WAY => TwoWay,
522 DL_TDOA => DlTdoa,
523 OWR_AOA => OwrAoa,
524 }
525
526 enum_mapping! {
527 ProtoSessionType => SessionType,
528 FIRA_RANGING_SESSION => FiraRangingSession,
529 FIRA_DATA_TRANSFER => FiraDataTransfer,
530 CCC => Ccc,
531 DEVICE_TEST_MODE => DeviceTestMode,
532 }
533
534 enum_mapping! {
535 ProtoDeviceType => DeviceType,
536 CONTROLEE => Controlee,
537 CONTROLLER => Controller,
538 }
539
540 enum_mapping! {
541 ProtoRangingRoundUsage => RangingRoundUsage,
542 SS_TWR => SsTwr,
543 DS_TWR => DsTwr,
544 SS_TWR_NON => SsTwrNon,
545 DS_TWR_NON => DsTwrNon,
546 }
547
548 enum_mapping! {
549 ProtoStsConfig => StsConfig,
550 STATIC => Static,
551 DYNAMIC => Dynamic,
552 DYNAMIC_FOR_CONTROLEE_INDIVIDUAL_KEY => DynamicForControleeIndividualKey,
553 }
554
555 enum_mapping! {
556 ProtoMultiNodeMode => MultiNodeMode,
557 UNICAST => Unicast,
558 ONE_TO_MANY => OneToMany,
559 MANY_TO_MANY => ManyToMany,
560 }
561
562 enum_mapping! {
563 ProtoUwbChannel => UwbChannel,
564 CHANNEL_5 => Channel5,
565 CHANNEL_6 => Channel6,
566 CHANNEL_8 => Channel8,
567 CHANNEL_9 => Channel9,
568 CHANNEL_10 => Channel10,
569 CHANNEL_12 => Channel12,
570 CHANNEL_13 => Channel13,
571 CHANNEL_14 => Channel14,
572 }
573
574 enum_mapping! {
575 ProtoMacFcsType => MacFcsType,
576 CRC_16 => Crc16,
577 CRC_32 => Crc32,
578 }
579
580 enum_mapping! {
581 ProtoAoaResultRequest => AoaResultRequest,
582 NO_AOA_REPORT => NoAoaReport,
583 REQ_AOA_RESULTS => ReqAoaResults,
584 REQ_AOA_RESULTS_AZIMUTH_ONLY => ReqAoaResultsAzimuthOnly,
585 REQ_AOA_RESULTS_ELEVATION_ONLY => ReqAoaResultsElevationOnly,
586 REQ_AOA_RESULTS_INTERLEAVED => ReqAoaResultsInterleaved,
587 }
588
589 enum_mapping! {
590 ProtoRangeDataNtfConfig => RangeDataNtfConfig,
591 RANGE_DATA_NTF_CONFIG_DISABLE => Disable,
592 RANGE_DATA_NTF_CONFIG_ENABLE => Enable,
593 RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY => EnableProximity,
594 }
595
596 enum_mapping! {
597 ProtoDeviceRole => DeviceRole,
598 RESPONDER => Responder,
599 INITIATOR => Initiator,
600 }
601
602 enum_mapping! {
603 ProtoRframeConfig => RframeConfig,
604 SP0 => SP0,
605 SP1 => SP1,
606 SP3 => SP3,
607 }
608
609 enum_mapping! {
610 ProtoPsduDataRate => PsduDataRate,
611 RATE_6M_81 => Rate6m81,
612 RATE_7M_80 => Rate7m80,
613 RATE_27M_2 => Rate27m2,
614 RATE_31M_2 => Rate31m2,
615 RATE_850K => Rate850k,
616 }
617
618 enum_mapping! {
619 ProtoPreambleDuration => PreambleDuration,
620 T32_SYMBOLS => T32Symbols,
621 T64_SYMBOLS => T64Symbols,
622 }
623
624 enum_mapping! {
625 ProtoRangingTimeStruct => RangingTimeStruct,
626 INTERVAL_BASED_SCHEDULING => IntervalBasedScheduling,
627 BLOCK_BASED_SCHEDULING => BlockBasedScheduling,
628 }
629
630 enum_mapping! {
631 ProtoTxAdaptivePayloadPower => TxAdaptivePayloadPower,
632 TX_ADAPTIVE_PAYLOAD_POWER_DISABLE => Disable,
633 TX_ADAPTIVE_PAYLOAD_POWER_ENABLE => Enable,
634 }
635
636 enum_mapping! {
637 ProtoPrfMode => PrfMode,
638 BPRF => Bprf,
639 HPRF_WITH_124_8_MHZ => HprfWith124_8MHz,
640 HPRF_WITH_249_6_MHZ => HprfWith249_6MHz,
641 }
642
643 enum_mapping! {
644 ProtoScheduledMode => ScheduledMode,
645 TIME_SCHEDULED_RANGING => TimeScheduledRanging,
646 }
647
648 enum_mapping! {
649 ProtoKeyRotation => KeyRotation,
650 KEY_ROTATION_DISABLE => Disable,
651 KEY_ROTATION_ENABLE => Enable,
652 }
653
654 enum_mapping! {
655 ProtoMacAddressMode => MacAddressMode,
656 MAC_ADDRESS_2_BYTES => MacAddress2Bytes,
657 MAC_ADDRESS_8_BYTES_2_BYTES_HEADER => MacAddress8Bytes2BytesHeader,
658 MAC_ADDRESS_8_BYTES => MacAddress8Bytes,
659 }
660
661 enum_mapping! {
662 ProtoHoppingMode => HoppingMode,
663 HOPPING_MODE_DISABLE => Disable,
664 FIRA_HOPPING_ENABLE => FiraHoppingEnable,
665 }
666
667 enum_mapping! {
668 ProtoBprfPhrDataRate => BprfPhrDataRate,
669 BPRF_PHR_DATA_RATE_850K => Rate850k,
670 BPRF_PHR_DATA_RATE_6M_81 => Rate6m81,
671 }
672
673 enum_mapping! {
674 ProtoStsLength => StsLength,
675 LENGTH_32 => Length32,
676 LENGTH_64 => Length64,
677 LENGTH_128 => Length128,
678 }
679
680 enum_mapping! {
681 ProtoUpdateMulticastListAction => UpdateMulticastListAction,
682 ADD_CONTROLEE => AddControlee,
683 REMOVE_CONTROLEE => RemoveControlee,
684 ADD_CONTROLEE_WITH_SHORT_SUB_SESSION_KEY => AddControleeWithShortSubSessionKey,
685 ADD_CONTROLEE_WITH_LONG_SUB_SESSION_KEY => AddControleeWithLongSubSessionKey,
686 }
687
688 pub enum ProtoRangingMeasurements {
689 TwoWay(Vec<ProtoTwoWayRangingMeasurement>),
690 OwrAoa(ProtoOwrAoaRangingMeasurement),
691 DlTDoa(Vec<ProtoDlTDoARangingMeasurement>),
692 }
693
694 impl<T> From<Result<T>> for ProtoStatus {
from(item: Result<T>) -> Self695 fn from(item: Result<T>) -> Self {
696 match item {
697 Ok(_) => Self::OK,
698 Err(Error::BadParameters) => Self::BAD_PARAMETERS,
699 Err(Error::MaxSessionsExceeded) => Self::MAX_SESSIONS_EXCEEDED,
700 Err(Error::MaxRrRetryReached) => Self::MAX_RR_RETRY_REACHED,
701 Err(Error::ProtocolSpecific) => Self::PROTOCOL_SPECIFIC,
702 Err(Error::RemoteRequest) => Self::REMOTE_REQUEST,
703 Err(Error::Timeout) => Self::TIMEOUT,
704 Err(Error::CommandRetry) => Self::COMMAND_RETRY,
705 Err(Error::DuplicatedSessionId) => Self::DUPLICATED_SESSION_ID,
706 Err(_) => Self::UNKNOWN,
707 }
708 }
709 }
710
711 impl From<ShortAddressTwoWayRangingMeasurement> for ProtoTwoWayRangingMeasurement {
from(item: ShortAddressTwoWayRangingMeasurement) -> Self712 fn from(item: ShortAddressTwoWayRangingMeasurement) -> Self {
713 let mut result = Self::new();
714 result.set_mac_address(item.mac_address.into());
715 result.set_status(item.status.into());
716 result.set_nlos(item.nlos.into());
717 result.set_distance(item.distance.into());
718 result.set_aoa_azimuth(item.aoa_azimuth.into());
719 result.set_aoa_azimuth_fom(item.aoa_azimuth_fom.into());
720 result.set_aoa_elevation(item.aoa_elevation.into());
721 result.set_aoa_elevation_fom(item.aoa_elevation_fom.into());
722 result.set_aoa_destination_azimuth(item.aoa_destination_azimuth.into());
723 result.set_aoa_destination_azimuth_fom(item.aoa_destination_azimuth_fom.into());
724 result.set_aoa_destination_elevation(item.aoa_destination_elevation.into());
725 result.set_aoa_destination_elevation_fom(item.aoa_destination_elevation_fom.into());
726 result.set_slot_index(item.slot_index.into());
727 result.set_rssi(item.rssi.into());
728 result
729 }
730 }
731
732 impl From<ExtendedAddressTwoWayRangingMeasurement> for ProtoTwoWayRangingMeasurement {
from(item: ExtendedAddressTwoWayRangingMeasurement) -> Self733 fn from(item: ExtendedAddressTwoWayRangingMeasurement) -> Self {
734 let mut result = Self::new();
735 result.set_mac_address(item.mac_address);
736 result.set_status(item.status.into());
737 result.set_nlos(item.nlos.into());
738 result.set_distance(item.distance.into());
739 result.set_aoa_azimuth(item.aoa_azimuth.into());
740 result.set_aoa_azimuth_fom(item.aoa_azimuth_fom.into());
741 result.set_aoa_elevation(item.aoa_elevation.into());
742 result.set_aoa_elevation_fom(item.aoa_elevation_fom.into());
743 result.set_aoa_destination_azimuth(item.aoa_destination_azimuth.into());
744 result.set_aoa_destination_azimuth_fom(item.aoa_destination_azimuth_fom.into());
745 result.set_aoa_destination_elevation(item.aoa_destination_elevation.into());
746 result.set_aoa_destination_elevation_fom(item.aoa_destination_elevation_fom.into());
747 result.set_slot_index(item.slot_index.into());
748 result.set_rssi(item.rssi.into());
749 result
750 }
751 }
752
753 impl From<ShortAddressOwrAoaRangingMeasurement> for ProtoOwrAoaRangingMeasurement {
from(item: ShortAddressOwrAoaRangingMeasurement) -> Self754 fn from(item: ShortAddressOwrAoaRangingMeasurement) -> Self {
755 let mut result = Self::new();
756 result.set_mac_address(item.mac_address.into());
757 result.set_status(item.status.into());
758 result.set_nlos(item.nlos.into());
759 result.set_block_index(item.block_index.into());
760 result.set_frame_sequence_number(item.frame_sequence_number.into());
761 result.set_aoa_azimuth(item.aoa_azimuth.into());
762 result.set_aoa_azimuth_fom(item.aoa_azimuth_fom.into());
763 result.set_aoa_elevation(item.aoa_elevation.into());
764 result.set_aoa_elevation_fom(item.aoa_elevation_fom.into());
765 result
766 }
767 }
768
769 impl From<ExtendedAddressOwrAoaRangingMeasurement> for ProtoOwrAoaRangingMeasurement {
from(item: ExtendedAddressOwrAoaRangingMeasurement) -> Self770 fn from(item: ExtendedAddressOwrAoaRangingMeasurement) -> Self {
771 let mut result = Self::new();
772 result.set_mac_address(item.mac_address);
773 result.set_status(item.status.into());
774 result.set_nlos(item.nlos.into());
775 result.set_block_index(item.block_index.into());
776 result.set_frame_sequence_number(item.frame_sequence_number.into());
777 result.set_aoa_azimuth(item.aoa_azimuth.into());
778 result.set_aoa_azimuth_fom(item.aoa_azimuth_fom.into());
779 result.set_aoa_elevation(item.aoa_elevation.into());
780 result.set_aoa_elevation_fom(item.aoa_elevation_fom.into());
781 result
782 }
783 }
784
785 impl From<ShortAddressDlTdoaRangingMeasurement> for ProtoDlTDoARangingMeasurement {
from(item: ShortAddressDlTdoaRangingMeasurement) -> Self786 fn from(item: ShortAddressDlTdoaRangingMeasurement) -> Self {
787 let mut result = Self::new();
788 result.set_mac_address(item.mac_address.into());
789 result.set_status(
790 StatusCode::try_from(item.measurement.status)
791 .unwrap_or(StatusCode::UciStatusFailed)
792 .into(),
793 );
794 result.set_message_control(item.measurement.message_control.into());
795 result.set_block_index(item.measurement.block_index.into());
796 result.set_round_index(item.measurement.round_index.into());
797 result.set_nlos(item.measurement.nlos.into());
798 result.set_aoa_azimuth(item.measurement.aoa_azimuth.into());
799 result.set_aoa_azimuth_fom(item.measurement.aoa_azimuth_fom.into());
800 result.set_aoa_elevation(item.measurement.aoa_elevation.into());
801 result.set_aoa_elevation_fom(item.measurement.aoa_elevation_fom.into());
802 result.set_rssi(item.measurement.rssi.into());
803 result.set_tx_timestamp(item.measurement.tx_timestamp);
804 result.set_rx_timestamp(item.measurement.rx_timestamp);
805 result.set_anchor_cfo(item.measurement.anchor_cfo.into());
806 result.set_cfo(item.measurement.cfo.into());
807 result.set_initiator_reply_time(item.measurement.initiator_reply_time);
808 result.set_responder_reply_time(item.measurement.responder_reply_time);
809 result.set_initiator_responder_tof(item.measurement.initiator_responder_tof.into());
810 result.set_dt_anchor_location(
811 item.measurement
812 .dt_anchor_location
813 .into_iter()
814 .map(|val| val as u32)
815 .collect::<Vec<u32>>(),
816 );
817 result.set_ranging_rounds(
818 item.measurement.ranging_rounds.into_iter().map(|val| val as u32).collect::<Vec<u32>>(),
819 );
820 result
821 }
822 }
823
824 impl From<ExtendedAddressDlTdoaRangingMeasurement> for ProtoDlTDoARangingMeasurement {
from(item: ExtendedAddressDlTdoaRangingMeasurement) -> Self825 fn from(item: ExtendedAddressDlTdoaRangingMeasurement) -> Self {
826 let mut result = Self::new();
827 result.set_mac_address(item.mac_address);
828 result.set_status(
829 StatusCode::try_from(item.measurement.status)
830 .unwrap_or(StatusCode::UciStatusFailed)
831 .into(),
832 );
833 result.set_message_control(item.measurement.message_control.into());
834 result.set_block_index(item.measurement.block_index.into());
835 result.set_round_index(item.measurement.round_index.into());
836 result.set_nlos(item.measurement.nlos.into());
837 result.set_aoa_azimuth(item.measurement.aoa_azimuth.into());
838 result.set_aoa_azimuth_fom(item.measurement.aoa_azimuth_fom.into());
839 result.set_aoa_elevation(item.measurement.aoa_elevation.into());
840 result.set_aoa_elevation_fom(item.measurement.aoa_elevation_fom.into());
841 result.set_rssi(item.measurement.rssi.into());
842 result.set_tx_timestamp(item.measurement.tx_timestamp);
843 result.set_rx_timestamp(item.measurement.rx_timestamp);
844 result.set_anchor_cfo(item.measurement.anchor_cfo.into());
845 result.set_cfo(item.measurement.cfo.into());
846 result.set_initiator_reply_time(item.measurement.initiator_reply_time);
847 result.set_responder_reply_time(item.measurement.responder_reply_time);
848 result.set_initiator_responder_tof(item.measurement.initiator_responder_tof.into());
849 result.set_dt_anchor_location(
850 item.measurement
851 .dt_anchor_location
852 .into_iter()
853 .map(|val| val as u32)
854 .collect::<Vec<u32>>(),
855 );
856 result.set_ranging_rounds(
857 item.measurement.ranging_rounds.into_iter().map(|val| val as u32).collect::<Vec<u32>>(),
858 );
859 result
860 }
861 }
862
863 impl From<SessionRangeData> for ProtoSessionRangeData {
from(item: SessionRangeData) -> Self864 fn from(item: SessionRangeData) -> Self {
865 let mut result = Self::new();
866 result.set_sequence_number(item.sequence_number);
867 result.set_session_id(item.session_token);
868 result.set_current_ranging_interval_ms(item.current_ranging_interval_ms);
869 result.set_ranging_measurement_type(item.ranging_measurement_type.into());
870 match to_proto_ranging_measurements(item.ranging_measurements) {
871 ProtoRangingMeasurements::TwoWay(twoway_measurements) => {
872 result.set_twoway_ranging_measurements(RepeatedField::from_vec(twoway_measurements))
873 }
874 ProtoRangingMeasurements::OwrAoa(owraoa_measurement) => {
875 result.set_owraoa_ranging_measurement(owraoa_measurement)
876 }
877 ProtoRangingMeasurements::DlTDoa(dltdoa_measurements) => {
878 result.set_dltdoa_ranging_measurements(RepeatedField::from_vec(dltdoa_measurements))
879 }
880 }
881 result
882 }
883 }
884
to_proto_ranging_measurements(item: RangingMeasurements) -> ProtoRangingMeasurements885 fn to_proto_ranging_measurements(item: RangingMeasurements) -> ProtoRangingMeasurements {
886 match item {
887 RangingMeasurements::ShortAddressTwoWay(arr) => {
888 ProtoRangingMeasurements::TwoWay(arr.into_iter().map(|item| item.into()).collect())
889 }
890 RangingMeasurements::ExtendedAddressTwoWay(arr) => {
891 ProtoRangingMeasurements::TwoWay(arr.into_iter().map(|item| item.into()).collect())
892 }
893 RangingMeasurements::ShortAddressOwrAoa(r) => ProtoRangingMeasurements::OwrAoa(r.into()),
894 RangingMeasurements::ExtendedAddressOwrAoa(r) => ProtoRangingMeasurements::OwrAoa(r.into()),
895 RangingMeasurements::ShortAddressDltdoa(arr) => {
896 ProtoRangingMeasurements::DlTDoa(arr.into_iter().map(|item| item.into()).collect())
897 }
898 RangingMeasurements::ExtendedAddressDltdoa(arr) => {
899 ProtoRangingMeasurements::DlTDoa(arr.into_iter().map(|item| item.into()).collect())
900 }
901 }
902 }
903
904 impl From<ProtoRangingRoundControl> for RangingRoundControl {
from(item: ProtoRangingRoundControl) -> Self905 fn from(item: ProtoRangingRoundControl) -> Self {
906 Self {
907 ranging_result_report_message: item.ranging_result_report_message,
908 control_message: item.control_message,
909 measurement_report_message: item.measurement_report_message,
910 }
911 }
912 }
913
914 impl From<RangingRoundControl> for ProtoRangingRoundControl {
from(item: RangingRoundControl) -> Self915 fn from(item: RangingRoundControl) -> Self {
916 let mut res = Self::new();
917 res.set_ranging_result_report_message(item.ranging_result_report_message);
918 res.set_control_message(item.control_message);
919 res.set_measurement_report_message(item.measurement_report_message);
920 res
921 }
922 }
923
924 impl From<ProtoResultReportConfig> for ResultReportConfig {
from(item: ProtoResultReportConfig) -> Self925 fn from(item: ProtoResultReportConfig) -> Self {
926 Self {
927 tof: item.tof,
928 aoa_azimuth: item.aoa_azimuth,
929 aoa_elevation: item.aoa_elevation,
930 aoa_fom: item.aoa_fom,
931 }
932 }
933 }
934
935 impl From<ResultReportConfig> for ProtoResultReportConfig {
from(item: ResultReportConfig) -> Self936 fn from(item: ResultReportConfig) -> Self {
937 let mut res = Self::new();
938 res.set_tof(item.tof);
939 res.set_aoa_azimuth(item.aoa_azimuth);
940 res.set_aoa_elevation(item.aoa_elevation);
941 res.set_aoa_fom(item.aoa_fom);
942 res
943 }
944 }
945
to_uwb_address(bytes: Vec<u8>, mode: ProtoMacAddressMode) -> Option<UwbAddress>946 fn to_uwb_address(bytes: Vec<u8>, mode: ProtoMacAddressMode) -> Option<UwbAddress> {
947 match mode {
948 ProtoMacAddressMode::MAC_ADDRESS_2_BYTES
949 | ProtoMacAddressMode::MAC_ADDRESS_8_BYTES_2_BYTES_HEADER => {
950 Some(UwbAddress::Short(bytes.try_into().ok()?))
951 }
952 ProtoMacAddressMode::MAC_ADDRESS_8_BYTES => {
953 Some(UwbAddress::Extended(bytes.try_into().ok()?))
954 }
955 }
956 }
957
958 impl TryFrom<ProtoControlee> for Controlee {
959 type Error = String;
try_from(item: ProtoControlee) -> std::result::Result<Self, Self::Error>960 fn try_from(item: ProtoControlee) -> std::result::Result<Self, Self::Error> {
961 Ok(Self {
962 short_address: item.short_address.to_ne_bytes()[0..2]
963 .try_into()
964 .map_err(|_| "Failed to convert short_address")?,
965 subsession_id: item.subsession_id,
966 })
967 }
968 }
969
970 impl From<PowerStats> for ProtoPowerStats {
from(item: PowerStats) -> Self971 fn from(item: PowerStats) -> Self {
972 let mut res = Self::new();
973 res.set_status(item.status.into());
974 res.set_idle_time_ms(item.idle_time_ms);
975 res.set_tx_time_ms(item.tx_time_ms);
976 res.set_rx_time_ms(item.rx_time_ms);
977 res.set_total_wake_count(item.total_wake_count);
978 res
979 }
980 }
981
982 impl From<FiraAppConfigParams> for ProtoFiraAppConfigParams {
from(item: FiraAppConfigParams) -> Self983 fn from(item: FiraAppConfigParams) -> Self {
984 let mut res = Self::new();
985 res.set_device_type((*item.device_type()).into());
986 res.set_ranging_round_usage((*item.ranging_round_usage()).into());
987 res.set_sts_config((*item.sts_config()).into());
988 res.set_multi_node_mode((*item.multi_node_mode()).into());
989 res.set_channel_number((*item.channel_number()).into());
990 res.set_device_mac_address(item.device_mac_address().clone().into());
991 res.set_dst_mac_address(
992 item.dst_mac_address()
993 .clone()
994 .into_iter()
995 .map(|addr| addr.into())
996 .collect::<Vec<_>>()
997 .into(),
998 );
999 res.set_slot_duration_rstu((*item.slot_duration_rstu()).into());
1000 res.set_ranging_interval_ms(*item.ranging_interval_ms());
1001 res.set_mac_fcs_type((*item.mac_fcs_type()).into());
1002 res.set_ranging_round_control(item.ranging_round_control().clone().into());
1003 res.set_aoa_result_request((*item.aoa_result_request()).into());
1004 res.set_range_data_ntf_config((*item.range_data_ntf_config()).into());
1005 res.set_range_data_ntf_proximity_near_cm((*item.range_data_ntf_proximity_near_cm()).into());
1006 res.set_range_data_ntf_proximity_far_cm((*item.range_data_ntf_proximity_far_cm()).into());
1007 res.set_device_role((*item.device_role()).into());
1008 res.set_rframe_config((*item.rframe_config()).into());
1009 res.set_preamble_code_index((*item.preamble_code_index()).into());
1010 res.set_sfd_id((*item.sfd_id()).into());
1011 res.set_psdu_data_rate((*item.psdu_data_rate()).into());
1012 res.set_preamble_duration((*item.preamble_duration()).into());
1013 res.set_ranging_time_struct((*item.ranging_time_struct()).into());
1014 res.set_slots_per_rr((*item.slots_per_rr()).into());
1015 res.set_tx_adaptive_payload_power((*item.tx_adaptive_payload_power()).into());
1016 res.set_responder_slot_index((*item.responder_slot_index()).into());
1017 res.set_prf_mode((*item.prf_mode()).into());
1018 res.set_scheduled_mode((*item.scheduled_mode()).into());
1019 res.set_key_rotation((*item.key_rotation()).into());
1020 res.set_key_rotation_rate((*item.key_rotation_rate()).into());
1021 res.set_session_priority((*item.session_priority()).into());
1022 res.set_mac_address_mode((*item.mac_address_mode()).into());
1023 res.set_vendor_id((*item.vendor_id()).into());
1024 res.set_static_sts_iv((*item.static_sts_iv()).into());
1025 res.set_number_of_sts_segments((*item.number_of_sts_segments()).into());
1026 res.set_max_rr_retry((*item.max_rr_retry()).into());
1027 res.set_uwb_initiation_time_ms(*item.uwb_initiation_time_ms());
1028 res.set_hopping_mode((*item.hopping_mode()).into());
1029 res.set_block_stride_length((*item.block_stride_length()).into());
1030 res.set_result_report_config(item.result_report_config().clone().into());
1031 res.set_in_band_termination_attempt_count(
1032 (*item.in_band_termination_attempt_count()).into(),
1033 );
1034 res.set_sub_session_id(*item.sub_session_id());
1035 res.set_bprf_phr_data_rate((*item.bprf_phr_data_rate()).into());
1036 res.set_max_number_of_measurements((*item.max_number_of_measurements()).into());
1037 res.set_sts_length((*item.sts_length()).into());
1038 res.set_number_of_range_measurements((*item.number_of_range_measurements()).into());
1039 res.set_number_of_aoa_azimuth_measurements(
1040 (*item.number_of_aoa_azimuth_measurements()).into(),
1041 );
1042 res.set_number_of_aoa_elevation_measurements(
1043 (*item.number_of_aoa_elevation_measurements()).into(),
1044 );
1045
1046 res
1047 }
1048 }
1049
1050 impl TryFrom<ProtoFiraAppConfigParams> for AppConfigParams {
1051 type Error = String;
try_from(mut item: ProtoFiraAppConfigParams) -> std::result::Result<Self, Self::Error>1052 fn try_from(mut item: ProtoFiraAppConfigParams) -> std::result::Result<Self, Self::Error> {
1053 let device_mac_address =
1054 to_uwb_address(item.device_mac_address.clone(), item.mac_address_mode)
1055 .ok_or("Failed to convert device_mac_address")?;
1056 let mut dst_mac_address = vec![];
1057 for addr in item.dst_mac_address.clone().into_iter() {
1058 let addr = to_uwb_address(addr, item.mac_address_mode)
1059 .ok_or("Failed to convert dst_mac_address")?;
1060 dst_mac_address.push(addr);
1061 }
1062
1063 let mut builder = FiraAppConfigParamsBuilder::new();
1064 builder
1065 .device_type(item.device_type.into())
1066 .ranging_round_usage(item.ranging_round_usage.into())
1067 .sts_config(item.sts_config.into())
1068 .multi_node_mode(item.multi_node_mode.into())
1069 .channel_number(item.channel_number.into())
1070 .device_mac_address(device_mac_address)
1071 .dst_mac_address(dst_mac_address)
1072 .slot_duration_rstu(
1073 item.slot_duration_rstu
1074 .try_into()
1075 .map_err(|_| "Failed to convert slot_duration_rstu")?,
1076 )
1077 .ranging_interval_ms(item.ranging_interval_ms)
1078 .mac_fcs_type(item.mac_fcs_type.into())
1079 .ranging_round_control(
1080 item.ranging_round_control.take().ok_or("ranging_round_control is empty")?.into(),
1081 )
1082 .aoa_result_request(item.aoa_result_request.into())
1083 .range_data_ntf_config(item.range_data_ntf_config.into())
1084 .range_data_ntf_proximity_near_cm(
1085 item.range_data_ntf_proximity_near_cm
1086 .try_into()
1087 .map_err(|_| "Failed to convert range_data_ntf_proximity_near_cm")?,
1088 )
1089 .range_data_ntf_proximity_far_cm(
1090 item.range_data_ntf_proximity_far_cm
1091 .try_into()
1092 .map_err(|_| "Failed to convert range_data_ntf_proximity_far_cm")?,
1093 )
1094 .device_role(item.device_role.into())
1095 .rframe_config(item.rframe_config.into())
1096 .preamble_code_index(
1097 item.preamble_code_index
1098 .try_into()
1099 .map_err(|_| "Failed to convert preamble_code_index")?,
1100 )
1101 .sfd_id(item.sfd_id.try_into().map_err(|_| "Failed to convert sfd_id")?)
1102 .psdu_data_rate(item.psdu_data_rate.into())
1103 .preamble_duration(item.preamble_duration.into())
1104 .ranging_time_struct(item.ranging_time_struct.into())
1105 .slots_per_rr(
1106 item.slots_per_rr.try_into().map_err(|_| "Failed to convert slots_per_rr")?,
1107 )
1108 .tx_adaptive_payload_power(item.tx_adaptive_payload_power.into())
1109 .responder_slot_index(
1110 item.responder_slot_index
1111 .try_into()
1112 .map_err(|_| "Failed to convert responder_slot_index")?,
1113 )
1114 .prf_mode(item.prf_mode.into())
1115 .scheduled_mode(item.scheduled_mode.into())
1116 .key_rotation(item.key_rotation.into())
1117 .key_rotation_rate(
1118 item.key_rotation_rate
1119 .try_into()
1120 .map_err(|_| "Failed to convert key_rotation_rate")?,
1121 )
1122 .session_priority(
1123 item.session_priority
1124 .try_into()
1125 .map_err(|_| "Failed to convert session_priority")?,
1126 )
1127 .mac_address_mode(item.mac_address_mode.into())
1128 .vendor_id(
1129 item.vendor_id.clone().try_into().map_err(|_| "Failed to convert vendor_id")?,
1130 )
1131 .static_sts_iv(
1132 item.static_sts_iv
1133 .clone()
1134 .try_into()
1135 .map_err(|_| "Failed to convert static_sts_iv")?,
1136 )
1137 .number_of_sts_segments(
1138 item.number_of_sts_segments
1139 .try_into()
1140 .map_err(|_| "Failed to convert number_of_sts_segments")?,
1141 )
1142 .max_rr_retry(
1143 item.max_rr_retry.try_into().map_err(|_| "Failed to convert max_rr_retry")?,
1144 )
1145 .uwb_initiation_time_ms(item.uwb_initiation_time_ms)
1146 .hopping_mode(item.hopping_mode.into())
1147 .block_stride_length(
1148 item.block_stride_length
1149 .try_into()
1150 .map_err(|_| "Failed to convert block_stride_length")?,
1151 )
1152 .result_report_config(
1153 item.result_report_config.take().ok_or("ranging_round_control is empty")?.into(),
1154 )
1155 .in_band_termination_attempt_count(
1156 item.in_band_termination_attempt_count
1157 .try_into()
1158 .map_err(|_| "Failed to convert in_band_termination_attempt_count")?,
1159 )
1160 .sub_session_id(item.sub_session_id)
1161 .bprf_phr_data_rate(item.bprf_phr_data_rate.into())
1162 .max_number_of_measurements(
1163 item.max_number_of_measurements
1164 .try_into()
1165 .map_err(|_| "Failed to convert max_number_of_measurements")?,
1166 )
1167 .sts_length(item.sts_length.into())
1168 .number_of_range_measurements(
1169 item.number_of_range_measurements
1170 .try_into()
1171 .map_err(|_| "Failed to convert number_of_range_measurements")?,
1172 )
1173 .number_of_aoa_azimuth_measurements(
1174 item.number_of_aoa_azimuth_measurements
1175 .try_into()
1176 .map_err(|_| "Failed to convert number_of_aoa_azimuth_measurements")?,
1177 )
1178 .number_of_aoa_elevation_measurements(
1179 item.number_of_aoa_elevation_measurements
1180 .try_into()
1181 .map_err(|_| "Failed to convert number_of_aoa_elevation_measurements")?,
1182 );
1183
1184 Ok(builder.build().ok_or("Failed to build FiraAppConfigParam from builder")?)
1185 }
1186 }
1187
1188 impl Drop for ProtoFiraAppConfigParams {
drop(&mut self)1189 fn drop(&mut self) {
1190 // Zero out the sensitive data before releasing memory.
1191 self.vendor_id.zeroize();
1192 self.static_sts_iv.zeroize();
1193 self.sub_session_id.zeroize();
1194 }
1195 }
1196