• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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.android.server.uwb.pm;
18 
19 import android.annotation.NonNull;
20 import android.content.AttributionSource;
21 import android.content.Context;
22 import android.os.Handler;
23 import android.os.RemoteException;
24 import android.uwb.IUwbRangingCallbacks;
25 import android.uwb.SessionHandle;
26 import android.uwb.UwbAddress;
27 
28 import com.android.internal.util.State;
29 import com.android.internal.util.StateMachine;
30 import com.android.server.uwb.UwbInjector;
31 import com.android.server.uwb.UwbServiceCore;
32 import com.android.server.uwb.data.ServiceProfileData.ServiceProfileInfo;
33 import com.android.server.uwb.data.UwbConfig;
34 import com.android.server.uwb.secure.csml.CsmlUtil;
35 import com.android.server.uwb.secure.csml.SessionData;
36 
37 import com.google.uwb.support.fira.FiraOpenSessionParams;
38 import com.google.uwb.support.generic.GenericSpecificationParams;
39 
40 import java.util.ArrayList;
41 import java.util.List;
42 import java.util.Optional;
43 import java.util.UUID;
44 
45 /**
46  * Abstract class for session with profiles
47  */
48 public abstract class RangingSessionController extends StateMachine {
49     public static String TAG = "RangingSessionController";
50 
51     public SessionInfo mSessionInfo;
52     public Handler mHandler;
53     public UwbInjector mUwbInjector;
54     private GenericSpecificationParams mSpecificationParams;
55     protected boolean mVerboseLoggingEnabled = false;
56 
57     protected State mIdleState = null;
58     protected State mDiscoveryState = null;
59     protected State mTransportState = null;
60     protected State mSecureSessionState = null;
61     protected State mRangingState = null;
62     protected State mEndSessionState = null;
63 
64     public static final int SESSION_INITIALIZED = 1;
65     public static final int SESSION_START = 2;
66     public static final int SESSION_STOP = 3;
67 
68     public static final int DISCOVERY_INIT = 101;
69     public static final int DISCOVERY_STARTED = 102;
70     public static final int DISCOVERY_SUCCESS = 103;
71     public static final int DISCOVERY_ENDED = 104;
72     public static final int DISCOVERY_FAILED = 105;
73 
74     public static final int TRANSPORT_INIT = 201;
75     public static final int TRANSPORT_STARTED = 202;
76     public static final int TRANSPORT_COMPLETED = 203;
77     public static final int TRANSPORT_FAILURE = 204;
78 
79     public static final int SECURE_SESSION_INIT = 301;
80     public static final int SECURE_SESSION_ESTABLISHED = 302;
81     public static final int SECURE_SESSION_FAILURE = 303;
82 
83     public static final int RANGING_INIT = 401;
84     public static final int RANGING_OPENED = 402;
85     public static final int RANGING_STARTED = 403;
86     public static final int RANGING_FAILURE = 404;
87     public static final int RANGING_ENDED = 405;
88 
RangingSessionController(SessionHandle sessionHandle, AttributionSource attributionSource, Context context, UwbInjector uwbInjector, ServiceProfileInfo serviceProfileInfo, IUwbRangingCallbacks rangingCallbacks, Handler handler, String chipId)89     public RangingSessionController(SessionHandle sessionHandle,
90             AttributionSource attributionSource,
91             Context context,
92             UwbInjector uwbInjector,
93             ServiceProfileInfo serviceProfileInfo,
94             IUwbRangingCallbacks rangingCallbacks,
95             Handler handler,
96             String chipId) {
97         super("RangingSessionController", handler);
98 
99         mSessionInfo = new SessionInfo(attributionSource, sessionHandle,
100                 serviceProfileInfo, context, rangingCallbacks, chipId);
101 
102         mIdleState = getIdleState();
103         mDiscoveryState = getDiscoveryState();
104         mTransportState = getTransportState();
105         mSecureSessionState = getSecureState();
106         mRangingState = getRangingState();
107         mEndSessionState = getEndingState();
108 
109         mUwbInjector = uwbInjector;
110         mHandler = handler;
111 
112         addState(mIdleState);
113         addState(mDiscoveryState);
114         {
115             addState(mTransportState, mDiscoveryState);
116             {
117                 addState(mSecureSessionState, mTransportState);
118                 {
119                     addState(mRangingState, mSecureSessionState);
120                 }
121             }
122         }
123         addState(mEndSessionState);
124 
125         setInitialState(mIdleState);
126 
127         start();
128 
129         sendMessage(SESSION_INITIALIZED);
130     }
131 
132     /** States need to be implemented by profiles */
getIdleState()133     public abstract State getIdleState();
134 
getDiscoveryState()135     public abstract State getDiscoveryState();
136 
getTransportState()137     public abstract State getTransportState();
138 
getSecureState()139     public abstract State getSecureState();
140 
getRangingState()141     public abstract State getRangingState();
142 
getEndingState()143     public abstract State getEndingState();
144 
enableVerboseLogging(boolean verbose)145     public void enableVerboseLogging(boolean verbose) {
146         mVerboseLoggingEnabled = verbose;
147     }
148 
startSession()149     public void startSession() {
150         sendMessage(SESSION_START);
151     }
152 
stopSession()153     public void stopSession() {
154         sendMessage(SESSION_STOP);
155     }
156 
closeSession()157     public void closeSession() {
158         sendMessage(RANGING_ENDED);
159     }
160 
getUwbConfig()161     public abstract UwbConfig getUwbConfig();
162 
openRangingSession()163     public void openRangingSession() throws RemoteException {
164 
165         FiraOpenSessionParams firaOpenSessionParams =
166                 UwbConfig.getOpenSessionParams(mSessionInfo, getUwbConfig());
167 
168         UwbServiceCore uwbServiceCore = mUwbInjector.getUwbServiceCore();
169 
170         uwbServiceCore.openRanging(
171                 mSessionInfo.mAttributionSource,
172                 mSessionInfo.mSessionHandle,
173                 mSessionInfo.mRangingCallbacks,
174                 firaOpenSessionParams.toBundle(),
175                 mUwbInjector.getMultichipData().getDefaultChipId()
176         );
177         sendMessage(RANGING_OPENED);
178     }
179 
startRanging()180     protected void startRanging() {
181         FiraOpenSessionParams firaOpenSessionParams =
182                 UwbConfig.getOpenSessionParams(mSessionInfo, getUwbConfig());
183         mUwbInjector.getUwbServiceCore().startRanging(mSessionInfo.mSessionHandle,
184                 firaOpenSessionParams.toBundle());
185         sendMessage(RANGING_STARTED);
186     }
187 
stopRanging()188     protected void stopRanging() {
189         mUwbInjector.getUwbServiceCore().stopRanging(mSessionInfo.mSessionHandle);
190     }
191 
closeRanging()192     protected void closeRanging() {
193         mUwbInjector.getUwbServiceCore().closeRanging(mSessionInfo.mSessionHandle);
194     }
195 
getSpecificationInfo()196     protected GenericSpecificationParams getSpecificationInfo() {
197         if (mSpecificationParams == null) {
198             mSpecificationParams =
199                     mUwbInjector.getUwbServiceCore().getCachedSpecificationParams(
200                             mSessionInfo.mChipId);
201         }
202         return mSpecificationParams;
203     }
204 
205     /**
206      * Holds all session related information
207      */
208     public static class SessionInfo {
209         public final AttributionSource mAttributionSource;
210         public final SessionHandle mSessionHandle;
211         public final Context mContext;
212         public final UUID service_instance_id;
213         public ServiceProfileInfo mServiceProfileInfo;
214         private int mSessionId;
215         public IUwbRangingCallbacks mRangingCallbacks;
216         private UwbAddress mDeviceAddress;
217         public final List<UwbAddress> mDestAddressList;
218         public Optional<Integer> subSessionId;
219         public final String mChipId;
220         public SessionData mSessionData;
221         private Optional<byte[]> mSharedSessionKeyInfo = Optional.empty();
222 
SessionInfo(AttributionSource attributionSource, SessionHandle sessionHandle, ServiceProfileInfo serviceProfileInfo, Context context, IUwbRangingCallbacks rangingCallbacks, String chipId)223         public SessionInfo(AttributionSource attributionSource, SessionHandle sessionHandle,
224                 ServiceProfileInfo serviceProfileInfo,
225                 Context context,
226                 IUwbRangingCallbacks rangingCallbacks,
227                 String chipId) {
228             mAttributionSource = attributionSource;
229             mSessionHandle = sessionHandle;
230             service_instance_id = serviceProfileInfo.serviceInstanceID;
231             mServiceProfileInfo = serviceProfileInfo;
232             mContext = context;
233             mRangingCallbacks = rangingCallbacks;
234             mDestAddressList = new ArrayList<>();
235             subSessionId = Optional.empty();
236             mChipId = chipId;
237         }
238 
getSessionId()239         public int getSessionId() {
240             return mSessionId;
241         }
242 
getDeviceAddress()243         public UwbAddress getDeviceAddress() {
244             return mDeviceAddress;
245         }
246 
setSessionId(int sessionID)247         public void setSessionId(int sessionID) {
248             mSessionId = sessionID;
249         }
250 
setUwbAddress(UwbAddress uwbAddress)251         public void setUwbAddress(UwbAddress uwbAddress) {
252             mDeviceAddress = uwbAddress;
253         }
254 
setSubSessionId(int subSessionId)255         public void setSubSessionId(int subSessionId) {
256             this.subSessionId = Optional.of(subSessionId);
257         }
258 
259         /**  Gets the session key info, required for controller of multicast case. */
260         @NonNull
getSharedSessionKeyInfo()261         public byte[] getSharedSessionKeyInfo() {
262             if (mSharedSessionKeyInfo.isEmpty()) {
263                 // only set once, as it is shared by all sub sessions.
264                 mSharedSessionKeyInfo = Optional.of(CsmlUtil.generate256BitRandomKeyInfo());
265             }
266             return mSharedSessionKeyInfo.get();
267         }
268     }
269 }
270