NfcService.java revision 05973d55daf68a286c932ee4e7ffbd6bb53789e0
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.Activity; 25import android.app.Application; 26import android.app.PendingIntent; 27import android.app.PendingIntent.CanceledException; 28import android.app.StatusBarManager; 29import android.content.ActivityNotFoundException; 30import android.content.BroadcastReceiver; 31import android.content.ComponentName; 32import android.content.Context; 33import android.content.Intent; 34import android.content.IntentFilter; 35import android.content.SharedPreferences; 36import android.net.Uri; 37import android.nfc.ErrorCodes; 38import android.nfc.FormatException; 39import android.nfc.ILlcpConnectionlessSocket; 40import android.nfc.ILlcpServiceSocket; 41import android.nfc.ILlcpSocket; 42import android.nfc.INfcAdapter; 43import android.nfc.INfcSecureElement; 44import android.nfc.INfcTag; 45import android.nfc.IP2pInitiator; 46import android.nfc.IP2pTarget; 47import android.nfc.LlcpPacket; 48import android.nfc.NdefMessage; 49import android.nfc.NdefRecord; 50import android.nfc.NfcAdapter; 51import android.nfc.Tag; 52import android.os.AsyncTask; 53import android.os.Bundle; 54import android.os.Handler; 55import android.os.Message; 56import android.os.PowerManager; 57import android.os.RemoteException; 58import android.os.ServiceManager; 59import android.util.Log; 60 61import java.io.ByteArrayOutputStream; 62import java.io.FileInputStream; 63import java.io.FileNotFoundException; 64import java.io.FileOutputStream; 65import java.io.IOException; 66import java.nio.charset.Charsets; 67import java.util.Arrays; 68import java.util.HashMap; 69import java.util.LinkedList; 70import java.util.ListIterator; 71import java.util.Timer; 72import java.util.TimerTask; 73 74public class NfcService extends Application { 75 static final boolean DBG = false; 76 77 private static final String MY_TAG_FILE_NAME = "mytag"; 78 79 static { 80 System.loadLibrary("nfc_jni"); 81 } 82 83 /** 84 * NFC Forum "URI Record Type Definition" 85 * 86 * This is a mapping of "URI Identifier Codes" to URI string prefixes, 87 * per section 3.2.2 of the NFC Forum URI Record Type Definition document. 88 */ 89 private static final String[] URI_PREFIX_MAP = new String[] { 90 "", // 0x00 91 "http://www.", // 0x01 92 "https://www.", // 0x02 93 "http://", // 0x03 94 "https://", // 0x04 95 "tel:", // 0x05 96 "mailto:", // 0x06 97 "ftp://anonymous:anonymous@", // 0x07 98 "ftp://ftp.", // 0x08 99 "ftps://", // 0x09 100 "sftp://", // 0x0A 101 "smb://", // 0x0B 102 "nfs://", // 0x0C 103 "ftp://", // 0x0D 104 "dav://", // 0x0E 105 "news:", // 0x0F 106 "telnet://", // 0x10 107 "imap:", // 0x11 108 "rtsp://", // 0x12 109 "urn:", // 0x13 110 "pop:", // 0x14 111 "sip:", // 0x15 112 "sips:", // 0x16 113 "tftp:", // 0x17 114 "btspp://", // 0x18 115 "btl2cap://", // 0x19 116 "btgoep://", // 0x1A 117 "tcpobex://", // 0x1B 118 "irdaobex://", // 0x1C 119 "file://", // 0x1D 120 "urn:epc:id:", // 0x1E 121 "urn:epc:tag:", // 0x1F 122 "urn:epc:pat:", // 0x20 123 "urn:epc:raw:", // 0x21 124 "urn:epc:", // 0x22 125 }; 126 127 public static final String SERVICE_NAME = "nfc"; 128 129 private static final String TAG = "NfcService"; 130 131 private static final String NFC_PERM = android.Manifest.permission.NFC; 132 private static final String NFC_PERM_ERROR = "NFC permission required"; 133 private static final String ADMIN_PERM = android.Manifest.permission.WRITE_SECURE_SETTINGS; 134 private static final String ADMIN_PERM_ERROR = "WRITE_SECURE_SETTINGS permission required"; 135 136 private static final String PREF = "NfcServicePrefs"; 137 138 private static final String PREF_NFC_ON = "nfc_on"; 139 private static final boolean NFC_ON_DEFAULT = true; 140 141 private static final String PREF_SECURE_ELEMENT_ON = "secure_element_on"; 142 private static final boolean SECURE_ELEMENT_ON_DEFAULT = false; 143 144 private static final String PREF_SECURE_ELEMENT_ID = "secure_element_id"; 145 private static final int SECURE_ELEMENT_ID_DEFAULT = 0; 146 147 private static final String PREF_LLCP_LTO = "llcp_lto"; 148 private static final int LLCP_LTO_DEFAULT = 150; 149 private static final int LLCP_LTO_MAX = 255; 150 151 /** Maximum Information Unit */ 152 private static final String PREF_LLCP_MIU = "llcp_miu"; 153 private static final int LLCP_MIU_DEFAULT = 128; 154 private static final int LLCP_MIU_MAX = 2176; 155 156 /** Well Known Service List */ 157 private static final String PREF_LLCP_WKS = "llcp_wks"; 158 private static final int LLCP_WKS_DEFAULT = 1; 159 private static final int LLCP_WKS_MAX = 15; 160 161 private static final String PREF_LLCP_OPT = "llcp_opt"; 162 private static final int LLCP_OPT_DEFAULT = 0; 163 private static final int LLCP_OPT_MAX = 3; 164 165 private static final String PREF_DISCOVERY_A = "discovery_a"; 166 private static final boolean DISCOVERY_A_DEFAULT = true; 167 168 private static final String PREF_DISCOVERY_B = "discovery_b"; 169 private static final boolean DISCOVERY_B_DEFAULT = true; 170 171 private static final String PREF_DISCOVERY_F = "discovery_f"; 172 private static final boolean DISCOVERY_F_DEFAULT = true; 173 174 private static final String PREF_DISCOVERY_15693 = "discovery_15693"; 175 private static final boolean DISCOVERY_15693_DEFAULT = true; 176 177 private static final String PREF_DISCOVERY_NFCIP = "discovery_nfcip"; 178 private static final boolean DISCOVERY_NFCIP_DEFAULT = true; 179 180 /** NFC Reader Discovery mode for enableDiscovery() */ 181 private static final int DISCOVERY_MODE_READER = 0; 182 183 /** Card Emulation Discovery mode for enableDiscovery() */ 184 private static final int DISCOVERY_MODE_CARD_EMULATION = 2; 185 186 private static final int LLCP_SERVICE_SOCKET_TYPE = 0; 187 private static final int LLCP_SOCKET_TYPE = 1; 188 private static final int LLCP_CONNECTIONLESS_SOCKET_TYPE = 2; 189 private static final int LLCP_SOCKET_NB_MAX = 5; // Maximum number of socket managed 190 private static final int LLCP_RW_MAX_VALUE = 15; // Receive Window 191 192 private static final int PROPERTY_LLCP_LTO = 0; 193 private static final String PROPERTY_LLCP_LTO_VALUE = "llcp.lto"; 194 private static final int PROPERTY_LLCP_MIU = 1; 195 private static final String PROPERTY_LLCP_MIU_VALUE = "llcp.miu"; 196 private static final int PROPERTY_LLCP_WKS = 2; 197 private static final String PROPERTY_LLCP_WKS_VALUE = "llcp.wks"; 198 private static final int PROPERTY_LLCP_OPT = 3; 199 private static final String PROPERTY_LLCP_OPT_VALUE = "llcp.opt"; 200 private static final int PROPERTY_NFC_DISCOVERY_A = 4; 201 private static final String PROPERTY_NFC_DISCOVERY_A_VALUE = "discovery.iso14443A"; 202 private static final int PROPERTY_NFC_DISCOVERY_B = 5; 203 private static final String PROPERTY_NFC_DISCOVERY_B_VALUE = "discovery.iso14443B"; 204 private static final int PROPERTY_NFC_DISCOVERY_F = 6; 205 private static final String PROPERTY_NFC_DISCOVERY_F_VALUE = "discovery.felica"; 206 private static final int PROPERTY_NFC_DISCOVERY_15693 = 7; 207 private static final String PROPERTY_NFC_DISCOVERY_15693_VALUE = "discovery.iso15693"; 208 private static final int PROPERTY_NFC_DISCOVERY_NFCIP = 8; 209 private static final String PROPERTY_NFC_DISCOVERY_NFCIP_VALUE = "discovery.nfcip"; 210 211 static final int MSG_NDEF_TAG = 0; 212 static final int MSG_CARD_EMULATION = 1; 213 static final int MSG_LLCP_LINK_ACTIVATION = 2; 214 static final int MSG_LLCP_LINK_DEACTIVATED = 3; 215 static final int MSG_TARGET_DESELECTED = 4; 216 static final int MSG_SHOW_MY_TAG_ICON = 5; 217 static final int MSG_HIDE_MY_TAG_ICON = 6; 218 static final int MSG_MOCK_NDEF = 7; 219 static final int MSG_SE_FIELD_ACTIVATED = 8; 220 static final int MSG_SE_FIELD_DEACTIVATED = 9; 221 222 // Locked on mNfcAdapter 223 IntentFilter[] mDispatchOverrideFilters; 224 PendingIntent mDispatchOverrideIntent; 225 226 // TODO: none of these appear to be synchronized but are 227 // read/written from different threads (notably Binder threads)... 228 private final LinkedList<RegisteredSocket> mRegisteredSocketList = new LinkedList<RegisteredSocket>(); 229 private int mLlcpLinkState = NfcAdapter.LLCP_LINK_STATE_DEACTIVATED; 230 private int mGeneratedSocketHandle = 0; 231 private int mNbSocketCreated = 0; 232 private volatile boolean mIsNfcEnabled = false; 233 private int mSelectedSeId = 0; 234 private boolean mNfcSecureElementState; 235 236 // Secure element 237 private Timer mTimerOpenSmx; 238 private boolean isClosed = false; 239 private boolean isOpened = false; 240 private boolean mOpenSmxPending = false; 241 private NativeNfcSecureElement mSecureElement; 242 private int mSecureElementHandle; 243 244 // fields below are used in multiple threads and protected by synchronized(this) 245 private final HashMap<Integer, Object> mObjectMap = new HashMap<Integer, Object>(); 246 private final HashMap<Integer, Object> mSocketMap = new HashMap<Integer, Object>(); 247 private boolean mScreenOn; 248 249 // fields below are final after onCreate() 250 Context mContext; 251 private NativeNfcManager mManager; 252 private SharedPreferences mPrefs; 253 private SharedPreferences.Editor mPrefsEditor; 254 private PowerManager.WakeLock mWakeLock; 255 private MyTagServer mMyTagServer; 256 private MyTagClient mMyTagClient; 257 258 private static NfcService sService; 259 260 public static NfcService getInstance() { 261 return sService; 262 } 263 264 @Override 265 public void onCreate() { 266 super.onCreate(); 267 268 Log.i(TAG, "Starting NFC service"); 269 270 sService = this; 271 272 mContext = this; 273 mManager = new NativeNfcManager(mContext, this); 274 mManager.initializeNativeStructure(); 275 276 mMyTagServer = new MyTagServer(); 277 mMyTagClient = new MyTagClient(this); 278 279 mSecureElement = new NativeNfcSecureElement(); 280 281 mPrefs = mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE); 282 mPrefsEditor = mPrefs.edit(); 283 284 mIsNfcEnabled = false; // real preference read later 285 286 PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE); 287 mScreenOn = pm.isScreenOn(); 288 mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "NfcService"); 289 290 ServiceManager.addService(SERVICE_NAME, mNfcAdapter); 291 292 IntentFilter filter = new IntentFilter(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION); 293 filter.addAction(Intent.ACTION_SCREEN_OFF); 294 filter.addAction(Intent.ACTION_SCREEN_ON); 295 mContext.registerReceiver(mReceiver, filter); 296 297 Thread t = new Thread() { 298 @Override 299 public void run() { 300 boolean nfc_on = mPrefs.getBoolean(PREF_NFC_ON, NFC_ON_DEFAULT); 301 if (nfc_on) { 302 _enable(false); 303 } 304 } 305 }; 306 t.start(); 307 } 308 309 @Override 310 public void onTerminate() { 311 super.onTerminate(); 312 // NFC application is persistent, it should not be destroyed by framework 313 Log.wtf(TAG, "NFC service is under attack!"); 314 } 315 316 private final INfcAdapter.Stub mNfcAdapter = new INfcAdapter.Stub() { 317 /** Protected by "this" */ 318 NdefMessage mLocalMessage = null; 319 320 @Override 321 public boolean enable() throws RemoteException { 322 mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR); 323 324 boolean isSuccess = false; 325 boolean previouslyEnabled = isEnabled(); 326 if (!previouslyEnabled) { 327 reset(); 328 isSuccess = _enable(previouslyEnabled); 329 } 330 return isSuccess; 331 } 332 333 @Override 334 public boolean disable() throws RemoteException { 335 boolean isSuccess = false; 336 mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR); 337 boolean previouslyEnabled = isEnabled(); 338 if (DBG) Log.d(TAG, "Disabling NFC. previous=" + previouslyEnabled); 339 340 if (previouslyEnabled) { 341 /* tear down the my tag server */ 342 mMyTagServer.stop(); 343 isSuccess = mManager.deinitialize(); 344 if (DBG) Log.d(TAG, "NFC success of deinitialize = " + isSuccess); 345 if (isSuccess) { 346 mIsNfcEnabled = false; 347 synchronized (this) { 348 // Clear out any old dispatch overrides 349 mDispatchOverrideFilters = null; 350 mDispatchOverrideIntent = null; 351 } 352 } 353 } 354 355 updateNfcOnSetting(previouslyEnabled); 356 357 return isSuccess; 358 } 359 360 @Override 361 public void enableForegroundDispatch(ComponentName activity, PendingIntent intent, 362 IntentFilter[] filters) { 363 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 364 synchronized (this) { 365 if (activity == null || filters == null || filters.length == 0 || intent == null) { 366 throw new IllegalArgumentException(); 367 } 368 if (mDispatchOverrideFilters != null) { 369 Log.e(TAG, "Replacing active dispatch overrides"); 370 } 371 mDispatchOverrideFilters = filters; 372 mDispatchOverrideIntent = intent; 373 } 374 } 375 376 @Override 377 public void disableForegroundDispatch(ComponentName activity) { 378 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 379 synchronized (this) { 380 if (mDispatchOverrideFilters == null && mDispatchOverrideIntent == null) { 381 Log.e(TAG, "No active foreground dispatching"); 382 } 383 mDispatchOverrideFilters = null; 384 mDispatchOverrideIntent = null; 385 } 386 } 387 388 @Override 389 public int createLlcpConnectionlessSocket(int sap) throws RemoteException { 390 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 391 392 // Check if NFC is enabled 393 if (!mIsNfcEnabled) { 394 return ErrorCodes.ERROR_NOT_INITIALIZED; 395 } 396 397 /* Check SAP is not already used */ 398 399 /* Check nb socket created */ 400 if (mNbSocketCreated < LLCP_SOCKET_NB_MAX) { 401 /* Store the socket handle */ 402 int sockeHandle = mGeneratedSocketHandle; 403 404 if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) { 405 NativeLlcpConnectionlessSocket socket; 406 407 socket = mManager.doCreateLlcpConnectionlessSocket(sap); 408 if (socket != null) { 409 synchronized(NfcService.this) { 410 /* Update the number of socket created */ 411 mNbSocketCreated++; 412 413 /* Add the socket into the socket map */ 414 mSocketMap.put(sockeHandle, socket); 415 } 416 return sockeHandle; 417 } else { 418 /* 419 * socket creation error - update the socket handle 420 * generation 421 */ 422 mGeneratedSocketHandle -= 1; 423 424 /* Get Error Status */ 425 int errorStatus = mManager.doGetLastError(); 426 427 switch (errorStatus) { 428 case ErrorCodes.ERROR_BUFFER_TO_SMALL: 429 return ErrorCodes.ERROR_BUFFER_TO_SMALL; 430 case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES: 431 return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; 432 default: 433 return ErrorCodes.ERROR_SOCKET_CREATION; 434 } 435 } 436 } else { 437 /* Check SAP is not already used */ 438 if (!CheckSocketSap(sap)) { 439 return ErrorCodes.ERROR_SAP_USED; 440 } 441 442 NativeLlcpConnectionlessSocket socket = new NativeLlcpConnectionlessSocket(sap); 443 444 synchronized(NfcService.this) { 445 /* Add the socket into the socket map */ 446 mSocketMap.put(sockeHandle, socket); 447 448 /* Update the number of socket created */ 449 mNbSocketCreated++; 450 } 451 /* Create new registered socket */ 452 RegisteredSocket registeredSocket = new RegisteredSocket( 453 LLCP_CONNECTIONLESS_SOCKET_TYPE, sockeHandle, sap); 454 455 /* Put this socket into a list of registered socket */ 456 mRegisteredSocketList.add(registeredSocket); 457 } 458 459 /* update socket handle generation */ 460 mGeneratedSocketHandle++; 461 462 return sockeHandle; 463 464 } else { 465 /* No socket available */ 466 return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; 467 } 468 469 } 470 471 @Override 472 public int createLlcpServiceSocket(int sap, String sn, int miu, int rw, int linearBufferLength) 473 throws RemoteException { 474 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 475 476 // Check if NFC is enabled 477 if (!mIsNfcEnabled) { 478 return ErrorCodes.ERROR_NOT_INITIALIZED; 479 } 480 481 if (mNbSocketCreated < LLCP_SOCKET_NB_MAX) { 482 int sockeHandle = mGeneratedSocketHandle; 483 484 if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) { 485 NativeLlcpServiceSocket socket; 486 487 socket = mManager.doCreateLlcpServiceSocket(sap, sn, miu, rw, linearBufferLength); 488 if (socket != null) { 489 synchronized(NfcService.this) { 490 /* Update the number of socket created */ 491 mNbSocketCreated++; 492 /* Add the socket into the socket map */ 493 mSocketMap.put(sockeHandle, socket); 494 } 495 } else { 496 /* socket creation error - update the socket handle counter */ 497 mGeneratedSocketHandle -= 1; 498 499 /* Get Error Status */ 500 int errorStatus = mManager.doGetLastError(); 501 502 switch (errorStatus) { 503 case ErrorCodes.ERROR_BUFFER_TO_SMALL: 504 return ErrorCodes.ERROR_BUFFER_TO_SMALL; 505 case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES: 506 return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; 507 default: 508 return ErrorCodes.ERROR_SOCKET_CREATION; 509 } 510 } 511 } else { 512 513 /* Check SAP is not already used */ 514 if (!CheckSocketSap(sap)) { 515 return ErrorCodes.ERROR_SAP_USED; 516 } 517 518 /* Service Name */ 519 if (!CheckSocketServiceName(sn)) { 520 return ErrorCodes.ERROR_SERVICE_NAME_USED; 521 } 522 523 /* Check socket options */ 524 if (!CheckSocketOptions(miu, rw, linearBufferLength)) { 525 return ErrorCodes.ERROR_SOCKET_OPTIONS; 526 } 527 528 NativeLlcpServiceSocket socket = new NativeLlcpServiceSocket(sap, sn, miu, rw, 529 linearBufferLength); 530 synchronized(NfcService.this) { 531 /* Add the socket into the socket map */ 532 mSocketMap.put(sockeHandle, socket); 533 534 /* Update the number of socket created */ 535 mNbSocketCreated++; 536 } 537 /* Create new registered socket */ 538 RegisteredSocket registeredSocket = new RegisteredSocket(LLCP_SERVICE_SOCKET_TYPE, 539 sockeHandle, sap, sn, miu, rw, linearBufferLength); 540 541 /* Put this socket into a list of registered socket */ 542 mRegisteredSocketList.add(registeredSocket); 543 } 544 545 /* update socket handle generation */ 546 mGeneratedSocketHandle += 1; 547 548 if (DBG) Log.d(TAG, "Llcp Service Socket Handle =" + sockeHandle); 549 return sockeHandle; 550 } else { 551 /* No socket available */ 552 return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; 553 } 554 } 555 556 @Override 557 public int createLlcpSocket(int sap, int miu, int rw, int linearBufferLength) 558 throws RemoteException { 559 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 560 561 // Check if NFC is enabled 562 if (!mIsNfcEnabled) { 563 return ErrorCodes.ERROR_NOT_INITIALIZED; 564 } 565 566 if (mNbSocketCreated < LLCP_SOCKET_NB_MAX) { 567 568 int sockeHandle = mGeneratedSocketHandle; 569 570 if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) { 571 if (DBG) Log.d(TAG, "creating llcp socket while activated"); 572 NativeLlcpSocket socket; 573 574 socket = mManager.doCreateLlcpSocket(sap, miu, rw, linearBufferLength); 575 576 if (socket != null) { 577 synchronized(NfcService.this) { 578 /* Update the number of socket created */ 579 mNbSocketCreated++; 580 /* Add the socket into the socket map */ 581 mSocketMap.put(sockeHandle, socket); 582 } 583 } else { 584 /* 585 * socket creation error - update the socket handle 586 * generation 587 */ 588 mGeneratedSocketHandle -= 1; 589 590 /* Get Error Status */ 591 int errorStatus = mManager.doGetLastError(); 592 593 Log.d(TAG, "failed to create llcp socket: " + ErrorCodes.asString(errorStatus)); 594 595 switch (errorStatus) { 596 case ErrorCodes.ERROR_BUFFER_TO_SMALL: 597 return ErrorCodes.ERROR_BUFFER_TO_SMALL; 598 case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES: 599 return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; 600 default: 601 return ErrorCodes.ERROR_SOCKET_CREATION; 602 } 603 } 604 } else { 605 if (DBG) Log.d(TAG, "registering llcp socket while not activated"); 606 607 /* Check SAP is not already used */ 608 if (!CheckSocketSap(sap)) { 609 return ErrorCodes.ERROR_SAP_USED; 610 } 611 612 /* Check Socket options */ 613 if (!CheckSocketOptions(miu, rw, linearBufferLength)) { 614 return ErrorCodes.ERROR_SOCKET_OPTIONS; 615 } 616 617 NativeLlcpSocket socket = new NativeLlcpSocket(sap, miu, rw); 618 synchronized(NfcService.this) { 619 /* Add the socket into the socket map */ 620 mSocketMap.put(sockeHandle, socket); 621 622 /* Update the number of socket created */ 623 mNbSocketCreated++; 624 } 625 /* Create new registered socket */ 626 RegisteredSocket registeredSocket = new RegisteredSocket(LLCP_SOCKET_TYPE, 627 sockeHandle, sap, miu, rw, linearBufferLength); 628 629 /* Put this socket into a list of registered socket */ 630 mRegisteredSocketList.add(registeredSocket); 631 } 632 633 /* update socket handle generation */ 634 mGeneratedSocketHandle++; 635 636 return sockeHandle; 637 } else { 638 /* No socket available */ 639 return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; 640 } 641 } 642 643 @Override 644 public int deselectSecureElement() throws RemoteException { 645 mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR); 646 647 // Check if NFC is enabled 648 if (!mIsNfcEnabled) { 649 return ErrorCodes.ERROR_NOT_INITIALIZED; 650 } 651 652 if (mSelectedSeId == 0) { 653 return ErrorCodes.ERROR_NO_SE_CONNECTED; 654 } 655 656 mManager.doDeselectSecureElement(mSelectedSeId); 657 mNfcSecureElementState = false; 658 mSelectedSeId = 0; 659 660 /* store preference */ 661 mPrefsEditor.putBoolean(PREF_SECURE_ELEMENT_ON, false); 662 mPrefsEditor.putInt(PREF_SECURE_ELEMENT_ID, 0); 663 mPrefsEditor.apply(); 664 665 return ErrorCodes.SUCCESS; 666 } 667 668 @Override 669 public ILlcpConnectionlessSocket getLlcpConnectionlessInterface() throws RemoteException { 670 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 671 return mLlcpConnectionlessSocketService; 672 } 673 674 @Override 675 public ILlcpSocket getLlcpInterface() throws RemoteException { 676 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 677 return mLlcpSocket; 678 } 679 680 @Override 681 public ILlcpServiceSocket getLlcpServiceInterface() throws RemoteException { 682 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 683 return mLlcpServerSocketService; 684 } 685 686 @Override 687 public INfcTag getNfcTagInterface() throws RemoteException { 688 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 689 return mNfcTagService; 690 } 691 692 @Override 693 public IP2pInitiator getP2pInitiatorInterface() throws RemoteException { 694 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 695 return mP2pInitiatorService; 696 } 697 698 @Override 699 public IP2pTarget getP2pTargetInterface() throws RemoteException { 700 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 701 return mP2pTargetService; 702 } 703 704 public INfcSecureElement getNfcSecureElementInterface() { 705 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 706 return mSecureElementService; 707 } 708 709 @Override 710 public String getProperties(String param) throws RemoteException { 711 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 712 713 if (param == null) { 714 return null; 715 } 716 717 if (param.equals(PROPERTY_LLCP_LTO_VALUE)) { 718 return Integer.toString(mPrefs.getInt(PREF_LLCP_LTO, LLCP_LTO_DEFAULT)); 719 } else if (param.equals(PROPERTY_LLCP_MIU_VALUE)) { 720 return Integer.toString(mPrefs.getInt(PREF_LLCP_MIU, LLCP_MIU_DEFAULT)); 721 } else if (param.equals(PROPERTY_LLCP_WKS_VALUE)) { 722 return Integer.toString(mPrefs.getInt(PREF_LLCP_WKS, LLCP_WKS_DEFAULT)); 723 } else if (param.equals(PROPERTY_LLCP_OPT_VALUE)) { 724 return Integer.toString(mPrefs.getInt(PREF_LLCP_OPT, LLCP_OPT_DEFAULT)); 725 } else if (param.equals(PROPERTY_NFC_DISCOVERY_A_VALUE)) { 726 return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_A, DISCOVERY_A_DEFAULT)); 727 } else if (param.equals(PROPERTY_NFC_DISCOVERY_B_VALUE)) { 728 return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_B, DISCOVERY_B_DEFAULT)); 729 } else if (param.equals(PROPERTY_NFC_DISCOVERY_F_VALUE)) { 730 return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_F, DISCOVERY_F_DEFAULT)); 731 } else if (param.equals(PROPERTY_NFC_DISCOVERY_NFCIP_VALUE)) { 732 return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_NFCIP, DISCOVERY_NFCIP_DEFAULT)); 733 } else if (param.equals(PROPERTY_NFC_DISCOVERY_15693_VALUE)) { 734 return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_15693, DISCOVERY_15693_DEFAULT)); 735 } else { 736 return "Unknown property"; 737 } 738 } 739 740 @Override 741 public int[] getSecureElementList() throws RemoteException { 742 mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR); 743 744 int[] list = null; 745 if (mIsNfcEnabled == true) { 746 list = mManager.doGetSecureElementList(); 747 } 748 return list; 749 } 750 751 @Override 752 public int getSelectedSecureElement() throws RemoteException { 753 mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR); 754 755 return mSelectedSeId; 756 } 757 758 @Override 759 public boolean isEnabled() throws RemoteException { 760 return mIsNfcEnabled; 761 } 762 763 @Override 764 public void openTagConnection(Tag tag) throws RemoteException { 765 // TODO: Remove obsolete code 766 } 767 768 @Override 769 public int selectSecureElement(int seId) throws RemoteException { 770 mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR); 771 772 // Check if NFC is enabled 773 if (!mIsNfcEnabled) { 774 return ErrorCodes.ERROR_NOT_INITIALIZED; 775 } 776 777 if (mSelectedSeId == seId) { 778 return ErrorCodes.ERROR_SE_ALREADY_SELECTED; 779 } 780 781 if (mSelectedSeId != 0) { 782 return ErrorCodes.ERROR_SE_CONNECTED; 783 } 784 785 mSelectedSeId = seId; 786 mManager.doSelectSecureElement(mSelectedSeId); 787 788 /* store */ 789 mPrefsEditor.putBoolean(PREF_SECURE_ELEMENT_ON, true); 790 mPrefsEditor.putInt(PREF_SECURE_ELEMENT_ID, mSelectedSeId); 791 mPrefsEditor.apply(); 792 793 mNfcSecureElementState = true; 794 795 return ErrorCodes.SUCCESS; 796 797 } 798 799 @Override 800 public int setProperties(String param, String value) throws RemoteException { 801 mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR); 802 803 if (isEnabled()) { 804 return ErrorCodes.ERROR_NFC_ON; 805 } 806 807 int val; 808 809 /* Check params validity */ 810 if (param == null || value == null) { 811 return ErrorCodes.ERROR_INVALID_PARAM; 812 } 813 814 if (param.equals(PROPERTY_LLCP_LTO_VALUE)) { 815 val = Integer.parseInt(value); 816 817 /* Check params */ 818 if (val > LLCP_LTO_MAX) 819 return ErrorCodes.ERROR_INVALID_PARAM; 820 821 /* Store value */ 822 mPrefsEditor.putInt(PREF_LLCP_LTO, val); 823 mPrefsEditor.apply(); 824 825 /* Update JNI */ 826 mManager.doSetProperties(PROPERTY_LLCP_LTO, val); 827 828 } else if (param.equals(PROPERTY_LLCP_MIU_VALUE)) { 829 val = Integer.parseInt(value); 830 831 /* Check params */ 832 if ((val < LLCP_MIU_DEFAULT) || (val > LLCP_MIU_MAX)) 833 return ErrorCodes.ERROR_INVALID_PARAM; 834 835 /* Store value */ 836 mPrefsEditor.putInt(PREF_LLCP_MIU, val); 837 mPrefsEditor.apply(); 838 839 /* Update JNI */ 840 mManager.doSetProperties(PROPERTY_LLCP_MIU, val); 841 842 } else if (param.equals(PROPERTY_LLCP_WKS_VALUE)) { 843 val = Integer.parseInt(value); 844 845 /* Check params */ 846 if (val > LLCP_WKS_MAX) 847 return ErrorCodes.ERROR_INVALID_PARAM; 848 849 /* Store value */ 850 mPrefsEditor.putInt(PREF_LLCP_WKS, val); 851 mPrefsEditor.apply(); 852 853 /* Update JNI */ 854 mManager.doSetProperties(PROPERTY_LLCP_WKS, val); 855 856 } else if (param.equals(PROPERTY_LLCP_OPT_VALUE)) { 857 val = Integer.parseInt(value); 858 859 /* Check params */ 860 if (val > LLCP_OPT_MAX) 861 return ErrorCodes.ERROR_INVALID_PARAM; 862 863 /* Store value */ 864 mPrefsEditor.putInt(PREF_LLCP_OPT, val); 865 mPrefsEditor.apply(); 866 867 /* Update JNI */ 868 mManager.doSetProperties(PROPERTY_LLCP_OPT, val); 869 870 } else if (param.equals(PROPERTY_NFC_DISCOVERY_A_VALUE)) { 871 boolean b = Boolean.parseBoolean(value); 872 873 /* Store value */ 874 mPrefsEditor.putBoolean(PREF_DISCOVERY_A, b); 875 mPrefsEditor.apply(); 876 877 /* Update JNI */ 878 mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_A, b ? 1 : 0); 879 880 } else if (param.equals(PROPERTY_NFC_DISCOVERY_B_VALUE)) { 881 boolean b = Boolean.parseBoolean(value); 882 883 /* Store value */ 884 mPrefsEditor.putBoolean(PREF_DISCOVERY_B, b); 885 mPrefsEditor.apply(); 886 887 /* Update JNI */ 888 mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_B, b ? 1 : 0); 889 890 } else if (param.equals(PROPERTY_NFC_DISCOVERY_F_VALUE)) { 891 boolean b = Boolean.parseBoolean(value); 892 893 /* Store value */ 894 mPrefsEditor.putBoolean(PREF_DISCOVERY_F, b); 895 mPrefsEditor.apply(); 896 897 /* Update JNI */ 898 mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_F, b ? 1 : 0); 899 900 } else if (param.equals(PROPERTY_NFC_DISCOVERY_15693_VALUE)) { 901 boolean b = Boolean.parseBoolean(value); 902 903 /* Store value */ 904 mPrefsEditor.putBoolean(PREF_DISCOVERY_15693, b); 905 mPrefsEditor.apply(); 906 907 /* Update JNI */ 908 mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_15693, b ? 1 : 0); 909 910 } else if (param.equals(PROPERTY_NFC_DISCOVERY_NFCIP_VALUE)) { 911 boolean b = Boolean.parseBoolean(value); 912 913 /* Store value */ 914 mPrefsEditor.putBoolean(PREF_DISCOVERY_NFCIP, b); 915 mPrefsEditor.apply(); 916 917 /* Update JNI */ 918 mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_NFCIP, b ? 1 : 0); 919 920 } else { 921 return ErrorCodes.ERROR_INVALID_PARAM; 922 } 923 924 return ErrorCodes.SUCCESS; 925 } 926 927 @Override 928 public NdefMessage localGet() throws RemoteException { 929 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 930 931 synchronized (this) { 932 return mLocalMessage; 933 } 934 } 935 936 @Override 937 public void localSet(NdefMessage message) throws RemoteException { 938 mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR); 939 940 synchronized (this) { 941 mLocalMessage = message; 942 Context context = NfcService.this.getApplicationContext(); 943 944 // Send a message to the UI thread to show or hide the icon so the requests are 945 // serialized and the icon can't get out of sync with reality. 946 if (message != null) { 947 FileOutputStream out = null; 948 949 try { 950 out = context.openFileOutput(MY_TAG_FILE_NAME, Context.MODE_PRIVATE); 951 byte[] bytes = message.toByteArray(); 952 if (bytes.length == 0) { 953 Log.w(TAG, "Setting a empty mytag"); 954 } 955 956 out.write(bytes); 957 } catch (IOException e) { 958 Log.e(TAG, "Could not write mytag file", e); 959 } finally { 960 try { 961 if (out != null) { 962 out.flush(); 963 out.close(); 964 } 965 } catch (IOException e) { 966 // Ignore 967 } 968 } 969 970 // Only show the icon if NFC is enabled. 971 if (mIsNfcEnabled) { 972 sendMessage(MSG_SHOW_MY_TAG_ICON, null); 973 } 974 } else { 975 context.deleteFile(MY_TAG_FILE_NAME); 976 sendMessage(MSG_HIDE_MY_TAG_ICON, null); 977 } 978 } 979 } 980 }; 981 982 private final ILlcpSocket mLlcpSocket = new ILlcpSocket.Stub() { 983 984 private final int CONNECT_FLAG = 0x01; 985 private final int CLOSE_FLAG = 0x02; 986 private final int RECV_FLAG = 0x04; 987 private final int SEND_FLAG = 0x08; 988 989 private int concurrencyFlags; 990 private Object sync; 991 992 @Override 993 public int close(int nativeHandle) throws RemoteException { 994 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 995 996 NativeLlcpSocket socket = null; 997 boolean isSuccess = false; 998 999 // Check if NFC is enabled 1000 if (!mIsNfcEnabled) { 1001 return ErrorCodes.ERROR_NOT_INITIALIZED; 1002 } 1003 1004 /* find the socket in the hmap */ 1005 socket = (NativeLlcpSocket) findSocket(nativeHandle); 1006 if (socket != null) { 1007 if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) { 1008 isSuccess = socket.doClose(); 1009 if (isSuccess) { 1010 /* Remove the socket closed from the hmap */ 1011 RemoveSocket(nativeHandle); 1012 /* Update mNbSocketCreated */ 1013 mNbSocketCreated--; 1014 return ErrorCodes.SUCCESS; 1015 } else { 1016 return ErrorCodes.ERROR_IO; 1017 } 1018 } else { 1019 /* Remove the socket closed from the hmap */ 1020 RemoveSocket(nativeHandle); 1021 1022 /* Remove registered socket from the list */ 1023 RemoveRegisteredSocket(nativeHandle); 1024 1025 /* Update mNbSocketCreated */ 1026 mNbSocketCreated--; 1027 1028 return ErrorCodes.SUCCESS; 1029 } 1030 } else { 1031 return ErrorCodes.ERROR_IO; 1032 } 1033 } 1034 1035 @Override 1036 public int connect(int nativeHandle, int sap) throws RemoteException { 1037 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1038 1039 NativeLlcpSocket socket = null; 1040 boolean isSuccess = false; 1041 1042 // Check if NFC is enabled 1043 if (!mIsNfcEnabled) { 1044 return ErrorCodes.ERROR_NOT_INITIALIZED; 1045 } 1046 1047 /* find the socket in the hmap */ 1048 socket = (NativeLlcpSocket) findSocket(nativeHandle); 1049 if (socket != null) { 1050 isSuccess = socket.doConnect(sap); 1051 if (isSuccess) { 1052 return ErrorCodes.SUCCESS; 1053 } else { 1054 return ErrorCodes.ERROR_IO; 1055 } 1056 } else { 1057 return ErrorCodes.ERROR_IO; 1058 } 1059 1060 } 1061 1062 @Override 1063 public int connectByName(int nativeHandle, String sn) throws RemoteException { 1064 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1065 1066 NativeLlcpSocket socket = null; 1067 boolean isSuccess = false; 1068 1069 // Check if NFC is enabled 1070 if (!mIsNfcEnabled) { 1071 return ErrorCodes.ERROR_NOT_INITIALIZED; 1072 } 1073 1074 /* find the socket in the hmap */ 1075 socket = (NativeLlcpSocket) findSocket(nativeHandle); 1076 if (socket != null) { 1077 isSuccess = socket.doConnectBy(sn); 1078 if (isSuccess) { 1079 return ErrorCodes.SUCCESS; 1080 } else { 1081 return ErrorCodes.ERROR_IO; 1082 } 1083 } else { 1084 return ErrorCodes.ERROR_IO; 1085 } 1086 1087 } 1088 1089 @Override 1090 public int getLocalSap(int nativeHandle) throws RemoteException { 1091 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1092 1093 NativeLlcpSocket socket = null; 1094 1095 // Check if NFC is enabled 1096 if (!mIsNfcEnabled) { 1097 return ErrorCodes.ERROR_NOT_INITIALIZED; 1098 } 1099 1100 /* find the socket in the hmap */ 1101 socket = (NativeLlcpSocket) findSocket(nativeHandle); 1102 if (socket != null) { 1103 return socket.getSap(); 1104 } else { 1105 return 0; 1106 } 1107 } 1108 1109 @Override 1110 public int getLocalSocketMiu(int nativeHandle) throws RemoteException { 1111 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1112 1113 NativeLlcpSocket socket = null; 1114 1115 // Check if NFC is enabled 1116 if (!mIsNfcEnabled) { 1117 return ErrorCodes.ERROR_NOT_INITIALIZED; 1118 } 1119 1120 /* find the socket in the hmap */ 1121 socket = (NativeLlcpSocket) findSocket(nativeHandle); 1122 if (socket != null) { 1123 return socket.getMiu(); 1124 } else { 1125 return 0; 1126 } 1127 } 1128 1129 @Override 1130 public int getLocalSocketRw(int nativeHandle) throws RemoteException { 1131 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1132 1133 NativeLlcpSocket socket = null; 1134 1135 // Check if NFC is enabled 1136 if (!mIsNfcEnabled) { 1137 return ErrorCodes.ERROR_NOT_INITIALIZED; 1138 } 1139 1140 /* find the socket in the hmap */ 1141 socket = (NativeLlcpSocket) findSocket(nativeHandle); 1142 if (socket != null) { 1143 return socket.getRw(); 1144 } else { 1145 return 0; 1146 } 1147 } 1148 1149 @Override 1150 public int getRemoteSocketMiu(int nativeHandle) throws RemoteException { 1151 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1152 1153 NativeLlcpSocket socket = null; 1154 1155 // Check if NFC is enabled 1156 if (!mIsNfcEnabled) { 1157 return ErrorCodes.ERROR_NOT_INITIALIZED; 1158 } 1159 1160 /* find the socket in the hmap */ 1161 socket = (NativeLlcpSocket) findSocket(nativeHandle); 1162 if (socket != null) { 1163 if (socket.doGetRemoteSocketMiu() != 0) { 1164 return socket.doGetRemoteSocketMiu(); 1165 } else { 1166 return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED; 1167 } 1168 } else { 1169 return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED; 1170 } 1171 } 1172 1173 @Override 1174 public int getRemoteSocketRw(int nativeHandle) throws RemoteException { 1175 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1176 1177 NativeLlcpSocket socket = null; 1178 1179 // Check if NFC is enabled 1180 if (!mIsNfcEnabled) { 1181 return ErrorCodes.ERROR_NOT_INITIALIZED; 1182 } 1183 1184 /* find the socket in the hmap */ 1185 socket = (NativeLlcpSocket) findSocket(nativeHandle); 1186 if (socket != null) { 1187 if (socket.doGetRemoteSocketRw() != 0) { 1188 return socket.doGetRemoteSocketRw(); 1189 } else { 1190 return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED; 1191 } 1192 } else { 1193 return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED; 1194 } 1195 } 1196 1197 @Override 1198 public int receive(int nativeHandle, byte[] receiveBuffer) throws RemoteException { 1199 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1200 1201 NativeLlcpSocket socket = null; 1202 int receiveLength = 0; 1203 1204 // Check if NFC is enabled 1205 if (!mIsNfcEnabled) { 1206 return ErrorCodes.ERROR_NOT_INITIALIZED; 1207 } 1208 1209 /* find the socket in the hmap */ 1210 socket = (NativeLlcpSocket) findSocket(nativeHandle); 1211 if (socket != null) { 1212 return socket.doReceive(receiveBuffer); 1213 } else { 1214 return 0; 1215 } 1216 } 1217 1218 @Override 1219 public int send(int nativeHandle, byte[] data) throws RemoteException { 1220 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1221 1222 NativeLlcpSocket socket = null; 1223 boolean isSuccess = false; 1224 1225 // Check if NFC is enabled 1226 if (!mIsNfcEnabled) { 1227 return ErrorCodes.ERROR_NOT_INITIALIZED; 1228 } 1229 1230 /* find the socket in the hmap */ 1231 socket = (NativeLlcpSocket) findSocket(nativeHandle); 1232 if (socket != null) { 1233 isSuccess = socket.doSend(data); 1234 if (isSuccess) { 1235 return ErrorCodes.SUCCESS; 1236 } else { 1237 return ErrorCodes.ERROR_IO; 1238 } 1239 } else { 1240 return ErrorCodes.ERROR_IO; 1241 } 1242 } 1243 }; 1244 1245 private final ILlcpServiceSocket mLlcpServerSocketService = new ILlcpServiceSocket.Stub() { 1246 1247 @Override 1248 public int accept(int nativeHandle) throws RemoteException { 1249 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1250 1251 NativeLlcpServiceSocket socket = null; 1252 NativeLlcpSocket clientSocket = null; 1253 1254 // Check if NFC is enabled 1255 if (!mIsNfcEnabled) { 1256 return ErrorCodes.ERROR_NOT_INITIALIZED; 1257 } 1258 1259 if (mNbSocketCreated < LLCP_SOCKET_NB_MAX) { 1260 /* find the socket in the hmap */ 1261 socket = (NativeLlcpServiceSocket) findSocket(nativeHandle); 1262 if (socket != null) { 1263 clientSocket = socket.doAccept(socket.getMiu(), 1264 socket.getRw(), socket.getLinearBufferLength()); 1265 if (clientSocket != null) { 1266 /* Add the socket into the socket map */ 1267 synchronized(this) { 1268 mSocketMap.put(clientSocket.getHandle(), clientSocket); 1269 mNbSocketCreated++; 1270 } 1271 return clientSocket.getHandle(); 1272 } else { 1273 return ErrorCodes.ERROR_IO; 1274 } 1275 } else { 1276 return ErrorCodes.ERROR_IO; 1277 } 1278 } else { 1279 return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; 1280 } 1281 1282 } 1283 1284 @Override 1285 public void close(int nativeHandle) throws RemoteException { 1286 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1287 1288 NativeLlcpServiceSocket socket = null; 1289 boolean isSuccess = false; 1290 1291 // Check if NFC is enabled 1292 if (!mIsNfcEnabled) { 1293 return; 1294 } 1295 1296 /* find the socket in the hmap */ 1297 boolean closed = false; 1298 socket = (NativeLlcpServiceSocket) findSocket(nativeHandle); 1299 if (socket != null) { 1300 if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) { 1301 isSuccess = socket.doClose(); 1302 if (isSuccess) { 1303 closed = true; 1304 } 1305 } else { 1306 closed = true; 1307 } 1308 } 1309 1310 // If the socket is closed remove it from the socket lists 1311 if (closed) { 1312 synchronized (this) { 1313 /* Remove the socket closed from the hmap */ 1314 RemoveSocket(nativeHandle); 1315 1316 /* Update mNbSocketCreated */ 1317 mNbSocketCreated--; 1318 1319 /* Remove registered socket from the list */ 1320 RemoveRegisteredSocket(nativeHandle); 1321 } 1322 } 1323 } 1324 }; 1325 1326 private final ILlcpConnectionlessSocket mLlcpConnectionlessSocketService = new ILlcpConnectionlessSocket.Stub() { 1327 1328 @Override 1329 public void close(int nativeHandle) throws RemoteException { 1330 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1331 1332 NativeLlcpConnectionlessSocket socket = null; 1333 boolean isSuccess = false; 1334 1335 // Check if NFC is enabled 1336 if (!mIsNfcEnabled) { 1337 return; 1338 } 1339 1340 /* find the socket in the hmap */ 1341 socket = (NativeLlcpConnectionlessSocket) findSocket(nativeHandle); 1342 if (socket != null) { 1343 if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) { 1344 isSuccess = socket.doClose(); 1345 if (isSuccess) { 1346 /* Remove the socket closed from the hmap */ 1347 RemoveSocket(nativeHandle); 1348 /* Update mNbSocketCreated */ 1349 mNbSocketCreated--; 1350 } 1351 } else { 1352 /* Remove the socket closed from the hmap */ 1353 RemoveSocket(nativeHandle); 1354 1355 /* Remove registered socket from the list */ 1356 RemoveRegisteredSocket(nativeHandle); 1357 1358 /* Update mNbSocketCreated */ 1359 mNbSocketCreated--; 1360 } 1361 } 1362 } 1363 1364 @Override 1365 public int getSap(int nativeHandle) throws RemoteException { 1366 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1367 1368 NativeLlcpConnectionlessSocket socket = null; 1369 1370 // Check if NFC is enabled 1371 if (!mIsNfcEnabled) { 1372 return ErrorCodes.ERROR_NOT_INITIALIZED; 1373 } 1374 1375 /* find the socket in the hmap */ 1376 socket = (NativeLlcpConnectionlessSocket) findSocket(nativeHandle); 1377 if (socket != null) { 1378 return socket.getSap(); 1379 } else { 1380 return 0; 1381 } 1382 } 1383 1384 @Override 1385 public LlcpPacket receiveFrom(int nativeHandle) throws RemoteException { 1386 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1387 1388 NativeLlcpConnectionlessSocket socket = null; 1389 LlcpPacket packet; 1390 1391 // Check if NFC is enabled 1392 if (!mIsNfcEnabled) { 1393 return null; 1394 } 1395 1396 /* find the socket in the hmap */ 1397 socket = (NativeLlcpConnectionlessSocket) findSocket(nativeHandle); 1398 if (socket != null) { 1399 packet = socket.doReceiveFrom(socket.getLinkMiu()); 1400 if (packet != null) { 1401 return packet; 1402 } 1403 return null; 1404 } else { 1405 return null; 1406 } 1407 } 1408 1409 @Override 1410 public int sendTo(int nativeHandle, LlcpPacket packet) throws RemoteException { 1411 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1412 1413 NativeLlcpConnectionlessSocket socket = null; 1414 boolean isSuccess = false; 1415 1416 // Check if NFC is enabled 1417 if (!mIsNfcEnabled) { 1418 return ErrorCodes.ERROR_NOT_INITIALIZED; 1419 } 1420 1421 /* find the socket in the hmap */ 1422 socket = (NativeLlcpConnectionlessSocket) findSocket(nativeHandle); 1423 if (socket != null) { 1424 isSuccess = socket.doSendTo(packet.getRemoteSap(), packet.getDataBuffer()); 1425 if (isSuccess) { 1426 return ErrorCodes.SUCCESS; 1427 } else { 1428 return ErrorCodes.ERROR_IO; 1429 } 1430 } else { 1431 return ErrorCodes.ERROR_IO; 1432 } 1433 } 1434 }; 1435 1436 private final INfcTag mNfcTagService = new INfcTag.Stub() { 1437 1438 @Override 1439 public int close(int nativeHandle) throws RemoteException { 1440 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1441 1442 NativeNfcTag tag = null; 1443 1444 // Check if NFC is enabled 1445 if (!mIsNfcEnabled) { 1446 return ErrorCodes.ERROR_NOT_INITIALIZED; 1447 } 1448 1449 /* find the tag in the hmap */ 1450 tag = (NativeNfcTag) findObject(nativeHandle); 1451 if (tag != null) { 1452 /* Remove the device from the hmap */ 1453 unregisterObject(nativeHandle); 1454 tag.disconnect(); 1455 return ErrorCodes.SUCCESS; 1456 } 1457 /* Restart polling loop for notification */ 1458 maybeEnableDiscovery(); 1459 return ErrorCodes.ERROR_DISCONNECT; 1460 } 1461 1462 @Override 1463 public int connect(int nativeHandle, int technology) throws RemoteException { 1464 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1465 1466 NativeNfcTag tag = null; 1467 1468 // Check if NFC is enabled 1469 if (!mIsNfcEnabled) { 1470 return ErrorCodes.ERROR_NOT_INITIALIZED; 1471 } 1472 1473 /* find the tag in the hmap */ 1474 tag = (NativeNfcTag) findObject(nativeHandle); 1475 if (tag == null) { 1476 return ErrorCodes.ERROR_DISCONNECT; 1477 } 1478 1479 // Note that on most tags, all technologies are behind a single 1480 // handle. This means that the connect at the lower levels 1481 // will do nothing, as the tag is already connected to that handle. 1482 if (tag.connect(technology)) { 1483 return ErrorCodes.SUCCESS; 1484 } else { 1485 return ErrorCodes.ERROR_DISCONNECT; 1486 } 1487 } 1488 1489 @Override 1490 public int reconnect(int nativeHandle) throws RemoteException { 1491 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1492 1493 NativeNfcTag tag = null; 1494 1495 // Check if NFC is enabled 1496 if (!mIsNfcEnabled) { 1497 return ErrorCodes.ERROR_NOT_INITIALIZED; 1498 } 1499 1500 /* find the tag in the hmap */ 1501 tag = (NativeNfcTag) findObject(nativeHandle); 1502 if (tag != null) { 1503 if (tag.reconnect()) { 1504 return ErrorCodes.SUCCESS; 1505 } else { 1506 return ErrorCodes.ERROR_DISCONNECT; 1507 } 1508 } 1509 return ErrorCodes.ERROR_DISCONNECT; 1510 } 1511 1512 @Override 1513 public int[] getTechList(int nativeHandle) throws RemoteException { 1514 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1515 1516 // Check if NFC is enabled 1517 if (!mIsNfcEnabled) { 1518 return null; 1519 } 1520 1521 /* find the tag in the hmap */ 1522 NativeNfcTag tag = (NativeNfcTag) findObject(nativeHandle); 1523 if (tag != null) { 1524 return tag.getTechList(); 1525 } 1526 return null; 1527 } 1528 1529 @Override 1530 public byte[] getUid(int nativeHandle) throws RemoteException { 1531 NativeNfcTag tag = null; 1532 byte[] uid; 1533 1534 // Check if NFC is enabled 1535 if (!mIsNfcEnabled) { 1536 return null; 1537 } 1538 1539 /* find the tag in the hmap */ 1540 tag = (NativeNfcTag) findObject(nativeHandle); 1541 if (tag != null) { 1542 uid = tag.getUid(); 1543 return uid; 1544 } 1545 return null; 1546 } 1547 1548 @Override 1549 public boolean isPresent(int nativeHandle) throws RemoteException { 1550 NativeNfcTag tag = null; 1551 1552 // Check if NFC is enabled 1553 if (!mIsNfcEnabled) { 1554 return false; 1555 } 1556 1557 /* find the tag in the hmap */ 1558 tag = (NativeNfcTag) findObject(nativeHandle); 1559 if (tag == null) { 1560 return false; 1561 } 1562 1563 return tag.presenceCheck(); 1564 } 1565 1566 @Override 1567 public boolean isNdef(int nativeHandle) throws RemoteException { 1568 NativeNfcTag tag = null; 1569 boolean isSuccess = false; 1570 1571 // Check if NFC is enabled 1572 if (!mIsNfcEnabled) { 1573 return isSuccess; 1574 } 1575 1576 /* find the tag in the hmap */ 1577 tag = (NativeNfcTag) findObject(nativeHandle); 1578 int[] ndefInfo = new int[2]; 1579 if (tag != null) { 1580 isSuccess = tag.checkNdef(ndefInfo); 1581 } 1582 return isSuccess; 1583 } 1584 1585 @Override 1586 public byte[] transceive(int nativeHandle, byte[] data, boolean raw) 1587 throws RemoteException { 1588 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1589 1590 NativeNfcTag tag = null; 1591 byte[] response; 1592 1593 // Check if NFC is enabled 1594 if (!mIsNfcEnabled) { 1595 return null; 1596 } 1597 1598 /* find the tag in the hmap */ 1599 tag = (NativeNfcTag) findObject(nativeHandle); 1600 if (tag != null) { 1601 response = tag.transceive(data, raw); 1602 return response; 1603 } 1604 return null; 1605 } 1606 1607 @Override 1608 public NdefMessage ndefRead(int nativeHandle) throws RemoteException { 1609 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1610 1611 NativeNfcTag tag; 1612 1613 // Check if NFC is enabled 1614 if (!mIsNfcEnabled) { 1615 return null; 1616 } 1617 1618 /* find the tag in the hmap */ 1619 tag = (NativeNfcTag) findObject(nativeHandle); 1620 if (tag != null) { 1621 byte[] buf = tag.read(); 1622 if (buf == null) 1623 return null; 1624 1625 /* Create an NdefMessage */ 1626 try { 1627 return new NdefMessage(buf); 1628 } catch (FormatException e) { 1629 return null; 1630 } 1631 } 1632 return null; 1633 } 1634 1635 @Override 1636 public int ndefWrite(int nativeHandle, NdefMessage msg) throws RemoteException { 1637 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1638 1639 NativeNfcTag tag; 1640 1641 // Check if NFC is enabled 1642 if (!mIsNfcEnabled) { 1643 return ErrorCodes.ERROR_NOT_INITIALIZED; 1644 } 1645 1646 /* find the tag in the hmap */ 1647 tag = (NativeNfcTag) findObject(nativeHandle); 1648 if (tag == null) { 1649 return ErrorCodes.ERROR_IO; 1650 } 1651 1652 if (tag.write(msg.toByteArray())) { 1653 return ErrorCodes.SUCCESS; 1654 } 1655 else { 1656 return ErrorCodes.ERROR_IO; 1657 } 1658 1659 } 1660 1661 @Override 1662 public int getLastError(int nativeHandle) throws RemoteException { 1663 return(mManager.doGetLastError()); 1664 } 1665 1666 @Override 1667 public boolean ndefIsWritable(int nativeHandle) throws RemoteException { 1668 throw new UnsupportedOperationException(); 1669 } 1670 1671 @Override 1672 public int ndefMakeReadOnly(int nativeHandle) throws RemoteException { 1673 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1674 1675 NativeNfcTag tag; 1676 1677 // Check if NFC is enabled 1678 if (!mIsNfcEnabled) { 1679 return ErrorCodes.ERROR_NOT_INITIALIZED; 1680 } 1681 1682 /* find the tag in the hmap */ 1683 tag = (NativeNfcTag) findObject(nativeHandle); 1684 if (tag == null) { 1685 return ErrorCodes.ERROR_IO; 1686 } 1687 1688 if (tag.makeReadonly()) { 1689 return ErrorCodes.SUCCESS; 1690 } 1691 else { 1692 return ErrorCodes.ERROR_IO; 1693 } 1694 } 1695 1696 @Override 1697 public int formatNdef(int nativeHandle, byte[] key) throws RemoteException { 1698 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1699 1700 NativeNfcTag tag; 1701 1702 // Check if NFC is enabled 1703 if (!mIsNfcEnabled) { 1704 return ErrorCodes.ERROR_NOT_INITIALIZED; 1705 } 1706 1707 /* find the tag in the hmap */ 1708 tag = (NativeNfcTag) findObject(nativeHandle); 1709 if (tag == null) { 1710 return ErrorCodes.ERROR_IO; 1711 } 1712 1713 if (tag.formatNdef(key)) { 1714 return ErrorCodes.SUCCESS; 1715 } 1716 else { 1717 return ErrorCodes.ERROR_IO; 1718 } 1719 } 1720 1721 1722 }; 1723 1724 private final IP2pInitiator mP2pInitiatorService = new IP2pInitiator.Stub() { 1725 1726 @Override 1727 public byte[] getGeneralBytes(int nativeHandle) throws RemoteException { 1728 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1729 1730 NativeP2pDevice device; 1731 1732 // Check if NFC is enabled 1733 if (!mIsNfcEnabled) { 1734 return null; 1735 } 1736 1737 /* find the device in the hmap */ 1738 device = (NativeP2pDevice) findObject(nativeHandle); 1739 if (device != null) { 1740 byte[] buff = device.getGeneralBytes(); 1741 if (buff == null) 1742 return null; 1743 return buff; 1744 } 1745 return null; 1746 } 1747 1748 @Override 1749 public int getMode(int nativeHandle) throws RemoteException { 1750 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1751 1752 NativeP2pDevice device; 1753 1754 // Check if NFC is enabled 1755 if (!mIsNfcEnabled) { 1756 return ErrorCodes.ERROR_NOT_INITIALIZED; 1757 } 1758 1759 /* find the device in the hmap */ 1760 device = (NativeP2pDevice) findObject(nativeHandle); 1761 if (device != null) { 1762 return device.getMode(); 1763 } 1764 return ErrorCodes.ERROR_INVALID_PARAM; 1765 } 1766 1767 @Override 1768 public byte[] receive(int nativeHandle) throws RemoteException { 1769 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1770 1771 NativeP2pDevice device; 1772 1773 // Check if NFC is enabled 1774 if (!mIsNfcEnabled) { 1775 return null; 1776 } 1777 1778 /* find the device in the hmap */ 1779 device = (NativeP2pDevice) findObject(nativeHandle); 1780 if (device != null) { 1781 byte[] buff = device.doReceive(); 1782 if (buff == null) 1783 return null; 1784 return buff; 1785 } 1786 /* Restart polling loop for notification */ 1787 maybeEnableDiscovery(); 1788 return null; 1789 } 1790 1791 @Override 1792 public boolean send(int nativeHandle, byte[] data) throws RemoteException { 1793 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1794 1795 NativeP2pDevice device; 1796 boolean isSuccess = false; 1797 1798 // Check if NFC is enabled 1799 if (!mIsNfcEnabled) { 1800 return isSuccess; 1801 } 1802 1803 /* find the device in the hmap */ 1804 device = (NativeP2pDevice) findObject(nativeHandle); 1805 if (device != null) { 1806 isSuccess = device.doSend(data); 1807 } 1808 return isSuccess; 1809 } 1810 }; 1811 1812 private final IP2pTarget mP2pTargetService = new IP2pTarget.Stub() { 1813 1814 @Override 1815 public int connect(int nativeHandle) throws RemoteException { 1816 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1817 1818 NativeP2pDevice device; 1819 1820 // Check if NFC is enabled 1821 if (!mIsNfcEnabled) { 1822 return ErrorCodes.ERROR_NOT_INITIALIZED; 1823 } 1824 1825 /* find the device in the hmap */ 1826 device = (NativeP2pDevice) findObject(nativeHandle); 1827 if (device != null) { 1828 if (device.doConnect()) { 1829 return ErrorCodes.SUCCESS; 1830 } 1831 } 1832 return ErrorCodes.ERROR_CONNECT; 1833 } 1834 1835 @Override 1836 public boolean disconnect(int nativeHandle) throws RemoteException { 1837 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1838 1839 NativeP2pDevice device; 1840 boolean isSuccess = false; 1841 1842 // Check if NFC is enabled 1843 if (!mIsNfcEnabled) { 1844 return isSuccess; 1845 } 1846 1847 /* find the device in the hmap */ 1848 device = (NativeP2pDevice) findObject(nativeHandle); 1849 if (device != null) { 1850 if (isSuccess = device.doDisconnect()) { 1851 /* remove the device from the hmap */ 1852 unregisterObject(nativeHandle); 1853 /* Restart polling loop for notification */ 1854 maybeEnableDiscovery(); 1855 } 1856 } 1857 return isSuccess; 1858 1859 } 1860 1861 @Override 1862 public byte[] getGeneralBytes(int nativeHandle) throws RemoteException { 1863 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1864 1865 NativeP2pDevice device; 1866 1867 // Check if NFC is enabled 1868 if (!mIsNfcEnabled) { 1869 return null; 1870 } 1871 1872 /* find the device in the hmap */ 1873 device = (NativeP2pDevice) findObject(nativeHandle); 1874 if (device != null) { 1875 byte[] buff = device.getGeneralBytes(); 1876 if (buff == null) 1877 return null; 1878 return buff; 1879 } 1880 return null; 1881 } 1882 1883 @Override 1884 public int getMode(int nativeHandle) throws RemoteException { 1885 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1886 1887 NativeP2pDevice device; 1888 1889 // Check if NFC is enabled 1890 if (!mIsNfcEnabled) { 1891 return ErrorCodes.ERROR_NOT_INITIALIZED; 1892 } 1893 1894 /* find the device in the hmap */ 1895 device = (NativeP2pDevice) findObject(nativeHandle); 1896 if (device != null) { 1897 return device.getMode(); 1898 } 1899 return ErrorCodes.ERROR_INVALID_PARAM; 1900 } 1901 1902 @Override 1903 public byte[] transceive(int nativeHandle, byte[] data) 1904 throws RemoteException { 1905 mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1906 1907 NativeP2pDevice device; 1908 1909 // Check if NFC is enabled 1910 if (!mIsNfcEnabled) { 1911 return null; 1912 } 1913 1914 /* find the device in the hmap */ 1915 device = (NativeP2pDevice) findObject(nativeHandle); 1916 if (device != null) { 1917 byte[] buff = device.doTransceive(data); 1918 if (buff == null) 1919 return null; 1920 return buff; 1921 } 1922 return null; 1923 } 1924 }; 1925 1926 private INfcSecureElement mSecureElementService = new INfcSecureElement.Stub() { 1927 1928 public int openSecureElementConnection() throws RemoteException { 1929 Log.d(TAG, "openSecureElementConnection"); 1930 int handle; 1931 1932 // Check if NFC is enabled 1933 if (!mIsNfcEnabled) { 1934 return 0; 1935 } 1936 1937 // Check in an open is already pending 1938 if (mOpenSmxPending) { 1939 return 0; 1940 } 1941 1942 handle = mSecureElement.doOpenSecureElementConnection(); 1943 1944 if (handle == 0) { 1945 mOpenSmxPending = false; 1946 } else { 1947 mSecureElementHandle = handle; 1948 1949 /* Start timer */ 1950 mTimerOpenSmx = new Timer(); 1951 mTimerOpenSmx.schedule(new TimerOpenSecureElement(), 30000); 1952 1953 /* Update state */ 1954 isOpened = true; 1955 isClosed = false; 1956 mOpenSmxPending = true; 1957 } 1958 1959 return handle; 1960 } 1961 1962 public int closeSecureElementConnection(int nativeHandle) 1963 throws RemoteException { 1964 1965 // Check if NFC is enabled 1966 if (!mIsNfcEnabled) { 1967 return ErrorCodes.ERROR_NOT_INITIALIZED; 1968 } 1969 1970 // Check if the SE connection is closed 1971 if (isClosed) { 1972 return -1; 1973 } 1974 1975 // Check if the SE connection is opened 1976 if (!isOpened) { 1977 return -1; 1978 } 1979 1980 if (mSecureElement.doDisconnect(nativeHandle)) { 1981 1982 /* Stop timer */ 1983 mTimerOpenSmx.cancel(); 1984 1985 /* Restart polling loop for notification */ 1986 mManager.enableDiscovery(DISCOVERY_MODE_READER); 1987 1988 /* Update state */ 1989 isOpened = false; 1990 isClosed = true; 1991 mOpenSmxPending = false; 1992 1993 return ErrorCodes.SUCCESS; 1994 } else { 1995 1996 /* Stop timer */ 1997 mTimerOpenSmx.cancel(); 1998 1999 /* Restart polling loop for notification */ 2000 mManager.enableDiscovery(DISCOVERY_MODE_READER); 2001 2002 /* Update state */ 2003 isOpened = false; 2004 isClosed = true; 2005 mOpenSmxPending = false; 2006 2007 return ErrorCodes.ERROR_DISCONNECT; 2008 } 2009 } 2010 2011 public int[] getSecureElementTechList(int nativeHandle) 2012 throws RemoteException { 2013 // Check if NFC is enabled 2014 if (!mIsNfcEnabled) { 2015 return null; 2016 } 2017 2018 // Check if the SE connection is closed 2019 if (isClosed) { 2020 return null; 2021 } 2022 2023 // Check if the SE connection is opened 2024 if (!isOpened) { 2025 return null; 2026 } 2027 2028 int[] techList = mSecureElement.doGetTechList(nativeHandle); 2029 2030 /* Stop and Restart timer */ 2031 mTimerOpenSmx.cancel(); 2032 mTimerOpenSmx = new Timer(); 2033 mTimerOpenSmx.schedule(new TimerOpenSecureElement(), 30000); 2034 2035 return techList; 2036 } 2037 2038 public byte[] getSecureElementUid(int nativeHandle) 2039 throws RemoteException { 2040 byte[] uid; 2041 2042 // Check if NFC is enabled 2043 if (!mIsNfcEnabled) { 2044 return null; 2045 } 2046 2047 // Check if the SE connection is closed 2048 if (isClosed) { 2049 return null; 2050 } 2051 2052 // Check if the SE connection is opened 2053 if (!isOpened) { 2054 return null; 2055 } 2056 2057 uid = mSecureElement.doGetUid(nativeHandle); 2058 2059 /* Stop and Restart timer */ 2060 mTimerOpenSmx.cancel(); 2061 mTimerOpenSmx = new Timer(); 2062 mTimerOpenSmx.schedule(new TimerOpenSecureElement(), 30000); 2063 2064 return uid; 2065 } 2066 2067 public byte[] exchangeAPDU(int nativeHandle, byte[] data) 2068 throws RemoteException { 2069 byte[] response; 2070 2071 // Check if NFC is enabled 2072 if (!mIsNfcEnabled) { 2073 return null; 2074 } 2075 2076 // Check if the SE connection is closed 2077 if (isClosed) { 2078 return null; 2079 } 2080 2081 // Check if the SE connection is opened 2082 if (!isOpened) { 2083 return null; 2084 } 2085 2086 response = mSecureElement.doTransceive(nativeHandle, data); 2087 2088 /* Stop and Restart timer */ 2089 mTimerOpenSmx.cancel(); 2090 mTimerOpenSmx = new Timer(); 2091 mTimerOpenSmx.schedule(new TimerOpenSecureElement(), 30000); 2092 2093 return response; 2094 2095 } 2096 }; 2097 2098 class TimerOpenSecureElement extends TimerTask { 2099 2100 @Override 2101 public void run() { 2102 if (mSecureElementHandle != 0) { 2103 Log.d(TAG, "Open SMX timer expired"); 2104 try { 2105 mSecureElementService 2106 .closeSecureElementConnection(mSecureElementHandle); 2107 } catch (RemoteException e) { 2108 } 2109 } 2110 2111 } 2112 2113 } 2114 2115 private boolean _enable(boolean oldEnabledState) { 2116 boolean isSuccess = mManager.initialize(); 2117 if (isSuccess) { 2118 applyProperties(); 2119 2120 /* Check Secure Element setting */ 2121 mNfcSecureElementState = mPrefs.getBoolean(PREF_SECURE_ELEMENT_ON, 2122 SECURE_ELEMENT_ON_DEFAULT); 2123 2124 if (mNfcSecureElementState) { 2125 int secureElementId = mPrefs.getInt(PREF_SECURE_ELEMENT_ID, 2126 SECURE_ELEMENT_ID_DEFAULT); 2127 int[] Se_list = mManager.doGetSecureElementList(); 2128 if (Se_list != null) { 2129 for (int i = 0; i < Se_list.length; i++) { 2130 if (Se_list[i] == secureElementId) { 2131 mManager.doSelectSecureElement(Se_list[i]); 2132 mSelectedSeId = Se_list[i]; 2133 break; 2134 } 2135 } 2136 } 2137 } 2138 2139 mIsNfcEnabled = true; 2140 2141 /* Start polling loop */ 2142 maybeEnableDiscovery(); 2143 2144 /* bring up the my tag server */ 2145 mMyTagServer.start(); 2146 2147 } else { 2148 mIsNfcEnabled = false; 2149 } 2150 2151 updateNfcOnSetting(oldEnabledState); 2152 2153 return isSuccess; 2154 } 2155 2156 /** Enable active tag discovery if screen is on and NFC is enabled */ 2157 private synchronized void maybeEnableDiscovery() { 2158 if (mScreenOn && mIsNfcEnabled) { 2159 mManager.enableDiscovery(DISCOVERY_MODE_READER); 2160 } 2161 } 2162 2163 /** Disable active tag discovery if necessary */ 2164 private synchronized void maybeDisableDiscovery() { 2165 if (mIsNfcEnabled) { 2166 mManager.disableDiscovery(); 2167 } 2168 } 2169 2170 private void applyProperties() { 2171 mManager.doSetProperties(PROPERTY_LLCP_LTO, mPrefs.getInt(PREF_LLCP_LTO, LLCP_LTO_DEFAULT)); 2172 mManager.doSetProperties(PROPERTY_LLCP_MIU, mPrefs.getInt(PREF_LLCP_MIU, LLCP_MIU_DEFAULT)); 2173 mManager.doSetProperties(PROPERTY_LLCP_WKS, mPrefs.getInt(PREF_LLCP_WKS, LLCP_WKS_DEFAULT)); 2174 mManager.doSetProperties(PROPERTY_LLCP_OPT, mPrefs.getInt(PREF_LLCP_OPT, LLCP_OPT_DEFAULT)); 2175 mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_A, 2176 mPrefs.getBoolean(PREF_DISCOVERY_A, DISCOVERY_A_DEFAULT) ? 1 : 0); 2177 mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_B, 2178 mPrefs.getBoolean(PREF_DISCOVERY_B, DISCOVERY_B_DEFAULT) ? 1 : 0); 2179 mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_F, 2180 mPrefs.getBoolean(PREF_DISCOVERY_F, DISCOVERY_F_DEFAULT) ? 1 : 0); 2181 mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_15693, 2182 mPrefs.getBoolean(PREF_DISCOVERY_15693, DISCOVERY_15693_DEFAULT) ? 1 : 0); 2183 mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_NFCIP, 2184 mPrefs.getBoolean(PREF_DISCOVERY_NFCIP, DISCOVERY_NFCIP_DEFAULT) ? 1 : 0); 2185 } 2186 2187 private void updateNfcOnSetting(boolean oldEnabledState) { 2188 int state; 2189 2190 mPrefsEditor.putBoolean(PREF_NFC_ON, mIsNfcEnabled); 2191 mPrefsEditor.apply(); 2192 2193 synchronized(this) { 2194 if (oldEnabledState != mIsNfcEnabled) { 2195 Intent intent = new Intent(NfcAdapter.ACTION_ADAPTER_STATE_CHANGE); 2196 intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 2197 intent.putExtra(NfcAdapter.EXTRA_NEW_BOOLEAN_STATE, mIsNfcEnabled); 2198 mContext.sendBroadcast(intent); 2199 } 2200 2201 if (mIsNfcEnabled) { 2202 2203 Context context = getApplicationContext(); 2204 2205 // Set this to null by default. If there isn't a tag on disk 2206 // or if there was an error reading the tag then this will cause 2207 // the status bar icon to be removed. 2208 NdefMessage myTag = null; 2209 2210 FileInputStream input = null; 2211 2212 try { 2213 input = context.openFileInput(MY_TAG_FILE_NAME); 2214 ByteArrayOutputStream bytes = new ByteArrayOutputStream(); 2215 2216 byte[] buffer = new byte[4096]; 2217 int read = 0; 2218 while ((read = input.read(buffer)) > 0) { 2219 bytes.write(buffer, 0, read); 2220 } 2221 2222 myTag = new NdefMessage(bytes.toByteArray()); 2223 } catch (FileNotFoundException e) { 2224 // Ignore. 2225 } catch (IOException e) { 2226 Log.e(TAG, "Could not read mytag file: ", e); 2227 context.deleteFile(MY_TAG_FILE_NAME); 2228 } catch (FormatException e) { 2229 Log.e(TAG, "Invalid NdefMessage for mytag", e); 2230 context.deleteFile(MY_TAG_FILE_NAME); 2231 } finally { 2232 try { 2233 if (input != null) { 2234 input.close(); 2235 } 2236 } catch (IOException e) { 2237 // Ignore 2238 } 2239 } 2240 2241 try { 2242 mNfcAdapter.localSet(myTag); 2243 } catch (RemoteException e) { 2244 // Ignore 2245 } 2246 } else { 2247 sendMessage(MSG_HIDE_MY_TAG_ICON, null); 2248 } 2249 } 2250 } 2251 2252 // Reset all internals 2253 private synchronized void reset() { 2254 // TODO: none of these appear to be synchronized but are 2255 // read/written from different threads (notably Binder threads)... 2256 2257 // Clear tables 2258 mObjectMap.clear(); 2259 mSocketMap.clear(); 2260 mRegisteredSocketList.clear(); 2261 2262 // Reset variables 2263 mLlcpLinkState = NfcAdapter.LLCP_LINK_STATE_DEACTIVATED; 2264 mNbSocketCreated = 0; 2265 mIsNfcEnabled = false; 2266 mSelectedSeId = 0; 2267 } 2268 2269 private synchronized Object findObject(int key) { 2270 Object device = null; 2271 2272 device = mObjectMap.get(key); 2273 if (device == null) { 2274 Log.w(TAG, "Handle not found !"); 2275 } 2276 2277 return device; 2278 } 2279 2280 synchronized void registerTagObject(NativeNfcTag nativeTag) { 2281 mObjectMap.put(nativeTag.getHandle(), nativeTag); 2282 } 2283 2284 synchronized void unregisterObject(int handle) { 2285 mObjectMap.remove(handle); 2286 } 2287 2288 private synchronized Object findSocket(int key) { 2289 Object socket = null; 2290 2291 socket = mSocketMap.get(key); 2292 2293 return socket; 2294 } 2295 2296 private void RemoveSocket(int key) { 2297 mSocketMap.remove(key); 2298 } 2299 2300 private boolean CheckSocketSap(int sap) { 2301 /* List of sockets registered */ 2302 ListIterator<RegisteredSocket> it = mRegisteredSocketList.listIterator(); 2303 2304 while (it.hasNext()) { 2305 RegisteredSocket registeredSocket = it.next(); 2306 2307 if (sap == registeredSocket.mSap) { 2308 /* SAP already used */ 2309 return false; 2310 } 2311 } 2312 return true; 2313 } 2314 2315 private boolean CheckSocketOptions(int miu, int rw, int linearBufferlength) { 2316 2317 if (rw > LLCP_RW_MAX_VALUE || miu < LLCP_MIU_DEFAULT || linearBufferlength < miu) { 2318 return false; 2319 } 2320 return true; 2321 } 2322 2323 private boolean CheckSocketServiceName(String sn) { 2324 2325 /* List of sockets registered */ 2326 ListIterator<RegisteredSocket> it = mRegisteredSocketList.listIterator(); 2327 2328 while (it.hasNext()) { 2329 RegisteredSocket registeredSocket = it.next(); 2330 2331 if (sn.equals(registeredSocket.mServiceName)) { 2332 /* Service Name already used */ 2333 return false; 2334 } 2335 } 2336 return true; 2337 } 2338 2339 private void RemoveRegisteredSocket(int nativeHandle) { 2340 /* check if sockets are registered */ 2341 ListIterator<RegisteredSocket> it = mRegisteredSocketList.listIterator(); 2342 2343 while (it.hasNext()) { 2344 RegisteredSocket registeredSocket = it.next(); 2345 if (registeredSocket.mHandle == nativeHandle) { 2346 /* remove the registered socket from the list */ 2347 it.remove(); 2348 if (DBG) Log.d(TAG, "socket removed"); 2349 } 2350 } 2351 } 2352 2353 /* 2354 * RegisteredSocket class to store the creation request of socket until the 2355 * LLCP link in not activated 2356 */ 2357 private class RegisteredSocket { 2358 private final int mType; 2359 2360 private final int mHandle; 2361 2362 private final int mSap; 2363 2364 private int mMiu; 2365 2366 private int mRw; 2367 2368 private String mServiceName; 2369 2370 private int mlinearBufferLength; 2371 2372 RegisteredSocket(int type, int handle, int sap, String sn, int miu, int rw, 2373 int linearBufferLength) { 2374 mType = type; 2375 mHandle = handle; 2376 mSap = sap; 2377 mServiceName = sn; 2378 mRw = rw; 2379 mMiu = miu; 2380 mlinearBufferLength = linearBufferLength; 2381 } 2382 2383 RegisteredSocket(int type, int handle, int sap, int miu, int rw, int linearBufferLength) { 2384 mType = type; 2385 mHandle = handle; 2386 mSap = sap; 2387 mRw = rw; 2388 mMiu = miu; 2389 mlinearBufferLength = linearBufferLength; 2390 } 2391 2392 RegisteredSocket(int type, int handle, int sap) { 2393 mType = type; 2394 mHandle = handle; 2395 mSap = sap; 2396 } 2397 } 2398 2399 /** For use by code in this process */ 2400 public LlcpSocket createLlcpSocket(int sap, int miu, int rw, int linearBufferLength) { 2401 try { 2402 int handle = mNfcAdapter.createLlcpSocket(sap, miu, rw, linearBufferLength); 2403 if (ErrorCodes.isError(handle)) { 2404 Log.e(TAG, "unable to create socket: " + ErrorCodes.asString(handle)); 2405 return null; 2406 } 2407 return new LlcpSocket(mLlcpSocket, handle); 2408 } catch (RemoteException e) { 2409 // This will never happen since the code is calling into it's own process 2410 throw new IllegalStateException("unable to talk to myself", e); 2411 } 2412 } 2413 2414 /** For use by code in this process */ 2415 public LlcpServiceSocket createLlcpServiceSocket(int sap, String sn, int miu, int rw, 2416 int linearBufferLength) { 2417 try { 2418 int handle = mNfcAdapter.createLlcpServiceSocket(sap, sn, miu, rw, linearBufferLength); 2419 if (ErrorCodes.isError(handle)) { 2420 Log.e(TAG, "unable to create socket: " + ErrorCodes.asString(handle)); 2421 return null; 2422 } 2423 return new LlcpServiceSocket(mLlcpServerSocketService, mLlcpSocket, handle); 2424 } catch (RemoteException e) { 2425 // This will never happen since the code is calling into it's own process 2426 throw new IllegalStateException("unable to talk to myself", e); 2427 } 2428 } 2429 2430 private void activateLlcpLink() { 2431 /* check if sockets are registered */ 2432 ListIterator<RegisteredSocket> it = mRegisteredSocketList.listIterator(); 2433 2434 if (DBG) Log.d(TAG, "Nb socket resgistered = " + mRegisteredSocketList.size()); 2435 2436 /* Mark the link state */ 2437 mLlcpLinkState = NfcAdapter.LLCP_LINK_STATE_ACTIVATED; 2438 2439 while (it.hasNext()) { 2440 RegisteredSocket registeredSocket = it.next(); 2441 2442 switch (registeredSocket.mType) { 2443 case LLCP_SERVICE_SOCKET_TYPE: 2444 if (DBG) Log.d(TAG, "Registered Llcp Service Socket"); 2445 if (DBG) Log.d(TAG, "SAP: " + registeredSocket.mSap + ", SN: " + registeredSocket.mServiceName); 2446 NativeLlcpServiceSocket serviceSocket; 2447 2448 serviceSocket = mManager.doCreateLlcpServiceSocket( 2449 registeredSocket.mSap, registeredSocket.mServiceName, 2450 registeredSocket.mMiu, registeredSocket.mRw, 2451 registeredSocket.mlinearBufferLength); 2452 2453 if (serviceSocket != null) { 2454 if (DBG) Log.d(TAG, "service socket created"); 2455 /* Add the socket into the socket map */ 2456 synchronized(NfcService.this) { 2457 mSocketMap.put(registeredSocket.mHandle, serviceSocket); 2458 } 2459 } else { 2460 Log.d(TAG, "FAILED to create service socket"); 2461 /* socket creation error - update the socket 2462 * handle counter */ 2463 mGeneratedSocketHandle -= 1; 2464 } 2465 2466 // NOTE: don't remove this socket from the registered sockets list. 2467 // If it's removed it won't be created the next time an LLCP 2468 // connection is activated and the server won't be found. 2469 break; 2470 2471 case LLCP_SOCKET_TYPE: 2472 if (DBG) Log.d(TAG, "Registered Llcp Socket"); 2473 NativeLlcpSocket clientSocket; 2474 clientSocket = mManager.doCreateLlcpSocket(registeredSocket.mSap, 2475 registeredSocket.mMiu, registeredSocket.mRw, 2476 registeredSocket.mlinearBufferLength); 2477 if (clientSocket != null) { 2478 if (DBG) Log.d(TAG, "socket created"); 2479 /* Add the socket into the socket map */ 2480 synchronized(NfcService.this) { 2481 mSocketMap.put(registeredSocket.mHandle, clientSocket); 2482 } 2483 } else { 2484 Log.d(TAG, "FAILED to create service socket"); 2485 /* socket creation error - update the socket 2486 * handle counter */ 2487 mGeneratedSocketHandle -= 1; 2488 } 2489 // This socket has been created, remove it from the registered sockets list. 2490 it.remove(); 2491 break; 2492 2493 case LLCP_CONNECTIONLESS_SOCKET_TYPE: 2494 if (DBG) Log.d(TAG, "Registered Llcp Connectionless Socket"); 2495 NativeLlcpConnectionlessSocket connectionlessSocket; 2496 connectionlessSocket = mManager.doCreateLlcpConnectionlessSocket( 2497 registeredSocket.mSap); 2498 if (connectionlessSocket != null) { 2499 if (DBG) Log.d(TAG, "connectionless socket created"); 2500 /* Add the socket into the socket map */ 2501 synchronized(NfcService.this) { 2502 mSocketMap.put(registeredSocket.mHandle, connectionlessSocket); 2503 } 2504 } else { 2505 Log.d(TAG, "FAILED to create service socket"); 2506 /* socket creation error - update the socket 2507 * handle counter */ 2508 mGeneratedSocketHandle -= 1; 2509 } 2510 // This socket has been created, remove it from the registered sockets list. 2511 it.remove(); 2512 break; 2513 } 2514 } 2515 2516 /* Broadcast Intent Link LLCP activated */ 2517 Intent LlcpLinkIntent = new Intent(); 2518 LlcpLinkIntent.setAction(NfcAdapter.ACTION_LLCP_LINK_STATE_CHANGED); 2519 2520 LlcpLinkIntent.putExtra(NfcAdapter.EXTRA_LLCP_LINK_STATE_CHANGED, 2521 NfcAdapter.LLCP_LINK_STATE_ACTIVATED); 2522 2523 if (DBG) Log.d(TAG, "Broadcasting LLCP activation"); 2524 mContext.sendOrderedBroadcast(LlcpLinkIntent, NFC_PERM); 2525 } 2526 2527 public void sendMockNdefTag(NdefMessage msg) { 2528 sendMessage(MSG_MOCK_NDEF, msg); 2529 } 2530 2531 void sendMessage(int what, Object obj) { 2532 Message msg = mHandler.obtainMessage(); 2533 msg.what = what; 2534 msg.obj = obj; 2535 mHandler.sendMessage(msg); 2536 } 2537 2538 final class NfcServiceHandler extends Handler { 2539 2540 public NdefMessage[] findAndReadNdef(NativeNfcTag nativeTag) { 2541 // Try to find NDEF on any of the technologies. 2542 int[] technologies = nativeTag.getTechList(); 2543 int[] handles = nativeTag.getHandleList(); 2544 int techIndex = 0; 2545 int lastHandleScanned = 0; 2546 boolean ndefFoundAndConnected = false; 2547 NdefMessage[] ndefMsgs = null; 2548 2549 while ((!ndefFoundAndConnected) && (techIndex < technologies.length)) { 2550 if (handles[techIndex] != lastHandleScanned) { 2551 // We haven't seen this handle yet, connect and checkndef 2552 if (nativeTag.connect(technologies[techIndex])) { 2553 int[] ndefinfo = new int[2]; 2554 if (nativeTag.checkNdef(ndefinfo)) { 2555 ndefFoundAndConnected = true; 2556 boolean generateEmptyNdef = false; 2557 2558 int supportedNdefLength = ndefinfo[0]; 2559 int cardState = ndefinfo[1]; 2560 byte[] buff = nativeTag.read(); 2561 if (buff != null) { 2562 ndefMsgs = new NdefMessage[1]; 2563 try { 2564 ndefMsgs[0] = new NdefMessage(buff); 2565 nativeTag.addNdefTechnology(ndefMsgs[0], 2566 nativeTag.getConnectedHandle(), 2567 nativeTag.getConnectedLibNfcType(), 2568 nativeTag.getConnectedTechnology(), 2569 supportedNdefLength, cardState); 2570 nativeTag.reconnect(); 2571 } catch (FormatException e) { 2572 // Create an intent anyway, without NDEF messages 2573 generateEmptyNdef = true; 2574 } 2575 } else { 2576 generateEmptyNdef = true; 2577 } 2578 2579 if (generateEmptyNdef) { 2580 ndefMsgs = new NdefMessage[] { }; 2581 nativeTag.addNdefTechnology(null, 2582 nativeTag.getConnectedHandle(), 2583 nativeTag.getConnectedLibNfcType(), 2584 nativeTag.getConnectedTechnology(), 2585 supportedNdefLength, cardState); 2586 nativeTag.reconnect(); 2587 } 2588 } // else, no NDEF on this tech, continue loop 2589 } else { 2590 // Connect failed, tag maybe lost. Try next handle 2591 // anyway. 2592 } 2593 } 2594 lastHandleScanned = handles[techIndex]; 2595 techIndex++; 2596 } 2597 2598 return ndefMsgs; 2599 } 2600 2601 @Override 2602 public void handleMessage(Message msg) { 2603 switch (msg.what) { 2604 case MSG_MOCK_NDEF: { 2605 NdefMessage ndefMsg = (NdefMessage) msg.obj; 2606 Tag tag = Tag.createMockTag(new byte[] { 0x00 }, 2607 new int[] { }, 2608 new Bundle[] { }); 2609 Log.d(TAG, "mock NDEF tag, starting corresponding activity"); 2610 Log.d(TAG, tag.toString()); 2611 dispatchTag(tag, new NdefMessage[] { ndefMsg }); 2612 break; 2613 } 2614 2615 case MSG_NDEF_TAG: 2616 if (DBG) Log.d(TAG, "Tag detected, notifying applications"); 2617 NativeNfcTag nativeTag = (NativeNfcTag) msg.obj; 2618 NdefMessage[] ndefMsgs = findAndReadNdef(nativeTag); 2619 2620 if (ndefMsgs != null) { 2621 dispatchNativeTag(nativeTag, ndefMsgs); 2622 } else { 2623 // No ndef found or connect failed, just try to reconnect and dispatch 2624 if (nativeTag.reconnect()) { 2625 dispatchNativeTag(nativeTag, null); 2626 } else { 2627 Log.w(TAG, "Failed to connect to tag"); 2628 nativeTag.disconnect(); 2629 } 2630 } 2631 break; 2632 2633 case MSG_CARD_EMULATION: 2634 if (DBG) Log.d(TAG, "Card Emulation message"); 2635 byte[] aid = (byte[]) msg.obj; 2636 /* Send broadcast ordered */ 2637 Intent TransactionIntent = new Intent(); 2638 TransactionIntent.setAction(NfcAdapter.ACTION_TRANSACTION_DETECTED); 2639 TransactionIntent.putExtra(NfcAdapter.EXTRA_AID, aid); 2640 if (DBG) Log.d(TAG, "Broadcasting Card Emulation event"); 2641 mContext.sendOrderedBroadcast(TransactionIntent, NFC_PERM); 2642 break; 2643 2644 case MSG_LLCP_LINK_ACTIVATION: 2645 NativeP2pDevice device = (NativeP2pDevice) msg.obj; 2646 2647 Log.d(TAG, "LLCP Activation message"); 2648 2649 if (device.getMode() == NativeP2pDevice.MODE_P2P_TARGET) { 2650 if (DBG) Log.d(TAG, "NativeP2pDevice.MODE_P2P_TARGET"); 2651 if (device.doConnect()) { 2652 /* Check Llcp compliancy */ 2653 if (mManager.doCheckLlcp()) { 2654 /* Activate Llcp Link */ 2655 if (mManager.doActivateLlcp()) { 2656 if (DBG) Log.d(TAG, "Initiator Activate LLCP OK"); 2657 activateLlcpLink(); 2658 } else { 2659 /* should not happen */ 2660 Log.w(TAG, "Initiator Activate LLCP NOK. Disconnect."); 2661 device.doDisconnect(); 2662 } 2663 2664 } else { 2665 if (DBG) Log.d(TAG, "Remote Target does not support LLCP. Disconnect."); 2666 device.doDisconnect(); 2667 } 2668 } else { 2669 if (DBG) Log.d(TAG, "Cannot connect remote Target. Restart polling loop."); 2670 device.doDisconnect(); 2671 } 2672 2673 } else if (device.getMode() == NativeP2pDevice.MODE_P2P_INITIATOR) { 2674 if (DBG) Log.d(TAG, "NativeP2pDevice.MODE_P2P_INITIATOR"); 2675 /* Check Llcp compliancy */ 2676 if (mManager.doCheckLlcp()) { 2677 /* Activate Llcp Link */ 2678 if (mManager.doActivateLlcp()) { 2679 if (DBG) Log.d(TAG, "Target Activate LLCP OK"); 2680 activateLlcpLink(); 2681 } 2682 } else { 2683 Log.w(TAG, "checkLlcp failed"); 2684 } 2685 } 2686 break; 2687 2688 case MSG_LLCP_LINK_DEACTIVATED: 2689 device = (NativeP2pDevice) msg.obj; 2690 2691 /* Mark the link state */ 2692 mLlcpLinkState = NfcAdapter.LLCP_LINK_STATE_DEACTIVATED; 2693 2694 Log.d(TAG, "LLCP Link Deactivated message. Restart polling loop."); 2695 if (device.getMode() == NativeP2pDevice.MODE_P2P_TARGET) { 2696 if (DBG) Log.d(TAG, "disconnecting from target"); 2697 /* Restart polling loop */ 2698 device.doDisconnect(); 2699 } else { 2700 if (DBG) Log.d(TAG, "not disconnecting from initiator"); 2701 } 2702 2703 /* Broadcast Intent Link LLCP activated */ 2704 Intent LlcpLinkIntent = new Intent(); 2705 LlcpLinkIntent.setAction(NfcAdapter.ACTION_LLCP_LINK_STATE_CHANGED); 2706 LlcpLinkIntent.putExtra(NfcAdapter.EXTRA_LLCP_LINK_STATE_CHANGED, 2707 NfcAdapter.LLCP_LINK_STATE_DEACTIVATED); 2708 if (DBG) Log.d(TAG, "Broadcasting LLCP deactivation"); 2709 mContext.sendOrderedBroadcast(LlcpLinkIntent, NFC_PERM); 2710 break; 2711 2712 case MSG_TARGET_DESELECTED: 2713 /* Broadcast Intent Target Deselected */ 2714 if (DBG) Log.d(TAG, "Target Deselected"); 2715 Intent TargetDeselectedIntent = new Intent(); 2716 TargetDeselectedIntent.setAction(mManager.INTERNAL_TARGET_DESELECTED_ACTION); 2717 if (DBG) Log.d(TAG, "Broadcasting Intent"); 2718 mContext.sendOrderedBroadcast(TargetDeselectedIntent, NFC_PERM); 2719 break; 2720 2721 case MSG_SHOW_MY_TAG_ICON: { 2722 StatusBarManager sb = (StatusBarManager) getSystemService( 2723 Context.STATUS_BAR_SERVICE); 2724 sb.setIcon("nfc", R.drawable.stat_sys_nfc, 0); 2725 break; 2726 } 2727 2728 case MSG_HIDE_MY_TAG_ICON: { 2729 StatusBarManager sb = (StatusBarManager) getSystemService( 2730 Context.STATUS_BAR_SERVICE); 2731 sb.removeIcon("nfc"); 2732 break; 2733 } 2734 2735 case MSG_SE_FIELD_ACTIVATED:{ 2736 if (DBG) Log.d(TAG, "SE FIELD ACTIVATED"); 2737 Intent eventFieldOnIntent = new Intent(); 2738 eventFieldOnIntent.setAction(NfcAdapter.ACTION_RF_FIELD_ON_DETECTED); 2739 if (DBG) Log.d(TAG, "Broadcasting Intent"); 2740 mContext.sendBroadcast(eventFieldOnIntent, NFC_PERM); 2741 break; 2742 } 2743 2744 case MSG_SE_FIELD_DEACTIVATED:{ 2745 if (DBG) Log.d(TAG, "SE FIELD DEACTIVATED"); 2746 Intent eventFieldOffIntent = new Intent(); 2747 eventFieldOffIntent.setAction(NfcAdapter.ACTION_RF_FIELD_OFF_DETECTED); 2748 if (DBG) Log.d(TAG, "Broadcasting Intent"); 2749 mContext.sendBroadcast(eventFieldOffIntent, NFC_PERM); 2750 break; 2751 } 2752 2753 default: 2754 Log.e(TAG, "Unknown message received"); 2755 break; 2756 } 2757 } 2758 2759 private Intent buildTagIntent(Tag tag, NdefMessage[] msgs, String action) { 2760 Intent intent = new Intent(action); 2761 intent.putExtra(NfcAdapter.EXTRA_TAG, tag); 2762 intent.putExtra(NfcAdapter.EXTRA_ID, tag.getId()); 2763 intent.putExtra(NfcAdapter.EXTRA_NDEF_MESSAGES, msgs); 2764 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2765 return intent; 2766 } 2767 2768 private void dispatchNativeTag(NativeNfcTag nativeTag, NdefMessage[] msgs) { 2769 Tag tag = new Tag(nativeTag.getUid(), nativeTag.getTechList(), 2770 nativeTag.getTechExtras(), nativeTag.getHandle()); 2771 if (dispatchTag(tag, msgs)) { 2772 registerTagObject(nativeTag); 2773 } else { 2774 nativeTag.disconnect(); 2775 } 2776 } 2777 2778 public byte[] concat(byte[]... arrays) { 2779 int length = 0; 2780 for (byte[] array : arrays) { 2781 length += array.length; 2782 } 2783 byte[] result = new byte[length]; 2784 int pos = 0; 2785 for (byte[] array : arrays) { 2786 System.arraycopy(array, 0, result, pos, array.length); 2787 pos += array.length; 2788 } 2789 return result; 2790 } 2791 2792 private Uri parseWellKnownUriRecord(NdefRecord record) { 2793 byte[] payload = record.getPayload(); 2794 2795 /* 2796 * payload[0] contains the URI Identifier Code, per the 2797 * NFC Forum "URI Record Type Definition" section 3.2.2. 2798 * 2799 * payload[1]...payload[payload.length - 1] contains the rest of 2800 * the URI. 2801 */ 2802 String prefix = URI_PREFIX_MAP[(payload[0] & 0xff)]; 2803 byte[] fullUri = concat(prefix.getBytes(Charsets.UTF_8), 2804 Arrays.copyOfRange(payload, 1, payload.length)); 2805 return Uri.parse(new String(fullUri, Charsets.UTF_8)); 2806 } 2807 2808 private boolean setTypeOrDataFromNdef(Intent intent, NdefRecord record) { 2809 short tnf = record.getTnf(); 2810 byte[] type = record.getType(); 2811 switch (tnf) { 2812 case NdefRecord.TNF_MIME_MEDIA: { 2813 intent.setType(new String(type, Charsets.US_ASCII)); 2814 return true; 2815 } 2816 case NdefRecord.TNF_ABSOLUTE_URI: { 2817 intent.setData(Uri.parse(new String(type, Charsets.UTF_8))); 2818 return true; 2819 } 2820 case NdefRecord.TNF_WELL_KNOWN: { 2821 if (Arrays.equals(type, NdefRecord.RTD_TEXT)) { 2822 intent.setType("text/plain"); 2823 return true; 2824 } else if (Arrays.equals(type, NdefRecord.RTD_SMART_POSTER)) { 2825 // Parse the smart poster looking for the URI 2826 try { 2827 NdefMessage msg = new NdefMessage(record.getPayload()); 2828 for (NdefRecord subRecord : msg.getRecords()) { 2829 if (subRecord.getTnf() == NdefRecord.TNF_WELL_KNOWN 2830 && Arrays.equals(subRecord.getType(), NdefRecord.RTD_URI)) { 2831 intent.setData(parseWellKnownUriRecord(subRecord)); 2832 return true; 2833 } 2834 } 2835 } catch (FormatException e) { 2836 return false; 2837 } 2838 } else if (Arrays.equals(type, NdefRecord.RTD_URI)) { 2839 intent.setData(parseWellKnownUriRecord(record)); 2840 return true; 2841 } 2842 return false; 2843 } 2844 } 2845 return false; 2846 } 2847 2848 private Uri buildTechListUri(Tag tag) { 2849 int[] techList = tag.getTechnologyList(); 2850 Arrays.sort(techList); 2851 Uri.Builder builder = new Uri.Builder(); 2852 builder.scheme("vnd.android.nfc").authority("tag"); 2853 for (int tech : techList) { 2854 builder.appendPath(Integer.toString(tech)); 2855 } 2856 builder.appendPath(""); 2857 return builder.build(); 2858 } 2859 2860 /** Returns false if no activities were found to dispatch to */ 2861 private boolean dispatchTag(Tag tag, NdefMessage[] msgs) { 2862 if (DBG) { 2863 Log.d(TAG, "Dispatching tag"); 2864 Log.d(TAG, tag.toString()); 2865 } 2866 2867 IntentFilter[] overrideFilters; 2868 PendingIntent overrideIntent; 2869 synchronized (mNfcAdapter) { 2870 overrideFilters = mDispatchOverrideFilters; 2871 overrideIntent = mDispatchOverrideIntent; 2872 } 2873 2874 // First look for dispatch overrides 2875 if (overrideFilters != null && overrideIntent != null) { 2876 if (DBG) Log.d(TAG, "Attempting to dispatch tag with override"); 2877 try { 2878 if (dispatchTagInternal(tag, msgs, overrideIntent, overrideFilters)) { 2879 if (DBG) Log.d(TAG, "Dispatched to override"); 2880 return true; 2881 } 2882 Log.w(TAG, "Dispatch override registered, but no filters matched"); 2883 } catch (CanceledException e) { 2884 Log.w(TAG, "Dispatch overrides pending intent was canceled"); 2885 synchronized (mNfcAdapter) { 2886 mDispatchOverrideFilters = null; 2887 mDispatchOverrideIntent = null; 2888 } 2889 } 2890 } 2891 2892 // Try a standard dispatch 2893 try { 2894 return dispatchTagInternal(tag, msgs, null, null); 2895 } catch (CanceledException e) { 2896 Log.e(TAG, "CanceledException unexpected here", e); 2897 return false; 2898 } 2899 } 2900 2901 // Dispatch to either an override pending intent or a standard startActivity() 2902 private boolean dispatchTagInternal(Tag tag, NdefMessage[] msgs, 2903 PendingIntent overrideIntent, IntentFilter[] overrideFilters) 2904 throws CanceledException{ 2905 Intent intent; 2906 if (msgs != null && msgs.length > 0) { 2907 NdefMessage msg = msgs[0]; 2908 NdefRecord[] records = msg.getRecords(); 2909 if (records.length > 0) { 2910 // Found valid NDEF data, try to dispatch that first 2911 NdefRecord record = records[0]; 2912 2913 intent = buildTagIntent(tag, msgs, NfcAdapter.ACTION_NDEF_DISCOVERED); 2914 setTypeOrDataFromNdef(intent, record); 2915 2916 if (startDispatchActivity(intent, overrideIntent, overrideFilters)) { 2917 // If an activity is found then skip further dispatching 2918 return true; 2919 } else { 2920 if (DBG) Log.d(TAG, "No activities for NDEF handling of " + intent); 2921 } 2922 } 2923 } 2924 2925 // Try the technology specific dispatch 2926 intent = buildTagIntent(tag, msgs, NfcAdapter.ACTION_TECHNOLOGY_DISCOVERED); 2927 intent.setData(buildTechListUri(tag)); 2928 if (startDispatchActivity(intent, overrideIntent, overrideFilters)) { 2929 return true; 2930 } else { 2931 if (DBG) Log.w(TAG, "No activities for technology handling of " + intent); 2932 } 2933 2934 // Try the generic intent 2935 intent = buildTagIntent(tag, msgs, NfcAdapter.ACTION_TAG_DISCOVERED); 2936 if (startDispatchActivity(intent, overrideIntent, overrideFilters)) { 2937 return true; 2938 } else { 2939 Log.e(TAG, "No tag fallback activity found for " + intent); 2940 return false; 2941 } 2942 } 2943 2944 private boolean startDispatchActivity(Intent intent, PendingIntent overrideIntent, 2945 IntentFilter[] overrideFilters) throws CanceledException { 2946 if (overrideIntent != null) { 2947 for (IntentFilter filter : overrideFilters) { 2948 if (filter.match(mContext.getContentResolver(), intent, false, TAG) >= 0) { 2949 Log.i(TAG, "Dispatching to override intent " + overrideIntent); 2950 overrideIntent.send(mContext, Activity.RESULT_OK, intent); 2951 return true; 2952 } 2953 } 2954 return false; 2955 } else { 2956 try { 2957 mContext.startActivity(intent); 2958 return true; 2959 } catch (ActivityNotFoundException e) { 2960 return false; 2961 } 2962 } 2963 } 2964 } 2965 2966 private NfcServiceHandler mHandler = new NfcServiceHandler(); 2967 2968 private class EnableDisableDiscoveryTask extends AsyncTask<Boolean, Void, Void> { 2969 @Override 2970 protected Void doInBackground(Boolean... enable) { 2971 if (enable != null && enable.length > 0 && enable[0]) { 2972 synchronized (NfcService.this) { 2973 mScreenOn = true; 2974 maybeEnableDiscovery(); 2975 } 2976 } else { 2977 mWakeLock.acquire(); 2978 synchronized (NfcService.this) { 2979 mScreenOn = false; 2980 maybeDisableDiscovery(); 2981 } 2982 mWakeLock.release(); 2983 } 2984 return null; 2985 } 2986 } 2987 2988 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 2989 @Override 2990 public void onReceive(Context context, Intent intent) { 2991 if (intent.getAction().equals( 2992 NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION)) { 2993 if (DBG) Log.d(TAG, "INERNAL_TARGET_DESELECTED_ACTION"); 2994 2995 /* Restart polling loop for notification */ 2996 maybeEnableDiscovery(); 2997 2998 } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) { 2999 // Perform discovery enable in thread to protect against ANR when the 3000 // NFC stack wedges. This is *not* the correct way to fix this issue - 3001 // configuration of the local NFC adapter should be very quick and should 3002 // be safe on the main thread, and the NFC stack should not wedge. 3003 new EnableDisableDiscoveryTask().execute(new Boolean(true)); 3004 } else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { 3005 // Perform discovery disable in thread to protect against ANR when the 3006 // NFC stack wedges. This is *not* the correct way to fix this issue - 3007 // configuration of the local NFC adapter should be very quick and should 3008 // be safe on the main thread, and the NFC stack should not wedge. 3009 new EnableDisableDiscoveryTask().execute(new Boolean(false)); 3010 } 3011 } 3012 }; 3013} 3014