WifiNanSessionState.java revision 956f54b391677d78379729dd14518edddf3c7660
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 17package com.android.server.wifi.nan; 18 19import android.net.wifi.nan.IWifiNanSessionListener; 20import android.net.wifi.nan.PublishData; 21import android.net.wifi.nan.PublishSettings; 22import android.net.wifi.nan.SubscribeData; 23import android.net.wifi.nan.SubscribeSettings; 24import android.net.wifi.nan.WifiNanSessionListener; 25import android.os.RemoteException; 26import android.util.Log; 27import android.util.SparseArray; 28 29import libcore.util.HexEncoding; 30 31import java.io.FileDescriptor; 32import java.io.PrintWriter; 33 34public class WifiNanSessionState { 35 private static final String TAG = "WifiNanSessionState"; 36 private static final boolean DBG = true; 37 private static final boolean VDBG = false; // STOPSHIP if true 38 39 private static final SparseArray<WifiNanSessionState> sSessionsByPubSubId = new SparseArray<>(); 40 41 private static final SparseArray<String> sMacByRequestorInstanceId = new SparseArray<>(); 42 43 private int mUid; 44 private int mSessionId; 45 private IWifiNanSessionListener mListener; 46 private int mEvents; 47 48 private boolean mPubSubIdValid = false; 49 private int mPubSubId; 50 51 private static final int SESSION_TYPE_NOT_INIT = 0; 52 private static final int SESSION_TYPE_PUBLISH = 1; 53 private static final int SESSION_TYPE_SUBSCRIBE = 2; 54 private int mSessionType = SESSION_TYPE_NOT_INIT; 55 56 public static WifiNanSessionState getNanSessionStateForPubSubId(int pubSubId) { 57 return sSessionsByPubSubId.get(pubSubId); 58 } 59 60 public WifiNanSessionState(int uid, int sessionId, IWifiNanSessionListener listener, 61 int events) { 62 mUid = uid; 63 mSessionId = sessionId; 64 mListener = listener; 65 mEvents = events; 66 } 67 68 public void destroy() { 69 stop(WifiNanStateManager.getInstance().getTransactionId()); 70 if (mPubSubIdValid) { 71 WifiNanSessionState.sSessionsByPubSubId.delete(mPubSubId); 72 sMacByRequestorInstanceId.clear(); 73 mListener = null; 74 mPubSubIdValid = false; 75 } 76 } 77 78 public int getUid() { 79 return mUid; 80 } 81 82 public int getSessionId() { 83 return mSessionId; 84 } 85 86 public void publish(short transactionId, PublishData data, PublishSettings settings) { 87 if (mSessionType == SESSION_TYPE_SUBSCRIBE) { 88 throw new IllegalStateException("A SUBSCRIBE session is being used for publish"); 89 } 90 mSessionType = SESSION_TYPE_PUBLISH; 91 92 WifiNanNative.getInstance().publish(transactionId, mPubSubIdValid ? mPubSubId : 0, data, 93 settings); 94 } 95 96 public void subscribe(short transactionId, SubscribeData data, SubscribeSettings settings) { 97 if (mSessionType == SESSION_TYPE_PUBLISH) { 98 throw new IllegalStateException("A PUBLISH session is being used for publish"); 99 } 100 mSessionType = SESSION_TYPE_SUBSCRIBE; 101 102 WifiNanNative.getInstance().subscribe(transactionId, mPubSubIdValid ? mPubSubId : 0, data, 103 settings); 104 } 105 106 public void sendMessage(short transactionId, int peerId, byte[] message, 107 int messageLength) { 108 if (!mPubSubIdValid) { 109 Log.e(TAG, "sendMessage: attempting to send a message on a non-live session " 110 + "(no successful publish or subscribe"); 111 onMessageSendFail(WifiNanSessionListener.FAIL_REASON_NO_MATCH_SESSION); 112 return; 113 } 114 115 String peerMacStr = sMacByRequestorInstanceId.get(peerId); 116 if (peerMacStr == null) { 117 Log.e(TAG, "sendMessage: attempting to send a message to an address which didn't " 118 + "match/contact us"); 119 onMessageSendFail(WifiNanSessionListener.FAIL_REASON_NO_MATCH_SESSION); 120 return; 121 } 122 byte[] peerMac = HexEncoding.decode(peerMacStr.toCharArray(), false); 123 124 WifiNanNative.getInstance().sendMessage(transactionId, mPubSubId, peerId, peerMac, message, 125 messageLength); 126 } 127 128 public void stop(short transactionId) { 129 if (!mPubSubIdValid || mSessionType == SESSION_TYPE_NOT_INIT) { 130 Log.e(TAG, "sendMessage: attempting to stop pub/sub on a non-live session (no " 131 + "successful publish or subscribe"); 132 return; 133 } 134 135 if (mSessionType == SESSION_TYPE_PUBLISH) { 136 WifiNanNative.getInstance().stopPublish(transactionId, mPubSubId); 137 } else if (mSessionType == SESSION_TYPE_SUBSCRIBE) { 138 WifiNanNative.getInstance().stopSubscribe(transactionId, mPubSubId); 139 } 140 } 141 142 public void onPublishSuccess(int publishId) { 143 if (mPubSubIdValid) { 144 WifiNanSessionState.sSessionsByPubSubId.delete(mPubSubId); 145 } 146 147 mPubSubId = publishId; 148 mPubSubIdValid = true; 149 WifiNanSessionState.sSessionsByPubSubId.put(mPubSubId, this); 150 } 151 152 public void onPublishFail(int status) { 153 mPubSubIdValid = false; 154 try { 155 if (mListener != null && (mEvents & WifiNanSessionListener.LISTEN_PUBLISH_FAIL) != 0) { 156 mListener.onPublishFail(status); 157 } 158 } catch (RemoteException e) { 159 Log.w(TAG, "onPublishFail: RemoteException (FYI): " + e); 160 } 161 } 162 163 public void onPublishTerminated(int status) { 164 mPubSubIdValid = false; 165 try { 166 if (mListener != null 167 && (mEvents & WifiNanSessionListener.LISTEN_PUBLISH_TERMINATED) != 0) { 168 mListener.onPublishTerminated(status); 169 } 170 } catch (RemoteException e) { 171 Log.w(TAG, "onPublishTerminated: RemoteException (FYI): " + e); 172 } 173 } 174 175 public void onSubscribeSuccess(int subscribeId) { 176 if (mPubSubIdValid) { 177 WifiNanSessionState.sSessionsByPubSubId.delete(mPubSubId); 178 } 179 180 mPubSubId = subscribeId; 181 mPubSubIdValid = true; 182 WifiNanSessionState.sSessionsByPubSubId.put(mPubSubId, this); 183 } 184 185 public void onSubscribeFail(int status) { 186 mPubSubIdValid = false; 187 try { 188 if (mListener != null 189 && (mEvents & WifiNanSessionListener.LISTEN_SUBSCRIBE_FAIL) != 0) { 190 mListener.onSubscribeFail(status); 191 } 192 } catch (RemoteException e) { 193 Log.w(TAG, "onSubscribeFail: RemoteException (FYI): " + e); 194 } 195 } 196 197 public void onSubscribeTerminated(int status) { 198 mPubSubIdValid = false; 199 try { 200 if (mListener != null 201 && (mEvents & WifiNanSessionListener.LISTEN_SUBSCRIBE_TERMINATED) != 0) { 202 mListener.onSubscribeTerminated(status); 203 } 204 } catch (RemoteException e) { 205 Log.w(TAG, "onSubscribeTerminated: RemoteException (FYI): " + e); 206 } 207 } 208 209 public void onMessageSendSuccess() { 210 try { 211 if (mListener != null 212 && (mEvents & WifiNanSessionListener.LISTEN_MESSAGE_SEND_SUCCESS) != 0) { 213 mListener.onMessageSendSuccess(); 214 } 215 } catch (RemoteException e) { 216 Log.w(TAG, "onMessageSendSuccess: RemoteException (FYI): " + e); 217 } 218 } 219 220 public void onMessageSendFail(int status) { 221 try { 222 if (mListener != null 223 && (mEvents & WifiNanSessionListener.LISTEN_MESSAGE_SEND_FAIL) != 0) { 224 mListener.onMessageSendFail(status); 225 } 226 } catch (RemoteException e) { 227 Log.w(TAG, "onMessageSendFail: RemoteException (FYI): " + e); 228 } 229 } 230 231 public void onMatch(int requestorInstanceId, byte[] peerMac, byte[] serviceSpecificInfo, 232 int serviceSpecificInfoLength, byte[] matchFilter, int matchFilterLength) { 233 String prevMac = sMacByRequestorInstanceId.get(requestorInstanceId); 234 sMacByRequestorInstanceId.put(requestorInstanceId, new String(HexEncoding.encode(peerMac))); 235 236 if (DBG) Log.d(TAG, "onMatch: previous peer MAC replaced - " + prevMac); 237 238 try { 239 if (mListener != null && (mEvents & WifiNanSessionListener.LISTEN_MATCH) != 0) { 240 mListener.onMatch(requestorInstanceId, serviceSpecificInfo, 241 serviceSpecificInfoLength, matchFilter, matchFilterLength); 242 } 243 } catch (RemoteException e) { 244 Log.w(TAG, "onMatch: RemoteException (FYI): " + e); 245 } 246 } 247 248 public void onMessageReceived(int requestorInstanceId, byte[] peerMac, byte[] message, 249 int messageLength) { 250 String prevMac = sMacByRequestorInstanceId.get(requestorInstanceId); 251 sMacByRequestorInstanceId.put(requestorInstanceId, new String(HexEncoding.encode(peerMac))); 252 253 if (DBG) { 254 Log.d(TAG, "onMessageReceived: previous peer MAC replaced - " + prevMac); 255 } 256 257 try { 258 if (mListener != null 259 && (mEvents & WifiNanSessionListener.LISTEN_MESSAGE_RECEIVED) != 0) { 260 mListener.onMessageReceived(requestorInstanceId, message, messageLength); 261 } 262 } catch (RemoteException e) { 263 Log.w(TAG, "onMessageReceived: RemoteException (FYI): " + e); 264 } 265 } 266 267 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 268 pw.println("NanSessionState:"); 269 pw.println(" mUid: " + mUid); 270 pw.println(" mSessionId: " + mSessionId); 271 pw.println(" mSessionType: " + mSessionType); 272 pw.println(" mEvents: " + mEvents); 273 pw.println(" mPubSubId: " + (mPubSubIdValid ? Integer.toString(mPubSubId) : "not valid")); 274 pw.println(" sMacByRequestorInstanceId: [" + sMacByRequestorInstanceId + "]"); 275 } 276 277 public static void dumpS(FileDescriptor fd, PrintWriter pw, String[] args) { 278 pw.println("NanSessionState Static:"); 279 pw.println(" sSessionsByPubSubId: " + WifiNanSessionState.sSessionsByPubSubId); 280 } 281} 282