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.IWifiNanEventListener; 21 import android.net.wifi.nan.IWifiNanSessionListener; 22 import android.net.wifi.nan.PublishData; 23 import android.net.wifi.nan.PublishSettings; 24 import android.net.wifi.nan.SubscribeData; 25 import android.net.wifi.nan.SubscribeSettings; 26 import android.os.Bundle; 27 import android.os.Handler; 28 import android.os.Looper; 29 import android.os.Message; 30 import android.util.Log; 31 import android.util.SparseArray; 32 33 import libcore.util.HexEncoding; 34 35 import java.io.FileDescriptor; 36 import java.io.PrintWriter; 37 import java.util.ArrayList; 38 import java.util.List; 39 40 public class WifiNanStateManager { 41 private static final String TAG = "WifiNanStateManager"; 42 private static final boolean DBG = false; 43 private static final boolean VDBG = false; // STOPSHIP if true 44 45 private static WifiNanStateManager sNanStateManagerSingleton; 46 47 private static final int MESSAGE_CONNECT = 0; 48 private static final int MESSAGE_DISCONNECT = 1; 49 private static final int MESSAGE_REQUEST_CONFIG = 4; 50 private static final int MESSAGE_CREATE_SESSION = 5; 51 private static final int MESSAGE_DESTROY_SESSION = 6; 52 private static final int MESSAGE_PUBLISH = 7; 53 private static final int MESSAGE_SUBSCRIBE = 8; 54 private static final int MESSAGE_SEND_MESSAGE = 9; 55 private static final int MESSAGE_STOP_SESSION = 10; 56 private static final int MESSAGE_ON_CONFIG_COMPLETED = 11; 57 private static final int MESSAGE_ON_CONFIG_FAILED = 12; 58 private static final int MESSAGE_ON_NAN_DOWN = 13; 59 private static final int MESSAGE_ON_INTERFACE_CHANGE = 14; 60 private static final int MESSAGE_ON_CLUSTER_CHANGE = 15; 61 private static final int MESSAGE_ON_PUBLISH_SUCCESS = 16; 62 private static final int MESSAGE_ON_PUBLISH_FAIL = 17; 63 private static final int MESSAGE_ON_PUBLISH_TERMINATED = 18; 64 private static final int MESSAGE_ON_SUBSCRIBE_SUCCESS = 19; 65 private static final int MESSAGE_ON_SUBSCRIBE_FAIL = 20; 66 private static final int MESSAGE_ON_SUBSCRIBE_TERMINATED = 21; 67 private static final int MESSAGE_ON_MESSAGE_SEND_SUCCESS = 22; 68 private static final int MESSAGE_ON_MESSAGE_SEND_FAIL = 23; 69 private static final int MESSAGE_ON_UNKNOWN_TRANSACTION = 24; 70 private static final int MESSAGE_ON_MATCH = 25; 71 private static final int MESSAGE_ON_MESSAGE_RECEIVED = 26; 72 private static final int MESSAGE_ON_CAPABILITIES_UPDATED = 27; 73 74 private static final String MESSAGE_BUNDLE_KEY_SESSION_ID = "session_id"; 75 private static final String MESSAGE_BUNDLE_KEY_EVENTS = "events"; 76 private static final String MESSAGE_BUNDLE_KEY_PUBLISH_DATA = "publish_data"; 77 private static final String MESSAGE_BUNDLE_KEY_PUBLISH_SETTINGS = "publish_settings"; 78 private static final String MESSAGE_BUNDLE_KEY_SUBSCRIBE_DATA = "subscribe_data"; 79 private static final String MESSAGE_BUNDLE_KEY_SUBSCRIBE_SETTINGS = "subscribe_settings"; 80 private static final String MESSAGE_BUNDLE_KEY_MESSAGE = "message"; 81 private static final String MESSAGE_BUNDLE_KEY_MESSAGE_PEER_ID = "message_peer_id"; 82 private static final String MESSAGE_BUNDLE_KEY_MESSAGE_ID = "message_id"; 83 private static final String MESSAGE_BUNDLE_KEY_RESPONSE_TYPE = "response_type"; 84 private static final String MESSAGE_BUNDLE_KEY_SSI_LENGTH = "ssi_length"; 85 private static final String MESSAGE_BUNDLE_KEY_SSI_DATA = "ssi_data"; 86 private static final String MESSAGE_BUNDLE_KEY_FILTER_LENGTH = "filter_length"; 87 private static final String MESSAGE_BUNDLE_KEY_FILTER_DATA = "filter_data"; 88 private static final String MESSAGE_BUNDLE_KEY_MAC_ADDRESS = "mac_address"; 89 private static final String MESSAGE_BUNDLE_KEY_MESSAGE_DATA = "message_data"; 90 private static final String MESSAGE_BUNDLE_KEY_MESSAGE_LENGTH = "message_length"; 91 92 private WifiNanNative.Capabilities mCapabilities; 93 94 private WifiNanStateHandler mHandler; 95 96 // no synchronization necessary: only access through Handler 97 private final SparseArray<WifiNanClientState> mClients = new SparseArray<>(); 98 private final SparseArray<TransactionInfoBase> mPendingResponses = new SparseArray<>(); 99 private short mNextTransactionId = 1; 100 WifiNanStateManager()101 private WifiNanStateManager() { 102 // EMPTY: singleton pattern 103 } 104 getInstance()105 public static WifiNanStateManager getInstance() { 106 if (sNanStateManagerSingleton == null) { 107 sNanStateManagerSingleton = new WifiNanStateManager(); 108 } 109 110 return sNanStateManagerSingleton; 111 } 112 start(Looper looper)113 public void start(Looper looper) { 114 Log.i(TAG, "start()"); 115 116 mHandler = new WifiNanStateHandler(looper); 117 } 118 connect(int uid, IWifiNanEventListener listener, int events)119 public void connect(int uid, IWifiNanEventListener listener, int events) { 120 Message msg = mHandler.obtainMessage(MESSAGE_CONNECT); 121 msg.arg1 = uid; 122 msg.arg2 = events; 123 msg.obj = listener; 124 mHandler.sendMessage(msg); 125 } 126 disconnect(int uid)127 public void disconnect(int uid) { 128 Message msg = mHandler.obtainMessage(MESSAGE_DISCONNECT); 129 msg.arg1 = uid; 130 mHandler.sendMessage(msg); 131 } 132 requestConfig(int uid, ConfigRequest configRequest)133 public void requestConfig(int uid, ConfigRequest configRequest) { 134 Message msg = mHandler.obtainMessage(MESSAGE_REQUEST_CONFIG); 135 msg.arg1 = uid; 136 msg.obj = configRequest; 137 mHandler.sendMessage(msg); 138 } 139 stopSession(int uid, int sessionId)140 public void stopSession(int uid, int sessionId) { 141 Message msg = mHandler.obtainMessage(MESSAGE_STOP_SESSION); 142 msg.arg1 = uid; 143 msg.arg2 = sessionId; 144 mHandler.sendMessage(msg); 145 } 146 destroySession(int uid, int sessionId)147 public void destroySession(int uid, int sessionId) { 148 Message msg = mHandler.obtainMessage(MESSAGE_DESTROY_SESSION); 149 msg.arg1 = uid; 150 msg.arg2 = sessionId; 151 mHandler.sendMessage(msg); 152 } 153 createSession(int uid, int sessionId, IWifiNanSessionListener listener, int events)154 public void createSession(int uid, int sessionId, IWifiNanSessionListener listener, 155 int events) { 156 Bundle data = new Bundle(); 157 data.putInt(MESSAGE_BUNDLE_KEY_EVENTS, events); 158 159 Message msg = mHandler.obtainMessage(MESSAGE_CREATE_SESSION); 160 msg.setData(data); 161 msg.arg1 = uid; 162 msg.arg2 = sessionId; 163 msg.obj = listener; 164 mHandler.sendMessage(msg); 165 } 166 publish(int uid, int sessionId, PublishData publishData, PublishSettings publishSettings)167 public void publish(int uid, int sessionId, PublishData publishData, 168 PublishSettings publishSettings) { 169 Bundle data = new Bundle(); 170 data.putParcelable(MESSAGE_BUNDLE_KEY_PUBLISH_DATA, publishData); 171 data.putParcelable(MESSAGE_BUNDLE_KEY_PUBLISH_SETTINGS, publishSettings); 172 173 Message msg = mHandler.obtainMessage(MESSAGE_PUBLISH); 174 msg.setData(data); 175 msg.arg1 = uid; 176 msg.arg2 = sessionId; 177 mHandler.sendMessage(msg); 178 } 179 subscribe(int uid, int sessionId, SubscribeData subscribeData, SubscribeSettings subscribeSettings)180 public void subscribe(int uid, int sessionId, SubscribeData subscribeData, 181 SubscribeSettings subscribeSettings) { 182 Bundle data = new Bundle(); 183 data.putParcelable(MESSAGE_BUNDLE_KEY_SUBSCRIBE_DATA, subscribeData); 184 data.putParcelable(MESSAGE_BUNDLE_KEY_SUBSCRIBE_SETTINGS, subscribeSettings); 185 186 Message msg = mHandler.obtainMessage(MESSAGE_SUBSCRIBE); 187 msg.setData(data); 188 msg.arg1 = uid; 189 msg.arg2 = sessionId; 190 mHandler.sendMessage(msg); 191 } 192 sendMessage(int uid, int sessionId, int peerId, byte[] message, int messageLength, int messageId)193 public void sendMessage(int uid, int sessionId, int peerId, byte[] message, int messageLength, 194 int messageId) { 195 Bundle data = new Bundle(); 196 data.putInt(MESSAGE_BUNDLE_KEY_SESSION_ID, sessionId); 197 data.putInt(MESSAGE_BUNDLE_KEY_MESSAGE_PEER_ID, peerId); 198 data.putByteArray(MESSAGE_BUNDLE_KEY_MESSAGE, message); 199 data.putInt(MESSAGE_BUNDLE_KEY_MESSAGE_ID, messageId); 200 201 Message msg = mHandler.obtainMessage(MESSAGE_SEND_MESSAGE); 202 msg.arg1 = uid; 203 msg.arg2 = messageLength; 204 msg.setData(data); 205 mHandler.sendMessage(msg); 206 } 207 onCapabilitiesUpdate(short transactionId, WifiNanNative.Capabilities capabilities)208 public void onCapabilitiesUpdate(short transactionId, WifiNanNative.Capabilities capabilities) { 209 Message msg = mHandler.obtainMessage(MESSAGE_ON_CAPABILITIES_UPDATED); 210 msg.arg1 = transactionId; 211 msg.obj = capabilities; 212 mHandler.sendMessage(msg); 213 } 214 onConfigCompleted(short transactionId)215 public void onConfigCompleted(short transactionId) { 216 Message msg = mHandler.obtainMessage(MESSAGE_ON_CONFIG_COMPLETED); 217 msg.arg1 = transactionId; 218 mHandler.sendMessage(msg); 219 } 220 onConfigFailed(short transactionId, int reason)221 public void onConfigFailed(short transactionId, int reason) { 222 Message msg = mHandler.obtainMessage(MESSAGE_ON_CONFIG_FAILED); 223 msg.arg1 = transactionId; 224 msg.arg2 = reason; 225 mHandler.sendMessage(msg); 226 } 227 onPublishSuccess(short transactionId, int publishId)228 public void onPublishSuccess(short transactionId, int publishId) { 229 Message msg = mHandler.obtainMessage(MESSAGE_ON_PUBLISH_SUCCESS); 230 msg.arg1 = transactionId; 231 msg.arg2 = publishId; 232 mHandler.sendMessage(msg); 233 } 234 onPublishFail(short transactionId, int status)235 public void onPublishFail(short transactionId, int status) { 236 Message msg = mHandler.obtainMessage(MESSAGE_ON_PUBLISH_FAIL); 237 msg.arg1 = transactionId; 238 msg.arg2 = status; 239 mHandler.sendMessage(msg); 240 } 241 onMessageSendSuccess(short transactionId)242 public void onMessageSendSuccess(short transactionId) { 243 Message msg = mHandler.obtainMessage(MESSAGE_ON_MESSAGE_SEND_SUCCESS); 244 msg.arg1 = transactionId; 245 mHandler.sendMessage(msg); 246 } 247 onMessageSendFail(short transactionId, int status)248 public void onMessageSendFail(short transactionId, int status) { 249 Message msg = mHandler.obtainMessage(MESSAGE_ON_MESSAGE_SEND_FAIL); 250 msg.arg1 = transactionId; 251 msg.arg2 = status; 252 mHandler.sendMessage(msg); 253 } 254 onSubscribeSuccess(short transactionId, int subscribeId)255 public void onSubscribeSuccess(short transactionId, int subscribeId) { 256 Message msg = mHandler.obtainMessage(MESSAGE_ON_SUBSCRIBE_SUCCESS); 257 msg.arg1 = transactionId; 258 msg.arg2 = subscribeId; 259 mHandler.sendMessage(msg); 260 } 261 onSubscribeFail(short transactionId, int status)262 public void onSubscribeFail(short transactionId, int status) { 263 Message msg = mHandler.obtainMessage(MESSAGE_ON_SUBSCRIBE_FAIL); 264 msg.arg1 = transactionId; 265 msg.arg2 = status; 266 mHandler.sendMessage(msg); 267 } 268 onUnknownTransaction(int responseType, short transactionId, int status)269 public void onUnknownTransaction(int responseType, short transactionId, int status) { 270 Message msg = mHandler.obtainMessage(MESSAGE_ON_UNKNOWN_TRANSACTION); 271 Bundle data = new Bundle(); 272 data.putInt(MESSAGE_BUNDLE_KEY_RESPONSE_TYPE, responseType); 273 msg.setData(data); 274 msg.arg1 = transactionId; 275 msg.arg2 = status; 276 mHandler.sendMessage(msg); 277 } 278 onInterfaceAddressChange(byte[] mac)279 public void onInterfaceAddressChange(byte[] mac) { 280 Message msg = mHandler.obtainMessage(MESSAGE_ON_INTERFACE_CHANGE); 281 msg.obj = mac; 282 mHandler.sendMessage(msg); 283 } 284 onClusterChange(int flag, byte[] clusterId)285 public void onClusterChange(int flag, byte[] clusterId) { 286 Message msg = mHandler.obtainMessage(MESSAGE_ON_CLUSTER_CHANGE); 287 msg.arg1 = flag; 288 msg.obj = clusterId; 289 mHandler.sendMessage(msg); 290 } 291 onMatch(int pubSubId, int requestorInstanceId, byte[] peerMac, byte[] serviceSpecificInfo, int serviceSpecificInfoLength, byte[] matchFilter, int matchFilterLength)292 public void onMatch(int pubSubId, int requestorInstanceId, byte[] peerMac, 293 byte[] serviceSpecificInfo, int serviceSpecificInfoLength, byte[] matchFilter, 294 int matchFilterLength) { 295 Message msg = mHandler.obtainMessage(MESSAGE_ON_MATCH); 296 msg.arg1 = pubSubId; 297 msg.arg2 = requestorInstanceId; 298 Bundle data = new Bundle(); 299 data.putByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS, peerMac); 300 data.putByteArray(MESSAGE_BUNDLE_KEY_SSI_DATA, serviceSpecificInfo); 301 data.putInt(MESSAGE_BUNDLE_KEY_SSI_LENGTH, serviceSpecificInfoLength); 302 data.putByteArray(MESSAGE_BUNDLE_KEY_FILTER_DATA, matchFilter); 303 data.putInt(MESSAGE_BUNDLE_KEY_FILTER_LENGTH, matchFilterLength); 304 msg.setData(data); 305 mHandler.sendMessage(msg); 306 } 307 onPublishTerminated(int publishId, int status)308 public void onPublishTerminated(int publishId, int status) { 309 Message msg = mHandler.obtainMessage(MESSAGE_ON_PUBLISH_TERMINATED); 310 msg.arg1 = publishId; 311 msg.arg2 = status; 312 mHandler.sendMessage(msg); 313 } 314 onSubscribeTerminated(int subscribeId, int status)315 public void onSubscribeTerminated(int subscribeId, int status) { 316 Message msg = mHandler.obtainMessage(MESSAGE_ON_SUBSCRIBE_TERMINATED); 317 msg.arg1 = subscribeId; 318 msg.arg2 = status; 319 mHandler.sendMessage(msg); 320 } 321 onMessageReceived(int pubSubId, int requestorInstanceId, byte[] peerMac, byte[] message, int messageLength)322 public void onMessageReceived(int pubSubId, int requestorInstanceId, byte[] peerMac, 323 byte[] message, int messageLength) { 324 Message msg = mHandler.obtainMessage(MESSAGE_ON_MESSAGE_RECEIVED); 325 msg.arg1 = pubSubId; 326 msg.arg2 = requestorInstanceId; 327 Bundle data = new Bundle(); 328 data.putByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS, peerMac); 329 data.putByteArray(MESSAGE_BUNDLE_KEY_MESSAGE_DATA, message); 330 data.putInt(MESSAGE_BUNDLE_KEY_MESSAGE_LENGTH, messageLength); 331 msg.setData(data); 332 mHandler.sendMessage(msg); 333 } 334 onNanDown(int reason)335 public void onNanDown(int reason) { 336 Message msg = mHandler.obtainMessage(MESSAGE_ON_NAN_DOWN); 337 msg.arg1 = reason; 338 mHandler.sendMessage(msg); 339 } 340 341 private class WifiNanStateHandler extends Handler { WifiNanStateHandler(android.os.Looper looper)342 WifiNanStateHandler(android.os.Looper looper) { 343 super(looper); 344 } 345 346 @Override handleMessage(Message msg)347 public void handleMessage(Message msg) { 348 if (DBG) { 349 Log.d(TAG, "Message: " + msg.what); 350 } 351 switch (msg.what) { 352 case MESSAGE_CONNECT: { 353 if (VDBG) { 354 Log.d(TAG, "NAN connection request received"); 355 } 356 connectLocal(msg.arg1, (IWifiNanEventListener) msg.obj, msg.arg2); 357 break; 358 } 359 case MESSAGE_DISCONNECT: { 360 if (VDBG) { 361 Log.d(TAG, "NAN disconnection request received"); 362 } 363 disconnectLocal(msg.arg1); 364 break; 365 } 366 case MESSAGE_REQUEST_CONFIG: { 367 if (VDBG) { 368 Log.d(TAG, "NAN configuration request received"); 369 } 370 requestConfigLocal(msg.arg1, (ConfigRequest) msg.obj); 371 break; 372 } 373 case MESSAGE_CREATE_SESSION: { 374 if (VDBG) { 375 Log.d(TAG, "Create session"); 376 } 377 int events = msg.getData().getInt(MESSAGE_BUNDLE_KEY_EVENTS); 378 createSessionLocal(msg.arg1, msg.arg2, (IWifiNanSessionListener) msg.obj, 379 events); 380 break; 381 } 382 case MESSAGE_DESTROY_SESSION: { 383 if (VDBG) { 384 Log.d(TAG, "Destroy session"); 385 } 386 destroySessionLocal(msg.arg1, msg.arg2); 387 break; 388 } 389 case MESSAGE_PUBLISH: { 390 Bundle data = msg.getData(); 391 PublishData publishData = (PublishData) data 392 .getParcelable(MESSAGE_BUNDLE_KEY_PUBLISH_DATA); 393 PublishSettings publishSettings = (PublishSettings) data 394 .getParcelable(MESSAGE_BUNDLE_KEY_PUBLISH_SETTINGS); 395 if (VDBG) { 396 Log.d(TAG, 397 "Publish: data='" + publishData + "', settings=" + publishSettings); 398 } 399 400 publishLocal(msg.arg1, msg.arg2, publishData, publishSettings); 401 break; 402 } 403 case MESSAGE_SUBSCRIBE: { 404 Bundle data = msg.getData(); 405 SubscribeData subscribeData = (SubscribeData) data 406 .getParcelable(MESSAGE_BUNDLE_KEY_SUBSCRIBE_DATA); 407 SubscribeSettings subscribeSettings = (SubscribeSettings) data 408 .getParcelable(MESSAGE_BUNDLE_KEY_SUBSCRIBE_SETTINGS); 409 if (VDBG) { 410 Log.d(TAG, "Subscribe: data='" + subscribeData + "', settings=" 411 + subscribeSettings); 412 } 413 414 subscribeLocal(msg.arg1, msg.arg2, subscribeData, subscribeSettings); 415 break; 416 } 417 case MESSAGE_SEND_MESSAGE: { 418 Bundle data = msg.getData(); 419 int sessionId = msg.getData().getInt(MESSAGE_BUNDLE_KEY_SESSION_ID); 420 int peerId = data.getInt(MESSAGE_BUNDLE_KEY_MESSAGE_PEER_ID); 421 byte[] message = data.getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE); 422 int messageId = data.getInt(MESSAGE_BUNDLE_KEY_MESSAGE_ID); 423 424 if (VDBG) { 425 Log.d(TAG, "Send Message: message='" + message + "' (ID=" + messageId 426 + ") to peerId=" + peerId); 427 } 428 429 sendFollowonMessageLocal(msg.arg1, sessionId, peerId, message, msg.arg2, 430 messageId); 431 break; 432 } 433 case MESSAGE_STOP_SESSION: { 434 if (VDBG) { 435 Log.d(TAG, "Stop session"); 436 } 437 stopSessionLocal(msg.arg1, msg.arg2); 438 break; 439 } 440 case MESSAGE_ON_CAPABILITIES_UPDATED: 441 onCapabilitiesUpdatedLocal((short) msg.arg1, 442 (WifiNanNative.Capabilities) msg.obj); 443 break; 444 case MESSAGE_ON_CONFIG_COMPLETED: 445 onConfigCompletedLocal((short) msg.arg1); 446 break; 447 case MESSAGE_ON_CONFIG_FAILED: 448 onConfigFailedLocal((short) msg.arg1, msg.arg2); 449 break; 450 case MESSAGE_ON_NAN_DOWN: 451 onNanDownLocal(msg.arg1); 452 break; 453 case MESSAGE_ON_INTERFACE_CHANGE: 454 onInterfaceAddressChangeLocal((byte[]) msg.obj); 455 break; 456 case MESSAGE_ON_CLUSTER_CHANGE: 457 onClusterChangeLocal(msg.arg1, (byte[]) msg.obj); 458 break; 459 case MESSAGE_ON_PUBLISH_SUCCESS: 460 onPublishSuccessLocal((short) msg.arg1, msg.arg2); 461 break; 462 case MESSAGE_ON_PUBLISH_FAIL: 463 onPublishFailLocal((short) msg.arg1, msg.arg2); 464 break; 465 case MESSAGE_ON_PUBLISH_TERMINATED: 466 onPublishTerminatedLocal(msg.arg1, msg.arg2); 467 break; 468 case MESSAGE_ON_SUBSCRIBE_SUCCESS: 469 onSubscribeSuccessLocal((short) msg.arg1, msg.arg2); 470 break; 471 case MESSAGE_ON_SUBSCRIBE_FAIL: 472 onSubscribeFailLocal((short) msg.arg1, msg.arg2); 473 break; 474 case MESSAGE_ON_SUBSCRIBE_TERMINATED: 475 onSubscribeTerminatedLocal(msg.arg1, msg.arg2); 476 break; 477 case MESSAGE_ON_MESSAGE_SEND_SUCCESS: 478 onMessageSendSuccessLocal((short) msg.arg1); 479 break; 480 case MESSAGE_ON_MESSAGE_SEND_FAIL: 481 onMessageSendFailLocal((short) msg.arg1, msg.arg2); 482 break; 483 case MESSAGE_ON_UNKNOWN_TRANSACTION: 484 onUnknownTransactionLocal( 485 msg.getData().getInt(MESSAGE_BUNDLE_KEY_RESPONSE_TYPE), 486 (short) msg.arg1, msg.arg2); 487 break; 488 case MESSAGE_ON_MATCH: { 489 int pubSubId = msg.arg1; 490 int requestorInstanceId = msg.arg2; 491 byte[] peerMac = msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS); 492 byte[] serviceSpecificInfo = msg.getData() 493 .getByteArray(MESSAGE_BUNDLE_KEY_SSI_DATA); 494 int serviceSpecificInfoLength = msg.getData() 495 .getInt(MESSAGE_BUNDLE_KEY_SSI_LENGTH); 496 byte[] matchFilter = msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_FILTER_DATA); 497 int matchFilterLength = msg.getData().getInt(MESSAGE_BUNDLE_KEY_FILTER_LENGTH); 498 onMatchLocal(pubSubId, requestorInstanceId, peerMac, serviceSpecificInfo, 499 serviceSpecificInfoLength, matchFilter, matchFilterLength); 500 break; 501 } 502 case MESSAGE_ON_MESSAGE_RECEIVED: { 503 int pubSubId = msg.arg1; 504 int requestorInstanceId = msg.arg2; 505 byte[] peerMac = msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS); 506 byte[] message = msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE_DATA); 507 int messageLength = msg.getData().getInt(MESSAGE_BUNDLE_KEY_MESSAGE_LENGTH); 508 onMessageReceivedLocal(pubSubId, requestorInstanceId, peerMac, message, 509 messageLength); 510 break; 511 } 512 default: 513 Log.e(TAG, "Unknown message code: " + msg.what); 514 } 515 } 516 } 517 518 /* 519 * Transaction management classes & operations 520 */ 521 522 // non-synchronized (should be ok as long as only used from NanStateManager, 523 // NanClientState, and NanSessionState) createNextTransactionId()524 /* package */ short createNextTransactionId() { 525 return mNextTransactionId++; 526 } 527 528 private static class TransactionInfoBase { 529 short mTransactionId; 530 } 531 532 private static class TransactionInfoSession extends TransactionInfoBase { 533 public WifiNanClientState mClient; 534 public WifiNanSessionState mSession; 535 } 536 537 private static class TransactionInfoMessage extends TransactionInfoSession { 538 public int mMessageId; 539 } 540 541 private static class TransactionInfoConfig extends TransactionInfoBase { 542 public ConfigRequest mConfig; 543 } 544 allocateAndRegisterTransactionId(TransactionInfoBase info)545 private void allocateAndRegisterTransactionId(TransactionInfoBase info) { 546 info.mTransactionId = createNextTransactionId(); 547 548 mPendingResponses.put(info.mTransactionId, info); 549 } 550 fillInTransactionInfoSession(TransactionInfoSession info, int uid, int sessionId)551 private void fillInTransactionInfoSession(TransactionInfoSession info, int uid, 552 int sessionId) { 553 WifiNanClientState client = mClients.get(uid); 554 if (client == null) { 555 throw new IllegalStateException( 556 "getAndRegisterTransactionId: no client exists for uid=" + uid); 557 } 558 info.mClient = client; 559 560 WifiNanSessionState session = info.mClient.getSession(sessionId); 561 if (session == null) { 562 throw new IllegalStateException( 563 "getAndRegisterSessionTransactionId: no session exists for uid=" + uid 564 + ", sessionId=" + sessionId); 565 } 566 info.mSession = session; 567 } 568 createTransactionInfo()569 private TransactionInfoBase createTransactionInfo() { 570 TransactionInfoBase info = new TransactionInfoBase(); 571 allocateAndRegisterTransactionId(info); 572 return info; 573 } 574 createTransactionInfoSession(int uid, int sessionId)575 private TransactionInfoSession createTransactionInfoSession(int uid, int sessionId) { 576 TransactionInfoSession info = new TransactionInfoSession(); 577 fillInTransactionInfoSession(info, uid, sessionId); 578 allocateAndRegisterTransactionId(info); 579 return info; 580 } 581 createTransactionInfoMessage(int uid, int sessionId, int messageId)582 private TransactionInfoMessage createTransactionInfoMessage(int uid, int sessionId, 583 int messageId) { 584 TransactionInfoMessage info = new TransactionInfoMessage(); 585 fillInTransactionInfoSession(info, uid, sessionId); 586 info.mMessageId = messageId; 587 allocateAndRegisterTransactionId(info); 588 return info; 589 } 590 createTransactionInfoConfig(ConfigRequest configRequest)591 private TransactionInfoConfig createTransactionInfoConfig(ConfigRequest configRequest) { 592 TransactionInfoConfig info = new TransactionInfoConfig(); 593 info.mConfig = configRequest; 594 allocateAndRegisterTransactionId(info); 595 return info; 596 } 597 getAndRemovePendingResponseTransactionInfo(short transactionId)598 private TransactionInfoBase getAndRemovePendingResponseTransactionInfo(short transactionId) { 599 TransactionInfoBase transInfo = mPendingResponses.get(transactionId); 600 if (transInfo != null) { 601 mPendingResponses.remove(transactionId); 602 } 603 604 return transInfo; 605 } 606 getNanSessionStateForPubSubId(int pubSubId)607 private WifiNanSessionState getNanSessionStateForPubSubId(int pubSubId) { 608 for (int i = 0; i < mClients.size(); ++i) { 609 WifiNanSessionState session = mClients.valueAt(i) 610 .getNanSessionStateForPubSubId(pubSubId); 611 if (session != null) { 612 return session; 613 } 614 } 615 616 return null; 617 } 618 619 /* 620 * Actions (calls from API to service) 621 */ connectLocal(int uid, IWifiNanEventListener listener, int events)622 private void connectLocal(int uid, IWifiNanEventListener listener, int events) { 623 if (VDBG) { 624 Log.v(TAG, "connect(): uid=" + uid + ", listener=" + listener + ", events=" + events); 625 } 626 627 if (mClients.get(uid) != null) { 628 Log.e(TAG, "connect: entry already exists for uid=" + uid); 629 return; 630 } 631 632 WifiNanClientState client = new WifiNanClientState(uid, listener, events); 633 mClients.put(uid, client); 634 } 635 disconnectLocal(int uid)636 private void disconnectLocal(int uid) { 637 if (VDBG) { 638 Log.v(TAG, "disconnect(): uid=" + uid); 639 } 640 641 WifiNanClientState client = mClients.get(uid); 642 mClients.delete(uid); 643 644 if (client == null) { 645 Log.e(TAG, "disconnect: no entry for uid=" + uid); 646 return; 647 } 648 649 List<Integer> toRemove = new ArrayList<>(); 650 for (int i = 0; i < mPendingResponses.size(); ++i) { 651 TransactionInfoBase info = mPendingResponses.valueAt(i); 652 if (!(info instanceof TransactionInfoSession)) { 653 continue; 654 } 655 if (((TransactionInfoSession) info).mClient.getUid() == uid) { 656 toRemove.add(i); 657 } 658 } 659 for (Integer id : toRemove) { 660 mPendingResponses.removeAt(id); 661 } 662 663 client.destroy(); 664 665 if (mClients.size() == 0) { 666 WifiNanNative.getInstance().disable(createTransactionInfo().mTransactionId); 667 return; 668 } 669 670 ConfigRequest merged = mergeConfigRequests(); 671 672 WifiNanNative.getInstance() 673 .enableAndConfigure(createTransactionInfoConfig(merged).mTransactionId, merged); 674 } 675 requestConfigLocal(int uid, ConfigRequest configRequest)676 private void requestConfigLocal(int uid, ConfigRequest configRequest) { 677 if (VDBG) { 678 Log.v(TAG, "requestConfig(): uid=" + uid + ", configRequest=" + configRequest); 679 } 680 681 WifiNanClientState client = mClients.get(uid); 682 if (client == null) { 683 Log.e(TAG, "requestConfig: no client exists for uid=" + uid); 684 return; 685 } 686 687 client.setConfigRequest(configRequest); 688 689 ConfigRequest merged = mergeConfigRequests(); 690 691 WifiNanNative.getInstance() 692 .enableAndConfigure(createTransactionInfoConfig(merged).mTransactionId, merged); 693 } 694 createSessionLocal(int uid, int sessionId, IWifiNanSessionListener listener, int events)695 private void createSessionLocal(int uid, int sessionId, IWifiNanSessionListener listener, 696 int events) { 697 if (VDBG) { 698 Log.v(TAG, "createSession(): uid=" + uid + ", sessionId=" + sessionId + ", listener=" 699 + listener + ", events=" + events); 700 } 701 702 WifiNanClientState client = mClients.get(uid); 703 if (client == null) { 704 Log.e(TAG, "createSession: no client exists for uid=" + uid); 705 return; 706 } 707 708 client.createSession(sessionId, listener, events); 709 } 710 destroySessionLocal(int uid, int sessionId)711 private void destroySessionLocal(int uid, int sessionId) { 712 if (VDBG) { 713 Log.v(TAG, "destroySession(): uid=" + uid + ", sessionId=" + sessionId); 714 } 715 716 WifiNanClientState client = mClients.get(uid); 717 if (client == null) { 718 Log.e(TAG, "destroySession: no client exists for uid=" + uid); 719 return; 720 } 721 722 List<Integer> toRemove = new ArrayList<>(); 723 for (int i = 0; i < mPendingResponses.size(); ++i) { 724 TransactionInfoBase info = mPendingResponses.valueAt(i); 725 if (!(info instanceof TransactionInfoSession)) { 726 continue; 727 } 728 TransactionInfoSession infoSession = (TransactionInfoSession) info; 729 if (infoSession.mClient.getUid() == uid 730 && infoSession.mSession.getSessionId() == sessionId) { 731 toRemove.add(i); 732 } 733 } 734 for (Integer id : toRemove) { 735 mPendingResponses.removeAt(id); 736 } 737 738 client.destroySession(sessionId); 739 } 740 publishLocal(int uid, int sessionId, PublishData publishData, PublishSettings publishSettings)741 private void publishLocal(int uid, int sessionId, PublishData publishData, 742 PublishSettings publishSettings) { 743 if (VDBG) { 744 Log.v(TAG, "publish(): uid=" + uid + ", sessionId=" + sessionId + ", data=" 745 + publishData + ", settings=" + publishSettings); 746 } 747 748 TransactionInfoSession info = createTransactionInfoSession(uid, sessionId); 749 750 info.mSession.publish(info.mTransactionId, publishData, publishSettings); 751 } 752 subscribeLocal(int uid, int sessionId, SubscribeData subscribeData, SubscribeSettings subscribeSettings)753 private void subscribeLocal(int uid, int sessionId, SubscribeData subscribeData, 754 SubscribeSettings subscribeSettings) { 755 if (VDBG) { 756 Log.v(TAG, "subscribe(): uid=" + uid + ", sessionId=" + sessionId + ", data=" 757 + subscribeData + ", settings=" + subscribeSettings); 758 } 759 760 TransactionInfoSession info = createTransactionInfoSession(uid, sessionId); 761 762 info.mSession.subscribe(info.mTransactionId, subscribeData, subscribeSettings); 763 } 764 sendFollowonMessageLocal(int uid, int sessionId, int peerId, byte[] message, int messageLength, int messageId)765 private void sendFollowonMessageLocal(int uid, int sessionId, int peerId, byte[] message, 766 int messageLength, int messageId) { 767 if (VDBG) { 768 Log.v(TAG, "sendMessage(): uid=" + uid + ", sessionId=" + sessionId + ", peerId=" 769 + peerId + ", messageLength=" + messageLength + ", messageId=" + messageId); 770 } 771 772 TransactionInfoMessage info = createTransactionInfoMessage(uid, sessionId, messageId); 773 774 info.mSession.sendMessage(info.mTransactionId, peerId, message, messageLength, messageId); 775 } 776 stopSessionLocal(int uid, int sessionId)777 private void stopSessionLocal(int uid, int sessionId) { 778 if (VDBG) { 779 Log.v(TAG, "stopSession(): uid=" + uid + ", sessionId=" + sessionId); 780 } 781 782 TransactionInfoSession info = createTransactionInfoSession(uid, sessionId); 783 784 info.mSession.stop(info.mTransactionId); 785 } 786 787 /* 788 * Callbacks (calls from HAL/Native to service) 789 */ 790 onCapabilitiesUpdatedLocal(short transactionId, WifiNanNative.Capabilities capabilities)791 private void onCapabilitiesUpdatedLocal(short transactionId, 792 WifiNanNative.Capabilities capabilities) { 793 if (VDBG) { 794 Log.v(TAG, "onCapabilitiesUpdatedLocal: transactionId=" + transactionId 795 + ", capabilites=" + capabilities); 796 } 797 798 mCapabilities = capabilities; 799 } 800 onConfigCompletedLocal(short transactionId)801 private void onConfigCompletedLocal(short transactionId) { 802 if (VDBG) { 803 Log.v(TAG, "onConfigCompleted: transactionId=" + transactionId); 804 } 805 806 TransactionInfoBase info = getAndRemovePendingResponseTransactionInfo(transactionId); 807 if (info == null) { 808 Log.e(TAG, "onConfigCompleted: no transaction info for transactionId=" + transactionId); 809 return; 810 } 811 if (!(info instanceof TransactionInfoConfig)) { 812 Log.e(TAG, "onConfigCompleted: invalid info structure stored for transactionId=" 813 + transactionId); 814 return; 815 } 816 TransactionInfoConfig infoConfig = (TransactionInfoConfig) info; 817 818 if (DBG) { 819 Log.d(TAG, "onConfigCompleted: request=" + infoConfig.mConfig); 820 } 821 822 for (int i = 0; i < mClients.size(); ++i) { 823 WifiNanClientState client = mClients.valueAt(i); 824 client.onConfigCompleted(infoConfig.mConfig); 825 } 826 } 827 onConfigFailedLocal(short transactionId, int reason)828 private void onConfigFailedLocal(short transactionId, int reason) { 829 if (VDBG) { 830 Log.v(TAG, "onEnableFailed: transactionId=" + transactionId + ", reason=" + reason); 831 } 832 833 TransactionInfoBase info = getAndRemovePendingResponseTransactionInfo(transactionId); 834 if (info == null) { 835 Log.e(TAG, "onConfigFailed: no transaction info for transactionId=" + transactionId); 836 return; 837 } 838 if (!(info instanceof TransactionInfoConfig)) { 839 Log.e(TAG, "onConfigCompleted: invalid info structure stored for transactionId=" 840 + transactionId); 841 return; 842 } 843 TransactionInfoConfig infoConfig = (TransactionInfoConfig) info; 844 845 if (DBG) { 846 Log.d(TAG, "onConfigFailed: request=" + infoConfig.mConfig); 847 } 848 849 for (int i = 0; i < mClients.size(); ++i) { 850 WifiNanClientState client = mClients.valueAt(i); 851 client.onConfigFailed(infoConfig.mConfig, reason); 852 } 853 } 854 onNanDownLocal(int reason)855 private void onNanDownLocal(int reason) { 856 if (VDBG) { 857 Log.v(TAG, "onNanDown: reason=" + reason); 858 } 859 860 int interested = 0; 861 for (int i = 0; i < mClients.size(); ++i) { 862 WifiNanClientState client = mClients.valueAt(i); 863 interested += client.onNanDown(reason); 864 } 865 866 if (interested == 0) { 867 Log.e(TAG, "onNanDown: event received but no listeners registered for this event " 868 + "- should be disabled from fw!"); 869 } 870 } 871 onInterfaceAddressChangeLocal(byte[] mac)872 private void onInterfaceAddressChangeLocal(byte[] mac) { 873 if (VDBG) { 874 Log.v(TAG, "onInterfaceAddressChange: mac=" + String.valueOf(HexEncoding.encode(mac))); 875 } 876 877 int interested = 0; 878 for (int i = 0; i < mClients.size(); ++i) { 879 WifiNanClientState client = mClients.valueAt(i); 880 interested += client.onInterfaceAddressChange(mac); 881 } 882 883 if (interested == 0) { 884 Log.e(TAG, "onInterfaceAddressChange: event received but no listeners registered " 885 + "for this event - should be disabled from fw!"); 886 } 887 } 888 onClusterChangeLocal(int flag, byte[] clusterId)889 private void onClusterChangeLocal(int flag, byte[] clusterId) { 890 if (VDBG) { 891 Log.v(TAG, "onClusterChange: flag=" + flag + ", clusterId=" 892 + String.valueOf(HexEncoding.encode(clusterId))); 893 } 894 895 int interested = 0; 896 for (int i = 0; i < mClients.size(); ++i) { 897 WifiNanClientState client = mClients.valueAt(i); 898 interested += client.onClusterChange(flag, clusterId); 899 } 900 901 if (interested == 0) { 902 Log.e(TAG, "onClusterChange: event received but no listeners registered for this " 903 + "event - should be disabled from fw!"); 904 } 905 } 906 onPublishSuccessLocal(short transactionId, int publishId)907 private void onPublishSuccessLocal(short transactionId, int publishId) { 908 if (VDBG) { 909 Log.v(TAG, "onPublishSuccess: transactionId=" + transactionId + ", publishId=" 910 + publishId); 911 } 912 913 TransactionInfoBase info = getAndRemovePendingResponseTransactionInfo(transactionId); 914 if (info == null) { 915 Log.e(TAG, "onPublishSuccess(): no info registered for transactionId=" + transactionId); 916 return; 917 } 918 if (!(info instanceof TransactionInfoSession)) { 919 Log.e(TAG, "onPublishSuccess: invalid info structure stored for transactionId=" 920 + transactionId); 921 return; 922 } 923 TransactionInfoSession infoSession = (TransactionInfoSession) info; 924 925 infoSession.mSession.onPublishSuccess(publishId); 926 } 927 onPublishFailLocal(short transactionId, int status)928 private void onPublishFailLocal(short transactionId, int status) { 929 if (VDBG) { 930 Log.v(TAG, "onPublishFail: transactionId=" + transactionId + ", status=" + status); 931 } 932 933 TransactionInfoBase info = getAndRemovePendingResponseTransactionInfo(transactionId); 934 if (info == null) { 935 Log.e(TAG, "onPublishFail(): no info registered for transactionId=" + transactionId); 936 return; 937 } 938 if (!(info instanceof TransactionInfoSession)) { 939 Log.e(TAG, "onPublishFail: invalid info structure stored for transactionId=" 940 + transactionId); 941 return; 942 } 943 TransactionInfoSession infoSession = (TransactionInfoSession) info; 944 945 infoSession.mSession.onPublishFail(status); 946 } 947 onPublishTerminatedLocal(int publishId, int status)948 private void onPublishTerminatedLocal(int publishId, int status) { 949 if (VDBG) { 950 Log.v(TAG, "onPublishTerminated: publishId=" + publishId + ", status=" + status); 951 } 952 953 WifiNanSessionState session = getNanSessionStateForPubSubId(publishId); 954 if (session == null) { 955 Log.e(TAG, "onPublishTerminated: no session found for publishId=" + publishId); 956 return; 957 } 958 959 session.onPublishTerminated(status); 960 } 961 onSubscribeSuccessLocal(short transactionId, int subscribeId)962 private void onSubscribeSuccessLocal(short transactionId, int subscribeId) { 963 if (VDBG) { 964 Log.v(TAG, "onSubscribeSuccess: transactionId=" + transactionId + ", subscribeId=" 965 + subscribeId); 966 } 967 968 TransactionInfoBase info = getAndRemovePendingResponseTransactionInfo(transactionId); 969 if (info == null) { 970 Log.e(TAG, 971 "onSubscribeSuccess(): no info registered for transactionId=" + transactionId); 972 return; 973 } 974 if (!(info instanceof TransactionInfoSession)) { 975 Log.e(TAG, "onSubscribeSuccess: invalid info structure stored for transactionId=" 976 + transactionId); 977 return; 978 } 979 TransactionInfoSession infoSession = (TransactionInfoSession) info; 980 981 infoSession.mSession.onSubscribeSuccess(subscribeId); 982 } 983 onSubscribeFailLocal(short transactionId, int status)984 private void onSubscribeFailLocal(short transactionId, int status) { 985 if (VDBG) { 986 Log.v(TAG, "onSubscribeFail: transactionId=" + transactionId + ", status=" + status); 987 } 988 989 TransactionInfoBase info = getAndRemovePendingResponseTransactionInfo(transactionId); 990 if (info == null) { 991 Log.e(TAG, "onSubscribeFail(): no info registered for transactionId=" + transactionId); 992 return; 993 } 994 if (!(info instanceof TransactionInfoSession)) { 995 Log.e(TAG, "onSubscribeFail: invalid info structure stored for transactionId=" 996 + transactionId); 997 return; 998 } 999 TransactionInfoSession infoSession = (TransactionInfoSession) info; 1000 1001 infoSession.mSession.onSubscribeFail(status); 1002 } 1003 onSubscribeTerminatedLocal(int subscribeId, int status)1004 private void onSubscribeTerminatedLocal(int subscribeId, int status) { 1005 if (VDBG) { 1006 Log.v(TAG, "onPublishTerminated: subscribeId=" + subscribeId + ", status=" + status); 1007 } 1008 1009 WifiNanSessionState session = getNanSessionStateForPubSubId(subscribeId); 1010 if (session == null) { 1011 Log.e(TAG, "onSubscribeTerminated: no session found for subscribeId=" + subscribeId); 1012 return; 1013 } 1014 1015 session.onSubscribeTerminated(status); 1016 } 1017 onMessageSendSuccessLocal(short transactionId)1018 private void onMessageSendSuccessLocal(short transactionId) { 1019 if (VDBG) { 1020 Log.v(TAG, "onMessageSendSuccess: transactionId=" + transactionId); 1021 } 1022 1023 TransactionInfoBase info = getAndRemovePendingResponseTransactionInfo(transactionId); 1024 if (info == null) { 1025 Log.e(TAG, "onMessageSendSuccess(): no info registered for transactionId=" 1026 + transactionId); 1027 return; 1028 } 1029 if (!(info instanceof TransactionInfoMessage)) { 1030 Log.e(TAG, "onMessageSendSuccess: invalid info structure stored for transactionId=" 1031 + transactionId); 1032 return; 1033 } 1034 TransactionInfoMessage infoMessage = (TransactionInfoMessage) info; 1035 1036 infoMessage.mSession.onMessageSendSuccess(infoMessage.mMessageId); 1037 } 1038 onMessageSendFailLocal(short transactionId, int status)1039 private void onMessageSendFailLocal(short transactionId, int status) { 1040 if (VDBG) { 1041 Log.v(TAG, "onMessageSendFail: transactionId=" + transactionId + ", status=" + status); 1042 } 1043 1044 TransactionInfoBase info = getAndRemovePendingResponseTransactionInfo(transactionId); 1045 if (info == null) { 1046 Log.e(TAG, 1047 "onMessageSendFail(): no info registered for transactionId=" + transactionId); 1048 return; 1049 } 1050 if (!(info instanceof TransactionInfoMessage)) { 1051 Log.e(TAG, "onMessageSendFail: invalid info structure stored for transactionId=" 1052 + transactionId); 1053 return; 1054 } 1055 TransactionInfoMessage infoMessage = (TransactionInfoMessage) info; 1056 1057 infoMessage.mSession.onMessageSendFail(infoMessage.mMessageId, status); 1058 } 1059 onUnknownTransactionLocal(int responseType, short transactionId, int status)1060 private void onUnknownTransactionLocal(int responseType, short transactionId, int status) { 1061 Log.e(TAG, "onUnknownTransaction: responseType=" + responseType + ", transactionId=" 1062 + transactionId + ", status=" + status); 1063 1064 TransactionInfoBase info = getAndRemovePendingResponseTransactionInfo(transactionId); 1065 if (info == null) { 1066 Log.e(TAG, "onUnknownTransaction(): no info registered for transactionId=" 1067 + transactionId); 1068 } 1069 } 1070 onMatchLocal(int pubSubId, int requestorInstanceId, byte[] peerMac, byte[] serviceSpecificInfo, int serviceSpecificInfoLength, byte[] matchFilter, int matchFilterLength)1071 private void onMatchLocal(int pubSubId, int requestorInstanceId, byte[] peerMac, 1072 byte[] serviceSpecificInfo, int serviceSpecificInfoLength, byte[] matchFilter, 1073 int matchFilterLength) { 1074 if (VDBG) { 1075 Log.v(TAG, "onMatch: pubSubId=" + pubSubId + ", requestorInstanceId=" 1076 + requestorInstanceId + ", peerMac=" 1077 + String.valueOf(HexEncoding.encode(peerMac)) + ", serviceSpecificInfoLength=" 1078 + serviceSpecificInfoLength + ", serviceSpecificInfo=" + serviceSpecificInfo 1079 + ", matchFilterLength=" + matchFilterLength + ", matchFilter=" + matchFilter); 1080 } 1081 1082 WifiNanSessionState session = getNanSessionStateForPubSubId(pubSubId); 1083 if (session == null) { 1084 Log.e(TAG, "onMatch: no session found for pubSubId=" + pubSubId); 1085 return; 1086 } 1087 1088 session.onMatch(requestorInstanceId, peerMac, serviceSpecificInfo, 1089 serviceSpecificInfoLength, matchFilter, matchFilterLength); 1090 } 1091 onMessageReceivedLocal(int pubSubId, int requestorInstanceId, byte[] peerMac, byte[] message, int messageLength)1092 private void onMessageReceivedLocal(int pubSubId, int requestorInstanceId, byte[] peerMac, 1093 byte[] message, int messageLength) { 1094 if (VDBG) { 1095 Log.v(TAG, 1096 "onMessageReceived: pubSubId=" + pubSubId + ", requestorInstanceId=" 1097 + requestorInstanceId + ", peerMac=" 1098 + String.valueOf(HexEncoding.encode(peerMac)) + ", messageLength=" 1099 + messageLength); 1100 } 1101 1102 WifiNanSessionState session = getNanSessionStateForPubSubId(pubSubId); 1103 if (session == null) { 1104 Log.e(TAG, "onMessageReceived: no session found for pubSubId=" + pubSubId); 1105 return; 1106 } 1107 1108 session.onMessageReceived(requestorInstanceId, peerMac, message, messageLength); 1109 } 1110 mergeConfigRequests()1111 private ConfigRequest mergeConfigRequests() { 1112 if (VDBG) { 1113 Log.v(TAG, "mergeConfigRequests(): mClients=[" + mClients + "]"); 1114 } 1115 1116 if (mClients.size() == 0) { 1117 Log.e(TAG, "mergeConfigRequests: invalid state - called with 0 clients registered!"); 1118 return null; 1119 } 1120 1121 if (mClients.size() == 1) { 1122 return mClients.valueAt(0).getConfigRequest(); 1123 } 1124 1125 // TODO: continue working on merge algorithm: 1126 // - if any request 5g: enable 1127 // - maximal master preference 1128 // - cluster range covering all requests: assume that [0,max] is a 1129 // non-request 1130 boolean support5gBand = false; 1131 int masterPreference = 0; 1132 boolean clusterIdValid = false; 1133 int clusterLow = 0; 1134 int clusterHigh = ConfigRequest.CLUSTER_ID_MAX; 1135 for (int i = 0; i < mClients.size(); ++i) { 1136 ConfigRequest cr = mClients.valueAt(i).getConfigRequest(); 1137 1138 if (cr.mSupport5gBand) { 1139 support5gBand = true; 1140 } 1141 1142 masterPreference = Math.max(masterPreference, cr.mMasterPreference); 1143 1144 if (cr.mClusterLow != 0 || cr.mClusterHigh != ConfigRequest.CLUSTER_ID_MAX) { 1145 if (!clusterIdValid) { 1146 clusterLow = cr.mClusterLow; 1147 clusterHigh = cr.mClusterHigh; 1148 } else { 1149 clusterLow = Math.min(clusterLow, cr.mClusterLow); 1150 clusterHigh = Math.max(clusterHigh, cr.mClusterHigh); 1151 } 1152 clusterIdValid = true; 1153 } 1154 } 1155 ConfigRequest.Builder builder = new ConfigRequest.Builder(); 1156 builder.setSupport5gBand(support5gBand).setMasterPreference(masterPreference) 1157 .setClusterLow(clusterLow).setClusterHigh(clusterHigh); 1158 1159 return builder.build(); 1160 } 1161 dump(FileDescriptor fd, PrintWriter pw, String[] args)1162 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1163 pw.println("NanStateManager:"); 1164 pw.println(" mClients: [" + mClients + "]"); 1165 pw.println(" mPendingResponses: [" + mPendingResponses + "]"); 1166 pw.println(" mCapabilities: [" + mCapabilities + "]"); 1167 pw.println(" mNextTransactionId: " + mNextTransactionId); 1168 for (int i = 0; i < mClients.size(); ++i) { 1169 mClients.valueAt(i).dump(fd, pw, args); 1170 } 1171 } 1172 } 1173