1"""Class for UWB ranging parameters."""
2
3import dataclasses
4from typing import Any, Dict, List, Optional
5
6
7class FiraParamEnums:
8  """Class for Fira parameter constants."""
9
10  # channels
11  UWB_CHANNEL_5 = 5
12  UWB_CHANNEL_9 = 9
13
14  # preamble codes
15  UWB_PREAMBLE_CODE_INDEX_9 = 9
16  UWB_PREAMBLE_CODE_INDEX_10 = 10
17  UWB_PREAMBLE_CODE_INDEX_11 = 11
18  UWB_PREAMBLE_CODE_INDEX_12 = 12
19
20  # ranging device types
21  DEVICE_TYPE_CONTROLEE = 0
22  DEVICE_TYPE_CONTROLLER = 1
23
24  # ranging device roles
25  DEVICE_ROLE_RESPONDER = 0
26  DEVICE_ROLE_INITIATOR = 1
27
28  # multi node modes
29  MULTI_NODE_MODE_UNICAST = 0
30  MULTI_NODE_MODE_ONE_TO_MANY = 1
31
32  # hopping modes
33  HOPPING_MODE_DISABLE = 0
34  HOPPING_MODE_FIRA_HOPPING_ENABLE = 1
35
36  # ranging round usage
37  RANGING_ROUND_USAGE_SS_TWR_DEFERRED_MODE = 1
38  RANGING_ROUND_USAGE_DS_TWR_DEFERRED_MODE = 2
39  RANGING_ROUND_USAGE_SS_TWR_NON_DEFERRED_MODE = 3
40  RANGING_ROUND_USAGE_DS_TWR_NON_DEFERRED_MODE = 4
41
42  # mac address mode
43  MAC_ADDRESS_MODE_2_BYTES = 0
44  MAC_ADDRESS_MODE_8_BYTES = 2
45
46  # initiation time in ms
47  INITIATION_TIME_MS = 0
48
49  # slot duration rstu
50  SLOT_DURATION_RSTU = 2400
51
52  # ranging interval ms
53  RANGING_INTERVAL_MS = 200
54
55  # slots per ranging round
56  SLOTS_PER_RR = 30
57
58  # in band termination attempt count
59  IN_BAND_TERMINATION_ATTEMPT_COUNT = 1
60
61  # aoa report request
62  AOA_RESULT_REQUEST_MODE_NO_AOA_REPORT = 0
63  AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS = 1
64
65  # ranging round retries
66  MAX_RANGING_ROUND_RETRIES = 0
67
68  # block stride
69  BLOCK_STRIDE_LENGTH = 0
70
71  # list update actions
72  MULTICAST_LIST_UPDATE_ACTION_ADD = 0
73  MULTICAST_LIST_UPDATE_ACTION_DELETE = 1
74  P_STS_MULTICAST_LIST_UPDATE_ACTION_ADD_16_BYTE = 2
75  P_STS_MULTICAST_LIST_UPDATE_ACTION_ADD_32_BYTE = 3
76
77  # sts config
78  STS_CONFIG_STATIC = 0
79  STS_CONFIG_PROVISIONED = 3
80  STS_CONFIG_PROVISIONED_FOR_CONTROLEE_INDIVIDUAL_KEY = 4
81
82
83@dataclasses.dataclass
84class UwbRangingReconfigureParams():
85  """Class for UWB ranging reconfigure parameters.
86
87  Attributes:
88    action: Type of reconfigure action.
89    address_list: new address list.
90    block_stride_length: block stride length
91    sub_session_id_list: provisioned sts sub session id list.
92    sub_session_key_list: provisioned sts sub session key list.
93  """
94  action: Optional[int] = None
95  address_list: Optional[List[List[int]]] = None
96  block_stride_length: Optional[int] = None
97  sub_session_id_list: Optional[List[int]] = None
98  sub_session_key_list: Optional[List[int]] = None
99
100  def to_dict(self) -> Dict[str, Any]:
101    """Returns UWB ranging reconfigure parameters in dictionary for sl4a.
102
103    Returns:
104      UWB ranging reconfigure parameters in dictionary.
105    """
106    reconfigure_params = {}
107    if self.address_list is not None:
108      reconfigure_params["action"] = self.action
109      reconfigure_params["addressList"] = self.address_list
110      if self.sub_session_id_list is not None:
111        reconfigure_params["subSessionIdList"] = self.sub_session_id_list
112      if self.sub_session_key_list is not None:
113        reconfigure_params["subSessionKeyList"] = self.sub_session_key_list
114    elif self.block_stride_length is not None:
115      reconfigure_params["blockStrideLength"] = self.block_stride_length
116    return reconfigure_params
117
118
119@dataclasses.dataclass
120class UwbRangingControleeParams():
121  """Class for UWB ranging controlee parameters.
122
123  Attributes:
124    action: Type of reconfigure action.
125    address_list: new address list.
126    sub_session_id_list: provisioned sts sub session id list.
127    sub_session_key_list: provisioned sts sub session key list.
128  """
129  action: Optional[int] = None
130  address_list: Optional[List[List[int]]] = None
131  sub_session_id_list: Optional[List[int]] = None
132  sub_session_key_list: Optional[List[int]] = None
133
134  def to_dict(self) -> Dict[str, Any]:
135    """Returns UWB ranging controlee parameters in dictionary for sl4a.
136
137    Returns:
138      UWB ranging controlee parameters in dictionary.
139    """
140    controlee_params = {}
141    if self.action is not None:
142      controlee_params["action"] = self.action
143    if self.address_list is not None:
144      controlee_params["addressList"] = self.address_list
145    if self.sub_session_id_list is not None:
146      controlee_params["subSessionIdList"] = self.sub_session_id_list
147    if self.sub_session_key_list is not None:
148      controlee_params["subSessionKeyList"] = self.sub_session_key_list
149    return controlee_params
150
151
152@dataclasses.dataclass
153class UwbRangingParams():
154  """Class for Uwb ranging parameters.
155
156  Attributes:
157    device_type: Type of ranging device - Controller or Controlee.
158    device_role: Role of ranging device - Initiator or Responder.
159    device_address: Address of the UWB device.
160    destination_addresses: List of UWB peer addresses.
161    channel: Channel for ranging. Possible values 5 or 9.
162    preamble: Preamble for ranging.
163    ranging_round_usage : Ranging Round Usage values.
164    hopping_mode : Hopping modes.
165    mac_address_mode : MAC address modes.
166    initiation_time_ms : Initiation Time in ms.
167    slot_duration_rstu : Slot duration RSTU.
168    ranging_interval_ms : Ranging interval in ms.
169    slots_per_ranging_round : Slots per Ranging Round.
170    in_band_termination_attempt_count : In Band Termination Attempt count.
171    aoa_result_request : AOA report request.
172    max_ranging_round_retries : Max Ranging round retries.
173    block_stride_length: Block Stride Length
174    session_id: Ranging session ID.
175    multi_node_mode: Ranging mode. Possible values 1 to 1 or 1 to many.
176    vendor_id: Ranging device vendor ID.
177    static_sts_iv: Static STS value.
178    sts_config: STS config.
179    session_key: Provisioned sts session key.
180    sub_session_id: Ranging sub session ID.
181    sub_session_key: Ranging sub session key.
182
183  Example:
184      An example of UWB ranging parameters passed to sl4a is below.
185
186      self.initiator_params = {
187        "sessionId": 10,
188        "deviceType": FiraParamEnums.RANGING_DEVICE_TYPE_CONTROLLER,
189        "deviceRole": FiraParamEnums.RANGING_DEVICE_ROLE_INITIATOR,
190        "multiNodeMode": FiraParamEnums.MULTI_NODE_MODE_ONE_TO_MANY,
191        "channel": FiraParamEnums.UWB_CHANNEL_9,
192        "deviceAddress": [1, 2],
193        "destinationAddresses": [[3, 4],],
194        "vendorId": [5, 6],
195        "staticStsIV": [5, 6, 7, 8, 9, 10],
196      }
197
198      The UwbRangingParams are passed to UwbManagerFacade#openRaningSession()
199      from the open_ranging() method as a JSONObject.
200      These are converted to FiraOpenSessionParams using
201      UwbManagerFacade#generateFiraOpenSessionParams().
202      If some of the values are skipped in the params, default values are used.
203      Please see com/google/uwb/support/fira/FiraParams.java for more details
204      on the default values.
205
206      If the passed params are invalid, then open_ranging() will fail.
207  """
208
209  device_type: int
210  device_role: int
211  device_address: List[int]
212  destination_addresses: List[List[int]]
213  session_id: int = 10
214  channel: int = FiraParamEnums.UWB_CHANNEL_9
215  preamble: int = FiraParamEnums.UWB_PREAMBLE_CODE_INDEX_10
216  multi_node_mode: int = FiraParamEnums.MULTI_NODE_MODE_ONE_TO_MANY
217  ranging_round_usage: int = (
218      FiraParamEnums.RANGING_ROUND_USAGE_DS_TWR_DEFERRED_MODE
219  )
220  mac_address_mode: int = FiraParamEnums.MAC_ADDRESS_MODE_2_BYTES
221  initiation_time_ms: int = FiraParamEnums.INITIATION_TIME_MS
222  slot_duration_rstu: int = FiraParamEnums.SLOT_DURATION_RSTU
223  ranging_interval_ms: int = FiraParamEnums.RANGING_INTERVAL_MS
224  slots_per_ranging_round: int = FiraParamEnums.SLOTS_PER_RR
225  in_band_termination_attempt_count: int = (
226      FiraParamEnums.IN_BAND_TERMINATION_ATTEMPT_COUNT
227  )
228  aoa_result_request: int = (
229      FiraParamEnums.AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS
230  )
231  hopping_mode: int = FiraParamEnums.HOPPING_MODE_FIRA_HOPPING_ENABLE
232  max_ranging_round_retries: int = FiraParamEnums.MAX_RANGING_ROUND_RETRIES
233  block_stride_length: int = FiraParamEnums.BLOCK_STRIDE_LENGTH
234  vendor_id: List[int] = dataclasses.field(default_factory=lambda: [5, 6])
235  static_sts_iv: List[int] = dataclasses.field(
236      default_factory=lambda: [5, 6, 7, 8, 9, 10])
237  sts_config: int = FiraParamEnums.STS_CONFIG_STATIC
238  session_key: List[int] = dataclasses.field(
239      default_factory=lambda: [1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 5, 4, 3, 2, 1]
240  )
241  sub_session_id: Optional[int] = None
242  sub_session_key: Optional[List[int]] = None
243
244  def to_dict(self) -> Dict[str, Any]:
245    """Returns UWB ranging parameters in dictionary for sl4a.
246
247    Returns:
248      UWB ranging parameters in dictionary.
249    """
250    dict = {
251        "deviceType": self.device_type,
252        "deviceRole": self.device_role,
253        "deviceAddress": self.device_address,
254        "destinationAddresses": self.destination_addresses,
255        "channel": self.channel,
256        "preamble": self.preamble,
257        "rangingRoundUsage": self.ranging_round_usage,
258        "macAddressMode": self.mac_address_mode,
259        "initiationTimeMs": self.initiation_time_ms,
260        "slotDurationRstu": self.slot_duration_rstu,
261        "slotsPerRangingRound": self.slots_per_ranging_round,
262        "rangingIntervalMs": self.ranging_interval_ms,
263        "hoppingMode": self.hopping_mode,
264        "maxRangingRoundRetries": self.max_ranging_round_retries,
265        "inBandTerminationAttemptCount": self.in_band_termination_attempt_count,
266        "aoaResultRequest": self.aoa_result_request,
267        "blockStrideLength": self.block_stride_length,
268        "sessionId": self.session_id,
269        "multiNodeMode": self.multi_node_mode,
270        "vendorId": self.vendor_id,
271        "staticStsIV": self.static_sts_iv,
272        "stsConfig": self.sts_config,
273        "sessionKey": self.session_key,
274    }
275    if self.sub_session_id is not None:
276      dict["subSessionId"] = self.sub_session_id
277    if self.sub_session_key is not None:
278      dict["subSessionKey"] = self.sub_session_key
279    return dict
280
281  def update(self, **kwargs: Any):
282    """Updates the UWB parameters with the new values.
283
284    Args:
285      **kwargs: uwb attributes with new values.
286    """
287    for key, value in kwargs.items():
288      if hasattr(self, key):
289        setattr(self, key, value)
290