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.android.server.wifi.aware; 18 19 import android.hardware.wifi.V1_0.NanCapabilities; 20 import android.hardware.wifi.V1_0.NanClusterEventInd; 21 import android.hardware.wifi.V1_0.NanClusterEventType; 22 import android.hardware.wifi.V1_0.NanDataPathConfirmInd; 23 import android.hardware.wifi.V1_0.NanDataPathRequestInd; 24 import android.hardware.wifi.V1_0.NanFollowupReceivedInd; 25 import android.hardware.wifi.V1_0.NanMatchInd; 26 import android.hardware.wifi.V1_0.NanStatusType; 27 import android.hardware.wifi.V1_0.WifiNanStatus; 28 import android.hardware.wifi.V1_2.IWifiNanIfaceEventCallback; 29 import android.hardware.wifi.V1_2.NanDataPathScheduleUpdateInd; 30 import android.os.ShellCommand; 31 import android.util.Log; 32 import android.util.SparseIntArray; 33 34 import libcore.util.HexEncoding; 35 36 import org.json.JSONException; 37 import org.json.JSONObject; 38 39 import java.io.FileDescriptor; 40 import java.io.PrintWriter; 41 import java.util.ArrayList; 42 import java.util.Arrays; 43 44 /** 45 * Manages the callbacks from Wi-Fi Aware HIDL (HAL). 46 */ 47 public class WifiAwareNativeCallback extends IWifiNanIfaceEventCallback.Stub implements 48 WifiAwareShellCommand.DelegatedShellCommand { 49 private static final String TAG = "WifiAwareNativeCallback"; 50 private static final boolean VDBG = false; 51 /* package */ boolean mDbg = false; 52 53 /* package */ boolean mIsHal12OrLater = false; 54 55 private final WifiAwareStateManager mWifiAwareStateManager; 56 WifiAwareNativeCallback(WifiAwareStateManager wifiAwareStateManager)57 public WifiAwareNativeCallback(WifiAwareStateManager wifiAwareStateManager) { 58 mWifiAwareStateManager = wifiAwareStateManager; 59 } 60 61 /* 62 * Counts of callbacks from HAL. Retrievable through shell command. 63 */ 64 private static final int CB_EV_CLUSTER = 0; 65 private static final int CB_EV_DISABLED = 1; 66 private static final int CB_EV_PUBLISH_TERMINATED = 2; 67 private static final int CB_EV_SUBSCRIBE_TERMINATED = 3; 68 private static final int CB_EV_MATCH = 4; 69 private static final int CB_EV_MATCH_EXPIRED = 5; 70 private static final int CB_EV_FOLLOWUP_RECEIVED = 6; 71 private static final int CB_EV_TRANSMIT_FOLLOWUP = 7; 72 private static final int CB_EV_DATA_PATH_REQUEST = 8; 73 private static final int CB_EV_DATA_PATH_CONFIRM = 9; 74 private static final int CB_EV_DATA_PATH_TERMINATED = 10; 75 private static final int CB_EV_DATA_PATH_SCHED_UPDATE = 11; 76 77 private SparseIntArray mCallbackCounter = new SparseIntArray(); 78 incrementCbCount(int callbackId)79 private void incrementCbCount(int callbackId) { 80 mCallbackCounter.put(callbackId, mCallbackCounter.get(callbackId) + 1); 81 } 82 83 /** 84 * Interpreter of adb shell command 'adb shell wifiaware native_cb ...'. 85 * 86 * @return -1 if parameter not recognized or invalid value, 0 otherwise. 87 */ 88 @Override onCommand(ShellCommand parentShell)89 public int onCommand(ShellCommand parentShell) { 90 final PrintWriter pwe = parentShell.getErrPrintWriter(); 91 final PrintWriter pwo = parentShell.getOutPrintWriter(); 92 93 String subCmd = parentShell.getNextArgRequired(); 94 if (VDBG) Log.v(TAG, "onCommand: subCmd='" + subCmd + "'"); 95 switch (subCmd) { 96 case "get_cb_count": { 97 String option = parentShell.getNextOption(); 98 if (VDBG) Log.v(TAG, "option='" + option + "'"); 99 boolean reset = false; 100 if (option != null) { 101 if ("--reset".equals(option)) { 102 reset = true; 103 } else { 104 pwe.println("Unknown option to 'get_cb_count'"); 105 return -1; 106 } 107 } 108 109 JSONObject j = new JSONObject(); 110 try { 111 for (int i = 0; i < mCallbackCounter.size(); ++i) { 112 j.put(Integer.toString(mCallbackCounter.keyAt(i)), 113 mCallbackCounter.valueAt(i)); 114 } 115 } catch (JSONException e) { 116 Log.e(TAG, "onCommand: get_cb_count e=" + e); 117 } 118 pwo.println(j.toString()); 119 if (reset) { 120 mCallbackCounter.clear(); 121 } 122 return 0; 123 } 124 default: 125 pwe.println("Unknown 'wifiaware native_cb <cmd>'"); 126 } 127 128 return -1; 129 } 130 131 @Override onReset()132 public void onReset() { 133 // NOP (onReset is intended for configuration reset - not data reset) 134 } 135 136 @Override onHelp(String command, ShellCommand parentShell)137 public void onHelp(String command, ShellCommand parentShell) { 138 final PrintWriter pw = parentShell.getOutPrintWriter(); 139 140 pw.println(" " + command); 141 pw.println(" get_cb_count [--reset]: gets the number of callbacks (and optionally reset " 142 + "count)"); 143 } 144 145 @Override notifyCapabilitiesResponse(short id, WifiNanStatus status, NanCapabilities capabilities)146 public void notifyCapabilitiesResponse(short id, WifiNanStatus status, 147 NanCapabilities capabilities) { 148 if (mDbg) { 149 Log.v(TAG, "notifyCapabilitiesResponse: id=" + id + ", status=" + statusString(status) 150 + ", capabilities=" + capabilities); 151 } 152 153 if (status.status == NanStatusType.SUCCESS) { 154 Capabilities frameworkCapabilities = new Capabilities(); 155 frameworkCapabilities.maxConcurrentAwareClusters = capabilities.maxConcurrentClusters; 156 frameworkCapabilities.maxPublishes = capabilities.maxPublishes; 157 frameworkCapabilities.maxSubscribes = capabilities.maxSubscribes; 158 frameworkCapabilities.maxServiceNameLen = capabilities.maxServiceNameLen; 159 frameworkCapabilities.maxMatchFilterLen = capabilities.maxMatchFilterLen; 160 frameworkCapabilities.maxTotalMatchFilterLen = capabilities.maxTotalMatchFilterLen; 161 frameworkCapabilities.maxServiceSpecificInfoLen = 162 capabilities.maxServiceSpecificInfoLen; 163 frameworkCapabilities.maxExtendedServiceSpecificInfoLen = 164 capabilities.maxExtendedServiceSpecificInfoLen; 165 frameworkCapabilities.maxNdiInterfaces = capabilities.maxNdiInterfaces; 166 frameworkCapabilities.maxNdpSessions = capabilities.maxNdpSessions; 167 frameworkCapabilities.maxAppInfoLen = capabilities.maxAppInfoLen; 168 frameworkCapabilities.maxQueuedTransmitMessages = 169 capabilities.maxQueuedTransmitFollowupMsgs; 170 frameworkCapabilities.maxSubscribeInterfaceAddresses = 171 capabilities.maxSubscribeInterfaceAddresses; 172 frameworkCapabilities.supportedCipherSuites = capabilities.supportedCipherSuites; 173 174 mWifiAwareStateManager.onCapabilitiesUpdateResponse(id, frameworkCapabilities); 175 } else { 176 Log.e(TAG, "notifyCapabilitiesResponse: error code=" + status.status + " (" 177 + status.description + ")"); 178 } 179 } 180 181 @Override notifyEnableResponse(short id, WifiNanStatus status)182 public void notifyEnableResponse(short id, WifiNanStatus status) { 183 if (mDbg) Log.v(TAG, "notifyEnableResponse: id=" + id + ", status=" + statusString(status)); 184 185 if (status.status == NanStatusType.ALREADY_ENABLED) { 186 Log.wtf(TAG, "notifyEnableResponse: id=" + id + ", already enabled!?"); 187 } 188 189 if (status.status == NanStatusType.SUCCESS 190 || status.status == NanStatusType.ALREADY_ENABLED) { 191 mWifiAwareStateManager.onConfigSuccessResponse(id); 192 } else { 193 mWifiAwareStateManager.onConfigFailedResponse(id, status.status); 194 } 195 } 196 197 @Override notifyConfigResponse(short id, WifiNanStatus status)198 public void notifyConfigResponse(short id, WifiNanStatus status) { 199 if (mDbg) Log.v(TAG, "notifyConfigResponse: id=" + id + ", status=" + statusString(status)); 200 201 if (status.status == NanStatusType.SUCCESS) { 202 mWifiAwareStateManager.onConfigSuccessResponse(id); 203 } else { 204 mWifiAwareStateManager.onConfigFailedResponse(id, status.status); 205 } 206 } 207 208 @Override notifyDisableResponse(short id, WifiNanStatus status)209 public void notifyDisableResponse(short id, WifiNanStatus status) { 210 if (mDbg) { 211 Log.v(TAG, "notifyDisableResponse: id=" + id + ", status=" + statusString(status)); 212 } 213 214 if (status.status != NanStatusType.SUCCESS) { 215 Log.e(TAG, "notifyDisableResponse: failure - code=" + status.status + " (" 216 + status.description + ")"); 217 } 218 mWifiAwareStateManager.onDisableResponse(id, status.status); 219 } 220 221 @Override notifyStartPublishResponse(short id, WifiNanStatus status, byte publishId)222 public void notifyStartPublishResponse(short id, WifiNanStatus status, byte publishId) { 223 if (mDbg) { 224 Log.v(TAG, "notifyStartPublishResponse: id=" + id + ", status=" + statusString(status) 225 + ", publishId=" + publishId); 226 } 227 228 if (status.status == NanStatusType.SUCCESS) { 229 mWifiAwareStateManager.onSessionConfigSuccessResponse(id, true, publishId); 230 } else { 231 mWifiAwareStateManager.onSessionConfigFailResponse(id, true, status.status); 232 } 233 } 234 235 @Override notifyStopPublishResponse(short id, WifiNanStatus status)236 public void notifyStopPublishResponse(short id, WifiNanStatus status) { 237 if (mDbg) { 238 Log.v(TAG, "notifyStopPublishResponse: id=" + id + ", status=" + statusString(status)); 239 } 240 241 if (status.status == NanStatusType.SUCCESS) { 242 // NOP 243 } else { 244 Log.e(TAG, "notifyStopPublishResponse: failure - code=" + status.status + " (" 245 + status.description + ")"); 246 } 247 } 248 249 @Override notifyStartSubscribeResponse(short id, WifiNanStatus status, byte subscribeId)250 public void notifyStartSubscribeResponse(short id, WifiNanStatus status, byte subscribeId) { 251 if (mDbg) { 252 Log.v(TAG, "notifyStartSubscribeResponse: id=" + id + ", status=" + statusString(status) 253 + ", subscribeId=" + subscribeId); 254 } 255 256 if (status.status == NanStatusType.SUCCESS) { 257 mWifiAwareStateManager.onSessionConfigSuccessResponse(id, false, subscribeId); 258 } else { 259 mWifiAwareStateManager.onSessionConfigFailResponse(id, false, status.status); 260 } 261 } 262 263 @Override notifyStopSubscribeResponse(short id, WifiNanStatus status)264 public void notifyStopSubscribeResponse(short id, WifiNanStatus status) { 265 if (mDbg) { 266 Log.v(TAG, "notifyStopSubscribeResponse: id=" + id + ", status=" 267 + statusString(status)); 268 } 269 270 if (status.status == NanStatusType.SUCCESS) { 271 // NOP 272 } else { 273 Log.e(TAG, "notifyStopSubscribeResponse: failure - code=" + status.status + " (" 274 + status.description + ")"); 275 } 276 } 277 278 @Override notifyTransmitFollowupResponse(short id, WifiNanStatus status)279 public void notifyTransmitFollowupResponse(short id, WifiNanStatus status) { 280 if (mDbg) { 281 Log.v(TAG, "notifyTransmitFollowupResponse: id=" + id + ", status=" 282 + statusString(status)); 283 } 284 285 if (status.status == NanStatusType.SUCCESS) { 286 mWifiAwareStateManager.onMessageSendQueuedSuccessResponse(id); 287 } else { 288 mWifiAwareStateManager.onMessageSendQueuedFailResponse(id, status.status); 289 } 290 } 291 292 @Override notifyCreateDataInterfaceResponse(short id, WifiNanStatus status)293 public void notifyCreateDataInterfaceResponse(short id, WifiNanStatus status) { 294 if (mDbg) { 295 Log.v(TAG, "notifyCreateDataInterfaceResponse: id=" + id + ", status=" 296 + statusString(status)); 297 } 298 299 mWifiAwareStateManager.onCreateDataPathInterfaceResponse(id, 300 status.status == NanStatusType.SUCCESS, status.status); 301 } 302 303 @Override notifyDeleteDataInterfaceResponse(short id, WifiNanStatus status)304 public void notifyDeleteDataInterfaceResponse(short id, WifiNanStatus status) { 305 if (mDbg) { 306 Log.v(TAG, "notifyDeleteDataInterfaceResponse: id=" + id + ", status=" 307 + statusString(status)); 308 } 309 310 mWifiAwareStateManager.onDeleteDataPathInterfaceResponse(id, 311 status.status == NanStatusType.SUCCESS, status.status); 312 } 313 314 @Override notifyInitiateDataPathResponse(short id, WifiNanStatus status, int ndpInstanceId)315 public void notifyInitiateDataPathResponse(short id, WifiNanStatus status, 316 int ndpInstanceId) { 317 if (mDbg) { 318 Log.v(TAG, "notifyInitiateDataPathResponse: id=" + id + ", status=" 319 + statusString(status) + ", ndpInstanceId=" + ndpInstanceId); 320 } 321 322 if (status.status == NanStatusType.SUCCESS) { 323 mWifiAwareStateManager.onInitiateDataPathResponseSuccess(id, ndpInstanceId); 324 } else { 325 mWifiAwareStateManager.onInitiateDataPathResponseFail(id, status.status); 326 } 327 } 328 329 @Override notifyRespondToDataPathIndicationResponse(short id, WifiNanStatus status)330 public void notifyRespondToDataPathIndicationResponse(short id, WifiNanStatus status) { 331 if (mDbg) { 332 Log.v(TAG, "notifyRespondToDataPathIndicationResponse: id=" + id 333 + ", status=" + statusString(status)); 334 } 335 336 mWifiAwareStateManager.onRespondToDataPathSetupRequestResponse(id, 337 status.status == NanStatusType.SUCCESS, status.status); 338 } 339 340 @Override notifyTerminateDataPathResponse(short id, WifiNanStatus status)341 public void notifyTerminateDataPathResponse(short id, WifiNanStatus status) { 342 if (mDbg) { 343 Log.v(TAG, "notifyTerminateDataPathResponse: id=" + id + ", status=" 344 + statusString(status)); 345 } 346 347 mWifiAwareStateManager.onEndDataPathResponse(id, status.status == NanStatusType.SUCCESS, 348 status.status); 349 } 350 351 @Override eventClusterEvent(NanClusterEventInd event)352 public void eventClusterEvent(NanClusterEventInd event) { 353 if (mDbg) { 354 Log.v(TAG, "eventClusterEvent: eventType=" + event.eventType + ", addr=" 355 + String.valueOf(HexEncoding.encode(event.addr))); 356 } 357 incrementCbCount(CB_EV_CLUSTER); 358 359 if (event.eventType == NanClusterEventType.DISCOVERY_MAC_ADDRESS_CHANGED) { 360 mWifiAwareStateManager.onInterfaceAddressChangeNotification(event.addr); 361 } else if (event.eventType == NanClusterEventType.STARTED_CLUSTER) { 362 mWifiAwareStateManager.onClusterChangeNotification( 363 WifiAwareClientState.CLUSTER_CHANGE_EVENT_STARTED, event.addr); 364 } else if (event.eventType == NanClusterEventType.JOINED_CLUSTER) { 365 mWifiAwareStateManager.onClusterChangeNotification( 366 WifiAwareClientState.CLUSTER_CHANGE_EVENT_JOINED, event.addr); 367 } else { 368 Log.e(TAG, "eventClusterEvent: invalid eventType=" + event.eventType); 369 } 370 } 371 372 @Override eventDisabled(WifiNanStatus status)373 public void eventDisabled(WifiNanStatus status) { 374 if (mDbg) Log.v(TAG, "eventDisabled: status=" + statusString(status)); 375 incrementCbCount(CB_EV_DISABLED); 376 377 mWifiAwareStateManager.onAwareDownNotification(status.status); 378 } 379 380 @Override eventPublishTerminated(byte sessionId, WifiNanStatus status)381 public void eventPublishTerminated(byte sessionId, WifiNanStatus status) { 382 if (mDbg) { 383 Log.v(TAG, "eventPublishTerminated: sessionId=" + sessionId + ", status=" 384 + statusString(status)); 385 } 386 incrementCbCount(CB_EV_PUBLISH_TERMINATED); 387 388 mWifiAwareStateManager.onSessionTerminatedNotification(sessionId, status.status, true); 389 } 390 391 @Override eventSubscribeTerminated(byte sessionId, WifiNanStatus status)392 public void eventSubscribeTerminated(byte sessionId, WifiNanStatus status) { 393 if (mDbg) { 394 Log.v(TAG, "eventSubscribeTerminated: sessionId=" + sessionId + ", status=" 395 + statusString(status)); 396 } 397 incrementCbCount(CB_EV_SUBSCRIBE_TERMINATED); 398 399 mWifiAwareStateManager.onSessionTerminatedNotification(sessionId, status.status, false); 400 } 401 402 @Override eventMatch(NanMatchInd event)403 public void eventMatch(NanMatchInd event) { 404 if (mDbg) { 405 Log.v(TAG, "eventMatch: discoverySessionId=" + event.discoverySessionId + ", peerId=" 406 + event.peerId + ", addr=" + String.valueOf(HexEncoding.encode(event.addr)) 407 + ", serviceSpecificInfo=" + Arrays.toString( 408 convertArrayListToNativeByteArray(event.serviceSpecificInfo)) + ", ssi.size()=" 409 + (event.serviceSpecificInfo == null ? 0 : event.serviceSpecificInfo.size()) 410 + ", matchFilter=" + Arrays.toString( 411 convertArrayListToNativeByteArray(event.matchFilter)) + ", mf.size()=" + ( 412 event.matchFilter == null ? 0 : event.matchFilter.size()) 413 + ", rangingIndicationType=" + event.rangingIndicationType 414 + ", rangingMeasurementInCm=" + event.rangingMeasurementInCm); 415 } 416 incrementCbCount(CB_EV_MATCH); 417 418 // TODO: b/69428593 get rid of conversion once HAL moves from CM to MM 419 mWifiAwareStateManager.onMatchNotification(event.discoverySessionId, event.peerId, 420 event.addr, convertArrayListToNativeByteArray(event.serviceSpecificInfo), 421 convertArrayListToNativeByteArray(event.matchFilter), event.rangingIndicationType, 422 event.rangingMeasurementInCm * 10); 423 } 424 425 @Override eventMatchExpired(byte discoverySessionId, int peerId)426 public void eventMatchExpired(byte discoverySessionId, int peerId) { 427 if (mDbg) { 428 Log.v(TAG, "eventMatchExpired: discoverySessionId=" + discoverySessionId 429 + ", peerId=" + peerId); 430 } 431 incrementCbCount(CB_EV_MATCH_EXPIRED); 432 433 // NOP 434 } 435 436 @Override eventFollowupReceived(NanFollowupReceivedInd event)437 public void eventFollowupReceived(NanFollowupReceivedInd event) { 438 if (mDbg) { 439 Log.v(TAG, "eventFollowupReceived: discoverySessionId=" + event.discoverySessionId 440 + ", peerId=" + event.peerId + ", addr=" + String.valueOf( 441 HexEncoding.encode(event.addr)) + ", serviceSpecificInfo=" + Arrays.toString( 442 convertArrayListToNativeByteArray(event.serviceSpecificInfo)) + ", ssi.size()=" 443 + (event.serviceSpecificInfo == null ? 0 : event.serviceSpecificInfo.size())); 444 } 445 incrementCbCount(CB_EV_FOLLOWUP_RECEIVED); 446 447 mWifiAwareStateManager.onMessageReceivedNotification(event.discoverySessionId, event.peerId, 448 event.addr, convertArrayListToNativeByteArray(event.serviceSpecificInfo)); 449 } 450 451 @Override eventTransmitFollowup(short id, WifiNanStatus status)452 public void eventTransmitFollowup(short id, WifiNanStatus status) { 453 if (mDbg) { 454 Log.v(TAG, "eventTransmitFollowup: id=" + id + ", status=" + statusString(status)); 455 } 456 incrementCbCount(CB_EV_TRANSMIT_FOLLOWUP); 457 458 if (status.status == NanStatusType.SUCCESS) { 459 mWifiAwareStateManager.onMessageSendSuccessNotification(id); 460 } else { 461 mWifiAwareStateManager.onMessageSendFailNotification(id, status.status); 462 } 463 } 464 465 @Override eventDataPathRequest(NanDataPathRequestInd event)466 public void eventDataPathRequest(NanDataPathRequestInd event) { 467 if (mDbg) { 468 Log.v(TAG, "eventDataPathRequest: discoverySessionId=" + event.discoverySessionId 469 + ", peerDiscMacAddr=" + String.valueOf( 470 HexEncoding.encode(event.peerDiscMacAddr)) + ", ndpInstanceId=" 471 + event.ndpInstanceId + ", appInfo.size()=" + event.appInfo.size()); 472 } 473 incrementCbCount(CB_EV_DATA_PATH_REQUEST); 474 475 mWifiAwareStateManager.onDataPathRequestNotification(event.discoverySessionId, 476 event.peerDiscMacAddr, event.ndpInstanceId, 477 convertArrayListToNativeByteArray(event.appInfo)); 478 } 479 480 @Override eventDataPathConfirm(NanDataPathConfirmInd event)481 public void eventDataPathConfirm(NanDataPathConfirmInd event) { 482 if (mDbg) { 483 Log.v(TAG, "onDataPathConfirm: ndpInstanceId=" + event.ndpInstanceId 484 + ", peerNdiMacAddr=" + String.valueOf(HexEncoding.encode(event.peerNdiMacAddr)) 485 + ", dataPathSetupSuccess=" + event.dataPathSetupSuccess + ", reason=" 486 + event.status.status + ", appInfo.size()=" + event.appInfo.size()); 487 } 488 if (mIsHal12OrLater) { 489 Log.wtf(TAG, "eventDataPathConfirm should not be called by a >=1.2 HAL!"); 490 } 491 incrementCbCount(CB_EV_DATA_PATH_CONFIRM); 492 493 mWifiAwareStateManager.onDataPathConfirmNotification(event.ndpInstanceId, 494 event.peerNdiMacAddr, event.dataPathSetupSuccess, event.status.status, 495 convertArrayListToNativeByteArray(event.appInfo), null); 496 } 497 498 @Override eventDataPathConfirm_1_2(android.hardware.wifi.V1_2.NanDataPathConfirmInd event)499 public void eventDataPathConfirm_1_2(android.hardware.wifi.V1_2.NanDataPathConfirmInd event) { 500 if (mDbg) { 501 Log.v(TAG, "eventDataPathConfirm_1_2: ndpInstanceId=" + event.V1_0.ndpInstanceId 502 + ", peerNdiMacAddr=" + String.valueOf( 503 HexEncoding.encode(event.V1_0.peerNdiMacAddr)) + ", dataPathSetupSuccess=" 504 + event.V1_0.dataPathSetupSuccess + ", reason=" + event.V1_0.status.status 505 + ", appInfo.size()=" + event.V1_0.appInfo.size()); 506 } 507 if (!mIsHal12OrLater) { 508 Log.wtf(TAG, "eventDataPathConfirm_1_2 should not be called by a <1.2 HAL!"); 509 return; 510 } 511 incrementCbCount(CB_EV_DATA_PATH_CONFIRM); 512 513 mWifiAwareStateManager.onDataPathConfirmNotification(event.V1_0.ndpInstanceId, 514 event.V1_0.peerNdiMacAddr, event.V1_0.dataPathSetupSuccess, 515 event.V1_0.status.status, convertArrayListToNativeByteArray(event.V1_0.appInfo), 516 event.channelInfo); 517 } 518 519 @Override eventDataPathScheduleUpdate(NanDataPathScheduleUpdateInd event)520 public void eventDataPathScheduleUpdate(NanDataPathScheduleUpdateInd event) { 521 if (mDbg) { 522 Log.v(TAG, "eventDataPathScheduleUpdate"); 523 } 524 if (!mIsHal12OrLater) { 525 Log.wtf(TAG, "eventDataPathScheduleUpdate should not be called by a <1.2 HAL!"); 526 return; 527 } 528 incrementCbCount(CB_EV_DATA_PATH_SCHED_UPDATE); 529 530 mWifiAwareStateManager.onDataPathScheduleUpdateNotification(event.peerDiscoveryAddress, 531 event.ndpInstanceIds, event.channelInfo); 532 } 533 534 @Override eventDataPathTerminated(int ndpInstanceId)535 public void eventDataPathTerminated(int ndpInstanceId) { 536 if (mDbg) Log.v(TAG, "eventDataPathTerminated: ndpInstanceId=" + ndpInstanceId); 537 incrementCbCount(CB_EV_DATA_PATH_TERMINATED); 538 539 mWifiAwareStateManager.onDataPathEndNotification(ndpInstanceId); 540 } 541 542 /** 543 * Dump the internal state of the class. 544 */ dump(FileDescriptor fd, PrintWriter pw, String[] args)545 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 546 pw.println("WifiAwareNativeCallback:"); 547 pw.println(" mCallbackCounter: " + mCallbackCounter); 548 } 549 550 551 // utilities 552 553 /** 554 * Converts an ArrayList<Byte> to a byte[]. 555 * 556 * @param from The input ArrayList<Byte></Byte> to convert from. 557 * 558 * @return A newly allocated byte[]. 559 */ convertArrayListToNativeByteArray(ArrayList<Byte> from)560 private byte[] convertArrayListToNativeByteArray(ArrayList<Byte> from) { 561 if (from == null) { 562 return null; 563 } 564 565 byte[] to = new byte[from.size()]; 566 for (int i = 0; i < from.size(); ++i) { 567 to[i] = from.get(i); 568 } 569 return to; 570 } 571 statusString(WifiNanStatus status)572 private static String statusString(WifiNanStatus status) { 573 if (status == null) { 574 return "status=null"; 575 } 576 StringBuilder sb = new StringBuilder(); 577 sb.append(status.status).append(" (").append(status.description).append(")"); 578 return sb.toString(); 579 } 580 } 581