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.wifi.hal;
18 
19 import android.hardware.wifi.V1_0.NanClusterEventInd;
20 import android.hardware.wifi.V1_0.NanDataPathConfirmInd;
21 import android.hardware.wifi.V1_0.NanDataPathRequestInd;
22 import android.hardware.wifi.V1_0.NanFollowupReceivedInd;
23 import android.hardware.wifi.V1_0.NanMatchInd;
24 import android.hardware.wifi.V1_0.NanStatusType;
25 import android.hardware.wifi.V1_0.WifiNanStatus;
26 import android.hardware.wifi.V1_2.NanDataPathScheduleUpdateInd;
27 import android.hardware.wifi.V1_6.IWifiNanIfaceEventCallback;
28 import android.hardware.wifi.V1_6.NanCipherSuiteType;
29 import android.hardware.wifi.V1_6.WifiChannelWidthInMhz;
30 import android.net.MacAddress;
31 import android.net.wifi.ScanResult;
32 import android.net.wifi.WifiAnnotations;
33 import android.net.wifi.aware.Characteristics;
34 import android.net.wifi.aware.WifiAwareChannelInfo;
35 import android.net.wifi.util.HexEncoding;
36 import android.util.Log;
37 
38 import com.android.server.wifi.aware.Capabilities;
39 import com.android.server.wifi.hal.WifiNanIface.NanClusterEventType;
40 import com.android.server.wifi.hal.WifiNanIface.NanRangingIndication;
41 import com.android.server.wifi.hal.WifiNanIface.NanStatusCode;
42 
43 import java.util.ArrayList;
44 import java.util.Arrays;
45 import java.util.List;
46 
47 /**
48  * Callback registered with the Vendor HAL service. On events, converts arguments
49  * to their framework equivalents and calls the registered framework callback.
50  */
51 public class WifiNanIfaceCallbackHidlImpl extends IWifiNanIfaceEventCallback.Stub {
52     private static final String TAG = "WifiNanIfaceCallbackHidlImpl";
53 
54     private boolean mVerboseLoggingEnabled;
55     private WifiNanIfaceHidlImpl mWifiNanIface;
56 
WifiNanIfaceCallbackHidlImpl(WifiNanIfaceHidlImpl wifiNanIface)57     public WifiNanIfaceCallbackHidlImpl(WifiNanIfaceHidlImpl wifiNanIface) {
58         mWifiNanIface = wifiNanIface;
59     }
60 
61     /**
62      * Enable verbose logging.
63      */
enableVerboseLogging(boolean verbose)64     public void enableVerboseLogging(boolean verbose) {
65         mVerboseLoggingEnabled = verbose;
66     }
67 
68     @Override
notifyCapabilitiesResponse(short id, WifiNanStatus status, android.hardware.wifi.V1_0.NanCapabilities capabilities)69     public void notifyCapabilitiesResponse(short id, WifiNanStatus status,
70             android.hardware.wifi.V1_0.NanCapabilities capabilities) {
71         if (!checkFrameworkCallback()) return;
72         if (mVerboseLoggingEnabled) {
73             Log.v(TAG, "notifyCapabilitiesResponse: id=" + id + ", status=" + statusString(status)
74                     + ", capabilities=" + capabilities);
75         }
76 
77         if (status.status == NanStatusType.SUCCESS) {
78             Capabilities frameworkCapabilities = toFrameworkCapability10(capabilities);
79             mWifiNanIface.getFrameworkCallback().notifyCapabilitiesResponse(
80                     id, frameworkCapabilities);
81         } else {
82             Log.e(TAG, "notifyCapabilitiesResponse: error code=" + status.status + " ("
83                     + status.description + ")");
84         }
85     }
86 
87     @Override
notifyCapabilitiesResponse_1_5(short id, WifiNanStatus status, android.hardware.wifi.V1_5.NanCapabilities capabilities)88     public void notifyCapabilitiesResponse_1_5(short id, WifiNanStatus status,
89             android.hardware.wifi.V1_5.NanCapabilities capabilities) {
90         if (!checkFrameworkCallback()) return;
91         if (mVerboseLoggingEnabled) {
92             Log.v(TAG, "notifyCapabilitiesResponse_1_5: id=" + id + ", status="
93                     + statusString(status) + ", capabilities=" + capabilities);
94         }
95 
96         if (status.status == NanStatusType.SUCCESS) {
97             Capabilities frameworkCapabilities = toFrameworkCapability10(capabilities.V1_0);
98             frameworkCapabilities.isInstantCommunicationModeSupported =
99                     capabilities.instantCommunicationModeSupportFlag;
100             mWifiNanIface.getFrameworkCallback().notifyCapabilitiesResponse(
101                     id, frameworkCapabilities);
102         } else {
103             Log.e(TAG, "notifyCapabilitiesResponse_1_5: error code=" + status.status + " ("
104                     + status.description + ")");
105         }
106     }
107 
108     @Override
notifyCapabilitiesResponse_1_6(short id, WifiNanStatus status, android.hardware.wifi.V1_6.NanCapabilities capabilities)109     public void notifyCapabilitiesResponse_1_6(short id, WifiNanStatus status,
110             android.hardware.wifi.V1_6.NanCapabilities capabilities) {
111         if (!checkFrameworkCallback()) return;
112         if (mVerboseLoggingEnabled) {
113             Log.v(TAG, "notifyCapabilitiesResponse_1_6: id=" + id + ", status="
114                     + statusString(status) + ", capabilities=" + capabilities);
115         }
116 
117         if (status.status == NanStatusType.SUCCESS) {
118             Capabilities frameworkCapabilities = toFrameworkCapability1_6(capabilities);
119             mWifiNanIface.getFrameworkCallback().notifyCapabilitiesResponse(
120                     id, frameworkCapabilities);
121         } else {
122             Log.e(TAG, "notifyCapabilitiesResponse_1_6: error code=" + status.status + " ("
123                     + status.description + ")");
124         }
125     }
126 
127     @Override
notifyEnableResponse(short id, WifiNanStatus status)128     public void notifyEnableResponse(short id, WifiNanStatus status) {
129         if (!checkFrameworkCallback()) return;
130         if (mVerboseLoggingEnabled) {
131             Log.v(TAG, "notifyEnableResponse: id=" + id + ", status=" + statusString(status));
132         }
133 
134         if (status.status == NanStatusType.ALREADY_ENABLED) {
135             Log.wtf(TAG, "notifyEnableResponse: id=" + id + ", already enabled!?");
136         }
137         mWifiNanIface.getFrameworkCallback().notifyEnableResponse(
138                 id, NanStatusCode.fromHidl(status.status));
139     }
140 
141     @Override
notifyConfigResponse(short id, WifiNanStatus status)142     public void notifyConfigResponse(short id, WifiNanStatus status) {
143         if (!checkFrameworkCallback()) return;
144         if (mVerboseLoggingEnabled) {
145             Log.v(TAG, "notifyConfigResponse: id=" + id + ", status=" + statusString(status));
146         }
147         mWifiNanIface.getFrameworkCallback().notifyConfigResponse(
148                 id, NanStatusCode.fromHidl(status.status));
149     }
150 
151     @Override
notifyDisableResponse(short id, WifiNanStatus status)152     public void notifyDisableResponse(short id, WifiNanStatus status) {
153         if (!checkFrameworkCallback()) return;
154         if (mVerboseLoggingEnabled) {
155             Log.v(TAG, "notifyDisableResponse: id=" + id + ", status=" + statusString(status));
156         }
157 
158         if (status.status != NanStatusType.SUCCESS) {
159             Log.e(TAG, "notifyDisableResponse: failure - code=" + status.status + " ("
160                     + status.description + ")");
161         }
162         mWifiNanIface.getFrameworkCallback().notifyDisableResponse(
163                 id, NanStatusCode.fromHidl(status.status));
164     }
165 
166     @Override
notifyStartPublishResponse(short id, WifiNanStatus status, byte publishId)167     public void notifyStartPublishResponse(short id, WifiNanStatus status, byte publishId) {
168         if (!checkFrameworkCallback()) return;
169         if (mVerboseLoggingEnabled) {
170             Log.v(TAG, "notifyStartPublishResponse: id=" + id + ", status=" + statusString(status)
171                     + ", publishId=" + publishId);
172         }
173         mWifiNanIface.getFrameworkCallback().notifyStartPublishResponse(
174                 id, NanStatusCode.fromHidl(status.status), publishId);
175     }
176 
177     @Override
notifyStopPublishResponse(short id, WifiNanStatus status)178     public void notifyStopPublishResponse(short id, WifiNanStatus status) {
179         if (!checkFrameworkCallback()) return;
180         if (mVerboseLoggingEnabled) {
181             Log.v(TAG, "notifyStopPublishResponse: id=" + id + ", status=" + statusString(status));
182         }
183 
184         if (status.status == NanStatusType.SUCCESS) {
185             // NOP
186         } else {
187             Log.e(TAG, "notifyStopPublishResponse: failure - code=" + status.status + " ("
188                     + status.description + ")");
189         }
190     }
191 
192     @Override
notifyStartSubscribeResponse(short id, WifiNanStatus status, byte subscribeId)193     public void notifyStartSubscribeResponse(short id, WifiNanStatus status, byte subscribeId) {
194         if (!checkFrameworkCallback()) return;
195         if (mVerboseLoggingEnabled) {
196             Log.v(TAG, "notifyStartSubscribeResponse: id=" + id + ", status=" + statusString(status)
197                     + ", subscribeId=" + subscribeId);
198         }
199         mWifiNanIface.getFrameworkCallback().notifyStartSubscribeResponse(
200                 id, NanStatusCode.fromHidl(status.status), subscribeId);
201     }
202 
203     @Override
notifyStopSubscribeResponse(short id, WifiNanStatus status)204     public void notifyStopSubscribeResponse(short id, WifiNanStatus status) {
205         if (!checkFrameworkCallback()) return;
206         if (mVerboseLoggingEnabled) {
207             Log.v(TAG, "notifyStopSubscribeResponse: id=" + id + ", status="
208                     + statusString(status));
209         }
210 
211         if (status.status == NanStatusType.SUCCESS) {
212             // NOP
213         } else {
214             Log.e(TAG, "notifyStopSubscribeResponse: failure - code=" + status.status + " ("
215                     + status.description + ")");
216         }
217     }
218 
219     @Override
notifyTransmitFollowupResponse(short id, WifiNanStatus status)220     public void notifyTransmitFollowupResponse(short id, WifiNanStatus status) {
221         if (!checkFrameworkCallback()) return;
222         if (mVerboseLoggingEnabled) {
223             Log.v(TAG, "notifyTransmitFollowupResponse: id=" + id + ", status="
224                     + statusString(status));
225         }
226         mWifiNanIface.getFrameworkCallback().notifyTransmitFollowupResponse(
227                 id, NanStatusCode.fromHidl(status.status));
228     }
229 
230     @Override
notifyCreateDataInterfaceResponse(short id, WifiNanStatus status)231     public void notifyCreateDataInterfaceResponse(short id, WifiNanStatus status) {
232         if (!checkFrameworkCallback()) return;
233         if (mVerboseLoggingEnabled) {
234             Log.v(TAG, "notifyCreateDataInterfaceResponse: id=" + id + ", status="
235                     + statusString(status));
236         }
237         mWifiNanIface.getFrameworkCallback().notifyCreateDataInterfaceResponse(
238                 id, NanStatusCode.fromHidl(status.status));
239     }
240 
241     @Override
notifyDeleteDataInterfaceResponse(short id, WifiNanStatus status)242     public void notifyDeleteDataInterfaceResponse(short id, WifiNanStatus status) {
243         if (!checkFrameworkCallback()) return;
244         if (mVerboseLoggingEnabled) {
245             Log.v(TAG, "notifyDeleteDataInterfaceResponse: id=" + id + ", status="
246                     + statusString(status));
247         }
248         mWifiNanIface.getFrameworkCallback().notifyDeleteDataInterfaceResponse(
249                 id, NanStatusCode.fromHidl(status.status));
250     }
251 
252     @Override
notifyInitiateDataPathResponse(short id, WifiNanStatus status, int ndpInstanceId)253     public void notifyInitiateDataPathResponse(short id, WifiNanStatus status,
254             int ndpInstanceId) {
255         if (!checkFrameworkCallback()) return;
256         if (mVerboseLoggingEnabled) {
257             Log.v(TAG, "notifyInitiateDataPathResponse: id=" + id + ", status="
258                     + statusString(status) + ", ndpInstanceId=" + ndpInstanceId);
259         }
260         mWifiNanIface.getFrameworkCallback().notifyInitiateDataPathResponse(
261                 id, NanStatusCode.fromHidl(status.status), ndpInstanceId);
262     }
263 
264     @Override
notifyRespondToDataPathIndicationResponse(short id, WifiNanStatus status)265     public void notifyRespondToDataPathIndicationResponse(short id, WifiNanStatus status) {
266         if (!checkFrameworkCallback()) return;
267         if (mVerboseLoggingEnabled) {
268             Log.v(TAG, "notifyRespondToDataPathIndicationResponse: id=" + id
269                     + ", status=" + statusString(status));
270         }
271         mWifiNanIface.getFrameworkCallback().notifyRespondToDataPathIndicationResponse(
272                 id, NanStatusCode.fromHidl(status.status));
273     }
274 
275     @Override
notifyTerminateDataPathResponse(short id, WifiNanStatus status)276     public void notifyTerminateDataPathResponse(short id, WifiNanStatus status) {
277         if (!checkFrameworkCallback()) return;
278         if (mVerboseLoggingEnabled) {
279             Log.v(TAG, "notifyTerminateDataPathResponse: id=" + id + ", status="
280                     + statusString(status));
281         }
282         mWifiNanIface.getFrameworkCallback().notifyTerminateDataPathResponse(
283                 id, NanStatusCode.fromHidl(status.status));
284     }
285 
286     @Override
eventClusterEvent(NanClusterEventInd event)287     public void eventClusterEvent(NanClusterEventInd event) {
288         if (!checkFrameworkCallback()) return;
289         if (mVerboseLoggingEnabled) {
290             Log.v(TAG, "eventClusterEvent: eventType=" + event.eventType + ", addr="
291                     + String.valueOf(HexEncoding.encode(event.addr)));
292         }
293         mWifiNanIface.getFrameworkCallback().eventClusterEvent(
294                 NanClusterEventType.fromHidl(event.eventType), event.addr);
295     }
296 
297     @Override
eventDisabled(WifiNanStatus status)298     public void eventDisabled(WifiNanStatus status) {
299         if (!checkFrameworkCallback()) return;
300         if (mVerboseLoggingEnabled) Log.v(TAG, "eventDisabled: status=" + statusString(status));
301         mWifiNanIface.getFrameworkCallback().eventDisabled(
302                 NanStatusCode.fromHidl(status.status));
303     }
304 
305     @Override
eventPublishTerminated(byte sessionId, WifiNanStatus status)306     public void eventPublishTerminated(byte sessionId, WifiNanStatus status) {
307         if (!checkFrameworkCallback()) return;
308         if (mVerboseLoggingEnabled) {
309             Log.v(TAG, "eventPublishTerminated: sessionId=" + sessionId + ", status="
310                     + statusString(status));
311         }
312         mWifiNanIface.getFrameworkCallback().eventPublishTerminated(
313                 sessionId, NanStatusCode.fromHidl(status.status));
314     }
315 
316     @Override
eventSubscribeTerminated(byte sessionId, WifiNanStatus status)317     public void eventSubscribeTerminated(byte sessionId, WifiNanStatus status) {
318         if (!checkFrameworkCallback()) return;
319         if (mVerboseLoggingEnabled) {
320             Log.v(TAG, "eventSubscribeTerminated: sessionId=" + sessionId + ", status="
321                     + statusString(status));
322         }
323         mWifiNanIface.getFrameworkCallback().eventSubscribeTerminated(
324                 sessionId, NanStatusCode.fromHidl(status.status));
325     }
326 
327     @Override
eventMatch(NanMatchInd event)328     public void eventMatch(NanMatchInd event) {
329         if (!checkFrameworkCallback()) return;
330         if (mVerboseLoggingEnabled) {
331             Log.v(TAG, "eventMatch: discoverySessionId=" + event.discoverySessionId + ", peerId="
332                     + event.peerId + ", addr=" + String.valueOf(HexEncoding.encode(event.addr))
333                     + ", serviceSpecificInfo=" + Arrays.toString(
334                     convertArrayListToNativeByteArray(event.serviceSpecificInfo)) + ", ssi.size()="
335                     + (event.serviceSpecificInfo == null ? 0 : event.serviceSpecificInfo.size())
336                     + ", matchFilter=" + Arrays.toString(
337                     convertArrayListToNativeByteArray(event.matchFilter)) + ", mf.size()=" + (
338                     event.matchFilter == null ? 0 : event.matchFilter.size())
339                     + ", rangingIndicationType=" + event.rangingIndicationType
340                     + ", rangingMeasurementInCm=" + event.rangingMeasurementInCm);
341         }
342         mWifiNanIface.getFrameworkCallback().eventMatch(event.discoverySessionId, event.peerId,
343                 event.addr, convertArrayListToNativeByteArray(event.serviceSpecificInfo),
344                 convertArrayListToNativeByteArray(event.matchFilter),
345                 NanRangingIndication.fromHidl(event.rangingIndicationType),
346                 event.rangingMeasurementInCm * 10, new byte[0], 0, null, null, null, null);
347     }
348 
349     @Override
eventMatch_1_6(android.hardware.wifi.V1_6.NanMatchInd event)350     public void eventMatch_1_6(android.hardware.wifi.V1_6.NanMatchInd event) {
351         if (!checkFrameworkCallback()) return;
352         if (mVerboseLoggingEnabled) {
353             Log.v(TAG, "eventMatch_1_6: discoverySessionId=" + event.discoverySessionId
354                     + ", peerId=" + event.peerId
355                     + ", addr=" + String.valueOf(HexEncoding.encode(event.addr))
356                     + ", serviceSpecificInfo=" + Arrays.toString(
357                     convertArrayListToNativeByteArray(event.serviceSpecificInfo)) + ", ssi.size()="
358                     + (event.serviceSpecificInfo == null ? 0 : event.serviceSpecificInfo.size())
359                     + ", matchFilter=" + Arrays.toString(
360                     convertArrayListToNativeByteArray(event.matchFilter)) + ", mf.size()=" + (
361                     event.matchFilter == null ? 0 : event.matchFilter.size())
362                     + ", rangingIndicationType=" + event.rangingIndicationType
363                     + ", rangingMeasurementInCm=" + event.rangingMeasurementInMm + ", "
364                     + "scid=" + Arrays.toString(convertArrayListToNativeByteArray(event.scid)));
365         }
366         mWifiNanIface.getFrameworkCallback().eventMatch(event.discoverySessionId, event.peerId,
367                 event.addr, convertArrayListToNativeByteArray(event.serviceSpecificInfo),
368                 convertArrayListToNativeByteArray(event.matchFilter),
369                 NanRangingIndication.fromHidl(event.rangingIndicationType),
370                 event.rangingMeasurementInMm, convertArrayListToNativeByteArray(event.scid),
371                 toPublicCipherSuites(event.peerCipherType), null, null, null, null);
372     }
373 
374     @Override
eventMatchExpired(byte discoverySessionId, int peerId)375     public void eventMatchExpired(byte discoverySessionId, int peerId) {
376         if (!checkFrameworkCallback()) return;
377         if (mVerboseLoggingEnabled) {
378             Log.v(TAG, "eventMatchExpired: discoverySessionId=" + discoverySessionId
379                     + ", peerId=" + peerId);
380         }
381         mWifiNanIface.getFrameworkCallback().eventMatchExpired(discoverySessionId, peerId);
382     }
383 
384     @Override
eventFollowupReceived(NanFollowupReceivedInd event)385     public void eventFollowupReceived(NanFollowupReceivedInd event) {
386         if (!checkFrameworkCallback()) return;
387         if (mVerboseLoggingEnabled) {
388             Log.v(TAG, "eventFollowupReceived: discoverySessionId=" + event.discoverySessionId
389                     + ", peerId=" + event.peerId + ", addr=" + String.valueOf(
390                     HexEncoding.encode(event.addr)) + ", serviceSpecificInfo=" + Arrays.toString(
391                     convertArrayListToNativeByteArray(event.serviceSpecificInfo)) + ", ssi.size()="
392                     + (event.serviceSpecificInfo == null ? 0 : event.serviceSpecificInfo.size()));
393         }
394         mWifiNanIface.getFrameworkCallback().eventFollowupReceived(
395                 event.discoverySessionId, event.peerId, event.addr,
396                 convertArrayListToNativeByteArray(event.serviceSpecificInfo));
397     }
398 
399     @Override
eventTransmitFollowup(short id, WifiNanStatus status)400     public void eventTransmitFollowup(short id, WifiNanStatus status) {
401         if (!checkFrameworkCallback()) return;
402         if (mVerboseLoggingEnabled) {
403             Log.v(TAG, "eventTransmitFollowup: id=" + id + ", status=" + statusString(status));
404         }
405         mWifiNanIface.getFrameworkCallback().eventTransmitFollowup(
406                 id, NanStatusCode.fromHidl(status.status));
407     }
408 
409     @Override
eventDataPathRequest(NanDataPathRequestInd event)410     public void eventDataPathRequest(NanDataPathRequestInd event) {
411         if (!checkFrameworkCallback()) return;
412         if (mVerboseLoggingEnabled) {
413             Log.v(TAG, "eventDataPathRequest: discoverySessionId=" + event.discoverySessionId
414                     + ", peerDiscMacAddr=" + String.valueOf(
415                     HexEncoding.encode(event.peerDiscMacAddr)) + ", ndpInstanceId="
416                     + event.ndpInstanceId + ", appInfo.size()=" + event.appInfo.size());
417         }
418         mWifiNanIface.getFrameworkCallback().eventDataPathRequest(event.discoverySessionId,
419                 event.peerDiscMacAddr, event.ndpInstanceId,
420                 convertArrayListToNativeByteArray(event.appInfo));
421     }
422 
423     @Override
eventDataPathConfirm(NanDataPathConfirmInd event)424     public void eventDataPathConfirm(NanDataPathConfirmInd event) {
425         if (!checkFrameworkCallback()) return;
426         if (mVerboseLoggingEnabled) {
427             Log.v(TAG, "onDataPathConfirm: ndpInstanceId=" + event.ndpInstanceId
428                     + ", peerNdiMacAddr=" + String.valueOf(HexEncoding.encode(event.peerNdiMacAddr))
429                     + ", dataPathSetupSuccess=" + event.dataPathSetupSuccess + ", reason="
430                     + event.status.status + ", appInfo.size()=" + event.appInfo.size());
431         }
432         mWifiNanIface.getFrameworkCallback().eventDataPathConfirm(
433                 NanStatusCode.fromHidl(event.status.status), event.ndpInstanceId,
434                 event.dataPathSetupSuccess, event.peerNdiMacAddr,
435                 convertArrayListToNativeByteArray(event.appInfo), null);
436     }
437 
438     @Override
eventDataPathConfirm_1_2(android.hardware.wifi.V1_2.NanDataPathConfirmInd event)439     public void eventDataPathConfirm_1_2(android.hardware.wifi.V1_2.NanDataPathConfirmInd event) {
440         if (!checkFrameworkCallback()) return;
441         if (mVerboseLoggingEnabled) {
442             Log.v(TAG, "eventDataPathConfirm_1_2: ndpInstanceId=" + event.V1_0.ndpInstanceId
443                     + ", peerNdiMacAddr=" + String.valueOf(
444                     HexEncoding.encode(event.V1_0.peerNdiMacAddr)) + ", dataPathSetupSuccess="
445                     + event.V1_0.dataPathSetupSuccess + ", reason=" + event.V1_0.status.status
446                     + ", appInfo.size()=" + event.V1_0.appInfo.size()
447                     + ", channelInfo" + event.channelInfo);
448         }
449         List<WifiAwareChannelInfo> wifiAwareChannelInfos =
450                 convertHalChannelInfo_1_2(event.channelInfo);
451         mWifiNanIface.getFrameworkCallback().eventDataPathConfirm(
452                 NanStatusCode.fromHidl(event.V1_0.status.status), event.V1_0.ndpInstanceId,
453                 event.V1_0.dataPathSetupSuccess, event.V1_0.peerNdiMacAddr,
454                 convertArrayListToNativeByteArray(event.V1_0.appInfo), wifiAwareChannelInfos);
455     }
456 
457     @Override
eventDataPathConfirm_1_6(android.hardware.wifi.V1_6.NanDataPathConfirmInd event)458     public void eventDataPathConfirm_1_6(android.hardware.wifi.V1_6.NanDataPathConfirmInd event) {
459         if (!checkFrameworkCallback()) return;
460         if (mVerboseLoggingEnabled) {
461             Log.v(TAG, "eventDataPathConfirm_1_6: ndpInstanceId=" + event.V1_0.ndpInstanceId
462                     + ", peerNdiMacAddr=" + String.valueOf(
463                     HexEncoding.encode(event.V1_0.peerNdiMacAddr)) + ", dataPathSetupSuccess="
464                     + event.V1_0.dataPathSetupSuccess + ", reason=" + event.V1_0.status.status
465                     + ", appInfo.size()=" + event.V1_0.appInfo.size()
466                     + ", channelInfo" + event.channelInfo);
467         }
468         List<WifiAwareChannelInfo> wifiAwareChannelInfos =
469                 convertHalChannelInfo_1_6(event.channelInfo);
470         mWifiNanIface.getFrameworkCallback().eventDataPathConfirm(
471                 NanStatusCode.fromHidl(event.V1_0.status.status), event.V1_0.ndpInstanceId,
472                 event.V1_0.dataPathSetupSuccess, event.V1_0.peerNdiMacAddr,
473                 convertArrayListToNativeByteArray(event.V1_0.appInfo), wifiAwareChannelInfos);
474     }
475 
476     @Override
eventDataPathScheduleUpdate(NanDataPathScheduleUpdateInd event)477     public void eventDataPathScheduleUpdate(NanDataPathScheduleUpdateInd event) {
478         if (!checkFrameworkCallback()) return;
479         if (mVerboseLoggingEnabled) {
480             Log.v(TAG, "eventDataPathScheduleUpdate: peerMac="
481                     + MacAddress.fromBytes(event.peerDiscoveryAddress)
482                     + ", ndpIds=" + event.ndpInstanceIds + ", channelInfo=" + event.channelInfo);
483         }
484         List<WifiAwareChannelInfo> wifiAwareChannelInfos =
485                 convertHalChannelInfo_1_2(event.channelInfo);
486         mWifiNanIface.getFrameworkCallback().eventDataPathScheduleUpdate(
487                 event.peerDiscoveryAddress, event.ndpInstanceIds, wifiAwareChannelInfos);
488     }
489 
490     @Override
eventDataPathScheduleUpdate_1_6( android.hardware.wifi.V1_6.NanDataPathScheduleUpdateInd event)491     public void eventDataPathScheduleUpdate_1_6(
492             android.hardware.wifi.V1_6.NanDataPathScheduleUpdateInd event) {
493         if (!checkFrameworkCallback()) return;
494         if (mVerboseLoggingEnabled) {
495             Log.v(TAG, "eventDataPathScheduleUpdate_1_6: peerMac="
496                     + MacAddress.fromBytes(event.peerDiscoveryAddress)
497                     + ", ndpIds=" + event.ndpInstanceIds + ", channelInfo=" + event.channelInfo);
498         }
499         List<WifiAwareChannelInfo> wifiAwareChannelInfos =
500                 convertHalChannelInfo_1_6(event.channelInfo);
501         mWifiNanIface.getFrameworkCallback().eventDataPathScheduleUpdate(
502                 event.peerDiscoveryAddress, event.ndpInstanceIds, wifiAwareChannelInfos);
503     }
504 
505     @Override
eventDataPathTerminated(int ndpInstanceId)506     public void eventDataPathTerminated(int ndpInstanceId) {
507         if (!checkFrameworkCallback()) return;
508         if (mVerboseLoggingEnabled) {
509             Log.v(TAG, "eventDataPathTerminated: ndpInstanceId=" + ndpInstanceId);
510         }
511         mWifiNanIface.getFrameworkCallback().eventDataPathTerminated(ndpInstanceId);
512     }
513 
toFrameworkCapability10( android.hardware.wifi.V1_0.NanCapabilities capabilities)514     private Capabilities toFrameworkCapability10(
515             android.hardware.wifi.V1_0.NanCapabilities capabilities) {
516         Capabilities frameworkCapabilities = new Capabilities();
517         frameworkCapabilities.maxConcurrentAwareClusters = capabilities.maxConcurrentClusters;
518         frameworkCapabilities.maxPublishes = capabilities.maxPublishes;
519         frameworkCapabilities.maxSubscribes = capabilities.maxSubscribes;
520         frameworkCapabilities.maxServiceNameLen = capabilities.maxServiceNameLen;
521         frameworkCapabilities.maxMatchFilterLen = capabilities.maxMatchFilterLen;
522         frameworkCapabilities.maxTotalMatchFilterLen = capabilities.maxTotalMatchFilterLen;
523         frameworkCapabilities.maxServiceSpecificInfoLen =
524                 capabilities.maxServiceSpecificInfoLen;
525         frameworkCapabilities.maxExtendedServiceSpecificInfoLen =
526                 capabilities.maxExtendedServiceSpecificInfoLen;
527         frameworkCapabilities.maxNdiInterfaces = capabilities.maxNdiInterfaces;
528         frameworkCapabilities.maxNdpSessions = capabilities.maxNdpSessions;
529         frameworkCapabilities.maxAppInfoLen = capabilities.maxAppInfoLen;
530         frameworkCapabilities.maxQueuedTransmitMessages =
531                 capabilities.maxQueuedTransmitFollowupMsgs;
532         frameworkCapabilities.maxSubscribeInterfaceAddresses =
533                 capabilities.maxSubscribeInterfaceAddresses;
534         frameworkCapabilities.supportedDataPathCipherSuites = toPublicCipherSuites(
535                 capabilities.supportedCipherSuites);
536         frameworkCapabilities.isInstantCommunicationModeSupported = false;
537         return frameworkCapabilities;
538     }
539 
toFrameworkCapability1_6( android.hardware.wifi.V1_6.NanCapabilities capabilities)540     private Capabilities toFrameworkCapability1_6(
541             android.hardware.wifi.V1_6.NanCapabilities capabilities) {
542         Capabilities frameworkCapabilities = new Capabilities();
543         frameworkCapabilities.maxConcurrentAwareClusters = capabilities.maxConcurrentClusters;
544         frameworkCapabilities.maxPublishes = capabilities.maxPublishes;
545         frameworkCapabilities.maxSubscribes = capabilities.maxSubscribes;
546         frameworkCapabilities.maxServiceNameLen = capabilities.maxServiceNameLen;
547         frameworkCapabilities.maxMatchFilterLen = capabilities.maxMatchFilterLen;
548         frameworkCapabilities.maxTotalMatchFilterLen = capabilities.maxTotalMatchFilterLen;
549         frameworkCapabilities.maxServiceSpecificInfoLen =
550                 capabilities.maxServiceSpecificInfoLen;
551         frameworkCapabilities.maxExtendedServiceSpecificInfoLen =
552                 capabilities.maxExtendedServiceSpecificInfoLen;
553         frameworkCapabilities.maxNdiInterfaces = capabilities.maxNdiInterfaces;
554         frameworkCapabilities.maxNdpSessions = capabilities.maxNdpSessions;
555         frameworkCapabilities.maxAppInfoLen = capabilities.maxAppInfoLen;
556         frameworkCapabilities.maxQueuedTransmitMessages =
557                 capabilities.maxQueuedTransmitFollowupMsgs;
558         frameworkCapabilities.maxSubscribeInterfaceAddresses =
559                 capabilities.maxSubscribeInterfaceAddresses;
560         frameworkCapabilities.supportedDataPathCipherSuites = toPublicCipherSuites(
561                 capabilities.supportedCipherSuites);
562         frameworkCapabilities.isInstantCommunicationModeSupported =
563                 capabilities.instantCommunicationModeSupportFlag;
564         return frameworkCapabilities;
565     }
566 
toPublicCipherSuites(int nativeCipherSuites)567     private int toPublicCipherSuites(int nativeCipherSuites) {
568         int publicCipherSuites = 0;
569 
570         if ((nativeCipherSuites & NanCipherSuiteType.SHARED_KEY_128_MASK) != 0) {
571             publicCipherSuites |= Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_SK_128;
572         }
573         if ((nativeCipherSuites & NanCipherSuiteType.SHARED_KEY_256_MASK) != 0) {
574             publicCipherSuites |= Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_SK_256;
575         }
576         if ((nativeCipherSuites & NanCipherSuiteType.PUBLIC_KEY_128_MASK) != 0) {
577             publicCipherSuites |= Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_128;
578         }
579         if ((nativeCipherSuites & NanCipherSuiteType.PUBLIC_KEY_256_MASK) != 0) {
580             publicCipherSuites |= Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_256;
581         }
582 
583         return publicCipherSuites;
584     }
585 
586     /**
587      * Converts an ArrayList<Byte> to a byte[].
588      *
589      * @param from The input ArrayList<Byte></Byte> to convert from.
590      *
591      * @return A newly allocated byte[].
592      */
convertArrayListToNativeByteArray(ArrayList<Byte> from)593     private byte[] convertArrayListToNativeByteArray(ArrayList<Byte> from) {
594         if (from == null) {
595             return null;
596         }
597 
598         byte[] to = new byte[from.size()];
599         for (int i = 0; i < from.size(); ++i) {
600             to[i] = from.get(i);
601         }
602         return to;
603     }
604 
statusString(WifiNanStatus status)605     private static String statusString(WifiNanStatus status) {
606         if (status == null) {
607             return "status=null";
608         }
609         StringBuilder sb = new StringBuilder();
610         sb.append(status.status).append(" (").append(status.description).append(")");
611         return sb.toString();
612     }
613 
614     /**
615      * Convert HAL channelBandwidth to framework enum
616      */
getChannelBandwidthFromHal(int channelBandwidth)617     private @WifiAnnotations.ChannelWidth int getChannelBandwidthFromHal(int channelBandwidth) {
618         switch(channelBandwidth) {
619             case WifiChannelWidthInMhz.WIDTH_40:
620                 return ScanResult.CHANNEL_WIDTH_40MHZ;
621             case WifiChannelWidthInMhz.WIDTH_80:
622                 return ScanResult.CHANNEL_WIDTH_80MHZ;
623             case WifiChannelWidthInMhz.WIDTH_160:
624                 return ScanResult.CHANNEL_WIDTH_160MHZ;
625             case WifiChannelWidthInMhz.WIDTH_80P80:
626                 return ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ;
627             case WifiChannelWidthInMhz.WIDTH_320:
628                 return ScanResult.CHANNEL_WIDTH_320MHZ;
629             default:
630                 return ScanResult.CHANNEL_WIDTH_20MHZ;
631         }
632     }
633 
634     /**
635      * Convert HAL V1_2 NanDataPathChannelInfo to WifiAwareChannelInfo
636      */
convertHalChannelInfo_1_2( List<android.hardware.wifi.V1_2.NanDataPathChannelInfo> channelInfos)637     private List<WifiAwareChannelInfo> convertHalChannelInfo_1_2(
638             List<android.hardware.wifi.V1_2.NanDataPathChannelInfo> channelInfos) {
639         List<WifiAwareChannelInfo> wifiAwareChannelInfos = new ArrayList<>();
640         if (channelInfos == null) {
641             return null;
642         }
643         for (android.hardware.wifi.V1_2.NanDataPathChannelInfo channelInfo : channelInfos) {
644             wifiAwareChannelInfos.add(new WifiAwareChannelInfo(channelInfo.channelFreq,
645                     getChannelBandwidthFromHal(channelInfo.channelBandwidth),
646                     channelInfo.numSpatialStreams));
647         }
648         return wifiAwareChannelInfos;
649     }
650 
651     /**
652      * Convert HAL V1_6 NanDataPathChannelInfo to WifiAwareChannelInfo
653      */
convertHalChannelInfo_1_6( List<android.hardware.wifi.V1_6.NanDataPathChannelInfo> channelInfos)654     private List<WifiAwareChannelInfo> convertHalChannelInfo_1_6(
655             List<android.hardware.wifi.V1_6.NanDataPathChannelInfo> channelInfos) {
656         List<WifiAwareChannelInfo> wifiAwareChannelInfos = new ArrayList<>();
657         if (channelInfos == null) {
658             return null;
659         }
660         for (android.hardware.wifi.V1_6.NanDataPathChannelInfo channelInfo : channelInfos) {
661             wifiAwareChannelInfos.add(new WifiAwareChannelInfo(channelInfo.channelFreq,
662                     getChannelBandwidthFromHal(channelInfo.channelBandwidth),
663                     channelInfo.numSpatialStreams));
664         }
665         return wifiAwareChannelInfos;
666     }
667 
checkFrameworkCallback()668     private boolean checkFrameworkCallback() {
669         if (mWifiNanIface == null) {
670             Log.e(TAG, "mWifiNanIface is null");
671             return false;
672         } else if (mWifiNanIface.getFrameworkCallback() == null) {
673             Log.e(TAG, "Framework callback is null");
674             return false;
675         }
676         return true;
677     }
678 }
679