• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.snippet.ranging;
18 
19 import static android.ranging.RangingPreference.DEVICE_ROLE_INITIATOR;
20 import static android.ranging.uwb.UwbComplexChannel.UWB_CHANNEL_9;
21 import static android.ranging.uwb.UwbComplexChannel.UWB_PREAMBLE_CODE_INDEX_11;
22 
23 import android.ranging.DataNotificationConfig;
24 import android.ranging.RangingConfig;
25 import android.ranging.RangingDevice;
26 import android.ranging.RangingPreference;
27 import android.ranging.SensorFusionParams;
28 import android.ranging.SessionConfig;
29 import android.ranging.ble.cs.BleCsRangingParams;
30 import android.ranging.ble.rssi.BleRssiRangingParams;
31 import android.ranging.oob.DeviceHandle;
32 import android.ranging.oob.OobInitiatorRangingConfig;
33 import android.ranging.oob.OobResponderRangingConfig;
34 import android.ranging.raw.RawInitiatorRangingConfig;
35 import android.ranging.raw.RawRangingDevice;
36 import android.ranging.raw.RawResponderRangingConfig;
37 import android.ranging.uwb.UwbAddress;
38 import android.ranging.uwb.UwbComplexChannel;
39 import android.ranging.uwb.UwbRangingParams;
40 import android.ranging.wifi.rtt.RttRangingParams;
41 
42 import com.google.android.mobly.snippet.SnippetObjectConverter;
43 
44 import org.json.JSONArray;
45 import org.json.JSONException;
46 import org.json.JSONObject;
47 
48 import java.lang.reflect.Type;
49 import java.time.Duration;
50 import java.util.UUID;
51 
52 public class RangingPreferenceConverter implements SnippetObjectConverter {
53 
54     RangingSnippet.OobTransportFactory mTransportHandleFactory;
55 
RangingPreferenceConverter(RangingSnippet.OobTransportFactory transportHandleFactory)56     RangingPreferenceConverter(RangingSnippet.OobTransportFactory transportHandleFactory) {
57         mTransportHandleFactory = transportHandleFactory;
58     }
59 
60     @Override
serialize(Object object)61     public JSONObject serialize(Object object) {
62         throw new UnsupportedOperationException("Not implemented");
63     }
64 
65     @Override
deserialize(JSONObject j, Type type)66     public RangingPreference deserialize(JSONObject j, Type type) throws JSONException {
67         if (type != RangingPreference.class) return null;
68 
69         return new RangingPreference.Builder(j.getInt("device_role"),
70                 getRangingParams(j.getJSONObject("ranging_params"), j.getInt("device_role")))
71                 .setSessionConfig(
72                         new SessionConfig.Builder()
73                                 .setSensorFusionParams(
74                                         getSensorFusionParams(
75                                                 j.getJSONObject("sensor_fusion_params"))
76                                 )
77                                 .setDataNotificationConfig(
78                                         getDataNotificationConfig(
79                                                 j.getBoolean("enable_range_data_notifications"))
80                                 )
81                                 .setRangingMeasurementsLimit(j.getInt("measurement_limit"))
82                                 .build()
83                 )
84                 .build();
85     }
86 
getRangingParams( JSONObject j, @RangingPreference.DeviceRole int role )87     private RangingConfig getRangingParams(
88             JSONObject j, @RangingPreference.DeviceRole int role
89     ) throws JSONException {
90         RangingConfig params;
91 
92         if (j.getInt("session_type") == RangingConfig.RANGING_SESSION_RAW) {
93             if (role == DEVICE_ROLE_INITIATOR) {
94                 params = getRawInitiatorRangingConfig(j);
95             } else {
96                 params = getRawResponderRangingConfig(j);
97             }
98         } else {
99             if (role == DEVICE_ROLE_INITIATOR) {
100                 params = getOobInitiatorRangingConfig(j);
101             } else {
102                 params = getOobResponderRangingConfig(j);
103             }
104         }
105 
106         return params;
107     }
108 
getOobInitiatorRangingConfig( JSONObject j )109     private OobInitiatorRangingConfig getOobInitiatorRangingConfig(
110             JSONObject j
111     ) throws JSONException {
112         OobInitiatorRangingConfig.Builder builder = new OobInitiatorRangingConfig.Builder();
113         JSONArray jPeers = j.getJSONArray("peer_ids");
114         for (int i = 0; i < jPeers.length(); i++) {
115             RangingDevice device = new RangingDevice.Builder()
116                     .setUuid(UUID.fromString(jPeers.getString(i)))
117                     .build();
118             builder.addDeviceHandle(new DeviceHandle.Builder(
119                     device,
120                     mTransportHandleFactory.createOobTransport(device)
121             ).build());
122         }
123         return builder
124                 .setFastestRangingInterval(
125                         Duration.ofMillis(j.getJSONArray("ranging_interval_ms").getInt(0)))
126                 .setSlowestRangingInterval(
127                         Duration.ofMillis(j.getJSONArray("ranging_interval_ms").getInt(1)))
128                 .setSecurityLevel(j.getInt("security_level"))
129                 .setRangingMode(j.getInt("ranging_mode"))
130                 .build();
131     }
132 
getOobResponderRangingConfig( JSONObject j )133     private OobResponderRangingConfig getOobResponderRangingConfig(
134             JSONObject j
135     ) throws JSONException {
136         RangingDevice device = new RangingDevice.Builder()
137                 .setUuid(UUID.fromString(j.getString("peer_id")))
138                 .build();
139         return new OobResponderRangingConfig.Builder(
140                 new DeviceHandle.Builder(
141                         device, mTransportHandleFactory.createOobTransport(device)).build())
142                 .build();
143     }
144 
getRawInitiatorRangingConfig( JSONObject j )145     private RawInitiatorRangingConfig getRawInitiatorRangingConfig(
146             JSONObject j
147     ) throws JSONException {
148         RawInitiatorRangingConfig.Builder builder = new RawInitiatorRangingConfig.Builder();
149         JSONArray jPeerParams = j.getJSONArray("peer_params");
150         for (int i = 0; i < jPeerParams.length(); i++) {
151             builder.addRawRangingDevice(getRawRangingDevice(jPeerParams.getJSONObject(i)));
152         }
153         return builder.build();
154     }
155 
getRawResponderRangingConfig( JSONObject j )156     private RawResponderRangingConfig getRawResponderRangingConfig(
157             JSONObject j
158     ) throws JSONException {
159         return new RawResponderRangingConfig.Builder()
160                 .setRawRangingDevice(getRawRangingDevice(j.getJSONObject("peer_params")))
161                 .build();
162     }
163 
getRawRangingDevice(JSONObject j)164     private RawRangingDevice getRawRangingDevice(JSONObject j) throws JSONException {
165         RawRangingDevice.Builder builder = new RawRangingDevice.Builder();
166         builder.setRangingDevice(
167                 new RangingDevice.Builder()
168                         .setUuid(UUID.fromString(j.getString("peer_id")))
169                         .build()
170         );
171         if (!j.isNull("uwb_params")) {
172             builder.setUwbRangingParams(getUwbParams(j.getJSONObject("uwb_params")));
173         }
174         if (!j.isNull("cs_params")) {
175             builder.setCsRangingParams(getCsParams(j.getJSONObject("cs_params")));
176         }
177         if (!j.isNull("rtt_params")) {
178             builder.setRttRangingParams(getRttParams(j.getJSONObject("rtt_params")));
179         }
180         if (!j.isNull("rssi_params")) {
181             builder.setBleRssiRangingParams(getBleRssiRangingParams(
182                     j.getJSONObject("rssi_params")));
183         }
184         return builder.build();
185     }
186 
getUwbParams(JSONObject j)187     private UwbRangingParams getUwbParams(JSONObject j) throws JSONException {
188         UwbRangingParams.Builder builder = new UwbRangingParams.Builder(
189                 j.getInt("session_id"),
190                 j.getInt("config_id"),
191                 UwbAddress.fromBytes(toBytes(j.getJSONArray("device_address"))),
192                 UwbAddress.fromBytes(toBytes(j.getJSONArray("peer_address")))
193         );
194 
195         builder.setSubSessionId(j.getInt("sub_session_id"))
196                 .setSessionKeyInfo(toBytes(j.getJSONArray("session_key_info")))
197                 .setComplexChannel(
198                         new UwbComplexChannel.Builder().setChannel(UWB_CHANNEL_9)
199                                 .setPreambleIndex(UWB_PREAMBLE_CODE_INDEX_11).build())
200                 .setRangingUpdateRate(j.getInt("ranging_update_rate"))
201                 .setSlotDuration(j.getInt("slot_duration_ms"));
202 
203         if (!j.isNull("sub_session_key_info")) {
204             builder.setSubSessionKeyInfo(toBytes(j.getJSONArray("sub_session_key_info")));
205         }
206         return builder.build();
207     }
208 
getRttParams(JSONObject j)209     private RttRangingParams getRttParams(JSONObject j) throws JSONException {
210         return new RttRangingParams.Builder(j.getString("service_name"))
211                 .setPeriodicRangingHwFeatureEnabled(
212                         j.getBoolean("enable_periodic_ranging_hw_feature"))
213                 .setRangingUpdateRate(j.getInt("ranging_update_rate"))
214                 .build();
215     }
216 
getBleRssiRangingParams(JSONObject j)217     private BleRssiRangingParams getBleRssiRangingParams(JSONObject j) throws JSONException {
218         return new BleRssiRangingParams.Builder(j.getString("peer_address"))
219                 .setRangingUpdateRate(j.getInt("ranging_update_rate"))
220                 .build();
221     }
222 
getCsParams(JSONObject j)223     private BleCsRangingParams getCsParams(JSONObject j) throws JSONException {
224         return new BleCsRangingParams.Builder(j.getString("peer_address"))
225                 .setRangingUpdateRate(j.getInt("ranging_update_rate"))
226                 .setSecurityLevel(j.getInt("security_level"))
227                 .build();
228     }
229 
getSensorFusionParams(JSONObject j)230     private SensorFusionParams getSensorFusionParams(JSONObject j) throws JSONException {
231         return new SensorFusionParams.Builder()
232                 .setSensorFusionEnabled(j.getBoolean("is_sensor_fusion_enabled"))
233                 .build();
234     }
235 
getDataNotificationConfig(boolean enableRangeDataNotifications)236     private DataNotificationConfig getDataNotificationConfig(boolean enableRangeDataNotifications) {
237         return new DataNotificationConfig.Builder()
238                 .setNotificationConfigType(
239                         enableRangeDataNotifications
240                                 ? DataNotificationConfig.NOTIFICATION_CONFIG_ENABLE
241                                 : DataNotificationConfig.NOTIFICATION_CONFIG_DISABLE
242                 )
243                 .build();
244     }
245 
toBytes(JSONArray jArray)246     private byte[] toBytes(JSONArray jArray) throws JSONException {
247         if (jArray == null) {
248             return null;
249         }
250         byte[] bArray = new byte[jArray.length()];
251         for (int i = 0; i < jArray.length(); i++) {
252             bArray[i] = (byte) jArray.getInt(i);
253         }
254         return bArray;
255     }
256 }
257