WifiAwareNativeCallback.java revision 1e7386343d09cb5b63661d52732999f8626ba140
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
17package com.android.server.wifi.aware;
18
19import android.hardware.wifi.V1_0.IWifiNanIfaceEventCallback;
20import android.hardware.wifi.V1_0.NanCapabilities;
21import android.hardware.wifi.V1_0.NanClusterEventInd;
22import android.hardware.wifi.V1_0.NanClusterEventType;
23import android.hardware.wifi.V1_0.NanDataPathConfirmInd;
24import android.hardware.wifi.V1_0.NanDataPathRequestInd;
25import android.hardware.wifi.V1_0.NanFollowupReceivedInd;
26import android.hardware.wifi.V1_0.NanMatchInd;
27import android.hardware.wifi.V1_0.NanStatusType;
28import android.hardware.wifi.V1_0.WifiNanStatus;
29import android.util.Log;
30
31import libcore.util.HexEncoding;
32
33import java.util.ArrayList;
34import java.util.Arrays;
35
36/**
37 * Manages the callbacks from Wi-Fi Aware HIDL (HAL).
38 */
39public class WifiAwareNativeCallback extends IWifiNanIfaceEventCallback.Stub {
40    private static final String TAG = "WifiAwareNativeCallback";
41    private static final boolean DBG = false;
42    private static final boolean VDBG = false;
43
44    private final WifiAwareStateManager mWifiAwareStateManager;
45
46    public WifiAwareNativeCallback(WifiAwareStateManager wifiAwareStateManager) {
47        mWifiAwareStateManager = wifiAwareStateManager;
48    }
49
50    @Override
51    public void notifyCapabilitiesResponse(short id, WifiNanStatus status,
52            NanCapabilities capabilities) {
53        if (VDBG) {
54            Log.v(TAG, "notifyCapabilitiesResponse: id=" + id + ", status=" + statusString(status)
55                    + ", capabilities=" + capabilities);
56        }
57
58        if (status.status == NanStatusType.SUCCESS) {
59            Capabilities frameworkCapabilities = new Capabilities();
60            frameworkCapabilities.maxConcurrentAwareClusters = capabilities.maxConcurrentClusters;
61            frameworkCapabilities.maxPublishes = capabilities.maxPublishes;
62            frameworkCapabilities.maxSubscribes = capabilities.maxSubscribes;
63            frameworkCapabilities.maxServiceNameLen = capabilities.maxServiceNameLen;
64            frameworkCapabilities.maxMatchFilterLen = capabilities.maxMatchFilterLen;
65            frameworkCapabilities.maxTotalMatchFilterLen = capabilities.maxTotalMatchFilterLen;
66            frameworkCapabilities.maxServiceSpecificInfoLen =
67                    capabilities.maxServiceSpecificInfoLen;
68            frameworkCapabilities.maxVsaDataLen = capabilities.maxVsaDataLen;
69            frameworkCapabilities.maxNdiInterfaces = capabilities.maxNdiInterfaces;
70            frameworkCapabilities.maxNdpSessions = capabilities.maxNdpSessions;
71            frameworkCapabilities.maxAppInfoLen = capabilities.maxAppInfoLen;
72            frameworkCapabilities.maxQueuedTransmitMessages =
73                    capabilities.maxQueuedTransmitFollowupMsgs;
74            frameworkCapabilities.maxSubscribeInterfaceAddresses =
75                    capabilities.maxSubscribeInterfaceAddresses;
76            frameworkCapabilities.supportedCipherSuites = capabilities.supportedCipherSuites;
77
78            mWifiAwareStateManager.onCapabilitiesUpdateResponse(id, frameworkCapabilities);
79        } else {
80            Log.e(TAG, "notifyCapabilitiesResponse: error code=" + status.status + " ("
81                    + status.description + ")");
82        }
83    }
84
85    @Override
86    public void notifyEnableResponse(short id, WifiNanStatus status) {
87        if (VDBG) Log.v(TAG, "notifyEnableResponse: id=" + id + ", status=" + statusString(status));
88
89        if (status.status == NanStatusType.SUCCESS) {
90            mWifiAwareStateManager.onConfigSuccessResponse(id);
91        } else {
92            mWifiAwareStateManager.onConfigFailedResponse(id, status.status);
93        }
94    }
95
96    @Override
97    public void notifyConfigResponse(short id, WifiNanStatus status) {
98        if (VDBG) Log.v(TAG, "notifyConfigResponse: id=" + id + ", status=" + statusString(status));
99
100        if (status.status == NanStatusType.SUCCESS) {
101            mWifiAwareStateManager.onConfigSuccessResponse(id);
102        } else {
103            mWifiAwareStateManager.onConfigFailedResponse(id, status.status);
104        }
105    }
106
107    @Override
108    public void notifyDisableResponse(short id, WifiNanStatus status) {
109        if (VDBG) {
110            Log.v(TAG, "notifyDisableResponse: id=" + id + ", status=" + statusString(status));
111        }
112
113        if (status.status == NanStatusType.SUCCESS) {
114            // NOP
115        } else {
116            Log.e(TAG, "notifyDisableResponse: failure - code=" + status.status + " ("
117                    + status.description + ")");
118        }
119    }
120
121    @Override
122    public void notifyStartPublishResponse(short id, WifiNanStatus status, byte publishId) {
123        if (VDBG) {
124            Log.v(TAG, "notifyStartPublishResponse: id=" + id + ", status=" + statusString(status)
125                    + ", publishId=" + publishId);
126        }
127
128        if (status.status == NanStatusType.SUCCESS) {
129            mWifiAwareStateManager.onSessionConfigSuccessResponse(id, true, publishId);
130        } else {
131            mWifiAwareStateManager.onSessionConfigFailResponse(id, true, status.status);
132        }
133    }
134
135    @Override
136    public void notifyStopPublishResponse(short id, WifiNanStatus status) {
137        if (VDBG) {
138            Log.v(TAG, "notifyStopPublishResponse: id=" + id + ", status=" + statusString(status));
139        }
140
141        if (status.status == NanStatusType.SUCCESS) {
142            // NOP
143        } else {
144            Log.e(TAG, "notifyStopPublishResponse: failure - code=" + status.status + " ("
145                    + status.description + ")");
146        }
147    }
148
149    @Override
150    public void notifyStartSubscribeResponse(short id, WifiNanStatus status, byte subscribeId) {
151        if (VDBG) {
152            Log.v(TAG, "notifyStartSubscribeResponse: id=" + id + ", status=" + statusString(status)
153                    + ", subscribeId=" + subscribeId);
154        }
155
156        if (status.status == NanStatusType.SUCCESS) {
157            mWifiAwareStateManager.onSessionConfigSuccessResponse(id, false, subscribeId);
158        } else {
159            mWifiAwareStateManager.onSessionConfigFailResponse(id, false, status.status);
160        }
161    }
162
163    @Override
164    public void notifyStopSubscribeResponse(short id, WifiNanStatus status) {
165        if (VDBG) {
166            Log.v(TAG, "notifyStopSubscribeResponse: id=" + id + ", status="
167                    + statusString(status));
168        }
169
170        if (status.status == NanStatusType.SUCCESS) {
171            // NOP
172        } else {
173            Log.e(TAG, "notifyStopSubscribeResponse: failure - code=" + status.status + " ("
174                    + status.description + ")");
175        }
176    }
177
178    @Override
179    public void notifyTransmitFollowupResponse(short id, WifiNanStatus status) {
180        if (VDBG) {
181            Log.v(TAG, "notifyTransmitFollowupResponse: id=" + id + ", status="
182                    + statusString(status));
183        }
184
185        if (status.status == NanStatusType.SUCCESS) {
186            mWifiAwareStateManager.onMessageSendQueuedSuccessResponse(id);
187        } else {
188            mWifiAwareStateManager.onMessageSendQueuedFailResponse(id, status.status);
189        }
190    }
191
192    @Override
193    public void notifyCreateDataInterfaceResponse(short id, WifiNanStatus status) {
194        if (VDBG) {
195            Log.v(TAG, "notifyCreateDataInterfaceResponse: id=" + id + ", status="
196                    + statusString(status));
197        }
198
199        mWifiAwareStateManager.onCreateDataPathInterfaceResponse(id,
200                status.status == NanStatusType.SUCCESS, status.status);
201    }
202
203    @Override
204    public void notifyDeleteDataInterfaceResponse(short id, WifiNanStatus status) {
205        if (VDBG) {
206            Log.v(TAG, "notifyDeleteDataInterfaceResponse: id=" + id + ", status="
207                    + statusString(status));
208        }
209
210        mWifiAwareStateManager.onDeleteDataPathInterfaceResponse(id,
211                status.status == NanStatusType.SUCCESS, status.status);
212    }
213
214    @Override
215    public void notifyInitiateDataPathResponse(short id, WifiNanStatus status,
216            int ndpInstanceId) {
217        if (VDBG) {
218            Log.v(TAG, "notifyInitiateDataPathResponse: id=" + id + ", status="
219                    + statusString(status) + ", ndpInstanceId=" + ndpInstanceId);
220        }
221
222        if (status.status == NanStatusType.SUCCESS) {
223            mWifiAwareStateManager.onInitiateDataPathResponseSuccess(id, ndpInstanceId);
224        } else {
225            mWifiAwareStateManager.onInitiateDataPathResponseFail(id, status.status);
226        }
227    }
228
229    @Override
230    public void notifyRespondToDataPathIndicationResponse(short id, WifiNanStatus status) {
231        if (VDBG) {
232            Log.v(TAG, "notifyRespondToDataPathIndicationResponse: id=" + id
233                    + ", status=" + statusString(status));
234        }
235
236        mWifiAwareStateManager.onRespondToDataPathSetupRequestResponse(id,
237                status.status == NanStatusType.SUCCESS, status.status);
238    }
239
240    @Override
241    public void notifyTerminateDataPathResponse(short id, WifiNanStatus status) {
242        if (VDBG) {
243            Log.v(TAG, "notifyTerminateDataPathResponse: id=" + id + ", status="
244                    + statusString(status));
245        }
246
247        mWifiAwareStateManager.onEndDataPathResponse(id, status.status == NanStatusType.SUCCESS,
248                status.status);
249    }
250
251    @Override
252    public void eventClusterEvent(NanClusterEventInd event) {
253        if (VDBG) {
254            Log.v(TAG, "eventClusterEvent: eventType=" + event.eventType + ", addr="
255                    + String.valueOf(HexEncoding.encode(event.addr)));
256        }
257
258        if (event.eventType == NanClusterEventType.DISCOVERY_MAC_ADDRESS_CHANGED) {
259            mWifiAwareStateManager.onInterfaceAddressChangeNotification(event.addr);
260        } else if (event.eventType == NanClusterEventType.STARTED_CLUSTER) {
261            mWifiAwareStateManager.onClusterChangeNotification(
262                    WifiAwareClientState.CLUSTER_CHANGE_EVENT_STARTED, event.addr);
263        } else if (event.eventType == NanClusterEventType.JOINED_CLUSTER) {
264            mWifiAwareStateManager.onClusterChangeNotification(
265                    WifiAwareClientState.CLUSTER_CHANGE_EVENT_JOINED, event.addr);
266        } else {
267            Log.e(TAG, "eventClusterEvent: invalid eventType=" + event.eventType);
268        }
269    }
270
271    @Override
272    public void eventDisabled(WifiNanStatus status) {
273        if (VDBG) Log.v(TAG, "eventDisabled: status=" + statusString(status));
274
275        mWifiAwareStateManager.onAwareDownNotification(status.status);
276    }
277
278    @Override
279    public void eventPublishTerminated(byte sessionId, WifiNanStatus status) {
280        if (VDBG) {
281            Log.v(TAG, "eventPublishTerminated: sessionId=" + sessionId + ", status="
282                    + statusString(status));
283        }
284
285        mWifiAwareStateManager.onSessionTerminatedNotification(sessionId, status.status, true);
286    }
287
288    @Override
289    public void eventSubscribeTerminated(byte sessionId, WifiNanStatus status) {
290        if (VDBG) {
291            Log.v(TAG, "eventSubscribeTerminated: sessionId=" + sessionId + ", status="
292                    + statusString(status));
293        }
294
295        mWifiAwareStateManager.onSessionTerminatedNotification(sessionId, status.status, false);
296    }
297
298    @Override
299    public void eventMatch(NanMatchInd event) {
300        if (VDBG) {
301            Log.v(TAG, "eventMatch: discoverySessionId=" + event.discoverySessionId + ", peerId="
302                    + event.peerId + ", addr=" + String.valueOf(HexEncoding.encode(event.addr))
303                    + ", serviceSpecificInfo=" + Arrays.toString(
304                    convertUcByteToLcByteArray(event.serviceSpecificInfo)) + ", matchFilter="
305                    + Arrays.toString(convertUcByteToLcByteArray(event.matchFilter)));
306        }
307
308        mWifiAwareStateManager.onMatchNotification(event.discoverySessionId, event.peerId,
309                event.addr, convertUcByteToLcByteArray(event.serviceSpecificInfo),
310                convertUcByteToLcByteArray(event.matchFilter));
311    }
312
313    @Override
314    public void eventMatchExpired(byte discoverySessionId, int peerId) {
315        if (VDBG) {
316            Log.v(TAG, "eventMatchExpired: discoverySessionId=" + discoverySessionId
317                    + ", peerId=" + peerId);
318        }
319
320        // NOP
321    }
322
323    @Override
324    public void eventFollowupReceived(NanFollowupReceivedInd event) {
325        if (VDBG) {
326            Log.v(TAG, "eventFollowupReceived: discoverySessionId=" + event.discoverySessionId
327                    + ", peerId=" + event.peerId + ", addr=" + String.valueOf(
328                    HexEncoding.encode(event.addr)));
329        }
330
331        mWifiAwareStateManager.onMessageReceivedNotification(event.discoverySessionId, event.peerId,
332                event.addr, convertUcByteToLcByteArray(event.serviceSpecificInfo));
333    }
334
335    @Override
336    public void eventTransmitFollowup(short id, WifiNanStatus status) {
337        Log.v(TAG, "eventTransmitFollowup: id=" + id + ", status=" + statusString(status));
338
339        if (status.status == NanStatusType.SUCCESS) {
340            mWifiAwareStateManager.onMessageSendSuccessNotification(id);
341        } else {
342            mWifiAwareStateManager.onMessageSendFailNotification(id, status.status);
343        }
344    }
345
346    @Override
347    public void eventDataPathRequest(NanDataPathRequestInd event) {
348        if (VDBG) {
349            Log.v(TAG, "eventDataPathRequest: discoverySessionId=" + event.discoverySessionId
350                    + ", peerDiscMacAddr=" + String.valueOf(
351                    HexEncoding.encode(event.peerDiscMacAddr)) + ", ndpInstanceId="
352                    + event.ndpInstanceId);
353        }
354
355        mWifiAwareStateManager.onDataPathRequestNotification(event.discoverySessionId,
356                event.peerDiscMacAddr, event.ndpInstanceId,
357                convertUcByteToLcByteArray(event.appInfo));
358    }
359
360    @Override
361    public void eventDataPathConfirm(NanDataPathConfirmInd event) {
362        if (VDBG) {
363            Log.v(TAG, "onDataPathConfirm: ndpInstanceId=" + event.ndpInstanceId
364                    + ", peerNdiMacAddr=" + String.valueOf(HexEncoding.encode(event.peerNdiMacAddr))
365                    + ", dataPathSetupSuccess=" + event.dataPathSetupSuccess + ", reason="
366                    + event.status.status);
367        }
368
369        mWifiAwareStateManager.onDataPathConfirmNotification(event.ndpInstanceId,
370                event.peerNdiMacAddr, event.dataPathSetupSuccess, event.status.status,
371                convertUcByteToLcByteArray(event.appInfo));
372    }
373
374    @Override
375    public void eventDataPathTerminated(int ndpInstanceId) {
376        if (VDBG) Log.v(TAG, "eventDataPathTerminated: ndpInstanceId=" + ndpInstanceId);
377
378        mWifiAwareStateManager.onDataPathEndNotification(ndpInstanceId);
379    }
380
381    // utilities
382
383    /**
384     * Converts an ArrayList<Byte> to a byte[].
385     *
386     * @param from The input ArrayList<Byte></Byte> to convert from.
387     *
388     * @return A newly allocated byte[].
389     */
390    private byte[] convertUcByteToLcByteArray(ArrayList<Byte> from) {
391        if (from == null) {
392            return null;
393        }
394
395        byte[] to = new byte[from.size()];
396        for (int i = 0; i < from.size(); ++i) {
397            to[i] = from.get(i);
398        }
399        return to;
400    }
401
402    private static String statusString(WifiNanStatus status) {
403        if (status == null) {
404            return "status=null";
405        }
406        StringBuilder sb = new StringBuilder();
407        sb.append(status.status).append(" (").append(status.description).append(")");
408        return sb.toString();
409    }
410}
411