1 /* 2 * Copyright (C) 2010 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.nfc; 18 19 import com.android.internal.nfc.LlcpServiceSocket; 20 import com.android.internal.nfc.LlcpSocket; 21 22 import android.app.Application; 23 import android.content.ActivityNotFoundException; 24 import android.content.BroadcastReceiver; 25 import android.content.Context; 26 import android.content.Intent; 27 import android.content.IntentFilter; 28 import android.content.SharedPreferences; 29 import android.nfc.ErrorCodes; 30 import android.nfc.FormatException; 31 import android.nfc.ILlcpConnectionlessSocket; 32 import android.nfc.ILlcpServiceSocket; 33 import android.nfc.ILlcpSocket; 34 import android.nfc.INfcAdapter; 35 import android.nfc.INfcTag; 36 import android.nfc.IP2pInitiator; 37 import android.nfc.IP2pTarget; 38 import android.nfc.LlcpPacket; 39 import android.nfc.NdefMessage; 40 import android.nfc.NdefTag; 41 import android.nfc.NfcAdapter; 42 import android.nfc.Tag; 43 import android.os.AsyncTask; 44 import android.os.Handler; 45 import android.os.Message; 46 import android.os.PowerManager; 47 import android.os.RemoteException; 48 import android.os.ServiceManager; 49 import android.util.Log; 50 51 import java.util.HashMap; 52 import java.util.LinkedList; 53 import java.util.ListIterator; 54 55 public class NfcService extends Application { 56 static final boolean DBG = false; 57 58 static { 59 System.loadLibrary("nfc_jni"); 60 } 61 62 public static final String SERVICE_NAME = "nfc"; 63 64 private static final String TAG = "NfcService"; 65 66 private static final String NFC_PERM = android.Manifest.permission.NFC; 67 private static final String NFC_PERM_ERROR = "NFC permission required"; 68 private static final String ADMIN_PERM = android.Manifest.permission.WRITE_SECURE_SETTINGS; 69 private static final String ADMIN_PERM_ERROR = "WRITE_SECURE_SETTINGS permission required"; 70 71 private static final String PREF = "NfcServicePrefs"; 72 73 private static final String PREF_NFC_ON = "nfc_on"; 74 private static final boolean NFC_ON_DEFAULT = true; 75 76 private static final String PREF_SECURE_ELEMENT_ON = "secure_element_on"; 77 private static final boolean SECURE_ELEMENT_ON_DEFAULT = false; 78 79 private static final String PREF_SECURE_ELEMENT_ID = "secure_element_id"; 80 private static final int SECURE_ELEMENT_ID_DEFAULT = 0; 81 82 private static final String PREF_LLCP_LTO = "llcp_lto"; 83 private static final int LLCP_LTO_DEFAULT = 150; 84 private static final int LLCP_LTO_MAX = 255; 85 86 /** Maximum Information Unit */ 87 private static final String PREF_LLCP_MIU = "llcp_miu"; 88 private static final int LLCP_MIU_DEFAULT = 128; 89 private static final int LLCP_MIU_MAX = 2176; 90 91 /** Well Known Service List */ 92 private static final String PREF_LLCP_WKS = "llcp_wks"; 93 private static final int LLCP_WKS_DEFAULT = 1; 94 private static final int LLCP_WKS_MAX = 15; 95 96 private static final String PREF_LLCP_OPT = "llcp_opt"; 97 private static final int LLCP_OPT_DEFAULT = 0; 98 private static final int LLCP_OPT_MAX = 3; 99 100 private static final String PREF_DISCOVERY_A = "discovery_a"; 101 private static final boolean DISCOVERY_A_DEFAULT = true; 102 103 private static final String PREF_DISCOVERY_B = "discovery_b"; 104 private static final boolean DISCOVERY_B_DEFAULT = true; 105 106 private static final String PREF_DISCOVERY_F = "discovery_f"; 107 private static final boolean DISCOVERY_F_DEFAULT = true; 108 109 private static final String PREF_DISCOVERY_15693 = "discovery_15693"; 110 private static final boolean DISCOVERY_15693_DEFAULT = true; 111 112 private static final String PREF_DISCOVERY_NFCIP = "discovery_nfcip"; 113 private static final boolean DISCOVERY_NFCIP_DEFAULT = false; 114 115 /** NFC Reader Discovery mode for enableDiscovery() */ 116 private static final int DISCOVERY_MODE_READER = 0; 117 118 /** Card Emulation Discovery mode for enableDiscovery() */ 119 private static final int DISCOVERY_MODE_CARD_EMULATION = 2; 120 121 private static final int LLCP_SERVICE_SOCKET_TYPE = 0; 122 private static final int LLCP_SOCKET_TYPE = 1; 123 private static final int LLCP_CONNECTIONLESS_SOCKET_TYPE = 2; 124 private static final int LLCP_SOCKET_NB_MAX = 5; // Maximum number of socket managed 125 private static final int LLCP_RW_MAX_VALUE = 15; // Receive Window 126 127 private static final int PROPERTY_LLCP_LTO = 0; 128 private static final String PROPERTY_LLCP_LTO_VALUE = "llcp.lto"; 129 private static final int PROPERTY_LLCP_MIU = 1; 130 private static final String PROPERTY_LLCP_MIU_VALUE = "llcp.miu"; 131 private static final int PROPERTY_LLCP_WKS = 2; 132 private static final String PROPERTY_LLCP_WKS_VALUE = "llcp.wks"; 133 private static final int PROPERTY_LLCP_OPT = 3; 134 private static final String PROPERTY_LLCP_OPT_VALUE = "llcp.opt"; 135 private static final int PROPERTY_NFC_DISCOVERY_A = 4; 136 private static final String PROPERTY_NFC_DISCOVERY_A_VALUE = "discovery.iso14443A"; 137 private static final int PROPERTY_NFC_DISCOVERY_B = 5; 138 private static final String PROPERTY_NFC_DISCOVERY_B_VALUE = "discovery.iso14443B"; 139 private static final int PROPERTY_NFC_DISCOVERY_F = 6; 140 private static final String PROPERTY_NFC_DISCOVERY_F_VALUE = "discovery.felica"; 141 private static final int PROPERTY_NFC_DISCOVERY_15693 = 7; 142 private static final String PROPERTY_NFC_DISCOVERY_15693_VALUE = "discovery.iso15693"; 143 private static final int PROPERTY_NFC_DISCOVERY_NFCIP = 8; 144 private static final String PROPERTY_NFC_DISCOVERY_NFCIP_VALUE = "discovery.nfcip"; 145 146 static final int MSG_NDEF_TAG = 0; 147 static final int MSG_CARD_EMULATION = 1; 148 static final int MSG_LLCP_LINK_ACTIVATION = 2; 149 static final int MSG_LLCP_LINK_DEACTIVATED = 3; 150 static final int MSG_TARGET_DESELECTED = 4; 151 152 // TODO: none of these appear to be synchronized but are 153 // read/written from different threads (notably Binder threads)... 154 private final LinkedList<RegisteredSocket> mRegisteredSocketList = new LinkedList<RegisteredSocket>(); 155 private int mLlcpLinkState = NfcAdapter.LLCP_LINK_STATE_DEACTIVATED; 156 private int mGeneratedSocketHandle = 0; 157 private int mNbSocketCreated = 0; 158 private volatile boolean mIsNfcEnabled = false; 159 private int mSelectedSeId = 0; 160 private boolean mNfcSecureElementState; 161 162 // fields below are used in multiple threads and protected by synchronized(this) 163 private final HashMap<Integer, Object> mObjectMap = new HashMap<Integer, Object>(); 164 private final HashMap<Integer, Object> mSocketMap = new HashMap<Integer, Object>(); 165 private boolean mScreenOn; 166 167 // fields below are final after onCreate() 168 private Context mContext; 169 private NativeNfcManager mManager; 170 private SharedPreferences mPrefs; 171 private SharedPreferences.Editor mPrefsEditor; 172 private PowerManager.WakeLock mWakeLock; 173 174 private static NfcService sService; 175 176 public static NfcService getInstance() { 177 return sService; 178 } 179 180 @Override 181 public void onCreate() { 182 super.onCreate(); 183 184 Log.i(TAG, "Starting NFC service"); 185 186 sService = this; 187 188 mContext = this; 189 mManager = new NativeNfcManager(mContext, this); 190 mManager.initializeNativeStructure(); 191 192 mPrefs = mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE); 193 mPrefsEditor = mPrefs.edit(); 194 195 mIsNfcEnabled = false; // real preference read later 196 197 PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE); 198 mScreenOn = pm.isScreenOn(); 199 mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "NfcService"); 200 201 ServiceManager.addService(SERVICE_NAME, mNfcAdapter); 202 203 IntentFilter filter = new IntentFilter(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION); 204 filter.addAction(Intent.ACTION_SCREEN_OFF); 205 filter.addAction(Intent.ACTION_SCREEN_ON); 206 mContext.registerReceiver(mReceiver, filter); 207 208 Thread t = new Thread() { 209 @Override 210 public void run() { 211 boolean nfc_on = mPrefs.getBoolean(PREF_NFC_ON, NFC_ON_DEFAULT); 212 if (nfc_on) { 213 _enable(false); 214 } 215 } 216 }; 217 t.start(); 218 } 219 220 @Override 221 public void onTerminate() { 222 super.onTerminate(); 223 // NFC application is persistent, it should not be destroyed by framework 224 Log.wtf(TAG, "NFC service is under attack!"); 225 } 226 227 private final INfcAdapter.Stub mNfcAdapter = new INfcAdapter.Stub() { 228 /** Protected by "this" */ 229 NdefMessage mLocalMessage = null; 230 231 @Override 232 public boolean enable() throws RemoteException { 233 mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR); 234 235 boolean isSuccess = false; 236 boolean previouslyEnabled = isEnabled(); 237 if (!previouslyEnabled) { 238 reset(); 239 isSuccess = _enable(previouslyEnabled); 240 } 241 return isSuccess; 242 } 243 244 @Override 245 public boolean disable() throws RemoteException { 246 boolean isSuccess = false; 247 mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR); 248 boolean previouslyEnabled = isEnabled(); 249 if (DBG) Log.d(TAG, "Disabling NFC. previous=" + previouslyEnabled); 250 251 if (previouslyEnabled) { 252 /* tear down the my tag server */ 253 isSuccess = mManager.deinitialize(); 254 if (DBG) Log.d(TAG, "NFC success of deinitialize = " + isSuccess); 255 if (isSuccess) { 256 mIsNfcEnabled = false; 257 } 258 } 259 260 updateNfcOnSetting(previouslyEnabled); 261 262 return isSuccess; 263 } 264 265 @Override 266 public int createLlcpConnectionlessSocket(int sap) throws RemoteException { 267 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 268 269 // Check if NFC is enabled 270 if (!mIsNfcEnabled) { 271 return ErrorCodes.ERROR_NOT_INITIALIZED; 272 } 273 274 /* Check SAP is not already used */ 275 276 /* Check nb socket created */ 277 if (mNbSocketCreated < LLCP_SOCKET_NB_MAX) { 278 /* Store the socket handle */ 279 int sockeHandle = mGeneratedSocketHandle; 280 281 if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) { 282 NativeLlcpConnectionlessSocket socket; 283 284 socket = mManager.doCreateLlcpConnectionlessSocket(sap); 285 if (socket != null) { 286 synchronized(NfcService.this) { 287 /* Update the number of socket created */ 288 mNbSocketCreated++; 289 290 /* Add the socket into the socket map */ 291 mSocketMap.put(sockeHandle, socket); 292 } 293 return sockeHandle; 294 } else { 295 /* 296 * socket creation error - update the socket handle 297 * generation 298 */ 299 mGeneratedSocketHandle -= 1; 300 301 /* Get Error Status */ 302 int errorStatus = mManager.doGetLastError(); 303 304 switch (errorStatus) { 305 case ErrorCodes.ERROR_BUFFER_TO_SMALL: 306 return ErrorCodes.ERROR_BUFFER_TO_SMALL; 307 case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES: 308 return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; 309 default: 310 return ErrorCodes.ERROR_SOCKET_CREATION; 311 } 312 } 313 } else { 314 /* Check SAP is not already used */ 315 if (!CheckSocketSap(sap)) { 316 return ErrorCodes.ERROR_SAP_USED; 317 } 318 319 NativeLlcpConnectionlessSocket socket = new NativeLlcpConnectionlessSocket(sap); 320 321 synchronized(NfcService.this) { 322 /* Add the socket into the socket map */ 323 mSocketMap.put(sockeHandle, socket); 324 325 /* Update the number of socket created */ 326 mNbSocketCreated++; 327 } 328 /* Create new registered socket */ 329 RegisteredSocket registeredSocket = new RegisteredSocket( 330 LLCP_CONNECTIONLESS_SOCKET_TYPE, sockeHandle, sap); 331 332 /* Put this socket into a list of registered socket */ 333 mRegisteredSocketList.add(registeredSocket); 334 } 335 336 /* update socket handle generation */ 337 mGeneratedSocketHandle++; 338 339 return sockeHandle; 340 341 } else { 342 /* No socket available */ 343 return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; 344 } 345 346 } 347 348 @Override 349 public int createLlcpServiceSocket(int sap, String sn, int miu, int rw, int linearBufferLength) 350 throws RemoteException { 351 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 352 353 // Check if NFC is enabled 354 if (!mIsNfcEnabled) { 355 return ErrorCodes.ERROR_NOT_INITIALIZED; 356 } 357 358 if (mNbSocketCreated < LLCP_SOCKET_NB_MAX) { 359 int sockeHandle = mGeneratedSocketHandle; 360 361 if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) { 362 NativeLlcpServiceSocket socket; 363 364 socket = mManager.doCreateLlcpServiceSocket(sap, sn, miu, rw, linearBufferLength); 365 if (socket != null) { 366 synchronized(NfcService.this) { 367 /* Update the number of socket created */ 368 mNbSocketCreated++; 369 /* Add the socket into the socket map */ 370 mSocketMap.put(sockeHandle, socket); 371 } 372 } else { 373 /* socket creation error - update the socket handle counter */ 374 mGeneratedSocketHandle -= 1; 375 376 /* Get Error Status */ 377 int errorStatus = mManager.doGetLastError(); 378 379 switch (errorStatus) { 380 case ErrorCodes.ERROR_BUFFER_TO_SMALL: 381 return ErrorCodes.ERROR_BUFFER_TO_SMALL; 382 case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES: 383 return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; 384 default: 385 return ErrorCodes.ERROR_SOCKET_CREATION; 386 } 387 } 388 } else { 389 390 /* Check SAP is not already used */ 391 if (!CheckSocketSap(sap)) { 392 return ErrorCodes.ERROR_SAP_USED; 393 } 394 395 /* Service Name */ 396 if (!CheckSocketServiceName(sn)) { 397 return ErrorCodes.ERROR_SERVICE_NAME_USED; 398 } 399 400 /* Check socket options */ 401 if (!CheckSocketOptions(miu, rw, linearBufferLength)) { 402 return ErrorCodes.ERROR_SOCKET_OPTIONS; 403 } 404 405 NativeLlcpServiceSocket socket = new NativeLlcpServiceSocket(sap, sn, miu, rw, 406 linearBufferLength); 407 synchronized(NfcService.this) { 408 /* Add the socket into the socket map */ 409 mSocketMap.put(sockeHandle, socket); 410 411 /* Update the number of socket created */ 412 mNbSocketCreated++; 413 } 414 /* Create new registered socket */ 415 RegisteredSocket registeredSocket = new RegisteredSocket(LLCP_SERVICE_SOCKET_TYPE, 416 sockeHandle, sap, sn, miu, rw, linearBufferLength); 417 418 /* Put this socket into a list of registered socket */ 419 mRegisteredSocketList.add(registeredSocket); 420 } 421 422 /* update socket handle generation */ 423 mGeneratedSocketHandle += 1; 424 425 if (DBG) Log.d(TAG, "Llcp Service Socket Handle =" + sockeHandle); 426 return sockeHandle; 427 } else { 428 /* No socket available */ 429 return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; 430 } 431 } 432 433 @Override 434 public int createLlcpSocket(int sap, int miu, int rw, int linearBufferLength) 435 throws RemoteException { 436 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 437 438 // Check if NFC is enabled 439 if (!mIsNfcEnabled) { 440 return ErrorCodes.ERROR_NOT_INITIALIZED; 441 } 442 443 if (mNbSocketCreated < LLCP_SOCKET_NB_MAX) { 444 445 int sockeHandle = mGeneratedSocketHandle; 446 447 if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) { 448 if (DBG) Log.d(TAG, "creating llcp socket while activated"); 449 NativeLlcpSocket socket; 450 451 socket = mManager.doCreateLlcpSocket(sap, miu, rw, linearBufferLength); 452 453 if (socket != null) { 454 synchronized(NfcService.this) { 455 /* Update the number of socket created */ 456 mNbSocketCreated++; 457 /* Add the socket into the socket map */ 458 mSocketMap.put(sockeHandle, socket); 459 } 460 } else { 461 /* 462 * socket creation error - update the socket handle 463 * generation 464 */ 465 mGeneratedSocketHandle -= 1; 466 467 /* Get Error Status */ 468 int errorStatus = mManager.doGetLastError(); 469 470 Log.d(TAG, "failed to create llcp socket: " + ErrorCodes.asString(errorStatus)); 471 472 switch (errorStatus) { 473 case ErrorCodes.ERROR_BUFFER_TO_SMALL: 474 return ErrorCodes.ERROR_BUFFER_TO_SMALL; 475 case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES: 476 return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; 477 default: 478 return ErrorCodes.ERROR_SOCKET_CREATION; 479 } 480 } 481 } else { 482 if (DBG) Log.d(TAG, "registering llcp socket while not activated"); 483 484 /* Check SAP is not already used */ 485 if (!CheckSocketSap(sap)) { 486 return ErrorCodes.ERROR_SAP_USED; 487 } 488 489 /* Check Socket options */ 490 if (!CheckSocketOptions(miu, rw, linearBufferLength)) { 491 return ErrorCodes.ERROR_SOCKET_OPTIONS; 492 } 493 494 NativeLlcpSocket socket = new NativeLlcpSocket(sap, miu, rw); 495 synchronized(NfcService.this) { 496 /* Add the socket into the socket map */ 497 mSocketMap.put(sockeHandle, socket); 498 499 /* Update the number of socket created */ 500 mNbSocketCreated++; 501 } 502 /* Create new registered socket */ 503 RegisteredSocket registeredSocket = new RegisteredSocket(LLCP_SOCKET_TYPE, 504 sockeHandle, sap, miu, rw, linearBufferLength); 505 506 /* Put this socket into a list of registered socket */ 507 mRegisteredSocketList.add(registeredSocket); 508 } 509 510 /* update socket handle generation */ 511 mGeneratedSocketHandle++; 512 513 return sockeHandle; 514 } else { 515 /* No socket available */ 516 return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; 517 } 518 } 519 520 @Override 521 public int deselectSecureElement() throws RemoteException { 522 mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR); 523 524 // Check if NFC is enabled 525 if (!mIsNfcEnabled) { 526 return ErrorCodes.ERROR_NOT_INITIALIZED; 527 } 528 529 if (mSelectedSeId == 0) { 530 return ErrorCodes.ERROR_NO_SE_CONNECTED; 531 } 532 533 mManager.doDeselectSecureElement(mSelectedSeId); 534 mNfcSecureElementState = false; 535 mSelectedSeId = 0; 536 537 /* store preference */ 538 mPrefsEditor.putBoolean(PREF_SECURE_ELEMENT_ON, false); 539 mPrefsEditor.putInt(PREF_SECURE_ELEMENT_ID, 0); 540 mPrefsEditor.apply(); 541 542 return ErrorCodes.SUCCESS; 543 } 544 545 @Override 546 public ILlcpConnectionlessSocket getLlcpConnectionlessInterface() throws RemoteException { 547 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 548 return mLlcpConnectionlessSocketService; 549 } 550 551 @Override 552 public ILlcpSocket getLlcpInterface() throws RemoteException { 553 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 554 return mLlcpSocket; 555 } 556 557 @Override 558 public ILlcpServiceSocket getLlcpServiceInterface() throws RemoteException { 559 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 560 return mLlcpServerSocketService; 561 } 562 563 @Override 564 public INfcTag getNfcTagInterface() throws RemoteException { 565 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 566 return mNfcTagService; 567 } 568 569 @Override 570 public IP2pInitiator getP2pInitiatorInterface() throws RemoteException { 571 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 572 return mP2pInitiatorService; 573 } 574 575 @Override 576 public IP2pTarget getP2pTargetInterface() throws RemoteException { 577 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 578 return mP2pTargetService; 579 } 580 581 @Override 582 public String getProperties(String param) throws RemoteException { 583 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 584 585 if (param == null) { 586 return null; 587 } 588 589 if (param.equals(PROPERTY_LLCP_LTO_VALUE)) { 590 return Integer.toString(mPrefs.getInt(PREF_LLCP_LTO, LLCP_LTO_DEFAULT)); 591 } else if (param.equals(PROPERTY_LLCP_MIU_VALUE)) { 592 return Integer.toString(mPrefs.getInt(PREF_LLCP_MIU, LLCP_MIU_DEFAULT)); 593 } else if (param.equals(PROPERTY_LLCP_WKS_VALUE)) { 594 return Integer.toString(mPrefs.getInt(PREF_LLCP_WKS, LLCP_WKS_DEFAULT)); 595 } else if (param.equals(PROPERTY_LLCP_OPT_VALUE)) { 596 return Integer.toString(mPrefs.getInt(PREF_LLCP_OPT, LLCP_OPT_DEFAULT)); 597 } else if (param.equals(PROPERTY_NFC_DISCOVERY_A_VALUE)) { 598 return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_A, DISCOVERY_A_DEFAULT)); 599 } else if (param.equals(PROPERTY_NFC_DISCOVERY_B_VALUE)) { 600 return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_B, DISCOVERY_B_DEFAULT)); 601 } else if (param.equals(PROPERTY_NFC_DISCOVERY_F_VALUE)) { 602 return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_F, DISCOVERY_F_DEFAULT)); 603 } else if (param.equals(PROPERTY_NFC_DISCOVERY_NFCIP_VALUE)) { 604 return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_NFCIP, DISCOVERY_NFCIP_DEFAULT)); 605 } else if (param.equals(PROPERTY_NFC_DISCOVERY_15693_VALUE)) { 606 return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_15693, DISCOVERY_15693_DEFAULT)); 607 } else { 608 return "Unknown property"; 609 } 610 } 611 612 @Override 613 public int[] getSecureElementList() throws RemoteException { 614 mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR); 615 616 int[] list = null; 617 if (mIsNfcEnabled == true) { 618 list = mManager.doGetSecureElementList(); 619 } 620 return list; 621 } 622 623 @Override 624 public int getSelectedSecureElement() throws RemoteException { 625 mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR); 626 627 return mSelectedSeId; 628 } 629 630 @Override 631 public boolean isEnabled() throws RemoteException { 632 return mIsNfcEnabled; 633 } 634 635 @Override 636 public void openTagConnection(Tag tag) throws RemoteException { 637 // TODO: Remove obsolete code 638 } 639 640 @Override 641 public int selectSecureElement(int seId) throws RemoteException { 642 mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR); 643 644 // Check if NFC is enabled 645 if (!mIsNfcEnabled) { 646 return ErrorCodes.ERROR_NOT_INITIALIZED; 647 } 648 649 if (mSelectedSeId == seId) { 650 return ErrorCodes.ERROR_SE_ALREADY_SELECTED; 651 } 652 653 if (mSelectedSeId != 0) { 654 return ErrorCodes.ERROR_SE_CONNECTED; 655 } 656 657 mSelectedSeId = seId; 658 mManager.doSelectSecureElement(mSelectedSeId); 659 660 /* store */ 661 mPrefsEditor.putBoolean(PREF_SECURE_ELEMENT_ON, true); 662 mPrefsEditor.putInt(PREF_SECURE_ELEMENT_ID, mSelectedSeId); 663 mPrefsEditor.apply(); 664 665 mNfcSecureElementState = true; 666 667 return ErrorCodes.SUCCESS; 668 669 } 670 671 @Override 672 public int setProperties(String param, String value) throws RemoteException { 673 mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR); 674 675 if (isEnabled()) { 676 return ErrorCodes.ERROR_NFC_ON; 677 } 678 679 int val; 680 681 /* Check params validity */ 682 if (param == null || value == null) { 683 return ErrorCodes.ERROR_INVALID_PARAM; 684 } 685 686 if (param.equals(PROPERTY_LLCP_LTO_VALUE)) { 687 val = Integer.parseInt(value); 688 689 /* Check params */ 690 if (val > LLCP_LTO_MAX) 691 return ErrorCodes.ERROR_INVALID_PARAM; 692 693 /* Store value */ 694 mPrefsEditor.putInt(PREF_LLCP_LTO, val); 695 mPrefsEditor.apply(); 696 697 /* Update JNI */ 698 mManager.doSetProperties(PROPERTY_LLCP_LTO, val); 699 700 } else if (param.equals(PROPERTY_LLCP_MIU_VALUE)) { 701 val = Integer.parseInt(value); 702 703 /* Check params */ 704 if ((val < LLCP_MIU_DEFAULT) || (val > LLCP_MIU_MAX)) 705 return ErrorCodes.ERROR_INVALID_PARAM; 706 707 /* Store value */ 708 mPrefsEditor.putInt(PREF_LLCP_MIU, val); 709 mPrefsEditor.apply(); 710 711 /* Update JNI */ 712 mManager.doSetProperties(PROPERTY_LLCP_MIU, val); 713 714 } else if (param.equals(PROPERTY_LLCP_WKS_VALUE)) { 715 val = Integer.parseInt(value); 716 717 /* Check params */ 718 if (val > LLCP_WKS_MAX) 719 return ErrorCodes.ERROR_INVALID_PARAM; 720 721 /* Store value */ 722 mPrefsEditor.putInt(PREF_LLCP_WKS, val); 723 mPrefsEditor.apply(); 724 725 /* Update JNI */ 726 mManager.doSetProperties(PROPERTY_LLCP_WKS, val); 727 728 } else if (param.equals(PROPERTY_LLCP_OPT_VALUE)) { 729 val = Integer.parseInt(value); 730 731 /* Check params */ 732 if (val > LLCP_OPT_MAX) 733 return ErrorCodes.ERROR_INVALID_PARAM; 734 735 /* Store value */ 736 mPrefsEditor.putInt(PREF_LLCP_OPT, val); 737 mPrefsEditor.apply(); 738 739 /* Update JNI */ 740 mManager.doSetProperties(PROPERTY_LLCP_OPT, val); 741 742 } else if (param.equals(PROPERTY_NFC_DISCOVERY_A_VALUE)) { 743 boolean b = Boolean.parseBoolean(value); 744 745 /* Store value */ 746 mPrefsEditor.putBoolean(PREF_DISCOVERY_A, b); 747 mPrefsEditor.apply(); 748 749 /* Update JNI */ 750 mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_A, b ? 1 : 0); 751 752 } else if (param.equals(PROPERTY_NFC_DISCOVERY_B_VALUE)) { 753 boolean b = Boolean.parseBoolean(value); 754 755 /* Store value */ 756 mPrefsEditor.putBoolean(PREF_DISCOVERY_B, b); 757 mPrefsEditor.apply(); 758 759 /* Update JNI */ 760 mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_B, b ? 1 : 0); 761 762 } else if (param.equals(PROPERTY_NFC_DISCOVERY_F_VALUE)) { 763 boolean b = Boolean.parseBoolean(value); 764 765 /* Store value */ 766 mPrefsEditor.putBoolean(PREF_DISCOVERY_F, b); 767 mPrefsEditor.apply(); 768 769 /* Update JNI */ 770 mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_F, b ? 1 : 0); 771 772 } else if (param.equals(PROPERTY_NFC_DISCOVERY_15693_VALUE)) { 773 boolean b = Boolean.parseBoolean(value); 774 775 /* Store value */ 776 mPrefsEditor.putBoolean(PREF_DISCOVERY_15693, b); 777 mPrefsEditor.apply(); 778 779 /* Update JNI */ 780 mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_15693, b ? 1 : 0); 781 782 } else if (param.equals(PROPERTY_NFC_DISCOVERY_NFCIP_VALUE)) { 783 boolean b = Boolean.parseBoolean(value); 784 785 /* Store value */ 786 mPrefsEditor.putBoolean(PREF_DISCOVERY_NFCIP, b); 787 mPrefsEditor.apply(); 788 789 /* Update JNI */ 790 mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_NFCIP, b ? 1 : 0); 791 792 } else { 793 return ErrorCodes.ERROR_INVALID_PARAM; 794 } 795 796 return ErrorCodes.SUCCESS; 797 } 798 }; 799 800 private final ILlcpSocket mLlcpSocket = new ILlcpSocket.Stub() { 801 802 private final int CONNECT_FLAG = 0x01; 803 private final int CLOSE_FLAG = 0x02; 804 private final int RECV_FLAG = 0x04; 805 private final int SEND_FLAG = 0x08; 806 807 private int concurrencyFlags; 808 private Object sync; 809 810 @Override 811 public int close(int nativeHandle) throws RemoteException { 812 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 813 814 NativeLlcpSocket socket = null; 815 boolean isSuccess = false; 816 817 // Check if NFC is enabled 818 if (!mIsNfcEnabled) { 819 return ErrorCodes.ERROR_NOT_INITIALIZED; 820 } 821 822 /* find the socket in the hmap */ 823 socket = (NativeLlcpSocket) findSocket(nativeHandle); 824 if (socket != null) { 825 if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) { 826 isSuccess = socket.doClose(); 827 if (isSuccess) { 828 /* Remove the socket closed from the hmap */ 829 RemoveSocket(nativeHandle); 830 /* Update mNbSocketCreated */ 831 mNbSocketCreated--; 832 return ErrorCodes.SUCCESS; 833 } else { 834 return ErrorCodes.ERROR_IO; 835 } 836 } else { 837 /* Remove the socket closed from the hmap */ 838 RemoveSocket(nativeHandle); 839 840 /* Remove registered socket from the list */ 841 RemoveRegisteredSocket(nativeHandle); 842 843 /* Update mNbSocketCreated */ 844 mNbSocketCreated--; 845 846 return ErrorCodes.SUCCESS; 847 } 848 } else { 849 return ErrorCodes.ERROR_IO; 850 } 851 } 852 853 @Override 854 public int connect(int nativeHandle, int sap) throws RemoteException { 855 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 856 857 NativeLlcpSocket socket = null; 858 boolean isSuccess = false; 859 860 // Check if NFC is enabled 861 if (!mIsNfcEnabled) { 862 return ErrorCodes.ERROR_NOT_INITIALIZED; 863 } 864 865 /* find the socket in the hmap */ 866 socket = (NativeLlcpSocket) findSocket(nativeHandle); 867 if (socket != null) { 868 isSuccess = socket.doConnect(sap); 869 if (isSuccess) { 870 return ErrorCodes.SUCCESS; 871 } else { 872 return ErrorCodes.ERROR_IO; 873 } 874 } else { 875 return ErrorCodes.ERROR_IO; 876 } 877 878 } 879 880 @Override 881 public int connectByName(int nativeHandle, String sn) throws RemoteException { 882 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 883 884 NativeLlcpSocket socket = null; 885 boolean isSuccess = false; 886 887 // Check if NFC is enabled 888 if (!mIsNfcEnabled) { 889 return ErrorCodes.ERROR_NOT_INITIALIZED; 890 } 891 892 /* find the socket in the hmap */ 893 socket = (NativeLlcpSocket) findSocket(nativeHandle); 894 if (socket != null) { 895 isSuccess = socket.doConnectBy(sn); 896 if (isSuccess) { 897 return ErrorCodes.SUCCESS; 898 } else { 899 return ErrorCodes.ERROR_IO; 900 } 901 } else { 902 return ErrorCodes.ERROR_IO; 903 } 904 905 } 906 907 @Override 908 public int getLocalSap(int nativeHandle) throws RemoteException { 909 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 910 911 NativeLlcpSocket socket = null; 912 913 // Check if NFC is enabled 914 if (!mIsNfcEnabled) { 915 return ErrorCodes.ERROR_NOT_INITIALIZED; 916 } 917 918 /* find the socket in the hmap */ 919 socket = (NativeLlcpSocket) findSocket(nativeHandle); 920 if (socket != null) { 921 return socket.getSap(); 922 } else { 923 return 0; 924 } 925 } 926 927 @Override 928 public int getLocalSocketMiu(int nativeHandle) throws RemoteException { 929 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 930 931 NativeLlcpSocket socket = null; 932 933 // Check if NFC is enabled 934 if (!mIsNfcEnabled) { 935 return ErrorCodes.ERROR_NOT_INITIALIZED; 936 } 937 938 /* find the socket in the hmap */ 939 socket = (NativeLlcpSocket) findSocket(nativeHandle); 940 if (socket != null) { 941 return socket.getMiu(); 942 } else { 943 return 0; 944 } 945 } 946 947 @Override 948 public int getLocalSocketRw(int nativeHandle) throws RemoteException { 949 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 950 951 NativeLlcpSocket socket = null; 952 953 // Check if NFC is enabled 954 if (!mIsNfcEnabled) { 955 return ErrorCodes.ERROR_NOT_INITIALIZED; 956 } 957 958 /* find the socket in the hmap */ 959 socket = (NativeLlcpSocket) findSocket(nativeHandle); 960 if (socket != null) { 961 return socket.getRw(); 962 } else { 963 return 0; 964 } 965 } 966 967 @Override 968 public int getRemoteSocketMiu(int nativeHandle) throws RemoteException { 969 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 970 971 NativeLlcpSocket socket = null; 972 973 // Check if NFC is enabled 974 if (!mIsNfcEnabled) { 975 return ErrorCodes.ERROR_NOT_INITIALIZED; 976 } 977 978 /* find the socket in the hmap */ 979 socket = (NativeLlcpSocket) findSocket(nativeHandle); 980 if (socket != null) { 981 if (socket.doGetRemoteSocketMiu() != 0) { 982 return socket.doGetRemoteSocketMiu(); 983 } else { 984 return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED; 985 } 986 } else { 987 return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED; 988 } 989 } 990 991 @Override 992 public int getRemoteSocketRw(int nativeHandle) throws RemoteException { 993 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 994 995 NativeLlcpSocket socket = null; 996 997 // Check if NFC is enabled 998 if (!mIsNfcEnabled) { 999 return ErrorCodes.ERROR_NOT_INITIALIZED; 1000 } 1001 1002 /* find the socket in the hmap */ 1003 socket = (NativeLlcpSocket) findSocket(nativeHandle); 1004 if (socket != null) { 1005 if (socket.doGetRemoteSocketRw() != 0) { 1006 return socket.doGetRemoteSocketRw(); 1007 } else { 1008 return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED; 1009 } 1010 } else { 1011 return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED; 1012 } 1013 } 1014 1015 @Override 1016 public int receive(int nativeHandle, byte[] receiveBuffer) throws RemoteException { 1017 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1018 1019 NativeLlcpSocket socket = null; 1020 int receiveLength = 0; 1021 1022 // Check if NFC is enabled 1023 if (!mIsNfcEnabled) { 1024 return ErrorCodes.ERROR_NOT_INITIALIZED; 1025 } 1026 1027 /* find the socket in the hmap */ 1028 socket = (NativeLlcpSocket) findSocket(nativeHandle); 1029 if (socket != null) { 1030 receiveLength = socket.doReceive(receiveBuffer); 1031 if (receiveLength != 0) { 1032 return receiveLength; 1033 } else { 1034 return ErrorCodes.ERROR_IO; 1035 } 1036 } else { 1037 return ErrorCodes.ERROR_IO; 1038 } 1039 } 1040 1041 @Override 1042 public int send(int nativeHandle, byte[] data) throws RemoteException { 1043 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1044 1045 NativeLlcpSocket socket = null; 1046 boolean isSuccess = false; 1047 1048 // Check if NFC is enabled 1049 if (!mIsNfcEnabled) { 1050 return ErrorCodes.ERROR_NOT_INITIALIZED; 1051 } 1052 1053 /* find the socket in the hmap */ 1054 socket = (NativeLlcpSocket) findSocket(nativeHandle); 1055 if (socket != null) { 1056 isSuccess = socket.doSend(data); 1057 if (isSuccess) { 1058 return ErrorCodes.SUCCESS; 1059 } else { 1060 return ErrorCodes.ERROR_IO; 1061 } 1062 } else { 1063 return ErrorCodes.ERROR_IO; 1064 } 1065 } 1066 }; 1067 1068 private final ILlcpServiceSocket mLlcpServerSocketService = new ILlcpServiceSocket.Stub() { 1069 1070 @Override 1071 public int accept(int nativeHandle) throws RemoteException { 1072 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1073 1074 NativeLlcpServiceSocket socket = null; 1075 NativeLlcpSocket clientSocket = null; 1076 1077 // Check if NFC is enabled 1078 if (!mIsNfcEnabled) { 1079 return ErrorCodes.ERROR_NOT_INITIALIZED; 1080 } 1081 1082 if (mNbSocketCreated < LLCP_SOCKET_NB_MAX) { 1083 /* find the socket in the hmap */ 1084 socket = (NativeLlcpServiceSocket) findSocket(nativeHandle); 1085 if (socket != null) { 1086 clientSocket = socket.doAccept(socket.getMiu(), 1087 socket.getRw(), socket.getLinearBufferLength()); 1088 if (clientSocket != null) { 1089 /* Add the socket into the socket map */ 1090 synchronized(this) { 1091 mSocketMap.put(clientSocket.getHandle(), clientSocket); 1092 mNbSocketCreated++; 1093 } 1094 return clientSocket.getHandle(); 1095 } else { 1096 return ErrorCodes.ERROR_IO; 1097 } 1098 } else { 1099 return ErrorCodes.ERROR_IO; 1100 } 1101 } else { 1102 return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; 1103 } 1104 1105 } 1106 1107 @Override 1108 public void close(int nativeHandle) throws RemoteException { 1109 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1110 1111 NativeLlcpServiceSocket socket = null; 1112 boolean isSuccess = false; 1113 1114 // Check if NFC is enabled 1115 if (!mIsNfcEnabled) { 1116 return; 1117 } 1118 1119 /* find the socket in the hmap */ 1120 boolean closed = false; 1121 socket = (NativeLlcpServiceSocket) findSocket(nativeHandle); 1122 if (socket != null) { 1123 if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) { 1124 isSuccess = socket.doClose(); 1125 if (isSuccess) { 1126 closed = true; 1127 } 1128 } else { 1129 closed = true; 1130 } 1131 } 1132 1133 // If the socket is closed remove it from the socket lists 1134 if (closed) { 1135 synchronized (this) { 1136 /* Remove the socket closed from the hmap */ 1137 RemoveSocket(nativeHandle); 1138 1139 /* Update mNbSocketCreated */ 1140 mNbSocketCreated--; 1141 1142 /* Remove registered socket from the list */ 1143 RemoveRegisteredSocket(nativeHandle); 1144 } 1145 } 1146 } 1147 }; 1148 1149 private final ILlcpConnectionlessSocket mLlcpConnectionlessSocketService = new ILlcpConnectionlessSocket.Stub() { 1150 1151 @Override 1152 public void close(int nativeHandle) throws RemoteException { 1153 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1154 1155 NativeLlcpConnectionlessSocket socket = null; 1156 boolean isSuccess = false; 1157 1158 // Check if NFC is enabled 1159 if (!mIsNfcEnabled) { 1160 return; 1161 } 1162 1163 /* find the socket in the hmap */ 1164 socket = (NativeLlcpConnectionlessSocket) findSocket(nativeHandle); 1165 if (socket != null) { 1166 if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) { 1167 isSuccess = socket.doClose(); 1168 if (isSuccess) { 1169 /* Remove the socket closed from the hmap */ 1170 RemoveSocket(nativeHandle); 1171 /* Update mNbSocketCreated */ 1172 mNbSocketCreated--; 1173 } 1174 } else { 1175 /* Remove the socket closed from the hmap */ 1176 RemoveSocket(nativeHandle); 1177 1178 /* Remove registered socket from the list */ 1179 RemoveRegisteredSocket(nativeHandle); 1180 1181 /* Update mNbSocketCreated */ 1182 mNbSocketCreated--; 1183 } 1184 } 1185 } 1186 1187 @Override 1188 public int getSap(int nativeHandle) throws RemoteException { 1189 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1190 1191 NativeLlcpConnectionlessSocket socket = null; 1192 1193 // Check if NFC is enabled 1194 if (!mIsNfcEnabled) { 1195 return ErrorCodes.ERROR_NOT_INITIALIZED; 1196 } 1197 1198 /* find the socket in the hmap */ 1199 socket = (NativeLlcpConnectionlessSocket) findSocket(nativeHandle); 1200 if (socket != null) { 1201 return socket.getSap(); 1202 } else { 1203 return 0; 1204 } 1205 } 1206 1207 @Override 1208 public LlcpPacket receiveFrom(int nativeHandle) throws RemoteException { 1209 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1210 1211 NativeLlcpConnectionlessSocket socket = null; 1212 LlcpPacket packet; 1213 1214 // Check if NFC is enabled 1215 if (!mIsNfcEnabled) { 1216 return null; 1217 } 1218 1219 /* find the socket in the hmap */ 1220 socket = (NativeLlcpConnectionlessSocket) findSocket(nativeHandle); 1221 if (socket != null) { 1222 packet = socket.doReceiveFrom(socket.getLinkMiu()); 1223 if (packet != null) { 1224 return packet; 1225 } 1226 return null; 1227 } else { 1228 return null; 1229 } 1230 } 1231 1232 @Override 1233 public int sendTo(int nativeHandle, LlcpPacket packet) throws RemoteException { 1234 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1235 1236 NativeLlcpConnectionlessSocket socket = null; 1237 boolean isSuccess = false; 1238 1239 // Check if NFC is enabled 1240 if (!mIsNfcEnabled) { 1241 return ErrorCodes.ERROR_NOT_INITIALIZED; 1242 } 1243 1244 /* find the socket in the hmap */ 1245 socket = (NativeLlcpConnectionlessSocket) findSocket(nativeHandle); 1246 if (socket != null) { 1247 isSuccess = socket.doSendTo(packet.getRemoteSap(), packet.getDataBuffer()); 1248 if (isSuccess) { 1249 return ErrorCodes.SUCCESS; 1250 } else { 1251 return ErrorCodes.ERROR_IO; 1252 } 1253 } else { 1254 return ErrorCodes.ERROR_IO; 1255 } 1256 } 1257 }; 1258 1259 private final INfcTag mNfcTagService = new INfcTag.Stub() { 1260 1261 @Override 1262 public int close(int nativeHandle) throws RemoteException { 1263 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1264 1265 NativeNfcTag tag = null; 1266 1267 // Check if NFC is enabled 1268 if (!mIsNfcEnabled) { 1269 return ErrorCodes.ERROR_NOT_INITIALIZED; 1270 } 1271 1272 /* find the tag in the hmap */ 1273 tag = (NativeNfcTag) findObject(nativeHandle); 1274 if (tag != null) { 1275 /* Remove the device from the hmap */ 1276 unregisterObject(nativeHandle); 1277 tag.disconnect(); 1278 return ErrorCodes.SUCCESS; 1279 } 1280 /* Restart polling loop for notification */ 1281 maybeEnableDiscovery(); 1282 return ErrorCodes.ERROR_DISCONNECT; 1283 } 1284 1285 @Override 1286 public int connect(int nativeHandle) throws RemoteException { 1287 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1288 1289 NativeNfcTag tag = null; 1290 1291 // Check if NFC is enabled 1292 if (!mIsNfcEnabled) { 1293 return ErrorCodes.ERROR_NOT_INITIALIZED; 1294 } 1295 1296 /* find the tag in the hmap */ 1297 tag = (NativeNfcTag) findObject(nativeHandle); 1298 if (tag == null) { 1299 return ErrorCodes.ERROR_DISCONNECT; 1300 } 1301 // TODO: register the tag as being locked rather than really connect 1302 return ErrorCodes.SUCCESS; 1303 } 1304 1305 @Override 1306 public String getType(int nativeHandle) throws RemoteException { 1307 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1308 1309 NativeNfcTag tag = null; 1310 String type; 1311 1312 // Check if NFC is enabled 1313 if (!mIsNfcEnabled) { 1314 return null; 1315 } 1316 1317 /* find the tag in the hmap */ 1318 tag = (NativeNfcTag) findObject(nativeHandle); 1319 if (tag != null) { 1320 type = tag.getType(); 1321 return type; 1322 } 1323 return null; 1324 } 1325 1326 @Override 1327 public byte[] getUid(int nativeHandle) throws RemoteException { 1328 NativeNfcTag tag = null; 1329 byte[] uid; 1330 1331 // Check if NFC is enabled 1332 if (!mIsNfcEnabled) { 1333 return null; 1334 } 1335 1336 /* find the tag in the hmap */ 1337 tag = (NativeNfcTag) findObject(nativeHandle); 1338 if (tag != null) { 1339 uid = tag.getUid(); 1340 return uid; 1341 } 1342 return null; 1343 } 1344 1345 @Override 1346 public boolean isPresent(int nativeHandle) throws RemoteException { 1347 NativeNfcTag tag = null; 1348 1349 // Check if NFC is enabled 1350 if (!mIsNfcEnabled) { 1351 return false; 1352 } 1353 1354 /* find the tag in the hmap */ 1355 tag = (NativeNfcTag) findObject(nativeHandle); 1356 if (tag == null) { 1357 return false; 1358 } 1359 1360 return tag.presenceCheck(); 1361 } 1362 1363 @Override 1364 public boolean isNdef(int nativeHandle) throws RemoteException { 1365 NativeNfcTag tag = null; 1366 boolean isSuccess = false; 1367 1368 // Check if NFC is enabled 1369 if (!mIsNfcEnabled) { 1370 return isSuccess; 1371 } 1372 1373 /* find the tag in the hmap */ 1374 tag = (NativeNfcTag) findObject(nativeHandle); 1375 if (tag != null) { 1376 isSuccess = tag.checkNdef(); 1377 } 1378 return isSuccess; 1379 } 1380 1381 @Override 1382 public byte[] transceive(int nativeHandle, byte[] data) throws RemoteException { 1383 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1384 1385 NativeNfcTag tag = null; 1386 byte[] response; 1387 1388 // Check if NFC is enabled 1389 if (!mIsNfcEnabled) { 1390 return null; 1391 } 1392 1393 /* find the tag in the hmap */ 1394 tag = (NativeNfcTag) findObject(nativeHandle); 1395 if (tag != null) { 1396 response = tag.transceive(data); 1397 return response; 1398 } 1399 return null; 1400 } 1401 1402 @Override 1403 public NdefMessage read(int nativeHandle) throws RemoteException { 1404 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1405 1406 NativeNfcTag tag; 1407 1408 // Check if NFC is enabled 1409 if (!mIsNfcEnabled) { 1410 return null; 1411 } 1412 1413 /* find the tag in the hmap */ 1414 tag = (NativeNfcTag) findObject(nativeHandle); 1415 if (tag != null) { 1416 byte[] buf = tag.read(); 1417 if (buf == null) 1418 return null; 1419 1420 /* Create an NdefMessage */ 1421 try { 1422 return new NdefMessage(buf); 1423 } catch (FormatException e) { 1424 return null; 1425 } 1426 } 1427 return null; 1428 } 1429 1430 @Override 1431 public int write(int nativeHandle, NdefMessage msg) throws RemoteException { 1432 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1433 1434 NativeNfcTag tag; 1435 1436 // Check if NFC is enabled 1437 if (!mIsNfcEnabled) { 1438 return ErrorCodes.ERROR_NOT_INITIALIZED; 1439 } 1440 1441 /* find the tag in the hmap */ 1442 tag = (NativeNfcTag) findObject(nativeHandle); 1443 if (tag == null) { 1444 return ErrorCodes.ERROR_IO; 1445 } 1446 1447 if (tag.write(msg.toByteArray())) { 1448 return ErrorCodes.SUCCESS; 1449 } 1450 else { 1451 return ErrorCodes.ERROR_IO; 1452 } 1453 1454 } 1455 1456 @Override 1457 public int getLastError(int nativeHandle) throws RemoteException { 1458 // TODO Auto-generated method stub 1459 return 0; 1460 } 1461 1462 @Override 1463 public int getModeHint(int nativeHandle) throws RemoteException { 1464 // TODO Auto-generated method stub 1465 return 0; 1466 } 1467 1468 @Override 1469 public int makeReadOnly(int nativeHandle) throws RemoteException { 1470 // TODO Auto-generated method stub 1471 return 0; 1472 } 1473 1474 1475 }; 1476 1477 private final IP2pInitiator mP2pInitiatorService = new IP2pInitiator.Stub() { 1478 1479 @Override 1480 public byte[] getGeneralBytes(int nativeHandle) throws RemoteException { 1481 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1482 1483 NativeP2pDevice device; 1484 1485 // Check if NFC is enabled 1486 if (!mIsNfcEnabled) { 1487 return null; 1488 } 1489 1490 /* find the device in the hmap */ 1491 device = (NativeP2pDevice) findObject(nativeHandle); 1492 if (device != null) { 1493 byte[] buff = device.getGeneralBytes(); 1494 if (buff == null) 1495 return null; 1496 return buff; 1497 } 1498 return null; 1499 } 1500 1501 @Override 1502 public int getMode(int nativeHandle) throws RemoteException { 1503 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1504 1505 NativeP2pDevice device; 1506 1507 // Check if NFC is enabled 1508 if (!mIsNfcEnabled) { 1509 return ErrorCodes.ERROR_NOT_INITIALIZED; 1510 } 1511 1512 /* find the device in the hmap */ 1513 device = (NativeP2pDevice) findObject(nativeHandle); 1514 if (device != null) { 1515 return device.getMode(); 1516 } 1517 return ErrorCodes.ERROR_INVALID_PARAM; 1518 } 1519 1520 @Override 1521 public byte[] receive(int nativeHandle) throws RemoteException { 1522 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1523 1524 NativeP2pDevice device; 1525 1526 // Check if NFC is enabled 1527 if (!mIsNfcEnabled) { 1528 return null; 1529 } 1530 1531 /* find the device in the hmap */ 1532 device = (NativeP2pDevice) findObject(nativeHandle); 1533 if (device != null) { 1534 byte[] buff = device.doReceive(); 1535 if (buff == null) 1536 return null; 1537 return buff; 1538 } 1539 /* Restart polling loop for notification */ 1540 maybeEnableDiscovery(); 1541 return null; 1542 } 1543 1544 @Override 1545 public boolean send(int nativeHandle, byte[] data) throws RemoteException { 1546 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1547 1548 NativeP2pDevice device; 1549 boolean isSuccess = false; 1550 1551 // Check if NFC is enabled 1552 if (!mIsNfcEnabled) { 1553 return isSuccess; 1554 } 1555 1556 /* find the device in the hmap */ 1557 device = (NativeP2pDevice) findObject(nativeHandle); 1558 if (device != null) { 1559 isSuccess = device.doSend(data); 1560 } 1561 return isSuccess; 1562 } 1563 }; 1564 1565 private final IP2pTarget mP2pTargetService = new IP2pTarget.Stub() { 1566 1567 @Override 1568 public int connect(int nativeHandle) throws RemoteException { 1569 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1570 1571 NativeP2pDevice device; 1572 1573 // Check if NFC is enabled 1574 if (!mIsNfcEnabled) { 1575 return ErrorCodes.ERROR_NOT_INITIALIZED; 1576 } 1577 1578 /* find the device in the hmap */ 1579 device = (NativeP2pDevice) findObject(nativeHandle); 1580 if (device != null) { 1581 if (device.doConnect()) { 1582 return ErrorCodes.SUCCESS; 1583 } 1584 } 1585 return ErrorCodes.ERROR_CONNECT; 1586 } 1587 1588 @Override 1589 public boolean disconnect(int nativeHandle) throws RemoteException { 1590 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1591 1592 NativeP2pDevice device; 1593 boolean isSuccess = false; 1594 1595 // Check if NFC is enabled 1596 if (!mIsNfcEnabled) { 1597 return isSuccess; 1598 } 1599 1600 /* find the device in the hmap */ 1601 device = (NativeP2pDevice) findObject(nativeHandle); 1602 if (device != null) { 1603 if (isSuccess = device.doDisconnect()) { 1604 /* remove the device from the hmap */ 1605 unregisterObject(nativeHandle); 1606 /* Restart polling loop for notification */ 1607 maybeEnableDiscovery(); 1608 } 1609 } 1610 return isSuccess; 1611 1612 } 1613 1614 @Override 1615 public byte[] getGeneralBytes(int nativeHandle) throws RemoteException { 1616 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1617 1618 NativeP2pDevice device; 1619 1620 // Check if NFC is enabled 1621 if (!mIsNfcEnabled) { 1622 return null; 1623 } 1624 1625 /* find the device in the hmap */ 1626 device = (NativeP2pDevice) findObject(nativeHandle); 1627 if (device != null) { 1628 byte[] buff = device.getGeneralBytes(); 1629 if (buff == null) 1630 return null; 1631 return buff; 1632 } 1633 return null; 1634 } 1635 1636 @Override 1637 public int getMode(int nativeHandle) throws RemoteException { 1638 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1639 1640 NativeP2pDevice device; 1641 1642 // Check if NFC is enabled 1643 if (!mIsNfcEnabled) { 1644 return ErrorCodes.ERROR_NOT_INITIALIZED; 1645 } 1646 1647 /* find the device in the hmap */ 1648 device = (NativeP2pDevice) findObject(nativeHandle); 1649 if (device != null) { 1650 return device.getMode(); 1651 } 1652 return ErrorCodes.ERROR_INVALID_PARAM; 1653 } 1654 1655 @Override 1656 public byte[] transceive(int nativeHandle, byte[] data) throws RemoteException { 1657 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1658 1659 NativeP2pDevice device; 1660 1661 // Check if NFC is enabled 1662 if (!mIsNfcEnabled) { 1663 return null; 1664 } 1665 1666 /* find the device in the hmap */ 1667 device = (NativeP2pDevice) findObject(nativeHandle); 1668 if (device != null) { 1669 byte[] buff = device.doTransceive(data); 1670 if (buff == null) 1671 return null; 1672 return buff; 1673 } 1674 return null; 1675 } 1676 }; 1677 1678 private boolean _enable(boolean oldEnabledState) { 1679 boolean isSuccess = mManager.initialize(); 1680 if (isSuccess) { 1681 applyProperties(); 1682 1683 /* Check Secure Element setting */ 1684 mNfcSecureElementState = mPrefs.getBoolean(PREF_SECURE_ELEMENT_ON, 1685 SECURE_ELEMENT_ON_DEFAULT); 1686 1687 if (mNfcSecureElementState) { 1688 int secureElementId = mPrefs.getInt(PREF_SECURE_ELEMENT_ID, 1689 SECURE_ELEMENT_ID_DEFAULT); 1690 int[] Se_list = mManager.doGetSecureElementList(); 1691 if (Se_list != null) { 1692 for (int i = 0; i < Se_list.length; i++) { 1693 if (Se_list[i] == secureElementId) { 1694 mManager.doSelectSecureElement(Se_list[i]); 1695 mSelectedSeId = Se_list[i]; 1696 break; 1697 } 1698 } 1699 } 1700 } 1701 1702 mIsNfcEnabled = true; 1703 1704 /* Start polling loop */ 1705 maybeEnableDiscovery(); 1706 } else { 1707 mIsNfcEnabled = false; 1708 } 1709 1710 updateNfcOnSetting(oldEnabledState); 1711 1712 return isSuccess; 1713 } 1714 1715 /** Enable active tag discovery if screen is on and NFC is enabled */ 1716 private synchronized void maybeEnableDiscovery() { 1717 if (mScreenOn && mIsNfcEnabled) { 1718 mManager.enableDiscovery(DISCOVERY_MODE_READER); 1719 } 1720 } 1721 1722 /** Disable active tag discovery if necessary */ 1723 private synchronized void maybeDisableDiscovery() { 1724 if (mIsNfcEnabled) { 1725 mManager.disableDiscovery(); 1726 } 1727 } 1728 1729 private void applyProperties() { 1730 mManager.doSetProperties(PROPERTY_LLCP_LTO, mPrefs.getInt(PREF_LLCP_LTO, LLCP_LTO_DEFAULT)); 1731 mManager.doSetProperties(PROPERTY_LLCP_MIU, mPrefs.getInt(PREF_LLCP_MIU, LLCP_MIU_DEFAULT)); 1732 mManager.doSetProperties(PROPERTY_LLCP_WKS, mPrefs.getInt(PREF_LLCP_WKS, LLCP_WKS_DEFAULT)); 1733 mManager.doSetProperties(PROPERTY_LLCP_OPT, mPrefs.getInt(PREF_LLCP_OPT, LLCP_OPT_DEFAULT)); 1734 mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_A, 1735 mPrefs.getBoolean(PREF_DISCOVERY_A, DISCOVERY_A_DEFAULT) ? 1 : 0); 1736 mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_B, 1737 mPrefs.getBoolean(PREF_DISCOVERY_B, DISCOVERY_B_DEFAULT) ? 1 : 0); 1738 mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_F, 1739 mPrefs.getBoolean(PREF_DISCOVERY_F, DISCOVERY_F_DEFAULT) ? 1 : 0); 1740 mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_15693, 1741 mPrefs.getBoolean(PREF_DISCOVERY_15693, DISCOVERY_15693_DEFAULT) ? 1 : 0); 1742 mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_NFCIP, 1743 mPrefs.getBoolean(PREF_DISCOVERY_NFCIP, DISCOVERY_NFCIP_DEFAULT) ? 1 : 0); 1744 } 1745 1746 private void updateNfcOnSetting(boolean oldEnabledState) { 1747 int state; 1748 1749 mPrefsEditor.putBoolean(PREF_NFC_ON, mIsNfcEnabled); 1750 mPrefsEditor.apply(); 1751 1752 synchronized(this) { 1753 if (oldEnabledState != mIsNfcEnabled) { 1754 Intent intent = new Intent(NfcAdapter.ACTION_ADAPTER_STATE_CHANGE); 1755 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 1756 intent.putExtra(NfcAdapter.EXTRA_NEW_BOOLEAN_STATE, mIsNfcEnabled); 1757 mContext.sendBroadcast(intent); 1758 } 1759 } 1760 } 1761 1762 // Reset all internals 1763 private synchronized void reset() { 1764 // TODO: none of these appear to be synchronized but are 1765 // read/written from different threads (notably Binder threads)... 1766 1767 // Clear tables 1768 mObjectMap.clear(); 1769 mSocketMap.clear(); 1770 mRegisteredSocketList.clear(); 1771 1772 // Reset variables 1773 mLlcpLinkState = NfcAdapter.LLCP_LINK_STATE_DEACTIVATED; 1774 mNbSocketCreated = 0; 1775 mIsNfcEnabled = false; 1776 mSelectedSeId = 0; 1777 } 1778 1779 private synchronized Object findObject(int key) { 1780 Object device = null; 1781 1782 device = mObjectMap.get(key); 1783 if (device == null) { 1784 Log.w(TAG, "Handle not found !"); 1785 } 1786 1787 return device; 1788 } 1789 1790 synchronized void registerTagObject(NativeNfcTag nativeTag) { 1791 mObjectMap.put(nativeTag.getHandle(), nativeTag); 1792 } 1793 1794 synchronized void unregisterObject(int handle) { 1795 mObjectMap.remove(handle); 1796 } 1797 1798 private synchronized Object findSocket(int key) { 1799 Object socket = null; 1800 1801 socket = mSocketMap.get(key); 1802 1803 return socket; 1804 } 1805 1806 private void RemoveSocket(int key) { 1807 mSocketMap.remove(key); 1808 } 1809 1810 private boolean CheckSocketSap(int sap) { 1811 /* List of sockets registered */ 1812 ListIterator<RegisteredSocket> it = mRegisteredSocketList.listIterator(); 1813 1814 while (it.hasNext()) { 1815 RegisteredSocket registeredSocket = it.next(); 1816 1817 if (sap == registeredSocket.mSap) { 1818 /* SAP already used */ 1819 return false; 1820 } 1821 } 1822 return true; 1823 } 1824 1825 private boolean CheckSocketOptions(int miu, int rw, int linearBufferlength) { 1826 1827 if (rw > LLCP_RW_MAX_VALUE || miu < LLCP_MIU_DEFAULT || linearBufferlength < miu) { 1828 return false; 1829 } 1830 return true; 1831 } 1832 1833 private boolean CheckSocketServiceName(String sn) { 1834 1835 /* List of sockets registered */ 1836 ListIterator<RegisteredSocket> it = mRegisteredSocketList.listIterator(); 1837 1838 while (it.hasNext()) { 1839 RegisteredSocket registeredSocket = it.next(); 1840 1841 if (sn.equals(registeredSocket.mServiceName)) { 1842 /* Service Name already used */ 1843 return false; 1844 } 1845 } 1846 return true; 1847 } 1848 1849 private void RemoveRegisteredSocket(int nativeHandle) { 1850 /* check if sockets are registered */ 1851 ListIterator<RegisteredSocket> it = mRegisteredSocketList.listIterator(); 1852 1853 while (it.hasNext()) { 1854 RegisteredSocket registeredSocket = it.next(); 1855 if (registeredSocket.mHandle == nativeHandle) { 1856 /* remove the registered socket from the list */ 1857 it.remove(); 1858 if (DBG) Log.d(TAG, "socket removed"); 1859 } 1860 } 1861 } 1862 1863 /* 1864 * RegisteredSocket class to store the creation request of socket until the 1865 * LLCP link in not activated 1866 */ 1867 private class RegisteredSocket { 1868 private final int mType; 1869 1870 private final int mHandle; 1871 1872 private final int mSap; 1873 1874 private int mMiu; 1875 1876 private int mRw; 1877 1878 private String mServiceName; 1879 1880 private int mlinearBufferLength; 1881 1882 RegisteredSocket(int type, int handle, int sap, String sn, int miu, int rw, 1883 int linearBufferLength) { 1884 mType = type; 1885 mHandle = handle; 1886 mSap = sap; 1887 mServiceName = sn; 1888 mRw = rw; 1889 mMiu = miu; 1890 mlinearBufferLength = linearBufferLength; 1891 } 1892 1893 RegisteredSocket(int type, int handle, int sap, int miu, int rw, int linearBufferLength) { 1894 mType = type; 1895 mHandle = handle; 1896 mSap = sap; 1897 mRw = rw; 1898 mMiu = miu; 1899 mlinearBufferLength = linearBufferLength; 1900 } 1901 1902 RegisteredSocket(int type, int handle, int sap) { 1903 mType = type; 1904 mHandle = handle; 1905 mSap = sap; 1906 } 1907 } 1908 1909 /** For use by code in this process */ 1910 public LlcpSocket createLlcpSocket(int sap, int miu, int rw, int linearBufferLength) { 1911 try { 1912 int handle = mNfcAdapter.createLlcpSocket(sap, miu, rw, linearBufferLength); 1913 if (ErrorCodes.isError(handle)) { 1914 Log.e(TAG, "unable to create socket: " + ErrorCodes.asString(handle)); 1915 return null; 1916 } 1917 return new LlcpSocket(mLlcpSocket, handle); 1918 } catch (RemoteException e) { 1919 // This will never happen since the code is calling into it's own process 1920 throw new IllegalStateException("unable to talk to myself", e); 1921 } 1922 } 1923 1924 /** For use by code in this process */ 1925 public LlcpServiceSocket createLlcpServiceSocket(int sap, String sn, int miu, int rw, 1926 int linearBufferLength) { 1927 try { 1928 int handle = mNfcAdapter.createLlcpServiceSocket(sap, sn, miu, rw, linearBufferLength); 1929 if (ErrorCodes.isError(handle)) { 1930 Log.e(TAG, "unable to create socket: " + ErrorCodes.asString(handle)); 1931 return null; 1932 } 1933 return new LlcpServiceSocket(mLlcpServerSocketService, mLlcpSocket, handle); 1934 } catch (RemoteException e) { 1935 // This will never happen since the code is calling into it's own process 1936 throw new IllegalStateException("unable to talk to myself", e); 1937 } 1938 } 1939 1940 private void activateLlcpLink() { 1941 /* check if sockets are registered */ 1942 ListIterator<RegisteredSocket> it = mRegisteredSocketList.listIterator(); 1943 1944 if (DBG) Log.d(TAG, "Nb socket resgistered = " + mRegisteredSocketList.size()); 1945 1946 /* Mark the link state */ 1947 mLlcpLinkState = NfcAdapter.LLCP_LINK_STATE_ACTIVATED; 1948 1949 while (it.hasNext()) { 1950 RegisteredSocket registeredSocket = it.next(); 1951 1952 switch (registeredSocket.mType) { 1953 case LLCP_SERVICE_SOCKET_TYPE: 1954 if (DBG) Log.d(TAG, "Registered Llcp Service Socket"); 1955 if (DBG) Log.d(TAG, "SAP: " + registeredSocket.mSap + ", SN: " + registeredSocket.mServiceName); 1956 NativeLlcpServiceSocket serviceSocket; 1957 1958 serviceSocket = mManager.doCreateLlcpServiceSocket( 1959 registeredSocket.mSap, registeredSocket.mServiceName, 1960 registeredSocket.mMiu, registeredSocket.mRw, 1961 registeredSocket.mlinearBufferLength); 1962 1963 if (serviceSocket != null) { 1964 if (DBG) Log.d(TAG, "service socket created"); 1965 /* Add the socket into the socket map */ 1966 synchronized(NfcService.this) { 1967 mSocketMap.put(registeredSocket.mHandle, serviceSocket); 1968 } 1969 } else { 1970 Log.d(TAG, "FAILED to create service socket"); 1971 /* socket creation error - update the socket 1972 * handle counter */ 1973 mGeneratedSocketHandle -= 1; 1974 } 1975 1976 // NOTE: don't remove this socket from the registered sockets list. 1977 // If it's removed it won't be created the next time an LLCP 1978 // connection is activated and the server won't be found. 1979 break; 1980 1981 case LLCP_SOCKET_TYPE: 1982 if (DBG) Log.d(TAG, "Registered Llcp Socket"); 1983 NativeLlcpSocket clientSocket; 1984 clientSocket = mManager.doCreateLlcpSocket(registeredSocket.mSap, 1985 registeredSocket.mMiu, registeredSocket.mRw, 1986 registeredSocket.mlinearBufferLength); 1987 if (clientSocket != null) { 1988 if (DBG) Log.d(TAG, "socket created"); 1989 /* Add the socket into the socket map */ 1990 synchronized(NfcService.this) { 1991 mSocketMap.put(registeredSocket.mHandle, clientSocket); 1992 } 1993 } else { 1994 Log.d(TAG, "FAILED to create service socket"); 1995 /* socket creation error - update the socket 1996 * handle counter */ 1997 mGeneratedSocketHandle -= 1; 1998 } 1999 // This socket has been created, remove it from the registered sockets list. 2000 it.remove(); 2001 break; 2002 2003 case LLCP_CONNECTIONLESS_SOCKET_TYPE: 2004 if (DBG) Log.d(TAG, "Registered Llcp Connectionless Socket"); 2005 NativeLlcpConnectionlessSocket connectionlessSocket; 2006 connectionlessSocket = mManager.doCreateLlcpConnectionlessSocket( 2007 registeredSocket.mSap); 2008 if (connectionlessSocket != null) { 2009 if (DBG) Log.d(TAG, "connectionless socket created"); 2010 /* Add the socket into the socket map */ 2011 synchronized(NfcService.this) { 2012 mSocketMap.put(registeredSocket.mHandle, connectionlessSocket); 2013 } 2014 } else { 2015 Log.d(TAG, "FAILED to create service socket"); 2016 /* socket creation error - update the socket 2017 * handle counter */ 2018 mGeneratedSocketHandle -= 1; 2019 } 2020 // This socket has been created, remove it from the registered sockets list. 2021 it.remove(); 2022 break; 2023 } 2024 } 2025 2026 /* Broadcast Intent Link LLCP activated */ 2027 Intent LlcpLinkIntent = new Intent(); 2028 LlcpLinkIntent.setAction(NfcAdapter.ACTION_LLCP_LINK_STATE_CHANGED); 2029 2030 LlcpLinkIntent.putExtra(NfcAdapter.EXTRA_LLCP_LINK_STATE_CHANGED, 2031 NfcAdapter.LLCP_LINK_STATE_ACTIVATED); 2032 2033 if (DBG) Log.d(TAG, "Broadcasting LLCP activation"); 2034 mContext.sendOrderedBroadcast(LlcpLinkIntent, NFC_PERM); 2035 } 2036 2037 void sendMessage(int what, Object obj) { 2038 Message msg = mHandler.obtainMessage(); 2039 msg.what = what; 2040 msg.obj = obj; 2041 mHandler.sendMessage(msg); 2042 } 2043 2044 private final Handler mHandler = new Handler() { 2045 @Override 2046 public void handleMessage(Message msg) { 2047 switch (msg.what) { 2048 case MSG_NDEF_TAG: 2049 if (DBG) Log.d(TAG, "Tag detected, notifying applications"); 2050 NativeNfcTag nativeTag = (NativeNfcTag) msg.obj; 2051 if (nativeTag.connect()) { 2052 if (nativeTag.checkNdef()) { 2053 boolean generateEmptyIntent = false; 2054 byte[] buff = nativeTag.read(); 2055 if (buff != null) { 2056 NdefMessage[] msgNdef = new NdefMessage[1]; 2057 try { 2058 msgNdef[0] = new NdefMessage(buff); 2059 NdefTag tag = new NdefTag(nativeTag.getUid(), 2060 TagTarget.internalTypeToRawTargets(nativeTag.getType()), 2061 nativeTag.getPollBytes(), nativeTag.getActivationBytes(), 2062 nativeTag.getHandle(), 2063 TagTarget.internalTypeToNdefTargets(nativeTag.getType()), 2064 new NdefMessage[][] {msgNdef}); 2065 Intent intent = buildNdefTagIntent(tag); 2066 if (DBG) Log.d(TAG, "NDEF tag found, starting corresponding activity"); 2067 if (DBG) Log.d(TAG, tag.toString()); 2068 try { 2069 mContext.startActivity(intent); 2070 registerTagObject(nativeTag); 2071 } catch (ActivityNotFoundException e) { 2072 Log.w(TAG, "No activity found, disconnecting"); 2073 nativeTag.disconnect(); 2074 } 2075 } catch (FormatException e) { 2076 // Create an intent anyway, without NDEF messages 2077 generateEmptyIntent = true; 2078 } 2079 } else { 2080 // Create an intent anyway, without NDEF messages 2081 generateEmptyIntent = true; 2082 } 2083 if (generateEmptyIntent) { 2084 // Create an intent with an empty ndef message array 2085 NdefTag tag = new NdefTag(nativeTag.getUid(), 2086 TagTarget.internalTypeToRawTargets(nativeTag.getType()), 2087 nativeTag.getPollBytes(), nativeTag.getActivationBytes(), 2088 nativeTag.getHandle(), 2089 TagTarget.internalTypeToNdefTargets(nativeTag.getType()), 2090 new NdefMessage[][] { {} }); 2091 Intent intent = buildNdefTagIntent(tag); 2092 if (DBG) Log.d(TAG, "NDEF tag found, but length 0 or invalid format, starting corresponding activity"); 2093 try { 2094 mContext.startActivity(intent); 2095 registerTagObject(nativeTag); 2096 } catch (ActivityNotFoundException e) { 2097 Log.w(TAG, "No activity found, disconnecting"); 2098 nativeTag.disconnect(); 2099 } 2100 } 2101 } else { 2102 Intent intent = new Intent(); 2103 Tag tag = new Tag(nativeTag.getUid(), false, 2104 TagTarget.internalTypeToRawTargets(nativeTag.getType()), 2105 nativeTag.getPollBytes(), nativeTag.getActivationBytes(), 2106 nativeTag.getHandle()); 2107 intent.setAction(NfcAdapter.ACTION_TAG_DISCOVERED); 2108 intent.putExtra(NfcAdapter.EXTRA_TAG, tag); 2109 intent.putExtra(NfcAdapter.EXTRA_ID, tag.getId()); 2110 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2111 if (DBG) Log.d(TAG, "Non-NDEF tag found, starting corresponding activity"); 2112 if (DBG) Log.d(TAG, tag.toString()); 2113 try { 2114 mContext.startActivity(intent); 2115 registerTagObject(nativeTag); 2116 } catch (ActivityNotFoundException e) { 2117 Log.w(TAG, "No activity found, disconnecting"); 2118 nativeTag.disconnect(); 2119 } 2120 } 2121 } else { 2122 Log.w(TAG, "Failed to connect to tag"); 2123 nativeTag.disconnect(); 2124 } 2125 break; 2126 case MSG_CARD_EMULATION: 2127 if (DBG) Log.d(TAG, "Card Emulation message"); 2128 byte[] aid = (byte[]) msg.obj; 2129 /* Send broadcast ordered */ 2130 Intent TransactionIntent = new Intent(); 2131 TransactionIntent.setAction(NfcAdapter.ACTION_TRANSACTION_DETECTED); 2132 TransactionIntent.putExtra(NfcAdapter.EXTRA_AID, aid); 2133 if (DBG) Log.d(TAG, "Broadcasting Card Emulation event"); 2134 mContext.sendOrderedBroadcast(TransactionIntent, NFC_PERM); 2135 break; 2136 2137 case MSG_LLCP_LINK_ACTIVATION: 2138 NativeP2pDevice device = (NativeP2pDevice) msg.obj; 2139 2140 Log.d(TAG, "LLCP Activation message"); 2141 2142 if (device.getMode() == NativeP2pDevice.MODE_P2P_TARGET) { 2143 if (DBG) Log.d(TAG, "NativeP2pDevice.MODE_P2P_TARGET"); 2144 if (device.doConnect()) { 2145 /* Check Llcp compliancy */ 2146 if (mManager.doCheckLlcp()) { 2147 /* Activate Llcp Link */ 2148 if (mManager.doActivateLlcp()) { 2149 if (DBG) Log.d(TAG, "Initiator Activate LLCP OK"); 2150 activateLlcpLink(); 2151 } else { 2152 /* should not happen */ 2153 Log.w(TAG, "Initiator Activate LLCP NOK. Disconnect."); 2154 device.doDisconnect(); 2155 } 2156 2157 } else { 2158 if (DBG) Log.d(TAG, "Remote Target does not support LLCP. Disconnect."); 2159 device.doDisconnect(); 2160 } 2161 } else { 2162 if (DBG) Log.d(TAG, "Cannot connect remote Target. Restart polling loop."); 2163 /* resume should be done in doConnect */ 2164 } 2165 2166 } else if (device.getMode() == NativeP2pDevice.MODE_P2P_INITIATOR) { 2167 if (DBG) Log.d(TAG, "NativeP2pDevice.MODE_P2P_INITIATOR"); 2168 /* Check Llcp compliancy */ 2169 if (mManager.doCheckLlcp()) { 2170 /* Activate Llcp Link */ 2171 if (mManager.doActivateLlcp()) { 2172 if (DBG) Log.d(TAG, "Target Activate LLCP OK"); 2173 activateLlcpLink(); 2174 } 2175 } else { 2176 Log.w(TAG, "checkLlcp failed"); 2177 } 2178 } 2179 break; 2180 2181 case MSG_LLCP_LINK_DEACTIVATED: 2182 device = (NativeP2pDevice) msg.obj; 2183 2184 Log.d(TAG, "LLCP Link Deactivated message. Restart polling loop."); 2185 if (device.getMode() == NativeP2pDevice.MODE_P2P_TARGET) { 2186 if (DBG) Log.d(TAG, "disconnecting from target"); 2187 /* Restart polling loop */ 2188 device.doDisconnect(); 2189 } else { 2190 if (DBG) Log.d(TAG, "not disconnecting from initiator"); 2191 } 2192 2193 /* Mark the link state */ 2194 mLlcpLinkState = NfcAdapter.LLCP_LINK_STATE_DEACTIVATED; 2195 2196 /* Broadcast Intent Link LLCP activated */ 2197 Intent LlcpLinkIntent = new Intent(); 2198 LlcpLinkIntent.setAction(NfcAdapter.ACTION_LLCP_LINK_STATE_CHANGED); 2199 LlcpLinkIntent.putExtra(NfcAdapter.EXTRA_LLCP_LINK_STATE_CHANGED, 2200 NfcAdapter.LLCP_LINK_STATE_DEACTIVATED); 2201 if (DBG) Log.d(TAG, "Broadcasting LLCP deactivation"); 2202 mContext.sendOrderedBroadcast(LlcpLinkIntent, NFC_PERM); 2203 break; 2204 2205 case MSG_TARGET_DESELECTED: 2206 /* Broadcast Intent Target Deselected */ 2207 if (DBG) Log.d(TAG, "Target Deselected"); 2208 Intent TargetDeselectedIntent = new Intent(); 2209 TargetDeselectedIntent.setAction(mManager.INTERNAL_TARGET_DESELECTED_ACTION); 2210 if (DBG) Log.d(TAG, "Broadcasting Intent"); 2211 mContext.sendOrderedBroadcast(TargetDeselectedIntent, NFC_PERM); 2212 break; 2213 2214 default: 2215 Log.e(TAG, "Unknown message received"); 2216 break; 2217 } 2218 } 2219 2220 private Intent buildNdefTagIntent(NdefTag tag) { 2221 Intent intent = new Intent(); 2222 intent.setAction(NfcAdapter.ACTION_TAG_DISCOVERED); 2223 intent.putExtra(NfcAdapter.EXTRA_TAG, tag); 2224 intent.putExtra(NfcAdapter.EXTRA_ID, tag.getId()); 2225 intent.putExtra(NfcAdapter.EXTRA_NDEF_MESSAGES, tag.getNdefMessages()); 2226 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2227 return intent; 2228 } 2229 }; 2230 2231 private class EnableDisableDiscoveryTask extends AsyncTask<Boolean, Void, Void> { 2232 @Override 2233 protected Void doInBackground(Boolean... enable) { 2234 if (enable != null && enable.length > 0 && enable[0]) { 2235 synchronized (NfcService.this) { 2236 mScreenOn = true; 2237 maybeEnableDiscovery(); 2238 } 2239 } else { 2240 mWakeLock.acquire(); 2241 synchronized (NfcService.this) { 2242 mScreenOn = false; 2243 maybeDisableDiscovery(); 2244 } 2245 mWakeLock.release(); 2246 } 2247 return null; 2248 } 2249 } 2250 2251 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 2252 @Override 2253 public void onReceive(Context context, Intent intent) { 2254 if (intent.getAction().equals( 2255 NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION)) { 2256 if (DBG) Log.d(TAG, "INERNAL_TARGET_DESELECTED_ACTION"); 2257 2258 /* Restart polling loop for notification */ 2259 maybeEnableDiscovery(); 2260 2261 } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) { 2262 // Perform discovery enable in thread to protect against ANR when the 2263 // NFC stack wedges. This is *not* the correct way to fix this issue - 2264 // configuration of the local NFC adapter should be very quick and should 2265 // be safe on the main thread, and the NFC stack should not wedge. 2266 new EnableDisableDiscoveryTask().execute(new Boolean(true)); 2267 } else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { 2268 // Perform discovery disable in thread to protect against ANR when the 2269 // NFC stack wedges. This is *not* the correct way to fix this issue - 2270 // configuration of the local NFC adapter should be very quick and should 2271 // be safe on the main thread, and the NFC stack should not wedge. 2272 new EnableDisableDiscoveryTask().execute(new Boolean(false)); 2273 } 2274 } 2275 }; 2276 } 2277