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