• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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.googlecode.android_scripting.facade.wifi;
18 
19 import android.app.Service;
20 import android.content.Context;
21 import android.net.wifi.RttManager;
22 import android.net.wifi.RttManager.ResponderCallback;
23 import android.net.wifi.RttManager.ResponderConfig;
24 import android.net.wifi.RttManager.RttCapabilities;
25 import android.net.wifi.RttManager.RttListener;
26 import android.net.wifi.RttManager.RttParams;
27 import android.net.wifi.RttManager.RttResult;
28 import android.os.Bundle;
29 import android.os.Parcelable;
30 
31 import com.googlecode.android_scripting.facade.EventFacade;
32 import com.googlecode.android_scripting.facade.FacadeManager;
33 import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
34 import com.googlecode.android_scripting.rpc.Rpc;
35 import com.googlecode.android_scripting.rpc.RpcParameter;
36 
37 import org.json.JSONArray;
38 import org.json.JSONException;
39 import org.json.JSONObject;
40 
41 import java.util.ArrayList;
42 import java.util.HashMap;
43 import java.util.Hashtable;
44 import java.util.Map;
45 
46 /**
47  * WifiRttManager functions.
48  */
49 public class WifiRttManagerFacade extends RpcReceiver {
50     private final Service mService;
51     private final RttManager mRtt;
52     private final EventFacade mEventFacade;
53     private final Map<Integer, RttListener> mRangingListeners;
54     private final Map<Integer, RttResponderCallback> mResponderCallbacks;
55 
WifiRttManagerFacade(FacadeManager manager)56     public WifiRttManagerFacade(FacadeManager manager) {
57         super(manager);
58         mService = manager.getService();
59         mRtt = (RttManager) mService.getSystemService(Context.WIFI_RTT_SERVICE);
60         mEventFacade = manager.getReceiver(EventFacade.class);
61         mRangingListeners = new Hashtable<Integer, RttListener>();
62         mResponderCallbacks = new HashMap<>();
63     }
64 
65     public static class RangingListener implements RttListener {
66         private static final String TAG = "WifiRttRanging";
67         private static int sCount = 0;
68         private final EventFacade mEventFacade;
69         public final int mId;
70 
RangingListener(EventFacade eventFacade)71         public RangingListener(EventFacade eventFacade) {
72             sCount += 1;
73             mId = sCount;
74             mEventFacade = eventFacade;
75         }
76 
packRttResult(RttResult result)77         public static Bundle packRttResult(RttResult result) {
78             Bundle rttResult = new Bundle();
79             rttResult.putString("BSSID", result.bssid);
80             rttResult.putInt("txRate", result.txRate);
81             rttResult.putInt("rxRate", result.rxRate);
82             rttResult.putInt("distance", result.distance);
83             rttResult.putInt("distanceStandardDeviation",
84                     result.distanceStandardDeviation);
85             rttResult.putInt("distanceSpread", result.distanceSpread);
86             rttResult.putInt("burstDuration", result.burstDuration);
87             rttResult.putLong("rtt", result.rtt);
88             rttResult.putLong("rttStandardDeviation",
89                     result.rttStandardDeviation);
90             rttResult.putLong("rttSpread", result.rttSpread);
91             rttResult.putLong("ts", result.ts);
92             rttResult.putInt("rssi", result.rssi);
93             rttResult.putInt("rssiSpread", result.rssiSpread);
94             rttResult.putInt("retryAfterDuration", result.retryAfterDuration);
95             rttResult.putInt("measurementType", result.measurementType);
96             rttResult.putInt("status", result.status);
97             rttResult.putInt("frameNumberPerBurstPeer",
98                     result.frameNumberPerBurstPeer);
99             rttResult.putInt("successMeasurementFrameNumber",
100                     result.successMeasurementFrameNumber);
101             rttResult.putInt("measurementFrameNumber",
102                     result.measurementFrameNumber);
103             rttResult.putInt("burstNumber", result.burstNumber);
104             rttResult.putInt("status", result.status);
105             return rttResult;
106         }
107 
108         @Override
onSuccess(RttResult[] results)109         public void onSuccess(RttResult[] results) {
110             if (results == null) {
111                 mEventFacade
112                         .postEvent(RangingListener.TAG + mId + "onSuccess", null);
113                 return;
114             }
115             Bundle msg = new Bundle();
116             Parcelable[] resultBundles = new Parcelable[results.length];
117             for (int i = 0; i < results.length; i++) {
118                 resultBundles[i] = packRttResult(results[i]);
119             }
120             msg.putParcelableArray("Results", resultBundles);
121             mEventFacade
122                     .postEvent(RangingListener.TAG + mId + "onSuccess", msg);
123         }
124 
125         @Override
onFailure(int reason, String description)126         public void onFailure(int reason, String description) {
127             Bundle msg = new Bundle();
128             msg.putInt("Reason", reason);
129             msg.putString("Description", description);
130             mEventFacade
131                     .postEvent(RangingListener.TAG + mId + "onFailure", msg);
132         }
133 
134         @Override
onAborted()135         public void onAborted() {
136             mEventFacade.postEvent(RangingListener.TAG + mId + "onAborted",
137                     new Bundle());
138         }
139     }
140 
141     /**
142      * A {@link ResponderCallback} that handles success and failures for enabling RTT responder
143      * mode.
144      */
145     private static class RttResponderCallback extends ResponderCallback {
146         private static final String TAG = "WifiRtt";
147 
148         // A monotonic increasing counter for responder callback ids.
149         private static int sCount = 0;
150 
151         private final int mId;
152         private final EventFacade mEventFacade;
153 
RttResponderCallback(EventFacade eventFacade)154         RttResponderCallback(EventFacade eventFacade) {
155             sCount++;
156             mId = sCount;
157             mEventFacade = eventFacade;
158         }
159 
160         @Override
onResponderEnabled(ResponderConfig config)161         public void onResponderEnabled(ResponderConfig config) {
162             Bundle bundle = new Bundle();
163             bundle.putString("macAddress", config.macAddress);
164             bundle.putInt("frequency", config.frequency);
165             bundle.putInt("centerFreq0", config.centerFreq0);
166             bundle.putInt("centerFreq1", config.centerFreq1);
167             bundle.putInt("channelWidth", config.channelWidth);
168             bundle.putInt("preamble", config.preamble);
169             mEventFacade.postEvent(TAG + mId + "onResponderEnabled", bundle);
170         }
171 
172         @Override
onResponderEnableFailure(int reason)173         public void onResponderEnableFailure(int reason) {
174             Bundle bundle = new Bundle();
175             bundle.putInt("reason", reason);
176             mEventFacade.postEvent(TAG + mId + "onResponderEnableFailure", bundle);
177         }
178     }
179 
180     @Rpc(description = "Get wifi Rtt capabilities.")
wifiRttGetCapabilities()181     public RttCapabilities wifiRttGetCapabilities() {
182         return mRtt.getRttCapabilities();
183     }
184 
parseRttParam(JSONObject j)185     public static RttParams parseRttParam(JSONObject j) throws JSONException {
186         RttParams result = new RttParams();
187         if (j.has("deviceType")) {
188             result.deviceType = j.getInt("deviceType");
189         }
190         if (j.has("requestType")) {
191             result.requestType = j.getInt("requestType");
192         }
193         if (j.has("bssid")) {
194             result.bssid = j.getString("bssid");
195         }
196         if (j.has("frequency")) {
197             result.frequency = j.getInt("frequency");
198         }
199         if (j.has("channelWidth")) {
200             result.channelWidth = j.getInt("channelWidth");
201         }
202         if (j.has("centerFreq0")) {
203             result.centerFreq0 = j.getInt("centerFreq0");
204         }
205         if (j.has("centerFreq1")) {
206             result.centerFreq1 = j.getInt("centerFreq1");
207         }
208         if (j.has("numberBurst")) {
209             result.numberBurst = j.getInt("numberBurst");
210         }
211         if (j.has("burstTimeout")) {
212             result.burstTimeout = j.getInt("burstTimeout");
213         }
214         if (j.has("interval")) {
215             result.interval = j.getInt("interval");
216         }
217         if (j.has("numSamplesPerBurst")) {
218             result.numSamplesPerBurst = j.getInt("numSamplesPerBurst");
219         }
220         if (j.has("numRetriesPerMeasurementFrame")) {
221             result.numRetriesPerMeasurementFrame = j
222                     .getInt("numRetriesPerMeasurementFrame");
223         }
224         if (j.has("numRetriesPerFTMR")) {
225             result.numRetriesPerFTMR = j.getInt("numRetriesPerFTMR");
226         }
227         if (j.has("LCIRequest")) {
228             result.LCIRequest = j.getBoolean("LCIRequest");
229         }
230         if (j.has("LCRRequest")) {
231             result.LCRRequest = j.getBoolean("LCRRequest");
232         }
233         if (j.has("preamble")) {
234             result.preamble = j.getInt("preamble");
235         }
236         if (j.has("bandwidth")) {
237             result.bandwidth = j.getInt("bandwidth");
238         }
239         return result;
240     }
241 
242     /**
243      * Start WiFi RTT ranging using the given params. Returns the id associated with the
244      * {@link RttListener} used for ranging.
245      */
246     @Rpc(description = "Start ranging.", returns = "Id of the listener associated with the "
247             + "started ranging.")
wifiRttStartRanging( @pcParametername = "params") JSONArray params)248     public Integer wifiRttStartRanging(
249             @RpcParameter(name = "params") JSONArray params)
250             throws JSONException {
251         RttParams[] rParams = new RttParams[params.length()];
252         for (int i = 0; i < params.length(); i++) {
253             rParams[i] = parseRttParam(params.getJSONObject(i));
254         }
255         RangingListener listener = new RangingListener(mEventFacade);
256         mRangingListeners.put(listener.mId, listener);
257         mRtt.startRanging(rParams, listener);
258         return listener.mId;
259     }
260 
261     /**
262      * Stop WiFi Rtt ranging for {@link RttListener} identified by the given {@code index}.
263      */
264     @Rpc(description = "Stop ranging.")
wifiRttStopRanging(@pcParametername = "index") Integer index)265     public void wifiRttStopRanging(@RpcParameter(name = "index") Integer index) {
266         mRtt.stopRanging(mRangingListeners.remove(index));
267     }
268 
269     /**
270      * Enable WiFi RTT responder role. Returns the id associated with the {@link ResponderCallback}
271      * used for enabling responder.
272      */
273     @Rpc(description = "Enable responder", returns = "Id of the callback associated with enabling")
wifiRttEnableResponder()274     public Integer wifiRttEnableResponder() {
275         RttResponderCallback callback = new RttResponderCallback(mEventFacade);
276         mResponderCallbacks.put(callback.mId, callback);
277         mRtt.enableResponder(callback);
278         return callback.mId;
279     }
280 
281     /**
282      * Disable WiFi RTT responder role for the {@link ResponderCallback} identified by the given
283      * {@code index}.
284      */
285     @Rpc(description = "Disable responder")
wifiRttDisableResponder(@pcParametername = "index") Integer index)286     public void wifiRttDisableResponder(@RpcParameter(name = "index") Integer index) {
287         mRtt.disableResponder(mResponderCallbacks.remove(index));
288     }
289 
290     @Override
shutdown()291     public void shutdown() {
292         ArrayList<Integer> keys = new ArrayList<Integer>(
293                 mRangingListeners.keySet());
294         for (int k : keys) {
295             wifiRttStopRanging(k);
296         }
297         for (int index : mResponderCallbacks.keySet()) {
298             wifiRttDisableResponder(index);
299         }
300     }
301 }
302