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