PageRenderTime 87ms CodeModel.GetById 4ms app.highlight 60ms RepoModel.GetById 11ms app.codeStats 1ms

/src/com/android/nfc/NfcService.java

https://github.com/Cafogen/android_packages_apps_Nfc
Java | 3101 lines | 2338 code | 465 blank | 298 comment | 533 complexity | fe76b2efa156b3871c8c0abb7ef7e4b7 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   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.RegisteredComponentCache.ComponentInfo;
  22import com.android.nfc.ndefpush.NdefPushClient;
  23import com.android.nfc.ndefpush.NdefPushServer;
  24import com.android.nfc3.R;
  25
  26import android.app.Activity;
  27import android.app.ActivityManagerNative;
  28import android.app.Application;
  29import android.app.IActivityManager;
  30import android.app.PendingIntent;
  31import android.app.PendingIntent.CanceledException;
  32import android.app.StatusBarManager;
  33import android.content.ActivityNotFoundException;
  34import android.content.BroadcastReceiver;
  35import android.content.ComponentName;
  36import android.content.Context;
  37import android.content.Intent;
  38import android.content.IntentFilter;
  39import android.content.SharedPreferences;
  40import android.content.pm.PackageManager;
  41import android.content.pm.ResolveInfo;
  42import android.net.Uri;
  43import android.nfc.ApduList;
  44import android.nfc.ErrorCodes;
  45import android.nfc.FormatException;
  46import android.nfc.ILlcpConnectionlessSocket;
  47import android.nfc.ILlcpServiceSocket;
  48import android.nfc.ILlcpSocket;
  49import android.nfc.INfcAdapter;
  50import android.nfc.INfcAdapterExtras;
  51import android.nfc.INfcTag;
  52import android.nfc.IP2pInitiator;
  53import android.nfc.IP2pTarget;
  54import android.nfc.LlcpPacket;
  55import android.nfc.NdefMessage;
  56import android.nfc.NdefRecord;
  57import android.nfc.NfcAdapter;
  58import android.nfc.Tag;
  59import android.nfc.TechListParcel;
  60import android.nfc.TransceiveResult;
  61import android.os.AsyncTask;
  62import android.os.Bundle;
  63import android.os.Handler;
  64import android.os.IBinder;
  65import android.os.Message;
  66import android.os.PowerManager;
  67import android.os.RemoteException;
  68import android.os.ServiceManager;
  69import android.util.Log;
  70
  71import java.io.ByteArrayOutputStream;
  72import java.io.DataInputStream;
  73import java.io.File;
  74import java.io.FileInputStream;
  75import java.io.FileNotFoundException;
  76import java.io.FileOutputStream;
  77import java.io.IOException;
  78import java.nio.charset.Charsets;
  79import java.util.ArrayList;
  80import java.util.Arrays;
  81import java.util.HashMap;
  82import java.util.HashSet;
  83import java.util.Iterator;
  84import java.util.List;
  85
  86public class NfcService extends Application {
  87    private static final String ACTION_MASTER_CLEAR_NOTIFICATION = "android.intent.action.MASTER_CLEAR_NOTIFICATION";
  88
  89    static final boolean DBG = false;
  90
  91    private static final String MY_TAG_FILE_NAME = "mytag";
  92    private static final String SE_RESET_SCRIPT_FILE_NAME = "/system/etc/se-reset-script";
  93    private static final String NFC_CONTROLLER_FIRMWARE_FILE_NAME = "/system/lib/libpn544_fw.so";
  94
  95    static {
  96        System.loadLibrary("nfc_jni");
  97    }
  98
  99    /**
 100     * NFC Forum "URI Record Type Definition"
 101     *
 102     * This is a mapping of "URI Identifier Codes" to URI string prefixes,
 103     * per section 3.2.2 of the NFC Forum URI Record Type Definition document.
 104     */
 105    private static final String[] URI_PREFIX_MAP = new String[] {
 106            "", // 0x00
 107            "http://www.", // 0x01
 108            "https://www.", // 0x02
 109            "http://", // 0x03
 110            "https://", // 0x04
 111            "tel:", // 0x05
 112            "mailto:", // 0x06
 113            "ftp://anonymous:anonymous@", // 0x07
 114            "ftp://ftp.", // 0x08
 115            "ftps://", // 0x09
 116            "sftp://", // 0x0A
 117            "smb://", // 0x0B
 118            "nfs://", // 0x0C
 119            "ftp://", // 0x0D
 120            "dav://", // 0x0E
 121            "news:", // 0x0F
 122            "telnet://", // 0x10
 123            "imap:", // 0x11
 124            "rtsp://", // 0x12
 125            "urn:", // 0x13
 126            "pop:", // 0x14
 127            "sip:", // 0x15
 128            "sips:", // 0x16
 129            "tftp:", // 0x17
 130            "btspp://", // 0x18
 131            "btl2cap://", // 0x19
 132            "btgoep://", // 0x1A
 133            "tcpobex://", // 0x1B
 134            "irdaobex://", // 0x1C
 135            "file://", // 0x1D
 136            "urn:epc:id:", // 0x1E
 137            "urn:epc:tag:", // 0x1F
 138            "urn:epc:pat:", // 0x20
 139            "urn:epc:raw:", // 0x21
 140            "urn:epc:", // 0x22
 141    };
 142
 143    public static final String SERVICE_NAME = "nfc";
 144
 145    private static final String TAG = "NfcService";
 146
 147    private static final String NFC_PERM = android.Manifest.permission.NFC;
 148    private static final String NFC_PERM_ERROR = "NFC permission required";
 149    private static final String ADMIN_PERM = android.Manifest.permission.WRITE_SECURE_SETTINGS;
 150    private static final String ADMIN_PERM_ERROR = "WRITE_SECURE_SETTINGS permission required";
 151    private static final String NFCEE_ADMIN_PERM = "com.android.nfc.permission.NFCEE_ADMIN";
 152    private static final String NFCEE_ADMIN_PERM_ERROR = "NFCEE_ADMIN permission required";
 153
 154    private static final String PREF = "NfcServicePrefs";
 155
 156    private static final String PREF_NFC_ON = "nfc_on";
 157    private static final boolean NFC_ON_DEFAULT = true;
 158
 159    private static final String PREF_FIRST_BOOT = "first_boot";
 160
 161    private static final String PREF_LLCP_LTO = "llcp_lto";
 162    private static final int LLCP_LTO_DEFAULT = 150;
 163    private static final int LLCP_LTO_MAX = 255;
 164
 165    /** Maximum Information Unit */
 166    private static final String PREF_LLCP_MIU = "llcp_miu";
 167    private static final int LLCP_MIU_DEFAULT = 128;
 168    private static final int LLCP_MIU_MAX = 2176;
 169
 170    /** Well Known Service List */
 171    private static final String PREF_LLCP_WKS = "llcp_wks";
 172    private static final int LLCP_WKS_DEFAULT = 1;
 173    private static final int LLCP_WKS_MAX = 15;
 174
 175    private static final String PREF_LLCP_OPT = "llcp_opt";
 176    private static final int LLCP_OPT_DEFAULT = 0;
 177    private static final int LLCP_OPT_MAX = 3;
 178
 179    private static final String PREF_DISCOVERY_A = "discovery_a";
 180    private static final boolean DISCOVERY_A_DEFAULT = true;
 181
 182    private static final String PREF_DISCOVERY_B = "discovery_b";
 183    private static final boolean DISCOVERY_B_DEFAULT = true;
 184
 185    private static final String PREF_DISCOVERY_F = "discovery_f";
 186    private static final boolean DISCOVERY_F_DEFAULT = true;
 187
 188    private static final String PREF_DISCOVERY_15693 = "discovery_15693";
 189    private static final boolean DISCOVERY_15693_DEFAULT = true;
 190
 191    private static final String PREF_DISCOVERY_NFCIP = "discovery_nfcip";
 192    private static final boolean DISCOVERY_NFCIP_DEFAULT = true;
 193
 194    private static final String PREF_FIRMWARE_MODTIME = "firmware_modtime";
 195    private static final long FIRMWARE_MODTIME_DEFAULT = -1;
 196
 197    /** NFC Reader Discovery mode for enableDiscovery() */
 198    private static final int DISCOVERY_MODE_READER = 0;
 199
 200    private static final int PROPERTY_LLCP_LTO = 0;
 201    private static final String PROPERTY_LLCP_LTO_VALUE = "llcp.lto";
 202    private static final int PROPERTY_LLCP_MIU = 1;
 203    private static final String PROPERTY_LLCP_MIU_VALUE = "llcp.miu";
 204    private static final int PROPERTY_LLCP_WKS = 2;
 205    private static final String PROPERTY_LLCP_WKS_VALUE = "llcp.wks";
 206    private static final int PROPERTY_LLCP_OPT = 3;
 207    private static final String PROPERTY_LLCP_OPT_VALUE = "llcp.opt";
 208    private static final int PROPERTY_NFC_DISCOVERY_A = 4;
 209    private static final String PROPERTY_NFC_DISCOVERY_A_VALUE = "discovery.iso14443A";
 210    private static final int PROPERTY_NFC_DISCOVERY_B = 5;
 211    private static final String PROPERTY_NFC_DISCOVERY_B_VALUE = "discovery.iso14443B";
 212    private static final int PROPERTY_NFC_DISCOVERY_F = 6;
 213    private static final String PROPERTY_NFC_DISCOVERY_F_VALUE = "discovery.felica";
 214    private static final int PROPERTY_NFC_DISCOVERY_15693 = 7;
 215    private static final String PROPERTY_NFC_DISCOVERY_15693_VALUE = "discovery.iso15693";
 216    private static final int PROPERTY_NFC_DISCOVERY_NFCIP = 8;
 217    private static final String PROPERTY_NFC_DISCOVERY_NFCIP_VALUE = "discovery.nfcip";
 218
 219    static final int MSG_NDEF_TAG = 0;
 220    static final int MSG_CARD_EMULATION = 1;
 221    static final int MSG_LLCP_LINK_ACTIVATION = 2;
 222    static final int MSG_LLCP_LINK_DEACTIVATED = 3;
 223    static final int MSG_TARGET_DESELECTED = 4;
 224    static final int MSG_SHOW_MY_TAG_ICON = 5;
 225    static final int MSG_HIDE_MY_TAG_ICON = 6;
 226    static final int MSG_MOCK_NDEF = 7;
 227    static final int MSG_SE_FIELD_ACTIVATED = 8;
 228    static final int MSG_SE_FIELD_DEACTIVATED = 9;
 229    static final int MSG_SE_APDU_RECEIVED = 10;
 230    static final int MSG_SE_EMV_CARD_REMOVAL = 11;
 231    static final int MSG_SE_MIFARE_ACCESS = 12;
 232
 233    static final int STATUS_CODE_TARGET_LOST = 146;
 234
 235    // Copied from com.android.nfc_extras to avoid library dependency
 236    // Must keep in sync with com.android.nfc_extras
 237    static final int ROUTE_OFF = 1;
 238    static final int ROUTE_ON_WHEN_SCREEN_ON = 2;
 239    public static final String ACTION_RF_FIELD_ON_DETECTED =
 240        "com.android.nfc_extras.action.RF_FIELD_ON_DETECTED";
 241    public static final String ACTION_RF_FIELD_OFF_DETECTED =
 242        "com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED";
 243    public static final String ACTION_AID_SELECTED =
 244        "com.android.nfc_extras.action.AID_SELECTED";
 245    public static final String EXTRA_AID = "com.android.nfc_extras.extra.AID";
 246
 247    public static final String ACTION_APDU_RECEIVED =
 248        "com.android.nfc_extras.action.APDU_RECEIVED";
 249    public static final String EXTRA_APDU_BYTES =
 250        "com.android.nfc_extras.extra.APDU_BYTES";
 251
 252    public static final String ACTION_EMV_CARD_REMOVAL =
 253        "com.android.nfc_extras.action.EMV_CARD_REMOVAL";
 254
 255    public static final String ACTION_MIFARE_ACCESS_DETECTED =
 256        "com.android.nfc_extras.action.MIFARE_ACCESS_DETECTED";
 257    public static final String EXTRA_MIFARE_BLOCK =
 258        "com.android.nfc_extras.extra.MIFARE_BLOCK";
 259
 260    // Locked on mNfcAdapter
 261    PendingIntent mDispatchOverrideIntent;
 262    IntentFilter[] mDispatchOverrideFilters;
 263    String[][] mDispatchOverrideTechLists;
 264
 265    // TODO: none of these appear to be synchronized but are
 266    // read/written from different threads (notably Binder threads)...
 267    private int mGeneratedSocketHandle = 0;
 268    private volatile boolean mIsNfcEnabled = false;
 269    private boolean mIsDiscoveryOn = false;
 270
 271    // NFC Execution Environment
 272    // fields below are protected by this
 273    private static final int SECURE_ELEMENT_ID = 11259375;  //TODO: remove hard-coded value
 274    private NativeNfcSecureElement mSecureElement;
 275    private OpenSecureElement mOpenEe;  // null when EE closed
 276    private int mEeRoutingState;  // contactless interface routing
 277
 278    // fields below are used in multiple threads and protected by synchronized(this)
 279    private final HashMap<Integer, Object> mObjectMap = new HashMap<Integer, Object>();
 280    private final HashMap<Integer, Object> mSocketMap = new HashMap<Integer, Object>();
 281    private boolean mScreenOn;
 282    private HashSet<String> mSePackages = new HashSet<String>();
 283
 284    // fields below are final after onCreate()
 285    Context mContext;
 286    private NativeNfcManager mManager;
 287    private SharedPreferences mPrefs;
 288    private SharedPreferences.Editor mPrefsEditor;
 289    private PowerManager.WakeLock mWakeLock;
 290    private IActivityManager mIActivityManager;
 291    NdefPushClient mNdefPushClient;
 292    NdefPushServer mNdefPushServer;
 293    RegisteredComponentCache mTechListFilters;
 294
 295    private static NfcService sService;
 296
 297    public static void enforceAdminPerm(Context context) {
 298        int admin = context.checkCallingOrSelfPermission(ADMIN_PERM);
 299        int nfcee = context.checkCallingOrSelfPermission(NFCEE_ADMIN_PERM);
 300        if (admin != PackageManager.PERMISSION_GRANTED
 301                && nfcee != PackageManager.PERMISSION_GRANTED) {
 302            throw new SecurityException(ADMIN_PERM_ERROR);
 303        }
 304    }
 305
 306    public static void enforceNfceeAdminPerm(Context context) {
 307        context.enforceCallingOrSelfPermission(NFCEE_ADMIN_PERM, NFCEE_ADMIN_PERM_ERROR);
 308    }
 309
 310    public static NfcService getInstance() {
 311        return sService;
 312    }
 313
 314    @Override
 315    public void onCreate() {
 316        super.onCreate();
 317
 318        Log.i(TAG, "Starting NFC service");
 319
 320        sService = this;
 321
 322        mContext = this;
 323        mManager = new NativeNfcManager(mContext, this);
 324        mManager.initializeNativeStructure();
 325
 326        mNdefPushClient = new NdefPushClient(this);
 327        mNdefPushServer = new NdefPushServer();
 328
 329        mTechListFilters = new RegisteredComponentCache(this,
 330                NfcAdapter.ACTION_TECH_DISCOVERED, NfcAdapter.ACTION_TECH_DISCOVERED);
 331
 332        mSecureElement = new NativeNfcSecureElement();
 333        mEeRoutingState = ROUTE_OFF;
 334
 335        mPrefs = mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE);
 336        mPrefsEditor = mPrefs.edit();
 337
 338        mIsNfcEnabled = false;  // real preference read later
 339
 340        PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
 341        mScreenOn = pm.isScreenOn();
 342        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "NfcService");
 343
 344        mIActivityManager = ActivityManagerNative.getDefault();
 345
 346        ServiceManager.addService(SERVICE_NAME, mNfcAdapter);
 347
 348        IntentFilter filter = new IntentFilter(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION);
 349        filter.addAction(Intent.ACTION_SCREEN_OFF);
 350        filter.addAction(Intent.ACTION_SCREEN_ON);
 351        filter.addAction(ACTION_MASTER_CLEAR_NOTIFICATION);
 352        mContext.registerReceiver(mReceiver, filter);
 353
 354        filter = new IntentFilter();
 355        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
 356        filter.addDataScheme("package");
 357
 358        mContext.registerReceiver(mReceiver, filter);
 359
 360        Thread t = new Thread() {
 361            @Override
 362            public void run() {
 363                Log.d(TAG,"checking on firmware download");
 364                boolean nfc_on = mPrefs.getBoolean(PREF_NFC_ON, NFC_ON_DEFAULT);
 365                if (nfc_on) {
 366                    Log.d(TAG,"NFC is on. Doing normal stuff");
 367                    _enable(false, true);
 368                } else {
 369                    Log.d(TAG,"NFC is off.  Checking firmware version");
 370                    _maybeUpdateFirmware();
 371                }
 372                resetSeOnFirstBoot();
 373            }
 374        };
 375        t.start();
 376    }
 377
 378    @Override
 379    public void onTerminate() {
 380        super.onTerminate();
 381        // NFC application is persistent, it should not be destroyed by framework
 382        Log.wtf(TAG, "NFC service is under attack!");
 383    }
 384
 385    private final INfcAdapter.Stub mNfcAdapter = new INfcAdapter.Stub() {
 386        /** Protected by "this" */
 387        NdefMessage mLocalMessage = null;
 388
 389        @Override
 390        public boolean enable() throws RemoteException {
 391            NfcService.enforceAdminPerm(mContext);
 392
 393            boolean isSuccess = false;
 394            boolean previouslyEnabled = isEnabled();
 395            if (!previouslyEnabled) {
 396                reset();
 397                isSuccess = _enable(previouslyEnabled, true);
 398            }
 399            return isSuccess;
 400        }
 401
 402        @Override
 403        public boolean disable() throws RemoteException {
 404            boolean isSuccess = false;
 405            NfcService.enforceAdminPerm(mContext);
 406            boolean previouslyEnabled = isEnabled();
 407            if (DBG) Log.d(TAG, "Disabling NFC.  previous=" + previouslyEnabled);
 408
 409            if (previouslyEnabled) {
 410                isSuccess = _disable(previouslyEnabled, true);
 411            }
 412            return isSuccess;
 413        }
 414
 415        @Override
 416        public void enableForegroundDispatch(ComponentName activity, PendingIntent intent,
 417                IntentFilter[] filters, TechListParcel techListsParcel) {
 418            // Permission check
 419            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
 420
 421            // Argument validation
 422            if (activity == null || intent == null) {
 423                throw new IllegalArgumentException();
 424            }
 425
 426            // Validate the IntentFilters
 427            if (filters != null) {
 428                if (filters.length == 0) {
 429                    filters = null;
 430                } else {
 431                    for (IntentFilter filter : filters) {
 432                        if (filter == null) {
 433                            throw new IllegalArgumentException("null IntentFilter");
 434                        }
 435                    }
 436                }
 437            }
 438
 439            // Validate the tech lists
 440            String[][] techLists = null;
 441            if (techListsParcel != null) {
 442                techLists = techListsParcel.getTechLists();
 443            }
 444
 445            synchronized (this) {
 446                if (mDispatchOverrideIntent != null) {
 447                    Log.e(TAG, "Replacing active dispatch overrides");
 448                }
 449                mDispatchOverrideIntent = intent;
 450                mDispatchOverrideFilters = filters;
 451                mDispatchOverrideTechLists = techLists;
 452            }
 453        }
 454
 455        @Override
 456        public void disableForegroundDispatch(ComponentName activity) {
 457            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
 458            synchronized (this) {
 459                if (mDispatchOverrideIntent == null) {
 460                    Log.e(TAG, "No active foreground dispatching");
 461                }
 462                mDispatchOverrideIntent = null;
 463                mDispatchOverrideFilters = null;
 464            }
 465        }
 466
 467        @Override
 468        public void enableForegroundNdefPush(ComponentName activity, NdefMessage msg) {
 469            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
 470            if (activity == null || msg == null) {
 471                throw new IllegalArgumentException();
 472            }
 473            if (mNdefPushClient.setForegroundMessage(msg)) {
 474                Log.e(TAG, "Replacing active NDEF push message");
 475            }
 476        }
 477
 478        @Override
 479        public void disableForegroundNdefPush(ComponentName activity) {
 480            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
 481            if (!mNdefPushClient.setForegroundMessage(null)) {
 482                Log.e(TAG, "No active foreground NDEF push message");
 483            }
 484        }
 485
 486        @Override
 487        public int createLlcpConnectionlessSocket(int sap) throws RemoteException {
 488            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
 489
 490            // Check if NFC is enabled
 491            if (!mIsNfcEnabled) {
 492                return ErrorCodes.ERROR_NOT_INITIALIZED;
 493            }
 494
 495            /* Check SAP is not already used */
 496
 497            /* Store the socket handle */
 498            int sockeHandle = mGeneratedSocketHandle;
 499            NativeLlcpConnectionlessSocket socket;
 500
 501            socket = mManager.doCreateLlcpConnectionlessSocket(sap);
 502            if (socket != null) {
 503                synchronized(NfcService.this) {
 504                    /* update socket handle generation */
 505                    mGeneratedSocketHandle++;
 506
 507                    /* Add the socket into the socket map */
 508                    mSocketMap.put(mGeneratedSocketHandle, socket);
 509                   return mGeneratedSocketHandle;
 510                }
 511            } else {
 512                /* Get Error Status */
 513                int errorStatus = mManager.doGetLastError();
 514
 515                switch (errorStatus) {
 516                    case ErrorCodes.ERROR_BUFFER_TO_SMALL:
 517                        return ErrorCodes.ERROR_BUFFER_TO_SMALL;
 518                    case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES:
 519                        return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES;
 520                    default:
 521                        return ErrorCodes.ERROR_SOCKET_CREATION;
 522                }
 523            }
 524        }
 525
 526        @Override
 527        public int createLlcpServiceSocket(int sap, String sn, int miu, int rw, int linearBufferLength)
 528                throws RemoteException {
 529            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
 530
 531            // Check if NFC is enabled
 532            if (!mIsNfcEnabled) {
 533                return ErrorCodes.ERROR_NOT_INITIALIZED;
 534            }
 535
 536            NativeLlcpServiceSocket socket;
 537
 538            socket = mManager.doCreateLlcpServiceSocket(sap, sn, miu, rw, linearBufferLength);
 539            if (socket != null) {
 540                synchronized(NfcService.this) {
 541                    /* update socket handle generation */
 542                    mGeneratedSocketHandle++;
 543
 544                    /* Add the socket into the socket map */
 545                    mSocketMap.put(mGeneratedSocketHandle, socket);
 546                   return mGeneratedSocketHandle;
 547                }
 548            } else {
 549                /* Get Error Status */
 550                int errorStatus = mManager.doGetLastError();
 551
 552                switch (errorStatus) {
 553                    case ErrorCodes.ERROR_BUFFER_TO_SMALL:
 554                        return ErrorCodes.ERROR_BUFFER_TO_SMALL;
 555                    case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES:
 556                        return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES;
 557                    default:
 558                        return ErrorCodes.ERROR_SOCKET_CREATION;
 559                }
 560            }
 561        }
 562
 563        @Override
 564        public int createLlcpSocket(int sap, int miu, int rw, int linearBufferLength)
 565                throws RemoteException {
 566            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
 567
 568            // Check if NFC is enabled
 569            if (!mIsNfcEnabled) {
 570                return ErrorCodes.ERROR_NOT_INITIALIZED;
 571            }
 572
 573            if (DBG) Log.d(TAG, "creating llcp socket");
 574            NativeLlcpSocket socket;
 575
 576            socket = mManager.doCreateLlcpSocket(sap, miu, rw, linearBufferLength);
 577
 578            if (socket != null) {
 579                synchronized(NfcService.this) {
 580                    /* update socket handle generation */
 581                    mGeneratedSocketHandle++;
 582
 583                    /* Add the socket into the socket map */
 584                    mSocketMap.put(mGeneratedSocketHandle, socket);
 585                   return mGeneratedSocketHandle;
 586                }
 587            } else {
 588                /* Get Error Status */
 589                int errorStatus = mManager.doGetLastError();
 590
 591                Log.d(TAG, "failed to create llcp socket: " + ErrorCodes.asString(errorStatus));
 592
 593                switch (errorStatus) {
 594                    case ErrorCodes.ERROR_BUFFER_TO_SMALL:
 595                        return ErrorCodes.ERROR_BUFFER_TO_SMALL;
 596                    case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES:
 597                        return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES;
 598                    default:
 599                        return ErrorCodes.ERROR_SOCKET_CREATION;
 600                }
 601            }
 602        }
 603
 604        @Override
 605        public ILlcpConnectionlessSocket getLlcpConnectionlessInterface() throws RemoteException {
 606            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
 607            return mLlcpConnectionlessSocketService;
 608        }
 609
 610        @Override
 611        public ILlcpSocket getLlcpInterface() throws RemoteException {
 612            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
 613            return mLlcpSocket;
 614        }
 615
 616        @Override
 617        public ILlcpServiceSocket getLlcpServiceInterface() throws RemoteException {
 618            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
 619            return mLlcpServerSocketService;
 620        }
 621
 622        @Override
 623        public INfcTag getNfcTagInterface() throws RemoteException {
 624            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
 625            return mNfcTagService;
 626        }
 627
 628        @Override
 629        public IP2pInitiator getP2pInitiatorInterface() throws RemoteException {
 630            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
 631            return mP2pInitiatorService;
 632        }
 633
 634        @Override
 635        public IP2pTarget getP2pTargetInterface() throws RemoteException {
 636            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
 637            return mP2pTargetService;
 638        }
 639
 640        @Override
 641        public INfcAdapterExtras getNfcAdapterExtrasInterface() {
 642            NfcService.enforceNfceeAdminPerm(mContext);
 643            return mExtrasService;
 644        }
 645
 646        @Override
 647        public String getProperties(String param) throws RemoteException {
 648            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
 649
 650            if (param == null) {
 651                return null;
 652            }
 653
 654            if (param.equals(PROPERTY_LLCP_LTO_VALUE)) {
 655                return Integer.toString(mPrefs.getInt(PREF_LLCP_LTO, LLCP_LTO_DEFAULT));
 656            } else if (param.equals(PROPERTY_LLCP_MIU_VALUE)) {
 657                return Integer.toString(mPrefs.getInt(PREF_LLCP_MIU, LLCP_MIU_DEFAULT));
 658            } else if (param.equals(PROPERTY_LLCP_WKS_VALUE)) {
 659                return Integer.toString(mPrefs.getInt(PREF_LLCP_WKS, LLCP_WKS_DEFAULT));
 660            } else if (param.equals(PROPERTY_LLCP_OPT_VALUE)) {
 661                return Integer.toString(mPrefs.getInt(PREF_LLCP_OPT, LLCP_OPT_DEFAULT));
 662            } else if (param.equals(PROPERTY_NFC_DISCOVERY_A_VALUE)) {
 663                return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_A, DISCOVERY_A_DEFAULT));
 664            } else if (param.equals(PROPERTY_NFC_DISCOVERY_B_VALUE)) {
 665                return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_B, DISCOVERY_B_DEFAULT));
 666            } else if (param.equals(PROPERTY_NFC_DISCOVERY_F_VALUE)) {
 667                return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_F, DISCOVERY_F_DEFAULT));
 668            } else if (param.equals(PROPERTY_NFC_DISCOVERY_NFCIP_VALUE)) {
 669                return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_NFCIP, DISCOVERY_NFCIP_DEFAULT));
 670            } else if (param.equals(PROPERTY_NFC_DISCOVERY_15693_VALUE)) {
 671                return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_15693, DISCOVERY_15693_DEFAULT));
 672            } else {
 673                return "Unknown property";
 674            }
 675        }
 676
 677        @Override
 678        public boolean isEnabled() throws RemoteException {
 679            return mIsNfcEnabled;
 680        }
 681
 682        @Override
 683        public int setProperties(String param, String value) throws RemoteException {
 684            NfcService.enforceAdminPerm(mContext);
 685
 686            if (isEnabled()) {
 687                return ErrorCodes.ERROR_NFC_ON;
 688            }
 689
 690            int val;
 691
 692            /* Check params validity */
 693            if (param == null || value == null) {
 694                return ErrorCodes.ERROR_INVALID_PARAM;
 695            }
 696
 697            if (param.equals(PROPERTY_LLCP_LTO_VALUE)) {
 698                val = Integer.parseInt(value);
 699
 700                /* Check params */
 701                if (val > LLCP_LTO_MAX)
 702                    return ErrorCodes.ERROR_INVALID_PARAM;
 703
 704                /* Store value */
 705                mPrefsEditor.putInt(PREF_LLCP_LTO, val);
 706                mPrefsEditor.apply();
 707
 708                /* Update JNI */
 709                mManager.doSetProperties(PROPERTY_LLCP_LTO, val);
 710
 711            } else if (param.equals(PROPERTY_LLCP_MIU_VALUE)) {
 712                val = Integer.parseInt(value);
 713
 714                /* Check params */
 715                if ((val < LLCP_MIU_DEFAULT) || (val > LLCP_MIU_MAX))
 716                    return ErrorCodes.ERROR_INVALID_PARAM;
 717
 718                /* Store value */
 719                mPrefsEditor.putInt(PREF_LLCP_MIU, val);
 720                mPrefsEditor.apply();
 721
 722                /* Update JNI */
 723                mManager.doSetProperties(PROPERTY_LLCP_MIU, val);
 724
 725            } else if (param.equals(PROPERTY_LLCP_WKS_VALUE)) {
 726                val = Integer.parseInt(value);
 727
 728                /* Check params */
 729                if (val > LLCP_WKS_MAX)
 730                    return ErrorCodes.ERROR_INVALID_PARAM;
 731
 732                /* Store value */
 733                mPrefsEditor.putInt(PREF_LLCP_WKS, val);
 734                mPrefsEditor.apply();
 735
 736                /* Update JNI */
 737                mManager.doSetProperties(PROPERTY_LLCP_WKS, val);
 738
 739            } else if (param.equals(PROPERTY_LLCP_OPT_VALUE)) {
 740                val = Integer.parseInt(value);
 741
 742                /* Check params */
 743                if (val > LLCP_OPT_MAX)
 744                    return ErrorCodes.ERROR_INVALID_PARAM;
 745
 746                /* Store value */
 747                mPrefsEditor.putInt(PREF_LLCP_OPT, val);
 748                mPrefsEditor.apply();
 749
 750                /* Update JNI */
 751                mManager.doSetProperties(PROPERTY_LLCP_OPT, val);
 752
 753            } else if (param.equals(PROPERTY_NFC_DISCOVERY_A_VALUE)) {
 754                boolean b = Boolean.parseBoolean(value);
 755
 756                /* Store value */
 757                mPrefsEditor.putBoolean(PREF_DISCOVERY_A, b);
 758                mPrefsEditor.apply();
 759
 760                /* Update JNI */
 761                mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_A, b ? 1 : 0);
 762
 763            } else if (param.equals(PROPERTY_NFC_DISCOVERY_B_VALUE)) {
 764                boolean b = Boolean.parseBoolean(value);
 765
 766                /* Store value */
 767                mPrefsEditor.putBoolean(PREF_DISCOVERY_B, b);
 768                mPrefsEditor.apply();
 769
 770                /* Update JNI */
 771                mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_B, b ? 1 : 0);
 772
 773            } else if (param.equals(PROPERTY_NFC_DISCOVERY_F_VALUE)) {
 774                boolean b = Boolean.parseBoolean(value);
 775
 776                /* Store value */
 777                mPrefsEditor.putBoolean(PREF_DISCOVERY_F, b);
 778                mPrefsEditor.apply();
 779
 780                /* Update JNI */
 781                mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_F, b ? 1 : 0);
 782
 783            } else if (param.equals(PROPERTY_NFC_DISCOVERY_15693_VALUE)) {
 784                boolean b = Boolean.parseBoolean(value);
 785
 786                /* Store value */
 787                mPrefsEditor.putBoolean(PREF_DISCOVERY_15693, b);
 788                mPrefsEditor.apply();
 789
 790                /* Update JNI */
 791                mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_15693, b ? 1 : 0);
 792
 793            } else if (param.equals(PROPERTY_NFC_DISCOVERY_NFCIP_VALUE)) {
 794                boolean b = Boolean.parseBoolean(value);
 795
 796                /* Store value */
 797                mPrefsEditor.putBoolean(PREF_DISCOVERY_NFCIP, b);
 798                mPrefsEditor.apply();
 799
 800                /* Update JNI */
 801                mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_NFCIP, b ? 1 : 0);
 802
 803            } else {
 804                return ErrorCodes.ERROR_INVALID_PARAM;
 805            }
 806
 807            return ErrorCodes.SUCCESS;
 808        }
 809
 810        @Override
 811        public NdefMessage localGet() throws RemoteException {
 812            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
 813
 814            synchronized (this) {
 815                return mLocalMessage;
 816            }
 817        }
 818
 819        @Override
 820        public void localSet(NdefMessage message) throws RemoteException {
 821            NfcService.enforceAdminPerm(mContext);
 822
 823            synchronized (this) {
 824                mLocalMessage = message;
 825                Context context = NfcService.this.getApplicationContext();
 826
 827                // Send a message to the UI thread to show or hide the icon so the requests are
 828                // serialized and the icon can't get out of sync with reality.
 829                if (message != null) {
 830                    FileOutputStream out = null;
 831
 832                    try {
 833                        out = context.openFileOutput(MY_TAG_FILE_NAME, Context.MODE_PRIVATE);
 834                        byte[] bytes = message.toByteArray();
 835                        if (bytes.length == 0) {
 836                            Log.w(TAG, "Setting a empty mytag");
 837                        }
 838
 839                        out.write(bytes);
 840                    } catch (IOException e) {
 841                        Log.e(TAG, "Could not write mytag file", e);
 842                    } finally {
 843                        try {
 844                            if (out != null) {
 845                                out.flush();
 846                                out.close();
 847                            }
 848                        } catch (IOException e) {
 849                            // Ignore
 850                        }
 851                    }
 852
 853                    // Only show the icon if NFC is enabled.
 854                    if (mIsNfcEnabled) {
 855                        sendMessage(MSG_SHOW_MY_TAG_ICON, null);
 856                    }
 857                } else {
 858                    context.deleteFile(MY_TAG_FILE_NAME);
 859                    sendMessage(MSG_HIDE_MY_TAG_ICON, null);
 860                }
 861            }
 862        }
 863    };
 864
 865    private final ILlcpSocket mLlcpSocket = new ILlcpSocket.Stub() {
 866
 867        private NativeLlcpSocket findSocket(int nativeHandle) {
 868            Object socket = NfcService.this.findSocket(nativeHandle);
 869            if (!(socket instanceof NativeLlcpSocket)) {
 870                return null;
 871            }
 872            return (NativeLlcpSocket) socket;
 873        }
 874
 875        @Override
 876        public int close(int nativeHandle) throws RemoteException {
 877            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
 878
 879            NativeLlcpSocket socket = null;
 880
 881            // Check if NFC is enabled
 882            if (!mIsNfcEnabled) {
 883                return ErrorCodes.ERROR_NOT_INITIALIZED;
 884            }
 885
 886            /* find the socket in the hmap */
 887            socket = findSocket(nativeHandle);
 888            if (socket != null) {
 889                socket.doClose();
 890                /* Remove the socket closed from the hmap */
 891                RemoveSocket(nativeHandle);
 892                return ErrorCodes.SUCCESS;
 893            } else {
 894                return ErrorCodes.ERROR_IO;
 895            }
 896        }
 897
 898        @Override
 899        public int connect(int nativeHandle, int sap) throws RemoteException {
 900            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
 901
 902            NativeLlcpSocket socket = null;
 903            boolean isSuccess = false;
 904
 905            // Check if NFC is enabled
 906            if (!mIsNfcEnabled) {
 907                return ErrorCodes.ERROR_NOT_INITIALIZED;
 908            }
 909
 910            /* find the socket in the hmap */
 911            socket = findSocket(nativeHandle);
 912            if (socket != null) {
 913                isSuccess = socket.doConnect(sap);
 914                if (isSuccess) {
 915                    return ErrorCodes.SUCCESS;
 916                } else {
 917                    return ErrorCodes.ERROR_IO;
 918                }
 919            } else {
 920                return ErrorCodes.ERROR_IO;
 921            }
 922
 923        }
 924
 925        @Override
 926        public int connectByName(int nativeHandle, String sn) throws RemoteException {
 927            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
 928
 929            NativeLlcpSocket socket = null;
 930            boolean isSuccess = false;
 931
 932            // Check if NFC is enabled
 933            if (!mIsNfcEnabled) {
 934                return ErrorCodes.ERROR_NOT_INITIALIZED;
 935            }
 936
 937            /* find the socket in the hmap */
 938            socket = findSocket(nativeHandle);
 939            if (socket != null) {
 940                isSuccess = socket.doConnectBy(sn);
 941                if (isSuccess) {
 942                    return ErrorCodes.SUCCESS;
 943                } else {
 944                    return ErrorCodes.ERROR_IO;
 945                }
 946            } else {
 947                return ErrorCodes.ERROR_IO;
 948            }
 949
 950        }
 951
 952        @Override
 953        public int getLocalSap(int nativeHandle) throws RemoteException {
 954            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
 955
 956            NativeLlcpSocket socket = null;
 957
 958            // Check if NFC is enabled
 959            if (!mIsNfcEnabled) {
 960                return ErrorCodes.ERROR_NOT_INITIALIZED;
 961            }
 962
 963            /* find the socket in the hmap */
 964            socket = findSocket(nativeHandle);
 965            if (socket != null) {
 966                return socket.getSap();
 967            } else {
 968                return 0;
 969            }
 970        }
 971
 972        @Override
 973        public int getLocalSocketMiu(int nativeHandle) throws RemoteException {
 974            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
 975
 976            NativeLlcpSocket socket = null;
 977
 978            // Check if NFC is enabled
 979            if (!mIsNfcEnabled) {
 980                return ErrorCodes.ERROR_NOT_INITIALIZED;
 981            }
 982
 983            /* find the socket in the hmap */
 984            socket = findSocket(nativeHandle);
 985            if (socket != null) {
 986                return socket.getMiu();
 987            } else {
 988                return 0;
 989            }
 990        }
 991
 992        @Override
 993        public int getLocalSocketRw(int nativeHandle) throws RemoteException {
 994            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
 995
 996            NativeLlcpSocket socket = null;
 997
 998            // Check if NFC is enabled
 999            if (!mIsNfcEnabled) {
1000                return ErrorCodes.ERROR_NOT_INITIALIZED;
1001            }
1002
1003            /* find the socket in the hmap */
1004            socket = findSocket(nativeHandle);
1005            if (socket != null) {
1006                return socket.getRw();
1007            } else {
1008                return 0;
1009            }
1010        }
1011
1012        @Override
1013        public int getRemoteSocketMiu(int nativeHandle) throws RemoteException {
1014            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1015
1016            NativeLlcpSocket socket = null;
1017
1018            // Check if NFC is enabled
1019            if (!mIsNfcEnabled) {
1020                return ErrorCodes.ERROR_NOT_INITIALIZED;
1021            }
1022
1023            /* find the socket in the hmap */
1024            socket = findSocket(nativeHandle);
1025            if (socket != null) {
1026                if (socket.doGetRemoteSocketMiu() != 0) {
1027                    return socket.doGetRemoteSocketMiu();
1028                } else {
1029                    return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED;
1030                }
1031            } else {
1032                return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED;
1033            }
1034        }
1035
1036        @Override
1037        public int getRemoteSocketRw(int nativeHandle) throws RemoteException {
1038            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1039
1040            NativeLlcpSocket socket = null;
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 = findSocket(nativeHandle);
1049            if (socket != null) {
1050                if (socket.doGetRemoteSocketRw() != 0) {
1051                    return socket.doGetRemoteSocketRw();
1052                } else {
1053                    return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED;
1054                }
1055            } else {
1056                return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED;
1057            }
1058        }
1059
1060        @Override
1061        public int receive(int nativeHandle, byte[] receiveBuffer) throws RemoteException {
1062            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1063
1064            NativeLlcpSocket socket = null;
1065
1066            // Check if NFC is enabled
1067            if (!mIsNfcEnabled) {
1068                return ErrorCodes.ERROR_NOT_INITIALIZED;
1069            }
1070
1071            /* find the socket in the hmap */
1072            socket = findSocket(nativeHandle);
1073            if (socket != null) {
1074                return socket.doReceive(receiveBuffer);
1075            } else {
1076                return 0;
1077            }
1078        }
1079
1080        @Override
1081        public int send(int nativeHandle, byte[] data) throws RemoteException {
1082            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1083
1084            NativeLlcpSocket socket = null;
1085            boolean isSuccess = false;
1086
1087            // Check if NFC is enabled
1088            if (!mIsNfcEnabled) {
1089                return ErrorCodes.ERROR_NOT_INITIALIZED;
1090            }
1091
1092            /* find the socket in the hmap */
1093            socket = findSocket(nativeHandle);
1094            if (socket != null) {
1095                isSuccess = socket.doSend(data);
1096                if (isSuccess) {
1097                    return ErrorCodes.SUCCESS;
1098                } else {
1099                    return ErrorCodes.ERROR_IO;
1100                }
1101            } else {
1102                return ErrorCodes.ERROR_IO;
1103            }
1104        }
1105    };
1106
1107    private final ILlcpServiceSocket mLlcpServerSocketService = new ILlcpServiceSocket.Stub() {
1108
1109        private NativeLlcpServiceSocket findSocket(int nativeHandle) {
1110            Object socket = NfcService.this.findSocket(nativeHandle);
1111            if (!(socket instanceof NativeLlcpServiceSocket)) {
1112                return null;
1113            }
1114            return (NativeLlcpServiceSocket) socket;
1115        }
1116
1117        @Override
1118        public int accept(int nativeHandle) throws RemoteException {
1119            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1120
1121            NativeLlcpServiceSocket socket = null;
1122            NativeLlcpSocket clientSocket = null;
1123
1124            // Check if NFC is enabled
1125            if (!mIsNfcEnabled) {
1126                return ErrorCodes.ERROR_NOT_INITIALIZED;
1127            }
1128
1129                /* find the socket in the hmap */
1130                socket = findSocket(nativeHandle);
1131                if (socket != null) {
1132                    clientSocket = socket.doAccept(socket.getMiu(),
1133                            socket.getRw(), socket.getLinearBufferLength());
1134                    if (clientSocket != null) {
1135                        /* Add the socket into the socket map */
1136                        synchronized(this) {
1137                            mGeneratedSocketHandle++;
1138                            mSocketMap.put(mGeneratedSocketHandle, clientSocket);
1139                            return mGeneratedSocketHandle;
1140                        }
1141                    } else {
1142                        return ErrorCodes.ERROR_IO;
1143                    }
1144                } else {
1145                    return ErrorCodes.ERROR_IO;
1146                }
1147        }
1148
1149        @Override
1150        public void close(int nativeHandle) throws RemoteException {
1151            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1152
1153            NativeLlcpServiceSocket socket = null;
1154
1155            // Check if NFC is enabled
1156            if (!mIsNfcEnabled) {
1157                return;
1158            }
1159
1160            /* find the socket in the hmap */
1161            socket = findSocket(nativeHandle);
1162            if (socket != null) {
1163                socket.doClose();
1164                synchronized (this) {
1165                    /* Remove the socket closed from the hmap */
1166                    RemoveSocket(nativeHandle);
1167                }
1168            }
1169        }
1170    };
1171
1172    private final ILlcpConnectionlessSocket mLlcpConnectionlessSocketService = new ILlcpConnectionlessSocket.Stub() {
1173
1174        private NativeLlcpConnectionlessSocket findSocket(int nativeHandle) {
1175            Object socket = NfcService.this.findSocket(nativeHandle);
1176            if (!(socket instanceof NativeLlcpConnectionlessSocket)) {
1177                return null;
1178            }
1179            return (NativeLlcpConnectionlessSocket) socket;
1180        }
1181
1182        @Override
1183        public void close(int nativeHandle) throws RemoteException {
1184            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1185
1186            NativeLlcpConnectionlessSocket socket = null;
1187
1188            // Check if NFC is enabled
1189            if (!mIsNfcEnabled) {
1190                return;
1191            }
1192
1193            /* find the socket in the hmap */
1194            socket = findSocket(nativeHandle);
1195            if (socket != null) {
1196                socket.doClose();
1197                /* Remove the socket closed from the hmap */
1198                RemoveSocket(nativeHandle);
1199            }
1200        }
1201
1202        @Override
1203        public int getSap(int nativeHandle) throws RemoteException {
1204            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1205
1206            NativeLlcpConnectionlessSocket socket = null;
1207
1208            // Check if NFC is enabled
1209            if (!mIsNfcEnabled) {
1210                return ErrorCodes.ERROR_NOT_INITIALIZED;
1211            }
1212
1213            /* find the socket in the hmap */
1214            socket = findSocket(nativeHandle);
1215            if (socket != null) {
1216                return socket.getSap();
1217            } else {
1218                return 0;
1219            }
1220        }
1221
1222        @Override
1223        public LlcpPacket receiveFrom(int nativeHandle) throws RemoteException {
1224            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1225
1226            NativeLlcpConnectionlessSocket socket = null;
1227            LlcpPacket packet;
1228
1229            // Check if NFC is enabled
1230            if (!mIsNfcEnabled) {
1231                return null;
1232            }
1233
1234            /* find the socket in the hmap */
1235            socket = findSocket(nativeHandle);
1236            if (socket != null) {
1237                packet = socket.doReceiveFrom(socket.getLinkMiu());
1238                if (packet != null) {
1239                    return packet;
1240                }
1241                return null;
1242            } else {
1243                return null;
1244            }
1245        }
1246
1247        @Override
1248        public int sendTo(int nativeHandle, LlcpPacket packet) throws RemoteException {
1249            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1250
1251            NativeLlcpConnectionlessSocket socket = null;
1252            boolean isSuccess = false;
1253
1254            // Check if NFC is enabled
1255            if (!mIsNfcEnabled) {
1256                return ErrorCodes.ERROR_NOT_INITIALIZED;
1257            }
1258
1259            /* find the socket in the hmap */
1260            socket = findSocket(nativeHandle);
1261            if (socket != null) {
1262                isSuccess = socket.doSendTo(packet.getRemoteSap(), packet.getDataBuffer());
1263                if (isSuccess) {
1264                    return ErrorCodes.SUCCESS;
1265                } else {
1266                    return ErrorCodes.ERROR_IO;
1267                }
1268            } else {
1269                return ErrorCodes.ERROR_IO;
1270            }
1271        }
1272    };
1273
1274    private final INfcTag mNfcTagService = new INfcTag.Stub() {
1275
1276        @Override
1277        public int close(int nativeHandle) throws RemoteException {
1278            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1279
1280            NativeNfcTag tag = null;
1281
1282            // Check if NFC is enabled
1283            if (!mIsNfcEnabled) {
1284                return ErrorCodes.ERROR_NOT_INITIALIZED;
1285            }
1286
1287            /* find the tag in the hmap */
1288            tag = (NativeNfcTag) findObject(nativeHandle);
1289            if (tag != null) {
1290                /* Remove the device from the hmap */
1291                unregisterObject(nativeHandle);
1292                tag.disconnect();
1293                return ErrorCodes.SUCCESS;
1294            }
1295            /* Restart polling loop for notification */
1296            applyRouting();
1297            return ErrorCodes.ERROR_DISCONNECT;
1298        }
1299
1300        @Override
1301        public int connect(int nativeHandle, int technology) throws RemoteException {
1302            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1303
1304            NativeNfcTag tag = null;
1305
1306            // Check if NFC is enabled
1307            if (!mIsNfcEnabled) {
1308                return ErrorCodes.ERROR_NOT_INITIALIZED;
1309            }
1310
1311            /* find the tag in the hmap */
1312            tag = (NativeNfcTag) findObject(nativeHandle);
1313            if (tag == null) {
1314                return ErrorCodes.ERROR_DISCONNECT;
1315            }
1316
1317            // Note that on most tags, all technologies are behind a single
1318            // handle. This means that the connect at the lower levels
1319            // will do nothing, as the tag is already connected to that handle.
1320            if (tag.connect(technology) == 0) {
1321                return ErrorCodes.SUCCESS;
1322            } else {
1323                return ErrorCodes.ERROR_DISCONNECT;
1324            }
1325        }
1326
1327        @Override
1328        public int reconnect(int nativeHandle) throws RemoteException {
1329            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1330
1331            NativeNfcTag tag = null;
1332
1333            // Check if NFC is enabled
1334            if (!mIsNfcEnabled) {
1335                return ErrorCodes.ERROR_NOT_INITIALIZED;
1336            }
1337
1338            /* find the tag in the hmap */
1339            tag = (NativeNfcTag) findObject(nativeHandle);
1340            if (tag != null) {
1341                if (tag.reconnect() == 0) {
1342                    return ErrorCodes.SUCCESS;
1343                } else {
1344                    return ErrorCodes.ERROR_DISCONNECT;
1345                }
1346            }
1347            return ErrorCodes.ERROR_DISCONNECT;
1348        }
1349
1350        @Override
1351        public int[] getTechList(int nativeHandle) throws RemoteException {
1352            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1353
1354            // Check if NFC is enabled
1355            if (!mIsNfcEnabled) {
1356                return null;
1357            }
1358
1359            /* find the tag in the hmap */
1360            NativeNfcTag tag = (NativeNfcTag) findObject(nativeHandle);
1361            if (tag != null) {
1362                return tag.getTechList();
1363        

Large files files are truncated, but you can click here to view the full file