1 /*
2  * Copyright (C) 2016 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.nan;
18 
19 import android.net.wifi.nan.ConfigRequest;
20 import android.net.wifi.nan.PublishData;
21 import android.net.wifi.nan.PublishSettings;
22 import android.net.wifi.nan.SubscribeData;
23 import android.net.wifi.nan.SubscribeSettings;
24 import android.net.wifi.nan.WifiNanSessionListener;
25 import android.util.Log;
26 
27 import com.android.server.wifi.WifiNative;
28 
29 import libcore.util.HexEncoding;
30 
31 /**
32  * Native calls to access the Wi-Fi NAN HAL.
33  *
34  * Relies on WifiNative to perform the actual HAL registration.
35  *
36  * {@hide}
37  */
38 public class WifiNanNative {
39     private static final String TAG = "WifiNanNative";
40     private static final boolean DBG = false;
41     private static final boolean VDBG = false; // STOPSHIP if true
42 
43     private static final int WIFI_SUCCESS = 0;
44 
45     private static boolean sNanNativeInit = false;
46 
47     private static WifiNanNative sWifiNanNativeSingleton;
48 
registerNanNatives()49     private static native int registerNanNatives();
50 
getInstance()51     public static WifiNanNative getInstance() {
52         // dummy reference - used to make sure that WifiNative is loaded before
53         // us since it is the one to load the shared library and starts its
54         // initialization.
55         WifiNative dummy = WifiNative.getWlanNativeInterface();
56         if (dummy == null) {
57             Log.w(TAG, "can't get access to WifiNative");
58             return null;
59         }
60 
61         if (sWifiNanNativeSingleton == null) {
62             sWifiNanNativeSingleton = new WifiNanNative();
63             registerNanNatives();
64         }
65 
66         return sWifiNanNativeSingleton;
67     }
68 
69     public static class Capabilities {
70         public int maxConcurrentNanClusters;
71         public int maxPublishes;
72         public int maxSubscribes;
73         public int maxServiceNameLen;
74         public int maxMatchFilterLen;
75         public int maxTotalMatchFilterLen;
76         public int maxServiceSpecificInfoLen;
77         public int maxVsaDataLen;
78         public int maxMeshDataLen;
79         public int maxNdiInterfaces;
80         public int maxNdpSessions;
81         public int maxAppInfoLen;
82 
83         @Override
toString()84         public String toString() {
85             return "Capabilities [maxConcurrentNanClusters=" + maxConcurrentNanClusters
86                     + ", maxPublishes=" + maxPublishes + ", maxSubscribes=" + maxSubscribes
87                     + ", maxServiceNameLen=" + maxServiceNameLen + ", maxMatchFilterLen="
88                     + maxMatchFilterLen + ", maxTotalMatchFilterLen=" + maxTotalMatchFilterLen
89                     + ", maxServiceSpecificInfoLen=" + maxServiceSpecificInfoLen
90                     + ", maxVsaDataLen=" + maxVsaDataLen + ", maxMeshDataLen=" + maxMeshDataLen
91                     + ", maxNdiInterfaces=" + maxNdiInterfaces + ", maxNdpSessions="
92                     + maxNdpSessions + ", maxAppInfoLen=" + maxAppInfoLen + "]";
93         }
94     }
95 
initNanHandlersNative(Object cls, int iface)96     /* package */ static native int initNanHandlersNative(Object cls, int iface);
97 
getCapabilitiesNative(short transactionId, Object cls, int iface)98     private static native int getCapabilitiesNative(short transactionId, Object cls, int iface);
99 
isNanInit(boolean tryToInit)100     private boolean isNanInit(boolean tryToInit) {
101         if (!tryToInit || sNanNativeInit) {
102             return sNanNativeInit;
103         }
104 
105         if (DBG) Log.d(TAG, "isNanInit: trying to init");
106         synchronized (WifiNative.sLock) {
107             boolean halStarted = WifiNative.getWlanNativeInterface().isHalStarted();
108             if (!halStarted) {
109                 halStarted = WifiNative.getWlanNativeInterface().startHal();
110             }
111             if (halStarted) {
112                 int ret = initNanHandlersNative(WifiNative.class, WifiNative.sWlan0Index);
113                 if (DBG) Log.d(TAG, "initNanHandlersNative: res=" + ret);
114                 sNanNativeInit = ret == WIFI_SUCCESS;
115 
116                 if (sNanNativeInit) {
117                     ret = getCapabilitiesNative(
118                             WifiNanStateManager.getInstance().createNextTransactionId(),
119                             WifiNative.class,
120                             WifiNative.sWlan0Index);
121                     if (DBG) Log.d(TAG, "getCapabilitiesNative: res=" + ret);
122                 }
123 
124                 return sNanNativeInit;
125             } else {
126                 Log.w(TAG, "isNanInit: HAL not initialized");
127                 return false;
128             }
129         }
130     }
131 
WifiNanNative()132     private WifiNanNative() {
133         // do nothing
134     }
135 
enableAndConfigureNative(short transactionId, Object cls, int iface, ConfigRequest configRequest)136     private static native int enableAndConfigureNative(short transactionId, Object cls, int iface,
137             ConfigRequest configRequest);
138 
enableAndConfigure(short transactionId, ConfigRequest configRequest)139     public void enableAndConfigure(short transactionId, ConfigRequest configRequest) {
140         boolean success;
141 
142         if (VDBG) Log.d(TAG, "enableAndConfigure: configRequest=" + configRequest);
143         if (isNanInit(true)) {
144             int ret;
145             synchronized (WifiNative.sLock) {
146                 ret = enableAndConfigureNative(transactionId, WifiNative.class,
147                         WifiNative.sWlan0Index, configRequest);
148             }
149             if (DBG) Log.d(TAG, "enableAndConfigureNative: ret=" + ret);
150             success = ret == WIFI_SUCCESS;
151         } else {
152             Log.w(TAG, "enableAndConfigure: NanInit fails");
153             success = false;
154         }
155 
156 
157         // TODO: do something on !success - send failure message back
158     }
159 
disableNative(short transactionId, Object cls, int iface)160     private static native int disableNative(short transactionId, Object cls, int iface);
161 
disable(short transactionId)162     public void disable(short transactionId) {
163         boolean success;
164 
165         if (VDBG) Log.d(TAG, "disableNan");
166         if (isNanInit(true)) {
167             int ret;
168             synchronized (WifiNative.sLock) {
169                 ret = disableNative(transactionId, WifiNative.class, WifiNative.sWlan0Index);
170             }
171             if (DBG) Log.d(TAG, "disableNative: ret=" + ret);
172             success = ret == WIFI_SUCCESS;
173         } else {
174             Log.w(TAG, "disable: cannot initialize NAN");
175             success = false;
176         }
177 
178         // TODO: do something on !success - send failure message back
179     }
180 
publishNative(short transactionId, int publishId, Object cls, int iface, PublishData publishData, PublishSettings publishSettings)181     private static native int publishNative(short transactionId, int publishId, Object cls,
182             int iface,
183             PublishData publishData, PublishSettings publishSettings);
184 
publish(short transactionId, int publishId, PublishData publishData, PublishSettings publishSettings)185     public void publish(short transactionId, int publishId, PublishData publishData,
186             PublishSettings publishSettings) {
187         boolean success;
188 
189         if (VDBG) {
190             Log.d(TAG, "publish: transactionId=" + transactionId + ",data='" + publishData
191                     + "', settings=" + publishSettings);
192         }
193 
194         if (isNanInit(true)) {
195             int ret;
196             synchronized (WifiNative.sLock) {
197                 ret = publishNative(transactionId, publishId, WifiNative.class,
198                         WifiNative.sWlan0Index, publishData, publishSettings);
199             }
200             if (DBG) Log.d(TAG, "publishNative: ret=" + ret);
201             success = ret == WIFI_SUCCESS;
202         } else {
203             Log.w(TAG, "publish: cannot initialize NAN");
204             success = false;
205         }
206 
207         // TODO: do something on !success - send failure message back
208     }
209 
subscribeNative(short transactionId, int subscribeId, Object cls, int iface, SubscribeData subscribeData, SubscribeSettings subscribeSettings)210     private static native int subscribeNative(short transactionId, int subscribeId, Object cls,
211             int iface, SubscribeData subscribeData, SubscribeSettings subscribeSettings);
212 
subscribe(short transactionId, int subscribeId, SubscribeData subscribeData, SubscribeSettings subscribeSettings)213     public void subscribe(short transactionId, int subscribeId, SubscribeData subscribeData,
214             SubscribeSettings subscribeSettings) {
215         boolean success;
216 
217         if (VDBG) {
218             Log.d(TAG, "subscribe: transactionId=" + transactionId + ", data='" + subscribeData
219                     + "', settings=" + subscribeSettings);
220         }
221 
222         if (isNanInit(true)) {
223             int ret;
224             synchronized (WifiNative.sLock) {
225                 ret = subscribeNative(transactionId, subscribeId, WifiNative.class,
226                         WifiNative.sWlan0Index, subscribeData, subscribeSettings);
227             }
228             if (DBG) Log.d(TAG, "subscribeNative: ret=" + ret);
229             success = ret == WIFI_SUCCESS;
230         } else {
231             Log.w(TAG, "subscribe: cannot initialize NAN");
232             success = false;
233         }
234 
235         // TODO: do something on !success - send failure message back
236     }
237 
sendMessageNative(short transactionId, Object cls, int iface, int pubSubId, int requestorInstanceId, byte[] dest, byte[] message, int messageLength)238     private static native int sendMessageNative(short transactionId, Object cls, int iface,
239             int pubSubId, int requestorInstanceId, byte[] dest, byte[] message, int messageLength);
240 
sendMessage(short transactionId, int pubSubId, int requestorInstanceId, byte[] dest, byte[] message, int messageLength)241     public void sendMessage(short transactionId, int pubSubId, int requestorInstanceId, byte[] dest,
242             byte[] message, int messageLength) {
243         boolean success;
244 
245         if (VDBG) {
246             Log.d(TAG,
247                     "sendMessage: transactionId=" + transactionId + ", pubSubId=" + pubSubId
248                             + ", requestorInstanceId=" + requestorInstanceId + ", dest="
249                             + String.valueOf(HexEncoding.encode(dest)) + ", messageLength="
250                             + messageLength);
251         }
252 
253         if (isNanInit(true)) {
254             int ret;
255             synchronized (WifiNative.sLock) {
256                 ret = sendMessageNative(transactionId, WifiNative.class, WifiNative.sWlan0Index,
257                         pubSubId, requestorInstanceId, dest, message, messageLength);
258             }
259             if (DBG) Log.d(TAG, "sendMessageNative: ret=" + ret);
260             success = ret == WIFI_SUCCESS;
261         } else {
262             Log.w(TAG, "sendMessage: cannot initialize NAN");
263             success = false;
264         }
265 
266         // TODO: do something on !success - send failure message back
267     }
268 
stopPublishNative(short transactionId, Object cls, int iface, int pubSubId)269     private static native int stopPublishNative(short transactionId, Object cls, int iface,
270             int pubSubId);
271 
stopPublish(short transactionId, int pubSubId)272     public void stopPublish(short transactionId, int pubSubId) {
273         boolean success;
274 
275         if (VDBG) {
276             Log.d(TAG, "stopPublish: transactionId=" + transactionId + ", pubSubId=" + pubSubId);
277         }
278 
279         if (isNanInit(true)) {
280             int ret;
281             synchronized (WifiNative.sLock) {
282                 ret = stopPublishNative(transactionId, WifiNative.class, WifiNative.sWlan0Index,
283                         pubSubId);
284             }
285             if (DBG) Log.d(TAG, "stopPublishNative: ret=" + ret);
286             success = ret == WIFI_SUCCESS;
287         } else {
288             Log.w(TAG, "stopPublish: cannot initialize NAN");
289             success = false;
290         }
291 
292         // TODO: do something on !success - send failure message back
293     }
294 
stopSubscribeNative(short transactionId, Object cls, int iface, int pubSubId)295     private static native int stopSubscribeNative(short transactionId, Object cls, int iface,
296             int pubSubId);
297 
stopSubscribe(short transactionId, int pubSubId)298     public void stopSubscribe(short transactionId, int pubSubId) {
299         boolean success;
300 
301         if (VDBG) {
302             Log.d(TAG, "stopSubscribe: transactionId=" + transactionId + ", pubSubId=" + pubSubId);
303         }
304 
305         if (isNanInit(true)) {
306             int ret;
307             synchronized (WifiNative.sLock) {
308                 ret = stopSubscribeNative(transactionId, WifiNative.class, WifiNative.sWlan0Index,
309                         pubSubId);
310             }
311             if (DBG) Log.d(TAG, "stopSubscribeNative: ret=" + ret);
312             success = ret == WIFI_SUCCESS;
313         } else {
314             Log.w(TAG, "stopSubscribe: cannot initialize NAN");
315             success = false;
316         }
317 
318         // TODO: do something on !success - send failure message back
319     }
320 
321     // EVENTS
322 
323     // NanResponseType for API responses: will add values as needed
324     public static final int NAN_RESPONSE_ENABLED = 0;
325     public static final int NAN_RESPONSE_PUBLISH = 2;
326     public static final int NAN_RESPONSE_PUBLISH_CANCEL = 3;
327     public static final int NAN_RESPONSE_TRANSMIT_FOLLOWUP = 4;
328     public static final int NAN_RESPONSE_SUBSCRIBE = 5;
329     public static final int NAN_RESPONSE_SUBSCRIBE_CANCEL = 6;
330     public static final int NAN_RESPONSE_GET_CAPABILITIES = 12;
331 
332     // direct copy from wifi_nan.h: need to keep in sync
333     public static final int NAN_STATUS_SUCCESS = 0;
334     public static final int NAN_STATUS_TIMEOUT = 1;
335     public static final int NAN_STATUS_DE_FAILURE = 2;
336     public static final int NAN_STATUS_INVALID_MSG_VERSION = 3;
337     public static final int NAN_STATUS_INVALID_MSG_LEN = 4;
338     public static final int NAN_STATUS_INVALID_MSG_ID = 5;
339     public static final int NAN_STATUS_INVALID_HANDLE = 6;
340     public static final int NAN_STATUS_NO_SPACE_AVAILABLE = 7;
341     public static final int NAN_STATUS_INVALID_PUBLISH_TYPE = 8;
342     public static final int NAN_STATUS_INVALID_TX_TYPE = 9;
343     public static final int NAN_STATUS_INVALID_MATCH_ALGORITHM = 10;
344     public static final int NAN_STATUS_DISABLE_IN_PROGRESS = 11;
345     public static final int NAN_STATUS_INVALID_TLV_LEN = 12;
346     public static final int NAN_STATUS_INVALID_TLV_TYPE = 13;
347     public static final int NAN_STATUS_MISSING_TLV_TYPE = 14;
348     public static final int NAN_STATUS_INVALID_TOTAL_TLVS_LEN = 15;
349     public static final int NAN_STATUS_INVALID_MATCH_HANDLE = 16;
350     public static final int NAN_STATUS_INVALID_TLV_VALUE = 17;
351     public static final int NAN_STATUS_INVALID_TX_PRIORITY = 18;
352     public static final int NAN_STATUS_INVALID_CONNECTION_MAP = 19;
353 
354     // NAN Configuration Response codes
355     public static final int NAN_STATUS_INVALID_RSSI_CLOSE_VALUE = 4096;
356     public static final int NAN_STATUS_INVALID_RSSI_MIDDLE_VALUE = 4097;
357     public static final int NAN_STATUS_INVALID_HOP_COUNT_LIMIT = 4098;
358     public static final int NAN_STATUS_INVALID_MASTER_PREFERENCE_VALUE = 4099;
359     public static final int NAN_STATUS_INVALID_LOW_CLUSTER_ID_VALUE = 4100;
360     public static final int NAN_STATUS_INVALID_HIGH_CLUSTER_ID_VALUE = 4101;
361     public static final int NAN_STATUS_INVALID_BACKGROUND_SCAN_PERIOD = 4102;
362     public static final int NAN_STATUS_INVALID_RSSI_PROXIMITY_VALUE = 4103;
363     public static final int NAN_STATUS_INVALID_SCAN_CHANNEL = 4104;
364     public static final int NAN_STATUS_INVALID_POST_NAN_CONNECTIVITY_CAPABILITIES_BITMAP = 4105;
365     public static final int NAN_STATUS_INVALID_FA_MAP_NUMCHAN_VALUE = 4106;
366     public static final int NAN_STATUS_INVALID_FA_MAP_DURATION_VALUE = 4107;
367     public static final int NAN_STATUS_INVALID_FA_MAP_CLASS_VALUE = 4108;
368     public static final int NAN_STATUS_INVALID_FA_MAP_CHANNEL_VALUE = 4109;
369     public static final int NAN_STATUS_INVALID_FA_MAP_AVAILABILITY_INTERVAL_BITMAP_VALUE = 4110;
370     public static final int NAN_STATUS_INVALID_FA_MAP_MAP_ID = 4111;
371     public static final int NAN_STATUS_INVALID_POST_NAN_DISCOVERY_CONN_TYPE_VALUE = 4112;
372     public static final int NAN_STATUS_INVALID_POST_NAN_DISCOVERY_DEVICE_ROLE_VALUE = 4113;
373     public static final int NAN_STATUS_INVALID_POST_NAN_DISCOVERY_DURATION_VALUE = 4114;
374     public static final int NAN_STATUS_INVALID_POST_NAN_DISCOVERY_BITMAP_VALUE = 4115;
375     public static final int NAN_STATUS_MISSING_FUTHER_AVAILABILITY_MAP = 4116;
376     public static final int NAN_STATUS_INVALID_BAND_CONFIG_FLAGS = 4117;
377 
378     // publish/subscribe termination reasons
379     public static final int NAN_TERMINATED_REASON_INVALID = 8192;
380     public static final int NAN_TERMINATED_REASON_TIMEOUT = 8193;
381     public static final int NAN_TERMINATED_REASON_USER_REQUEST = 8194;
382     public static final int NAN_TERMINATED_REASON_FAILURE = 8195;
383     public static final int NAN_TERMINATED_REASON_COUNT_REACHED = 8196;
384     public static final int NAN_TERMINATED_REASON_DE_SHUTDOWN = 8197;
385     public static final int NAN_TERMINATED_REASON_DISABLE_IN_PROGRESS = 8198;
386     public static final int NAN_TERMINATED_REASON_POST_DISC_ATTR_EXPIRED = 8199;
387     public static final int NAN_TERMINATED_REASON_POST_DISC_LEN_EXCEEDED = 8200;
388     public static final int NAN_TERMINATED_REASON_FURTHER_AVAIL_MAP_EMPTY = 8201;
389 
translateHalStatusToPublicStatus(int halStatus)390     private static int translateHalStatusToPublicStatus(int halStatus) {
391         switch (halStatus) {
392             case NAN_STATUS_NO_SPACE_AVAILABLE:
393                 return WifiNanSessionListener.FAIL_REASON_NO_RESOURCES;
394 
395             case NAN_STATUS_TIMEOUT:
396             case NAN_STATUS_DE_FAILURE:
397             case NAN_STATUS_DISABLE_IN_PROGRESS:
398                 return WifiNanSessionListener.FAIL_REASON_OTHER;
399 
400             case NAN_STATUS_INVALID_MSG_VERSION:
401             case NAN_STATUS_INVALID_MSG_LEN:
402             case NAN_STATUS_INVALID_MSG_ID:
403             case NAN_STATUS_INVALID_HANDLE:
404             case NAN_STATUS_INVALID_PUBLISH_TYPE:
405             case NAN_STATUS_INVALID_TX_TYPE:
406             case NAN_STATUS_INVALID_MATCH_ALGORITHM:
407             case NAN_STATUS_INVALID_TLV_LEN:
408             case NAN_STATUS_INVALID_TLV_TYPE:
409             case NAN_STATUS_MISSING_TLV_TYPE:
410             case NAN_STATUS_INVALID_TOTAL_TLVS_LEN:
411             case NAN_STATUS_INVALID_MATCH_HANDLE:
412             case NAN_STATUS_INVALID_TLV_VALUE:
413             case NAN_STATUS_INVALID_TX_PRIORITY:
414             case NAN_STATUS_INVALID_CONNECTION_MAP:
415             case NAN_STATUS_INVALID_RSSI_CLOSE_VALUE:
416             case NAN_STATUS_INVALID_RSSI_MIDDLE_VALUE:
417             case NAN_STATUS_INVALID_HOP_COUNT_LIMIT:
418             case NAN_STATUS_INVALID_MASTER_PREFERENCE_VALUE:
419             case NAN_STATUS_INVALID_LOW_CLUSTER_ID_VALUE:
420             case NAN_STATUS_INVALID_HIGH_CLUSTER_ID_VALUE:
421             case NAN_STATUS_INVALID_BACKGROUND_SCAN_PERIOD:
422             case NAN_STATUS_INVALID_RSSI_PROXIMITY_VALUE:
423             case NAN_STATUS_INVALID_SCAN_CHANNEL:
424             case NAN_STATUS_INVALID_POST_NAN_CONNECTIVITY_CAPABILITIES_BITMAP:
425             case NAN_STATUS_INVALID_FA_MAP_NUMCHAN_VALUE:
426             case NAN_STATUS_INVALID_FA_MAP_DURATION_VALUE:
427             case NAN_STATUS_INVALID_FA_MAP_CLASS_VALUE:
428             case NAN_STATUS_INVALID_FA_MAP_CHANNEL_VALUE:
429             case NAN_STATUS_INVALID_FA_MAP_AVAILABILITY_INTERVAL_BITMAP_VALUE:
430             case NAN_STATUS_INVALID_FA_MAP_MAP_ID:
431             case NAN_STATUS_INVALID_POST_NAN_DISCOVERY_CONN_TYPE_VALUE:
432             case NAN_STATUS_INVALID_POST_NAN_DISCOVERY_DEVICE_ROLE_VALUE:
433             case NAN_STATUS_INVALID_POST_NAN_DISCOVERY_DURATION_VALUE:
434             case NAN_STATUS_INVALID_POST_NAN_DISCOVERY_BITMAP_VALUE:
435             case NAN_STATUS_MISSING_FUTHER_AVAILABILITY_MAP:
436             case NAN_STATUS_INVALID_BAND_CONFIG_FLAGS:
437                 return WifiNanSessionListener.FAIL_REASON_INVALID_ARGS;
438 
439                 // publish/subscribe termination reasons
440             case NAN_TERMINATED_REASON_TIMEOUT:
441             case NAN_TERMINATED_REASON_USER_REQUEST:
442             case NAN_TERMINATED_REASON_COUNT_REACHED:
443                 return WifiNanSessionListener.TERMINATE_REASON_DONE;
444 
445             case NAN_TERMINATED_REASON_INVALID:
446             case NAN_TERMINATED_REASON_FAILURE:
447             case NAN_TERMINATED_REASON_DE_SHUTDOWN:
448             case NAN_TERMINATED_REASON_DISABLE_IN_PROGRESS:
449             case NAN_TERMINATED_REASON_POST_DISC_ATTR_EXPIRED:
450             case NAN_TERMINATED_REASON_POST_DISC_LEN_EXCEEDED:
451             case NAN_TERMINATED_REASON_FURTHER_AVAIL_MAP_EMPTY:
452                 return WifiNanSessionListener.TERMINATE_REASON_FAIL;
453         }
454 
455         return WifiNanSessionListener.FAIL_REASON_OTHER;
456     }
457 
458     // callback from native
onNanNotifyResponse(short transactionId, int responseType, int status, int value)459     private static void onNanNotifyResponse(short transactionId, int responseType, int status,
460             int value) {
461         if (VDBG) {
462             Log.v(TAG,
463                     "onNanNotifyResponse: transactionId=" + transactionId + ", responseType="
464                     + responseType + ", status=" + status + ", value=" + value);
465         }
466 
467         switch (responseType) {
468             case NAN_RESPONSE_ENABLED:
469                 if (status == NAN_STATUS_SUCCESS) {
470                     WifiNanStateManager.getInstance().onConfigCompleted(transactionId);
471                 } else {
472                     WifiNanStateManager.getInstance().onConfigFailed(transactionId,
473                             translateHalStatusToPublicStatus(status));
474                 }
475                 break;
476             case NAN_RESPONSE_PUBLISH_CANCEL:
477                 if (status != NAN_STATUS_SUCCESS) {
478                     Log.e(TAG, "onNanNotifyResponse: NAN_RESPONSE_PUBLISH_CANCEL error - status="
479                             + status + ", value=" + value);
480                 }
481                 break;
482             case NAN_RESPONSE_TRANSMIT_FOLLOWUP:
483                 if (status == NAN_STATUS_SUCCESS) {
484                     WifiNanStateManager.getInstance().onMessageSendSuccess(transactionId);
485                 } else {
486                     WifiNanStateManager.getInstance().onMessageSendFail(transactionId,
487                             translateHalStatusToPublicStatus(status));
488                 }
489                 break;
490             case NAN_RESPONSE_SUBSCRIBE_CANCEL:
491                 if (status != NAN_STATUS_SUCCESS) {
492                     Log.e(TAG, "onNanNotifyResponse: NAN_RESPONSE_PUBLISH_CANCEL error - status="
493                             + status + ", value=" + value);
494                 }
495                 break;
496             default:
497                 WifiNanStateManager.getInstance().onUnknownTransaction(responseType, transactionId,
498                         translateHalStatusToPublicStatus(status));
499                 break;
500         }
501     }
502 
onNanNotifyResponsePublishSubscribe(short transactionId, int responseType, int status, int value, int pubSubId)503     private static void onNanNotifyResponsePublishSubscribe(short transactionId, int responseType,
504             int status, int value, int pubSubId) {
505         if (VDBG) {
506             Log.v(TAG,
507                     "onNanNotifyResponsePublishSubscribe: transactionId=" + transactionId
508                             + ", responseType=" + responseType + ", status=" + status + ", value="
509                             + value + ", pubSubId=" + pubSubId);
510         }
511 
512         switch (responseType) {
513             case NAN_RESPONSE_PUBLISH:
514                 if (status == NAN_STATUS_SUCCESS) {
515                     WifiNanStateManager.getInstance().onPublishSuccess(transactionId, pubSubId);
516                 } else {
517                     WifiNanStateManager.getInstance().onPublishFail(transactionId,
518                             translateHalStatusToPublicStatus(status));
519                 }
520                 break;
521             case NAN_RESPONSE_SUBSCRIBE:
522                 if (status == NAN_STATUS_SUCCESS) {
523                     WifiNanStateManager.getInstance().onSubscribeSuccess(transactionId, pubSubId);
524                 } else {
525                     WifiNanStateManager.getInstance().onSubscribeFail(transactionId,
526                             translateHalStatusToPublicStatus(status));
527                 }
528                 break;
529             default:
530                 WifiNanStateManager.getInstance().onUnknownTransaction(responseType, transactionId,
531                         translateHalStatusToPublicStatus(status));
532                 break;
533         }
534     }
535 
onNanNotifyResponseCapabilities(short transactionId, int status, int value, Capabilities capabilities)536     private static void onNanNotifyResponseCapabilities(short transactionId, int status, int value,
537             Capabilities capabilities) {
538         if (VDBG) {
539             Log.v(TAG, "onNanNotifyResponsePublishSubscribe: transactionId=" + transactionId
540                     + ", status=" + status + ", value=" + value + ", capabilities=" + capabilities);
541         }
542 
543         if (status == NAN_STATUS_SUCCESS) {
544             WifiNanStateManager.getInstance().onCapabilitiesUpdate(transactionId, capabilities);
545         } else {
546             Log.e(TAG,
547                     "onNanNotifyResponseCapabilities: error status=" + status + ", value=" + value);
548         }
549     }
550 
551     public static final int NAN_EVENT_ID_DISC_MAC_ADDR = 0;
552     public static final int NAN_EVENT_ID_STARTED_CLUSTER = 1;
553     public static final int NAN_EVENT_ID_JOINED_CLUSTER = 2;
554 
555     // callback from native
onDiscoveryEngineEvent(int eventType, byte[] mac)556     private static void onDiscoveryEngineEvent(int eventType, byte[] mac) {
557         if (VDBG) {
558             Log.v(TAG, "onDiscoveryEngineEvent: eventType=" + eventType + ", mac="
559                     + String.valueOf(HexEncoding.encode(mac)));
560         }
561 
562         if (eventType == NAN_EVENT_ID_DISC_MAC_ADDR) {
563             WifiNanStateManager.getInstance().onInterfaceAddressChange(mac);
564         } else if (eventType == NAN_EVENT_ID_STARTED_CLUSTER) {
565             WifiNanStateManager.getInstance()
566                     .onClusterChange(WifiNanClientState.CLUSTER_CHANGE_EVENT_STARTED, mac);
567         } else if (eventType == NAN_EVENT_ID_JOINED_CLUSTER) {
568             WifiNanStateManager.getInstance()
569                     .onClusterChange(WifiNanClientState.CLUSTER_CHANGE_EVENT_JOINED, mac);
570         } else {
571             Log.w(TAG, "onDiscoveryEngineEvent: invalid eventType=" + eventType);
572         }
573     }
574 
575     // callback from native
onMatchEvent(int pubSubId, int requestorInstanceId, byte[] mac, byte[] serviceSpecificInfo, int serviceSpecificInfoLength, byte[] matchFilter, int matchFilterLength)576     private static void onMatchEvent(int pubSubId, int requestorInstanceId, byte[] mac,
577             byte[] serviceSpecificInfo, int serviceSpecificInfoLength, byte[] matchFilter,
578             int matchFilterLength) {
579         if (VDBG) {
580             Log.v(TAG, "onMatchEvent: pubSubId=" + pubSubId + ", requestorInstanceId="
581                     + requestorInstanceId + ", mac=" + String.valueOf(HexEncoding.encode(mac))
582                     + ", serviceSpecificInfo=" + serviceSpecificInfo + ", matchFilterLength="
583                     + matchFilterLength + ", matchFilter=" + matchFilter);
584         }
585 
586         WifiNanStateManager.getInstance().onMatch(pubSubId, requestorInstanceId, mac,
587                 serviceSpecificInfo, serviceSpecificInfoLength, matchFilter, matchFilterLength);
588     }
589 
590     // callback from native
onPublishTerminated(int publishId, int status)591     private static void onPublishTerminated(int publishId, int status) {
592         if (VDBG) Log.v(TAG, "onPublishTerminated: publishId=" + publishId + ", status=" + status);
593 
594         WifiNanStateManager.getInstance().onPublishTerminated(publishId,
595                 translateHalStatusToPublicStatus(status));
596     }
597 
598     // callback from native
onSubscribeTerminated(int subscribeId, int status)599     private static void onSubscribeTerminated(int subscribeId, int status) {
600         if (VDBG) {
601             Log.v(TAG, "onSubscribeTerminated: subscribeId=" + subscribeId + ", status=" + status);
602         }
603 
604         WifiNanStateManager.getInstance().onSubscribeTerminated(subscribeId,
605                 translateHalStatusToPublicStatus(status));
606     }
607 
608     // callback from native
onFollowupEvent(int pubSubId, int requestorInstanceId, byte[] mac, byte[] message, int messageLength)609     private static void onFollowupEvent(int pubSubId, int requestorInstanceId, byte[] mac,
610             byte[] message, int messageLength) {
611         if (VDBG) {
612             Log.v(TAG, "onFollowupEvent: pubSubId=" + pubSubId + ", requestorInstanceId="
613                     + requestorInstanceId + ", mac=" + String.valueOf(HexEncoding.encode(mac))
614                     + ", messageLength=" + messageLength);
615         }
616 
617         WifiNanStateManager.getInstance().onMessageReceived(pubSubId, requestorInstanceId, mac,
618                 message, messageLength);
619     }
620 
621     // callback from native
onDisabledEvent(int status)622     private static void onDisabledEvent(int status) {
623         if (VDBG) Log.v(TAG, "onDisabledEvent: status=" + status);
624 
625         WifiNanStateManager.getInstance().onNanDown(translateHalStatusToPublicStatus(status));
626     }
627 }
628