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