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