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 android.net.wifi.nan; 18 19 import android.os.Bundle; 20 import android.os.Handler; 21 import android.os.Looper; 22 import android.os.Message; 23 import android.util.Log; 24 25 /** 26 * Base class for NAN session events callbacks. Should be extended by 27 * applications wanting notifications. The callbacks are registered when a 28 * publish or subscribe session is created using 29 * {@link WifiNanManager#publish(PublishData, PublishSettings, WifiNanSessionListener, int)} 30 * or 31 * {@link WifiNanManager#subscribe(SubscribeData, SubscribeSettings, WifiNanSessionListener, int)} 32 * . These are callbacks applying to a specific NAN session. Events 33 * corresponding to the NAN link are delivered using {@link WifiNanEventListener}. 34 * <p> 35 * A single listener is registered at session creation - it cannot be replaced. 36 * <p> 37 * During registration specify which specific events are desired using a set of 38 * {@code NanSessionListener.LISTEN_*} flags OR'd together. Only those events 39 * will be delivered to the registered listener. Override those callbacks 40 * {@code NanSessionListener.on*} for the registered events. 41 * 42 * @hide PROPOSED_NAN_API 43 */ 44 public class WifiNanSessionListener { 45 private static final String TAG = "WifiNanSessionListener"; 46 private static final boolean DBG = false; 47 private static final boolean VDBG = false; // STOPSHIP if true 48 49 /** 50 * Publish fail callback event registration flag. Corresponding callback is 51 * {@link WifiNanSessionListener#onPublishFail(int)}. 52 * 53 * @hide 54 */ 55 public static final int LISTEN_PUBLISH_FAIL = 0x1 << 0; 56 57 /** 58 * Publish terminated callback event registration flag. Corresponding 59 * callback is {@link WifiNanSessionListener#onPublishTerminated(int)}. 60 */ 61 public static final int LISTEN_PUBLISH_TERMINATED = 0x1 << 1; 62 63 /** 64 * Subscribe fail callback event registration flag. Corresponding callback 65 * is {@link WifiNanSessionListener#onSubscribeFail(int)}. 66 * 67 * @hide 68 */ 69 public static final int LISTEN_SUBSCRIBE_FAIL = 0x1 << 2; 70 71 /** 72 * Subscribe terminated callback event registration flag. Corresponding 73 * callback is {@link WifiNanSessionListener#onSubscribeTerminated(int)}. 74 */ 75 public static final int LISTEN_SUBSCRIBE_TERMINATED = 0x1 << 3; 76 77 /** 78 * Match (discovery: publish or subscribe) callback event registration flag. 79 * Corresponding callback is 80 * {@link WifiNanSessionListener#onMatch(int, byte[], int, byte[], int)}. 81 * 82 * @hide 83 */ 84 public static final int LISTEN_MATCH = 0x1 << 4; 85 86 /** 87 * Message sent successfully callback event registration flag. Corresponding 88 * callback is {@link WifiNanSessionListener#onMessageSendSuccess()}. 89 * 90 * @hide 91 */ 92 public static final int LISTEN_MESSAGE_SEND_SUCCESS = 0x1 << 5; 93 94 /** 95 * Message sending failure callback event registration flag. Corresponding 96 * callback is {@link WifiNanSessionListener#onMessageSendFail(int)}. 97 * 98 * @hide 99 */ 100 public static final int LISTEN_MESSAGE_SEND_FAIL = 0x1 << 6; 101 102 /** 103 * Message received callback event registration flag. Corresponding callback 104 * is {@link WifiNanSessionListener#onMessageReceived(int, byte[], int)}. 105 * 106 * @hide 107 */ 108 public static final int LISTEN_MESSAGE_RECEIVED = 0x1 << 7; 109 110 /** 111 * List of hidden events: which are mandatory - i.e. they will be added to 112 * every request. 113 * 114 * @hide 115 */ 116 public static final int LISTEN_HIDDEN_FLAGS = LISTEN_PUBLISH_FAIL | LISTEN_SUBSCRIBE_FAIL 117 | LISTEN_MATCH | LISTEN_MESSAGE_SEND_SUCCESS | LISTEN_MESSAGE_SEND_FAIL 118 | LISTEN_MESSAGE_RECEIVED; 119 120 /** 121 * Failure reason flag for {@link WifiNanEventListener} and 122 * {@link WifiNanSessionListener} callbacks. Indicates no resources to execute 123 * the requested operation. 124 */ 125 public static final int FAIL_REASON_NO_RESOURCES = 0; 126 127 /** 128 * Failure reason flag for {@link WifiNanEventListener} and 129 * {@link WifiNanSessionListener} callbacks. Indicates invalid argument in the 130 * requested operation. 131 */ 132 public static final int FAIL_REASON_INVALID_ARGS = 1; 133 134 /** 135 * Failure reason flag for {@link WifiNanEventListener} and 136 * {@link WifiNanSessionListener} callbacks. Indicates a message is transmitted 137 * without a match (i.e. a discovery) occurring first. 138 */ 139 public static final int FAIL_REASON_NO_MATCH_SESSION = 2; 140 141 /** 142 * Failure reason flag for {@link WifiNanEventListener} and 143 * {@link WifiNanSessionListener} callbacks. Indicates an unspecified error 144 * occurred during the operation. 145 */ 146 public static final int FAIL_REASON_OTHER = 3; 147 148 /** 149 * Failure reason flag for 150 * {@link WifiNanSessionListener#onPublishTerminated(int)} and 151 * {@link WifiNanSessionListener#onSubscribeTerminated(int)} callbacks. 152 * Indicates that publish or subscribe session is done - i.e. all the 153 * requested operations (per {@link PublishSettings} or 154 * {@link SubscribeSettings}) have been executed. 155 */ 156 public static final int TERMINATE_REASON_DONE = 0; 157 158 /** 159 * Failure reason flag for 160 * {@link WifiNanSessionListener#onPublishTerminated(int)} and 161 * {@link WifiNanSessionListener#onSubscribeTerminated(int)} callbacks. 162 * Indicates that publish or subscribe session is terminated due to a 163 * failure. 164 */ 165 public static final int TERMINATE_REASON_FAIL = 1; 166 167 private static final String MESSAGE_BUNDLE_KEY_PEER_ID = "peer_id"; 168 private static final String MESSAGE_BUNDLE_KEY_MESSAGE = "message"; 169 private static final String MESSAGE_BUNDLE_KEY_MESSAGE2 = "message2"; 170 171 private final Handler mHandler; 172 173 /** 174 * Constructs a {@link WifiNanSessionListener} using the looper of the current 175 * thread. I.e. all callbacks will be delivered on the current thread. 176 */ WifiNanSessionListener()177 public WifiNanSessionListener() { 178 this(Looper.myLooper()); 179 } 180 181 /** 182 * Constructs a {@link WifiNanSessionListener} using the specified looper. I.e. 183 * all callbacks will delivered on the thread of the specified looper. 184 * 185 * @param looper The looper on which to execute the callbacks. 186 */ WifiNanSessionListener(Looper looper)187 public WifiNanSessionListener(Looper looper) { 188 if (VDBG) Log.v(TAG, "ctor: looper=" + looper); 189 mHandler = new Handler(looper) { 190 @Override 191 public void handleMessage(Message msg) { 192 if (DBG) Log.d(TAG, "What=" + msg.what + ", msg=" + msg); 193 switch (msg.what) { 194 case LISTEN_PUBLISH_FAIL: 195 WifiNanSessionListener.this.onPublishFail(msg.arg1); 196 break; 197 case LISTEN_PUBLISH_TERMINATED: 198 WifiNanSessionListener.this.onPublishTerminated(msg.arg1); 199 break; 200 case LISTEN_SUBSCRIBE_FAIL: 201 WifiNanSessionListener.this.onSubscribeFail(msg.arg1); 202 break; 203 case LISTEN_SUBSCRIBE_TERMINATED: 204 WifiNanSessionListener.this.onSubscribeTerminated(msg.arg1); 205 break; 206 case LISTEN_MATCH: 207 WifiNanSessionListener.this.onMatch( 208 msg.getData().getInt(MESSAGE_BUNDLE_KEY_PEER_ID), 209 msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE), msg.arg1, 210 msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE2), msg.arg2); 211 break; 212 case LISTEN_MESSAGE_SEND_SUCCESS: 213 WifiNanSessionListener.this.onMessageSendSuccess(msg.arg1); 214 break; 215 case LISTEN_MESSAGE_SEND_FAIL: 216 WifiNanSessionListener.this.onMessageSendFail(msg.arg1, msg.arg2); 217 break; 218 case LISTEN_MESSAGE_RECEIVED: 219 WifiNanSessionListener.this.onMessageReceived(msg.arg2, 220 msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE), msg.arg1); 221 break; 222 } 223 } 224 }; 225 } 226 227 /** 228 * Called when a publish operation fails. It is dummy method (empty 229 * implementation printing out a log message). Override to implement your 230 * custom response. 231 * 232 * @param reason The failure reason using {@code NanSessionListener.FAIL_*} 233 * codes. 234 */ onPublishFail(int reason)235 public void onPublishFail(int reason) { 236 if (VDBG) Log.v(TAG, "onPublishFail: called in stub - override if interested"); 237 } 238 239 /** 240 * Called when a publish operation terminates. Event will only be delivered 241 * if registered using {@link WifiNanSessionListener#LISTEN_PUBLISH_TERMINATED}. 242 * A dummy (empty implementation printing out a warning). Make sure to 243 * override if registered. 244 * 245 * @param reason The termination reason using 246 * {@code NanSessionListener.TERMINATE_*} codes. 247 */ onPublishTerminated(int reason)248 public void onPublishTerminated(int reason) { 249 Log.w(TAG, "onPublishTerminated: called in stub - override if interested or disable"); 250 } 251 252 /** 253 * Called when a subscribe operation fails. It is dummy method (empty 254 * implementation printing out a log message). Override to implement your 255 * custom response. 256 * 257 * @param reason The failure reason using {@code NanSessionListener.FAIL_*} 258 * codes. 259 */ onSubscribeFail(int reason)260 public void onSubscribeFail(int reason) { 261 if (VDBG) Log.v(TAG, "onSubscribeFail: called in stub - override if interested"); 262 } 263 264 /** 265 * Called when a subscribe operation terminates. Event will only be 266 * delivered if registered using 267 * {@link WifiNanSessionListener#LISTEN_SUBSCRIBE_TERMINATED}. A dummy (empty 268 * implementation printing out a warning). Make sure to override if 269 * registered. 270 * 271 * @param reason The termination reason using 272 * {@code NanSessionListener.TERMINATE_*} codes. 273 */ onSubscribeTerminated(int reason)274 public void onSubscribeTerminated(int reason) { 275 Log.w(TAG, "onSubscribeTerminated: called in stub - override if interested or disable"); 276 } 277 278 /** 279 * Called when a discovery (publish or subscribe) operation results in a 280 * match - i.e. when a peer is discovered. It is dummy method (empty 281 * implementation printing out a log message). Override to implement your 282 * custom response. 283 * 284 * @param peerId The ID of the peer matching our discovery operation. 285 * @param serviceSpecificInfo The service specific information (arbitrary 286 * byte array) provided by the peer as part of its discovery 287 * packet. 288 * @param serviceSpecificInfoLength The length of the service specific 289 * information array. 290 * @param matchFilter The filter (Tx on advertiser and Rx on listener) which 291 * resulted in this match. 292 * @param matchFilterLength The length of the match filter array. 293 */ onMatch(int peerId, byte[] serviceSpecificInfo, int serviceSpecificInfoLength, byte[] matchFilter, int matchFilterLength)294 public void onMatch(int peerId, byte[] serviceSpecificInfo, 295 int serviceSpecificInfoLength, byte[] matchFilter, int matchFilterLength) { 296 if (VDBG) Log.v(TAG, "onMatch: called in stub - override if interested"); 297 } 298 299 /** 300 * Called when a message is transmitted successfully - i.e. when we know 301 * that it was received successfully (corresponding to an ACK being 302 * received). It is dummy method (empty implementation printing out a log 303 * message). Override to implement your custom response. 304 * <p> 305 * Note that either this callback or 306 * {@link WifiNanSessionListener#onMessageSendFail(int, int)} will be 307 * received - never both. 308 */ onMessageSendSuccess(int messageId)309 public void onMessageSendSuccess(int messageId) { 310 if (VDBG) Log.v(TAG, "onMessageSendSuccess: called in stub - override if interested"); 311 } 312 313 /** 314 * Called when a message transmission fails - i.e. when no ACK is received. 315 * The hardware will usually attempt to re-transmit several times - this 316 * event is received after all retries are exhausted. There is a possibility 317 * that message was received by the destination successfully but the ACK was 318 * lost. It is dummy method (empty implementation printing out a log 319 * message). Override to implement your custom response. 320 * <p> 321 * Note that either this callback or 322 * {@link WifiNanSessionListener#onMessageSendSuccess(int)} will be received 323 * - never both 324 * 325 * @param reason The failure reason using {@code NanSessionListener.FAIL_*} 326 * codes. 327 */ onMessageSendFail(int messageId, int reason)328 public void onMessageSendFail(int messageId, int reason) { 329 if (VDBG) Log.v(TAG, "onMessageSendFail: called in stub - override if interested"); 330 } 331 332 /** 333 * Called when a message is received from a discovery session peer. It is 334 * dummy method (empty implementation printing out a log message). Override 335 * to implement your custom response. 336 * 337 * @param peerId The ID of the peer sending the message. 338 * @param message A byte array containing the message. 339 * @param messageLength The length of the byte array containing the relevant 340 * message bytes. 341 */ onMessageReceived(int peerId, byte[] message, int messageLength)342 public void onMessageReceived(int peerId, byte[] message, int messageLength) { 343 if (VDBG) Log.v(TAG, "onMessageReceived: called in stub - override if interested"); 344 } 345 346 /** 347 * {@hide} 348 */ 349 public IWifiNanSessionListener callback = new IWifiNanSessionListener.Stub() { 350 @Override 351 public void onPublishFail(int reason) { 352 if (VDBG) Log.v(TAG, "onPublishFail: reason=" + reason); 353 354 Message msg = mHandler.obtainMessage(LISTEN_PUBLISH_FAIL); 355 msg.arg1 = reason; 356 mHandler.sendMessage(msg); 357 } 358 359 @Override 360 public void onPublishTerminated(int reason) { 361 if (VDBG) Log.v(TAG, "onPublishResponse: reason=" + reason); 362 363 Message msg = mHandler.obtainMessage(LISTEN_PUBLISH_TERMINATED); 364 msg.arg1 = reason; 365 mHandler.sendMessage(msg); 366 } 367 368 @Override 369 public void onSubscribeFail(int reason) { 370 if (VDBG) Log.v(TAG, "onSubscribeFail: reason=" + reason); 371 372 Message msg = mHandler.obtainMessage(LISTEN_SUBSCRIBE_FAIL); 373 msg.arg1 = reason; 374 mHandler.sendMessage(msg); 375 } 376 377 @Override 378 public void onSubscribeTerminated(int reason) { 379 if (VDBG) Log.v(TAG, "onSubscribeTerminated: reason=" + reason); 380 381 Message msg = mHandler.obtainMessage(LISTEN_SUBSCRIBE_TERMINATED); 382 msg.arg1 = reason; 383 mHandler.sendMessage(msg); 384 } 385 386 @Override 387 public void onMatch(int peerId, byte[] serviceSpecificInfo, 388 int serviceSpecificInfoLength, byte[] matchFilter, int matchFilterLength) { 389 if (VDBG) Log.v(TAG, "onMatch: peerId=" + peerId); 390 391 Bundle data = new Bundle(); 392 data.putInt(MESSAGE_BUNDLE_KEY_PEER_ID, peerId); 393 data.putByteArray(MESSAGE_BUNDLE_KEY_MESSAGE, serviceSpecificInfo); 394 data.putByteArray(MESSAGE_BUNDLE_KEY_MESSAGE2, matchFilter); 395 396 Message msg = mHandler.obtainMessage(LISTEN_MATCH); 397 msg.arg1 = serviceSpecificInfoLength; 398 msg.arg2 = matchFilterLength; 399 msg.setData(data); 400 mHandler.sendMessage(msg); 401 } 402 403 @Override 404 public void onMessageSendSuccess(int messageId) { 405 if (VDBG) Log.v(TAG, "onMessageSendSuccess"); 406 407 Message msg = mHandler.obtainMessage(LISTEN_MESSAGE_SEND_SUCCESS); 408 msg.arg1 = messageId; 409 mHandler.sendMessage(msg); 410 } 411 412 @Override 413 public void onMessageSendFail(int messageId, int reason) { 414 if (VDBG) Log.v(TAG, "onMessageSendFail: reason=" + reason); 415 416 Message msg = mHandler.obtainMessage(LISTEN_MESSAGE_SEND_FAIL); 417 msg.arg1 = messageId; 418 msg.arg2 = reason; 419 mHandler.sendMessage(msg); 420 } 421 422 @Override 423 public void onMessageReceived(int peerId, byte[] message, int messageLength) { 424 if (VDBG) { 425 Log.v(TAG, "onMessageReceived: peerId='" + peerId + "', messageLength=" 426 + messageLength); 427 } 428 429 Bundle data = new Bundle(); 430 data.putByteArray(MESSAGE_BUNDLE_KEY_MESSAGE, message); 431 432 Message msg = mHandler.obtainMessage(LISTEN_MESSAGE_RECEIVED); 433 msg.arg1 = messageLength; 434 msg.arg2 = peerId; 435 msg.setData(data); 436 mHandler.sendMessage(msg); 437 } 438 }; 439 } 440