• 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 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