1 /*
2  * Copyright 2020 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 android.uwb;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.content.AttributionSource;
22 import android.os.CancellationSignal;
23 import android.os.PersistableBundle;
24 import android.os.Process;
25 import android.os.RemoteException;
26 import android.util.Log;
27 
28 import java.util.Hashtable;
29 import java.util.List;
30 import java.util.concurrent.Executor;
31 
32 /**
33  * @hide
34  */
35 public class RangingManager extends android.uwb.IUwbRangingCallbacks.Stub {
36     private final String mTag = "Uwb.RangingManager[" + this + "]";
37 
38     private final IUwbAdapter mAdapter;
39     private final Hashtable<SessionHandle, RangingSession> mRangingSessionTable = new Hashtable<>();
40     private static int sNextSessionId = 1;
41 
RangingManager(IUwbAdapter adapter)42     public RangingManager(IUwbAdapter adapter) {
43         mAdapter = adapter;
44     }
45 
46     /**
47      * Open a new ranging session
48      *
49      * @param attributionSource Attribution source to use for the enforcement of
50      *                          {@link android.Manifest.permission#UWB_RANGING} runtime
51      *                          permission.
52      * @param params the parameters that define the ranging session
53      * @param executor {@link Executor} to run callbacks
54      * @param callbacks {@link RangingSession.Callback} to associate with the {@link RangingSession}
55      *                  that is being opened.
56      * @param chipId identifier of UWB chip to be used in ranging session, or {@code null} if
57      *                the default chip should be used
58      * @return a {@link CancellationSignal} that may be used to cancel the opening of the
59      *         {@link RangingSession}.
60      */
openSession(@onNull AttributionSource attributionSource, @NonNull PersistableBundle params, @NonNull Executor executor, @NonNull RangingSession.Callback callbacks, @Nullable String chipId)61     public CancellationSignal openSession(@NonNull AttributionSource attributionSource,
62             @NonNull PersistableBundle params,
63             @NonNull Executor executor,
64             @NonNull RangingSession.Callback callbacks,
65             @Nullable String chipId) {
66         if (chipId != null) {
67             try {
68                 List<String> validChipIds = mAdapter.getChipIds();
69                 if (!validChipIds.contains(chipId)) {
70                     throw new IllegalArgumentException("openSession - received invalid chipId: "
71                             + chipId);
72                 }
73             } catch (RemoteException e)  {
74                 e.rethrowFromSystemServer();
75             }
76         }
77 
78         synchronized (this) {
79             SessionHandle sessionHandle =
80                     new SessionHandle(sNextSessionId++, attributionSource, Process.myPid());
81             RangingSession session =
82                     new RangingSession(executor, callbacks, mAdapter, sessionHandle, chipId);
83             Log.v(mTag, "openSession - sessionHandle: " + sessionHandle);
84             mRangingSessionTable.put(sessionHandle, session);
85             try {
86                 mAdapter.openRanging(attributionSource,
87                         sessionHandle,
88                         this,
89                         params,
90                         chipId);
91             } catch (RemoteException e) {
92                 throw e.rethrowFromSystemServer();
93             }
94 
95             CancellationSignal cancellationSignal = new CancellationSignal();
96             cancellationSignal.setOnCancelListener(() -> session.close());
97             return cancellationSignal;
98         }
99     }
100 
hasSession(SessionHandle sessionHandle)101     private boolean hasSession(SessionHandle sessionHandle) {
102         return mRangingSessionTable.containsKey(sessionHandle);
103     }
104 
105     @Override
onRangingOpened(SessionHandle sessionHandle)106     public void onRangingOpened(SessionHandle sessionHandle) {
107         synchronized (this) {
108             if (!hasSession(sessionHandle)) {
109                 Log.w(mTag,
110                         "onRangingOpened - received unexpected SessionHandle: " + sessionHandle);
111                 return;
112             }
113 
114             RangingSession session = mRangingSessionTable.get(sessionHandle);
115             session.onRangingOpened();
116         }
117     }
118 
119     @Override
onRangingOpenFailed(SessionHandle sessionHandle, @RangingChangeReason int reason, PersistableBundle parameters)120     public void onRangingOpenFailed(SessionHandle sessionHandle, @RangingChangeReason int reason,
121             PersistableBundle parameters) {
122         synchronized (this) {
123             if (!hasSession(sessionHandle)) {
124                 Log.w(mTag,
125                         "onRangingOpenedFailed - received unexpected SessionHandle: "
126                                 + sessionHandle);
127                 return;
128             }
129 
130             RangingSession session = mRangingSessionTable.get(sessionHandle);
131             session.onRangingOpenFailed(convertToReason(reason), parameters);
132             mRangingSessionTable.remove(sessionHandle);
133         }
134     }
135 
136     @Override
onRangingReconfigured(SessionHandle sessionHandle, PersistableBundle parameters)137     public void onRangingReconfigured(SessionHandle sessionHandle, PersistableBundle parameters) {
138         synchronized (this) {
139             if (!hasSession(sessionHandle)) {
140                 Log.w(mTag,
141                         "onRangingReconfigured - received unexpected SessionHandle: "
142                                 + sessionHandle);
143                 return;
144             }
145 
146             RangingSession session = mRangingSessionTable.get(sessionHandle);
147             session.onRangingReconfigured(parameters);
148         }
149     }
150 
151     @Override
onRangingReconfigureFailed(SessionHandle sessionHandle, @RangingChangeReason int reason, PersistableBundle params)152     public void onRangingReconfigureFailed(SessionHandle sessionHandle,
153             @RangingChangeReason int reason, PersistableBundle params) {
154         synchronized (this) {
155             if (!hasSession(sessionHandle)) {
156                 Log.w(mTag, "onRangingReconfigureFailed - received unexpected SessionHandle: "
157                         + sessionHandle);
158                 return;
159             }
160 
161             RangingSession session = mRangingSessionTable.get(sessionHandle);
162             session.onRangingReconfigureFailed(convertToReason(reason), params);
163         }
164     }
165 
166 
167     @Override
onRangingStarted(SessionHandle sessionHandle, PersistableBundle parameters)168     public void onRangingStarted(SessionHandle sessionHandle, PersistableBundle parameters) {
169         synchronized (this) {
170             if (!hasSession(sessionHandle)) {
171                 Log.w(mTag,
172                         "onRangingStarted - received unexpected SessionHandle: " + sessionHandle);
173                 return;
174             }
175 
176             RangingSession session = mRangingSessionTable.get(sessionHandle);
177             session.onRangingStarted(parameters);
178         }
179     }
180 
181     @Override
onRangingStartFailed(SessionHandle sessionHandle, @RangingChangeReason int reason, PersistableBundle params)182     public void onRangingStartFailed(SessionHandle sessionHandle, @RangingChangeReason int reason,
183             PersistableBundle params) {
184         synchronized (this) {
185             if (!hasSession(sessionHandle)) {
186                 Log.w(mTag, "onRangingStartFailed - received unexpected SessionHandle: "
187                         + sessionHandle);
188                 return;
189             }
190 
191             RangingSession session = mRangingSessionTable.get(sessionHandle);
192             session.onRangingStartFailed(convertToReason(reason), params);
193         }
194     }
195 
196     @Override
onRangingStopped(SessionHandle sessionHandle, @RangingChangeReason int reason, PersistableBundle params)197     public void onRangingStopped(SessionHandle sessionHandle, @RangingChangeReason int reason,
198             PersistableBundle params) {
199         synchronized (this) {
200             if (!hasSession(sessionHandle)) {
201                 Log.w(mTag, "onRangingStopped - received unexpected SessionHandle: "
202                         + sessionHandle);
203                 return;
204             }
205 
206             RangingSession session = mRangingSessionTable.get(sessionHandle);
207             session.onRangingStopped(convertToReason(reason), params);
208         }
209     }
210 
211     @Override
onRangingStopFailed(SessionHandle sessionHandle, @RangingChangeReason int reason, PersistableBundle parameters)212     public void onRangingStopFailed(SessionHandle sessionHandle, @RangingChangeReason int reason,
213             PersistableBundle parameters) {
214         synchronized (this) {
215             if (!hasSession(sessionHandle)) {
216                 Log.w(mTag, "onRangingStopFailed - received unexpected SessionHandle: "
217                         + sessionHandle);
218                 return;
219             }
220 
221             RangingSession session = mRangingSessionTable.get(sessionHandle);
222             session.onRangingStopFailed(convertToReason(reason), parameters);
223         }
224     }
225 
226     @Override
onRangingClosed(SessionHandle sessionHandle, @RangingChangeReason int reason, PersistableBundle params)227     public void onRangingClosed(SessionHandle sessionHandle, @RangingChangeReason int reason,
228             PersistableBundle params) {
229         synchronized (this) {
230             if (!hasSession(sessionHandle)) {
231                 Log.w(mTag, "onRangingClosed - received unexpected SessionHandle: "
232                         + sessionHandle);
233                 return;
234             }
235 
236             RangingSession session = mRangingSessionTable.get(sessionHandle);
237             session.onRangingClosed(convertToReason(reason), params);
238             mRangingSessionTable.remove(sessionHandle);
239         }
240     }
241 
242     @Override
onRangingResult(SessionHandle sessionHandle, RangingReport result)243     public void onRangingResult(SessionHandle sessionHandle, RangingReport result) {
244         synchronized (this) {
245             if (!hasSession(sessionHandle)) {
246                 Log.w(mTag, "onRangingResult - received unexpected SessionHandle: "
247                         + sessionHandle);
248                 return;
249             }
250 
251             RangingSession session = mRangingSessionTable.get(sessionHandle);
252             session.onRangingResult(result);
253         }
254     }
255 
256     @Override
onControleeAdded(SessionHandle sessionHandle, PersistableBundle parameters)257     public void onControleeAdded(SessionHandle sessionHandle, PersistableBundle parameters) {
258         synchronized (this) {
259             if (!hasSession(sessionHandle)) {
260                 Log.w(mTag, "onControleeAdded - received unexpected SessionHandle: "
261                         + sessionHandle);
262                 return;
263             }
264 
265             RangingSession session = mRangingSessionTable.get(sessionHandle);
266             session.onControleeAdded(parameters);
267         }
268     }
269 
270     @Override
onControleeAddFailed(SessionHandle sessionHandle, @RangingChangeReason int reason, PersistableBundle parameters)271     public void onControleeAddFailed(SessionHandle sessionHandle, @RangingChangeReason int reason,
272             PersistableBundle parameters) {
273         synchronized (this) {
274             if (!hasSession(sessionHandle)) {
275                 Log.w(mTag, "onControleeAddFailed - received unexpected SessionHandle: "
276                         + sessionHandle);
277                 return;
278             }
279 
280             RangingSession session = mRangingSessionTable.get(sessionHandle);
281             session.onControleeAddFailed(reason, parameters);
282         }
283     }
284 
285     @Override
onControleeRemoved(SessionHandle sessionHandle, PersistableBundle parameters)286     public void onControleeRemoved(SessionHandle sessionHandle, PersistableBundle parameters) {
287         synchronized (this) {
288             if (!hasSession(sessionHandle)) {
289                 Log.w(mTag, "onControleeRemoved - received unexpected SessionHandle: "
290                         + sessionHandle);
291                 return;
292             }
293 
294             RangingSession session = mRangingSessionTable.get(sessionHandle);
295             session.onControleeRemoved(parameters);
296         }
297     }
298 
299     @Override
onControleeRemoveFailed(SessionHandle sessionHandle, @RangingChangeReason int reason, PersistableBundle parameters)300     public void onControleeRemoveFailed(SessionHandle sessionHandle,
301             @RangingChangeReason int reason, PersistableBundle parameters) {
302         synchronized (this) {
303             if (!hasSession(sessionHandle)) {
304                 Log.w(mTag, "onControleeRemoveFailed - received unexpected SessionHandle: "
305                         + sessionHandle);
306                 return;
307             }
308 
309             RangingSession session = mRangingSessionTable.get(sessionHandle);
310             session.onControleeRemoveFailed(reason, parameters);
311         }
312     }
313 
314     @Override
onRangingPaused(SessionHandle sessionHandle, PersistableBundle parameters)315     public void onRangingPaused(SessionHandle sessionHandle, PersistableBundle parameters) {
316         synchronized (this) {
317             if (!hasSession(sessionHandle)) {
318                 Log.w(mTag, "onRangingPaused - received unexpected SessionHandle: "
319                         + sessionHandle);
320                 return;
321             }
322 
323             RangingSession session = mRangingSessionTable.get(sessionHandle);
324             session.onRangingPaused(parameters);
325         }
326     }
327 
328     @Override
onRangingPauseFailed(SessionHandle sessionHandle, @RangingChangeReason int reason, PersistableBundle parameters)329     public void onRangingPauseFailed(SessionHandle sessionHandle, @RangingChangeReason int reason,
330             PersistableBundle parameters) {
331         synchronized (this) {
332             if (!hasSession(sessionHandle)) {
333                 Log.w(mTag, "onRangingPauseFailed - received unexpected SessionHandle: "
334                         + sessionHandle);
335                 return;
336             }
337 
338             RangingSession session = mRangingSessionTable.get(sessionHandle);
339             session.onRangingPauseFailed(reason, parameters);
340         }
341     }
342 
343     @Override
onRangingResumed(SessionHandle sessionHandle, PersistableBundle parameters)344     public void onRangingResumed(SessionHandle sessionHandle, PersistableBundle parameters) {
345         synchronized (this) {
346             if (!hasSession(sessionHandle)) {
347                 Log.w(mTag, "onRangingResumed - received unexpected SessionHandle: "
348                         + sessionHandle);
349                 return;
350             }
351 
352             RangingSession session = mRangingSessionTable.get(sessionHandle);
353             session.onRangingResumed(parameters);
354         }
355     }
356 
357     @Override
onRangingResumeFailed(SessionHandle sessionHandle, @RangingChangeReason int reason, PersistableBundle parameters)358     public void onRangingResumeFailed(SessionHandle sessionHandle, @RangingChangeReason int reason,
359             PersistableBundle parameters) {
360         synchronized (this) {
361             if (!hasSession(sessionHandle)) {
362                 Log.w(mTag, "onRangingResumeFailed - received unexpected SessionHandle: "
363                         + sessionHandle);
364                 return;
365             }
366 
367             RangingSession session = mRangingSessionTable.get(sessionHandle);
368             session.onRangingResumeFailed(reason, parameters);
369         }
370     }
371 
372     @Override
onDataSent(SessionHandle sessionHandle, UwbAddress remoteDeviceAddress, PersistableBundle parameters)373     public void onDataSent(SessionHandle sessionHandle, UwbAddress remoteDeviceAddress,
374             PersistableBundle parameters) {
375         synchronized (this) {
376             if (!hasSession(sessionHandle)) {
377                 Log.w(mTag, "onDataSent - received unexpected SessionHandle: " + sessionHandle);
378                 return;
379             }
380 
381             RangingSession session = mRangingSessionTable.get(sessionHandle);
382             session.onDataSent(remoteDeviceAddress, parameters);
383         }
384     }
385 
386     @Override
onDataSendFailed(SessionHandle sessionHandle, UwbAddress remoteDeviceAddress, @RangingChangeReason int reason, PersistableBundle parameters)387     public void onDataSendFailed(SessionHandle sessionHandle, UwbAddress remoteDeviceAddress,
388             @RangingChangeReason int reason, PersistableBundle parameters) {
389         synchronized (this) {
390             if (!hasSession(sessionHandle)) {
391                 Log.w(mTag, "onDataSendFailed - received unexpected SessionHandle: "
392                         + sessionHandle);
393                 return;
394             }
395 
396             RangingSession session = mRangingSessionTable.get(sessionHandle);
397             session.onDataSendFailed(remoteDeviceAddress, reason, parameters);
398         }
399     }
400 
401     @Override
onDataTransferPhaseConfigured(SessionHandle sessionHandle, PersistableBundle parameters)402     public void onDataTransferPhaseConfigured(SessionHandle sessionHandle,
403             PersistableBundle parameters) {
404         synchronized (this) {
405             if (!hasSession(sessionHandle)) {
406                 Log.w(mTag, "onDataTransferPhaseConfigured - received unexpected SessionHandle: "
407                         + sessionHandle);
408                 return;
409             }
410 
411             RangingSession session = mRangingSessionTable.get(sessionHandle);
412             session.onDataTransferPhaseConfigured(parameters);
413         }
414     }
415 
416     @Override
onDataTransferPhaseConfigFailed(SessionHandle sessionHandle, @RangingChangeReason int reason, PersistableBundle parameters)417     public void onDataTransferPhaseConfigFailed(SessionHandle sessionHandle,
418             @RangingChangeReason int reason, PersistableBundle parameters) {
419         synchronized (this) {
420             if (!hasSession(sessionHandle)) {
421                 Log.w(mTag, "onDataTransferPhaseConfigFailed - received unknown SessionHandle: "
422                         + sessionHandle);
423                 return;
424             }
425 
426             RangingSession session = mRangingSessionTable.get(sessionHandle);
427             session.onDataTransferPhaseConfigFailed(reason, parameters);
428         }
429     }
430 
431     @Override
onDataReceived(SessionHandle sessionHandle, UwbAddress remoteDeviceAddress, PersistableBundle parameters, byte[] data)432     public void onDataReceived(SessionHandle sessionHandle, UwbAddress remoteDeviceAddress,
433             PersistableBundle parameters, byte[] data) {
434         synchronized (this) {
435             if (!hasSession(sessionHandle)) {
436                 Log.w(mTag, "onDataReceived - received unexpected SessionHandle: "
437                         + sessionHandle);
438                 return;
439             }
440 
441             RangingSession session = mRangingSessionTable.get(sessionHandle);
442             session.onDataReceived(remoteDeviceAddress, parameters, data);
443         }
444     }
445 
446     @Override
onDataReceiveFailed(SessionHandle sessionHandle, UwbAddress remoteDeviceAddress, @RangingChangeReason int reason, PersistableBundle parameters)447     public void onDataReceiveFailed(SessionHandle sessionHandle, UwbAddress remoteDeviceAddress,
448             @RangingChangeReason int reason, PersistableBundle parameters) {
449         synchronized (this) {
450             if (!hasSession(sessionHandle)) {
451                 Log.w(mTag, "onDataReceiveFailed - received unexpected SessionHandle: "
452                         + sessionHandle);
453                 return;
454             }
455 
456             RangingSession session = mRangingSessionTable.get(sessionHandle);
457             session.onDataReceiveFailed(remoteDeviceAddress, reason, parameters);
458         }
459     }
460 
461     @Override
onServiceDiscovered(SessionHandle sessionHandle, @NonNull PersistableBundle parameters)462     public void onServiceDiscovered(SessionHandle sessionHandle,
463             @NonNull PersistableBundle parameters) {
464         synchronized (this) {
465             if (!hasSession(sessionHandle)) {
466                 Log.w(mTag, "onServiceDiscovered - received unexpected SessionHandle: "
467                         + sessionHandle);
468                 return;
469             }
470 
471             RangingSession session = mRangingSessionTable.get(sessionHandle);
472             session.onServiceDiscovered(parameters);
473         }
474     }
475 
476     @Override
onHybridSessionControllerConfigured(SessionHandle sessionHandle, PersistableBundle parameters)477     public void onHybridSessionControllerConfigured(SessionHandle sessionHandle,
478             PersistableBundle parameters) {
479         synchronized (this) {
480             if (!hasSession(sessionHandle)) {
481                 Log.w(mTag, "onHybridSessionControllerConfigured - received unexpected"
482                         + "SessionHandle: " + sessionHandle);
483                 return;
484             }
485 
486             RangingSession session = mRangingSessionTable.get(sessionHandle);
487             session.onHybridSessionControllerConfigured(parameters);
488         }
489     }
490 
491     @Override
onHybridSessionControllerConfigurationFailed(SessionHandle sessionHandle, @RangingChangeReason int reason, PersistableBundle parameters)492     public void onHybridSessionControllerConfigurationFailed(SessionHandle sessionHandle,
493             @RangingChangeReason int reason, PersistableBundle parameters) {
494         synchronized (this) {
495             if (!hasSession(sessionHandle)) {
496                 Log.w(mTag, "onHybridSessionControllerConfigurationFailed - received"
497                         + "unexpected SessionHandle: " + sessionHandle);
498                 return;
499             }
500 
501             RangingSession session = mRangingSessionTable.get(sessionHandle);
502             session.onHybridSessionControllerConfigurationFailed(reason, parameters);
503         }
504     }
505 
506     @Override
onHybridSessionControleeConfigured(SessionHandle sessionHandle, PersistableBundle parameters)507     public void onHybridSessionControleeConfigured(SessionHandle sessionHandle,
508             PersistableBundle parameters) {
509         synchronized (this) {
510             if (!hasSession(sessionHandle)) {
511                 Log.w(mTag, "onHybridSessionControleeConfigured - received unexpected"
512                         + "SessionHandle: " + sessionHandle);
513                 return;
514             }
515 
516             RangingSession session = mRangingSessionTable.get(sessionHandle);
517             session.onHybridSessionControleeConfigured(parameters);
518         }
519     }
520 
521     @Override
onHybridSessionControleeConfigurationFailed(SessionHandle sessionHandle, @RangingChangeReason int reason, PersistableBundle parameters)522     public void onHybridSessionControleeConfigurationFailed(SessionHandle sessionHandle,
523             @RangingChangeReason int reason, PersistableBundle parameters) {
524         synchronized (this) {
525             if (!hasSession(sessionHandle)) {
526                 Log.w(mTag, "onHybridSessionControleeConfigurationFailed - received"
527                         + "unexpected SessionHandle: " + sessionHandle);
528                 return;
529             }
530 
531             RangingSession session = mRangingSessionTable.get(sessionHandle);
532             session.onHybridSessionControleeConfigurationFailed(reason, parameters);
533         }
534     }
535 
536     @Override
onServiceConnected(SessionHandle sessionHandle, @NonNull PersistableBundle parameters)537     public void onServiceConnected(SessionHandle sessionHandle,
538             @NonNull PersistableBundle parameters) {
539         synchronized (this) {
540             if (!hasSession(sessionHandle)) {
541                 Log.w(mTag, "onServiceConnected - received unexpected SessionHandle: "
542                         + sessionHandle);
543                 return;
544             }
545 
546             RangingSession session = mRangingSessionTable.get(sessionHandle);
547             session.onServiceConnected(parameters);
548         }
549     }
550 
551     @Override
onRangingRoundsUpdateDtTagStatus(SessionHandle sessionHandle, @NonNull PersistableBundle parameters)552     public void onRangingRoundsUpdateDtTagStatus(SessionHandle sessionHandle,
553             @NonNull PersistableBundle parameters) {
554         synchronized (this) {
555             if (!hasSession(sessionHandle)) {
556                 Log.w(mTag, "onRangingRoundsUpdateDtTagStatus - received unexpected "
557                         + "SessionHandle: " + sessionHandle);
558                 return;
559             }
560 
561             RangingSession session = mRangingSessionTable.get(sessionHandle);
562             session.onRangingRoundsUpdateDtTagStatus(parameters);
563         }
564     }
565 
566     // TODO(b/211025367): Remove this conversion and use direct API values.
567     @RangingSession.Callback.Reason
convertToReason(@angingChangeReason int reason)568     private static int convertToReason(@RangingChangeReason int reason) {
569         switch (reason) {
570             case RangingChangeReason.LOCAL_API:
571                 return RangingSession.Callback.REASON_LOCAL_REQUEST;
572 
573             case RangingChangeReason.MAX_SESSIONS_REACHED:
574                 return RangingSession.Callback.REASON_MAX_SESSIONS_REACHED;
575 
576             case RangingChangeReason.SYSTEM_POLICY:
577                 return RangingSession.Callback.REASON_SYSTEM_POLICY;
578 
579             case RangingChangeReason.SYSTEM_REGULATION:
580                 return RangingSession.Callback.REASON_SYSTEM_REGULATION;
581 
582             case RangingChangeReason.REMOTE_REQUEST:
583                 return RangingSession.Callback.REASON_REMOTE_REQUEST;
584 
585             case RangingChangeReason.PROTOCOL_SPECIFIC:
586                 return RangingSession.Callback.REASON_PROTOCOL_SPECIFIC_ERROR;
587 
588             case RangingChangeReason.BAD_PARAMETERS:
589                 return RangingSession.Callback.REASON_BAD_PARAMETERS;
590 
591             case RangingChangeReason.MAX_RR_RETRY_REACHED:
592                 return RangingSession.Callback.REASON_MAX_RR_RETRY_REACHED;
593 
594             case RangingChangeReason.INSUFFICIENT_SLOTS_PER_RR:
595                 return RangingSession.Callback.REASON_INSUFFICIENT_SLOTS_PER_RR;
596 
597             case RangingChangeReason.INBAND_SESSION_STOP:
598                 return RangingSession.Callback.REASON_INBAND_SESSION_STOP;
599 
600             case RangingChangeReason.UNKNOWN:
601             default:
602                 return RangingSession.Callback.REASON_UNKNOWN;
603         }
604     }
605 }
606