NfcService.java revision 3ca6ffff72f4599e80f85de5ae8e7f55012f38d6
1f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly/*
2f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * Copyright (C) 2010 The Android Open Source Project
3f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly *
4f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * Licensed under the Apache License, Version 2.0 (the "License");
5f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * you may not use this file except in compliance with the License.
6f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * You may obtain a copy of the License at
7f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly *
8f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly *      http://www.apache.org/licenses/LICENSE-2.0
9f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly *
10f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * Unless required by applicable law or agreed to in writing, software
11f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * distributed under the License is distributed on an "AS IS" BASIS,
12f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * See the License for the specific language governing permissions and
14f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * limitations under the License.
15f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly */
16f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1713d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellypackage com.android.nfc;
18f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
192f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pellyimport android.app.Application;
203ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamiltonimport android.app.StatusBarManager;
21b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneauimport android.content.ActivityNotFoundException;
2213d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellyimport android.content.BroadcastReceiver;
2313d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellyimport android.content.Context;
2413d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellyimport android.content.Intent;
2513d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellyimport android.content.IntentFilter;
260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pellyimport android.content.SharedPreferences;
27f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.ErrorCodes;
28f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.FormatException;
29f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.ILlcpConnectionlessSocket;
30f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.ILlcpServiceSocket;
31f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.ILlcpSocket;
320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pellyimport android.nfc.INfcAdapter;
33f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.INfcTag;
34f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.IP2pInitiator;
35f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.IP2pTarget;
36f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.LlcpPacket;
37f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.NdefMessage;
38b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneauimport android.nfc.NdefTag;
39f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.NfcAdapter;
400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pellyimport android.nfc.Tag;
41b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneauimport android.os.Handler;
42b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneauimport android.os.Message;
43f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.os.RemoteException;
4413d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellyimport android.os.ServiceManager;
45f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.util.Log;
46f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
473ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamiltonimport java.util.HashMap;
483ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamiltonimport java.util.LinkedList;
493ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamiltonimport java.util.ListIterator;
503ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton
512f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pellypublic class NfcService extends Application {
5213d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly    static {
5313d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly        System.loadLibrary("nfc_jni");
5413d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly    }
5513d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly
56f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final String TAG = "NfcService";
57f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
58bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly    private static final String NFC_PERM = android.Manifest.permission.NFC;
59bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly    private static final String NFC_PERM_ERROR = "NFC permission required";
60bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly    private static final String ADMIN_PERM = android.Manifest.permission.WRITE_SECURE_SETTINGS;
61bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly    private static final String ADMIN_PERM_ERROR = "WRITE_SECURE_SETTINGS permission required";
62bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF = "NfcServicePrefs";
64f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_NFC_ON = "nfc_on";
660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final boolean NFC_ON_DEFAULT = true;
67f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_SECURE_ELEMENT_ON = "secure_element_on";
690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final boolean SECURE_ELEMENT_ON_DEFAULT = false;
70f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_SECURE_ELEMENT_ID = "secure_element_id";
720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int SECURE_ELEMENT_ID_DEFAULT = 0;
73f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_LLCP_LTO = "llcp_lto";
750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_LTO_DEFAULT = 150;
760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_LTO_MAX = 255;
77f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    /** Maximum Information Unit */
790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_LLCP_MIU = "llcp_miu";
800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_MIU_DEFAULT = 128;
810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_MIU_MAX = 2176;
82f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    /** Well Known Service List */
840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_LLCP_WKS = "llcp_wks";
850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_WKS_DEFAULT = 1;
860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_WKS_MAX = 15;
87f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_LLCP_OPT = "llcp_opt";
890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_OPT_DEFAULT = 0;
900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_OPT_MAX = 3;
91f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_DISCOVERY_A = "discovery_a";
930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final boolean DISCOVERY_A_DEFAULT = true;
94f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_DISCOVERY_B = "discovery_b";
960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final boolean DISCOVERY_B_DEFAULT = true;
97f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_DISCOVERY_F = "discovery_f";
990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final boolean DISCOVERY_F_DEFAULT = true;
100f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_DISCOVERY_15693 = "discovery_15693";
1020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final boolean DISCOVERY_15693_DEFAULT = true;
103f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_DISCOVERY_NFCIP = "discovery_nfcip";
1050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final boolean DISCOVERY_NFCIP_DEFAULT = true;
106f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    /** NFC Reader Discovery mode for enableDiscovery() */
1080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int DISCOVERY_MODE_READER = 0;
109f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    /** Card Emulation Discovery mode for enableDiscovery() */
1110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int DISCOVERY_MODE_CARD_EMULATION = 2;
112f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_SERVICE_SOCKET_TYPE = 0;
1140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_SOCKET_TYPE = 1;
1150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_CONNECTIONLESS_SOCKET_TYPE = 2;
1160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_SOCKET_NB_MAX = 5;  // Maximum number of socket managed
1170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_RW_MAX_VALUE = 15;  // Receive Window
118f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
119f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final int PROPERTY_LLCP_LTO = 0;
120f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final String PROPERTY_LLCP_LTO_VALUE = "llcp.lto";
1210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int PROPERTY_LLCP_MIU = 1;
122f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final String PROPERTY_LLCP_MIU_VALUE = "llcp.miu";
1230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int PROPERTY_LLCP_WKS = 2;
124f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final String PROPERTY_LLCP_WKS_VALUE = "llcp.wks";
1250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int PROPERTY_LLCP_OPT = 3;
126f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final String PROPERTY_LLCP_OPT_VALUE = "llcp.opt";
127f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final int PROPERTY_NFC_DISCOVERY_A = 4;
128f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final String PROPERTY_NFC_DISCOVERY_A_VALUE = "discovery.iso14443A";
1290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int PROPERTY_NFC_DISCOVERY_B = 5;
130f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final String PROPERTY_NFC_DISCOVERY_B_VALUE = "discovery.iso14443B";
1310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int PROPERTY_NFC_DISCOVERY_F = 6;
132f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final String PROPERTY_NFC_DISCOVERY_F_VALUE = "discovery.felica";
1330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int PROPERTY_NFC_DISCOVERY_15693 = 7;
134f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final String PROPERTY_NFC_DISCOVERY_15693_VALUE = "discovery.iso15693";
1350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int PROPERTY_NFC_DISCOVERY_NFCIP = 8;
136f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final String PROPERTY_NFC_DISCOVERY_NFCIP_VALUE = "discovery.nfcip";
137f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
138b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    static final int MSG_NDEF_TAG = 0;
139b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    static final int MSG_CARD_EMULATION = 1;
140b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    static final int MSG_LLCP_LINK_ACTIVATION = 2;
141b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    static final int MSG_LLCP_LINK_DEACTIVATED = 3;
142b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    static final int MSG_TARGET_DESELECTED = 4;
1433ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton    static final int MSG_SHOW_MY_TAG_ICON = 5;
1443ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton    static final int MSG_HIDE_MY_TAG_ICON = 6;
145b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
14674180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick    // TODO: none of these appear to be synchronized but are
14774180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick    // read/written from different threads (notably Binder threads)...
148f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private final LinkedList<RegisteredSocket> mRegisteredSocketList = new LinkedList<RegisteredSocket>();
149f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private int mLlcpLinkState = NfcAdapter.LLCP_LINK_STATE_DEACTIVATED;
150f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private int mGeneratedSocketHandle = 0;
151f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private int mNbSocketCreated = 0;
15274180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick    private volatile boolean mIsNfcEnabled = false;
153f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private int mSelectedSeId = 0;
1540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private boolean mNfcSecureElementState;
155f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private boolean mOpenPending = false;
156f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1572f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    // fields below are used in multiple threads and protected by synchronized(this)
1582f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    private final HashMap<Integer, Object> mObjectMap = new HashMap<Integer, Object>();
1592f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    private final HashMap<Integer, Object> mSocketMap = new HashMap<Integer, Object>();
1602f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    private int mTimeout = 0;
1612f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    private boolean mBootComplete = false;
16265945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly    private boolean mScreenOn;
1632f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly
1642f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    // fields below are final after onCreate()
1650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private Context mContext;
1660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private NativeNfcManager mManager;
1670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private SharedPreferences mPrefs;
1680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private SharedPreferences.Editor mPrefsEditor;
169f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    @Override
1710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    public void onCreate() {
1722f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly        super.onCreate();
1732f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly
1742f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly        Log.i(TAG, "Starting NFC service");
1752f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly
1760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mContext = this;
177b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        mManager = new NativeNfcManager(mContext, this);
1780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mManager.initializeNativeStructure();
17974180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick
1800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mPrefs = mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE);
1810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mPrefsEditor = mPrefs.edit();
182f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
183d6fdd3fbb880f1503d56616608e6823b51320dc3Nick Pelly        mIsNfcEnabled = false;  // real preference read later
18465945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly        mScreenOn = true;  // assume screen is on during boot
185f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        ServiceManager.addService("nfc", mNfcAdapter);
187f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        IntentFilter filter = new IntentFilter(NfcAdapter.ACTION_LLCP_LINK_STATE_CHANGED);
1890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        filter.addAction(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION);
1902f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly        filter.addAction(Intent.ACTION_BOOT_COMPLETED);
19165945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly        filter.addAction(Intent.ACTION_SCREEN_OFF);
19265945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly        filter.addAction(Intent.ACTION_SCREEN_ON);
1930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mContext.registerReceiver(mReceiver, filter);
1940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
1950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        Thread t = new Thread() {
1960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            @Override
1970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            public void run() {
1980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                boolean nfc_on = mPrefs.getBoolean(PREF_NFC_ON, NFC_ON_DEFAULT);
1990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (nfc_on) {
2000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    _enable(false);
201f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
202f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
2030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        };
2040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        t.start();
2050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    }
2060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
2070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    @Override
2082f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    public void onTerminate() {
2092f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly        super.onTerminate();
2102f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly        // NFC application is persistent, it should not be destroyed by framework
2110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        Log.wtf(TAG, "NFC service is under attack!");
2120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    }
2130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
2140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private final INfcAdapter.Stub mNfcAdapter = new INfcAdapter.Stub() {
2153ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton        /** Protected by "this" */
2163ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton        // TODO read this from permanent storage at boot time
2173ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton        NdefMessage mLocalMessage = null;
2183ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton
2190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public boolean enable() throws RemoteException {
2200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
2210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
2220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
2230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean previouslyEnabled = isEnabled();
2240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!previouslyEnabled) {
2250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                reset();
2260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                isSuccess = _enable(previouslyEnabled);
227f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
2280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return isSuccess;
229f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
230f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public boolean disable() throws RemoteException {
2320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
2330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
2340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean previouslyEnabled = isEnabled();
2350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            Log.d(TAG, "Disabling NFC.  previous=" + previouslyEnabled);
2360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
2370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (previouslyEnabled) {
2380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                isSuccess = mManager.deinitialize();
2390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                Log.d(TAG, "NFC success of deinitialize = " + isSuccess);
2400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (isSuccess) {
2410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mIsNfcEnabled = false;
2420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
243f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
2440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
2450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            updateNfcOnSetting(previouslyEnabled);
2460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
2470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return isSuccess;
248f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
249f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int createLlcpConnectionlessSocket(int sap) throws RemoteException {
251bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
252bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
253f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
254f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
255f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
256f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
257f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* Check SAP is not already used */
2590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
2600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* Check nb socket created */
2610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mNbSocketCreated < LLCP_SOCKET_NB_MAX) {
2620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store the socket handle */
2630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                int sockeHandle = mGeneratedSocketHandle;
2640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
265f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
2660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    NativeLlcpConnectionlessSocket socket;
2670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
2680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    socket = mManager.doCreateLlcpConnectionlessSocket(sap);
2690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (socket != null) {
2702f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        synchronized(NfcService.this) {
2712f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            /* Update the number of socket created */
2722f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mNbSocketCreated++;
2730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
2742f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            /* Add the socket into the socket map */
2752f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mSocketMap.put(sockeHandle, socket);
2762f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        }
2770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return sockeHandle;
278f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    } else {
2790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /*
2800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                         * socket creation error - update the socket handle
2810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                         * generation
2820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                         */
2830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        mGeneratedSocketHandle -= 1;
2840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
2850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Get Error Status */
2860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        int errorStatus = mManager.doGetLastError();
2870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
2880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        switch (errorStatus) {
2890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            case ErrorCodes.ERROR_BUFFER_TO_SMALL:
2900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_BUFFER_TO_SMALL;
2910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES:
2920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES;
2930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            default:
2940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_SOCKET_CREATION;
2950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        }
296f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    }
297f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
2980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Check SAP is not already used */
2990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (!CheckSocketSap(sap)) {
3000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_SAP_USED;
3010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
302f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
3030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    NativeLlcpConnectionlessSocket socket = new NativeLlcpConnectionlessSocket(sap);
304f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
3052f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    synchronized(NfcService.this) {
3062f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        /* Add the socket into the socket map */
3072f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mSocketMap.put(sockeHandle, socket);
3080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3092f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        /* Update the number of socket created */
3102f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mNbSocketCreated++;
3112f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    }
3120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Create new registered socket */
3130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    RegisteredSocket registeredSocket = new RegisteredSocket(
3140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            LLCP_CONNECTIONLESS_SOCKET_TYPE, sockeHandle, sap);
3150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Put this socket into a list of registered socket */
3170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mRegisteredSocketList.add(registeredSocket);
318f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
3190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* update socket handle generation */
3210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mGeneratedSocketHandle++;
3220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return sockeHandle;
3240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
325f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
3260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* No socket available */
3270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES;
328f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
3290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
330f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
331f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
3320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int createLlcpServiceSocket(int sap, String sn, int miu, int rw, int linearBufferLength)
3330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                throws RemoteException {
334bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
335bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
336f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
337f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
338f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
339f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
340f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
3410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mNbSocketCreated < LLCP_SOCKET_NB_MAX) {
3420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                int sockeHandle = mGeneratedSocketHandle;
3430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
3450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    NativeLlcpServiceSocket socket;
3460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    socket = mManager.doCreateLlcpServiceSocket(sap, sn, miu, rw, linearBufferLength);
3480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (socket != null) {
3492f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        synchronized(NfcService.this) {
3502f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            /* Update the number of socket created */
3512f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mNbSocketCreated++;
3522f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            /* Add the socket into the socket map */
3532f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mSocketMap.put(sockeHandle, socket);
3542f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        }
3550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    } else {
3560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* socket creation error - update the socket handle counter */
3570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        mGeneratedSocketHandle -= 1;
3580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Get Error Status */
3600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        int errorStatus = mManager.doGetLastError();
3610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        switch (errorStatus) {
3630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            case ErrorCodes.ERROR_BUFFER_TO_SMALL:
3640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_BUFFER_TO_SMALL;
3650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES:
3660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES;
3670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            default:
3680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_SOCKET_CREATION;
3690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        }
3700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
371f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
3720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Check SAP is not already used */
3740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (!CheckSocketSap(sap)) {
3750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_SAP_USED;
3760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
3770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Service Name */
3790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (!CheckSocketServiceName(sn)) {
3800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_SERVICE_NAME_USED;
3810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
3820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Check socket options */
3840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (!CheckSocketOptions(miu, rw, linearBufferLength)) {
3850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_SOCKET_OPTIONS;
3860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
3870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    NativeLlcpServiceSocket socket = new NativeLlcpServiceSocket(sn);
3892f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    synchronized(NfcService.this) {
3902f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        /* Add the socket into the socket map */
3912f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mSocketMap.put(sockeHandle, socket);
3920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3932f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        /* Update the number of socket created */
3942f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mNbSocketCreated++;
3952f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    }
3960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Create new registered socket */
3970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    RegisteredSocket registeredSocket = new RegisteredSocket(LLCP_SERVICE_SOCKET_TYPE,
3980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            sockeHandle, sap, sn, miu, rw, linearBufferLength);
3990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Put this socket into a list of registered socket */
4010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mRegisteredSocketList.add(registeredSocket);
402f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
4030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* update socket handle generation */
4050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mGeneratedSocketHandle += 1;
4060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                Log.d(TAG, "Llcp Service Socket Handle =" + sockeHandle);
4080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return sockeHandle;
409f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
4100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* No socket available */
4110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES;
412f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
413f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
414f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
4150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int createLlcpSocket(int sap, int miu, int rw, int linearBufferLength)
4160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                throws RemoteException {
417bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
418bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
419f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
420f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
421f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
422f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
423f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
4240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mNbSocketCreated < LLCP_SOCKET_NB_MAX) {
4250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                int sockeHandle = mGeneratedSocketHandle;
4270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
4290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    NativeLlcpSocket socket;
4300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    socket = mManager.doCreateLlcpSocket(sap, miu, rw, linearBufferLength);
4320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (socket != null) {
4342f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        synchronized(NfcService.this) {
4352f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            /* Update the number of socket created */
4362f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mNbSocketCreated++;
4372f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            /* Add the socket into the socket map */
4382f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mSocketMap.put(sockeHandle, socket);
4392f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        }
4400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    } else {
4410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /*
4420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                         * socket creation error - update the socket handle
4430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                         * generation
4440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                         */
4450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        mGeneratedSocketHandle -= 1;
4460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Get Error Status */
4480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        int errorStatus = mManager.doGetLastError();
4490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        switch (errorStatus) {
4510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            case ErrorCodes.ERROR_BUFFER_TO_SMALL:
4520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_BUFFER_TO_SMALL;
4530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES:
4540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES;
4550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            default:
4560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_SOCKET_CREATION;
4570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        }
4580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
459f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
460f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
4610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Check SAP is not already used */
4620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (!CheckSocketSap(sap)) {
4630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_SAP_USED;
4640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
465f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
4660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Check Socket options */
4670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (!CheckSocketOptions(miu, rw, linearBufferLength)) {
4680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_SOCKET_OPTIONS;
4690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
470bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
4710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    NativeLlcpSocket socket = new NativeLlcpSocket(sap, miu, rw);
4722f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    synchronized(NfcService.this) {
4732f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        /* Add the socket into the socket map */
4742f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mSocketMap.put(sockeHandle, socket);
475f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
4762f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        /* Update the number of socket created */
4772f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mNbSocketCreated++;
4782f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    }
4790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Create new registered socket */
4800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    RegisteredSocket registeredSocket = new RegisteredSocket(LLCP_SOCKET_TYPE,
4810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            sockeHandle, sap, miu, rw, linearBufferLength);
4820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Put this socket into a list of registered socket */
4840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mRegisteredSocketList.add(registeredSocket);
4850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
4860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* update socket handle generation */
4880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mGeneratedSocketHandle++;
4890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return sockeHandle;
491f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
4920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* No socket available */
4930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES;
494f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
495f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
496f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
4970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int deselectSecureElement() throws RemoteException {
4980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
499f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
500f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
501f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
502f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
503f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
504f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
5050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mSelectedSeId == 0) {
5060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NO_SE_CONNECTED;
507f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
5080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mManager.doDeselectSecureElement(mSelectedSeId);
5100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mNfcSecureElementState = false;
5110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mSelectedSeId = 0;
5120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* store preference */
5140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mPrefsEditor.putBoolean(PREF_SECURE_ELEMENT_ON, false);
5150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mPrefsEditor.putInt(PREF_SECURE_ELEMENT_ID, 0);
5162f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick            mPrefsEditor.apply();
5170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return ErrorCodes.SUCCESS;
519f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
520f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
5210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public ILlcpConnectionlessSocket getLlcpConnectionlessInterface() throws RemoteException {
522bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
5230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mLlcpConnectionlessSocketService;
5240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
525bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
5260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public ILlcpSocket getLlcpInterface() throws RemoteException {
5270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
5280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mLlcpSocket;
5290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
530f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
5310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public ILlcpServiceSocket getLlcpServiceInterface() throws RemoteException {
5320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
5330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mLlcpServerSocketService;
5340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
535f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
5360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public INfcTag getNfcTagInterface() throws RemoteException {
5370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
5380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mNfcTagService;
5390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
5400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5412f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly        public synchronized int getOpenTimeout() throws RemoteException {
5420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
5430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mTimeout;
5440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
5450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public IP2pInitiator getP2pInitiatorInterface() throws RemoteException {
5470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
5480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mP2pInitiatorService;
5490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
5500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public IP2pTarget getP2pTargetInterface() throws RemoteException {
5520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
5530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mP2pTargetService;
5540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
5550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public String getProperties(String param) throws RemoteException {
5570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
5580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (param == null) {
5600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return null;
5610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
5620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (param.equals(PROPERTY_LLCP_LTO_VALUE)) {
5640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Integer.toString(mPrefs.getInt(PREF_LLCP_LTO, LLCP_LTO_DEFAULT));
5650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_LLCP_MIU_VALUE)) {
5660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Integer.toString(mPrefs.getInt(PREF_LLCP_MIU, LLCP_MIU_DEFAULT));
5670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_LLCP_WKS_VALUE)) {
5680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Integer.toString(mPrefs.getInt(PREF_LLCP_WKS, LLCP_WKS_DEFAULT));
5690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_LLCP_OPT_VALUE)) {
5700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Integer.toString(mPrefs.getInt(PREF_LLCP_OPT, LLCP_OPT_DEFAULT));
5710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_A_VALUE)) {
5720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_A, DISCOVERY_A_DEFAULT));
5730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_B_VALUE)) {
5740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_B, DISCOVERY_B_DEFAULT));
5750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_F_VALUE)) {
5760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_F, DISCOVERY_F_DEFAULT));
5770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_NFCIP_VALUE)) {
5780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_NFCIP, DISCOVERY_NFCIP_DEFAULT));
5790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_15693_VALUE)) {
5800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_15693, DISCOVERY_15693_DEFAULT));
581f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
5820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return "Unknown property";
583f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
584f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
585f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
5860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int[] getSecureElementList() throws RemoteException {
5870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
588bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
5890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            int[] list = null;
5900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mIsNfcEnabled == true) {
5910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                list = mManager.doGetSecureElementList();
5920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
5930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return list;
5940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
5950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getSelectedSecureElement() throws RemoteException {
5970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
5980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mSelectedSeId;
6000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
6010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public boolean isEnabled() throws RemoteException {
6030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mIsNfcEnabled;
6040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
6050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public void openTagConnection(Tag tag) throws RemoteException {
607b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            // TODO: Remove obsolete code
6080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
6090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int selectSecureElement(int seId) throws RemoteException {
6110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
612f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
613f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
614f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
615f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
616f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
617f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
6180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mSelectedSeId == seId) {
6190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_SE_ALREADY_SELECTED;
6200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
6210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mSelectedSeId != 0) {
6230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_SE_CONNECTED;
6240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
6250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mSelectedSeId = seId;
6270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mManager.doSelectSecureElement(mSelectedSeId);
6280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* store */
6300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mPrefsEditor.putBoolean(PREF_SECURE_ELEMENT_ON, true);
6310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mPrefsEditor.putInt(PREF_SECURE_ELEMENT_ID, mSelectedSeId);
6322f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick            mPrefsEditor.apply();
6330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mNfcSecureElementState = true;
6350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return ErrorCodes.SUCCESS;
6370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
6390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6402f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly        public synchronized void setOpenTimeout(int timeout) throws RemoteException {
6410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
6420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mTimeout = timeout;
6430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
6440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int setProperties(String param, String value) throws RemoteException {
6460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
6470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (isEnabled()) {
6490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NFC_ON;
6500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
6510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            int val;
6530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* Check params validity */
6550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (param == null || value == null) {
6560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_INVALID_PARAM;
6570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
6580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (param.equals(PROPERTY_LLCP_LTO_VALUE)) {
6600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                val = Integer.parseInt(value);
6610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Check params */
6630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (val > LLCP_LTO_MAX)
6640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_INVALID_PARAM;
6650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
6670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putInt(PREF_LLCP_LTO, val);
6682f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
6690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
6710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_LLCP_LTO, val);
6720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_LLCP_MIU_VALUE)) {
6740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                val = Integer.parseInt(value);
6750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Check params */
6770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if ((val < LLCP_MIU_DEFAULT) || (val > LLCP_MIU_MAX))
6780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_INVALID_PARAM;
6790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
6810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putInt(PREF_LLCP_MIU, val);
6822f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
6830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
6850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_LLCP_MIU, val);
6860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_LLCP_WKS_VALUE)) {
6880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                val = Integer.parseInt(value);
6890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Check params */
6910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (val > LLCP_WKS_MAX)
6920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_INVALID_PARAM;
6930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
6950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putInt(PREF_LLCP_WKS, val);
6962f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
6970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
6990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_LLCP_WKS, val);
7000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_LLCP_OPT_VALUE)) {
7020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                val = Integer.parseInt(value);
7030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Check params */
7050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (val > LLCP_OPT_MAX)
7060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_INVALID_PARAM;
7070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
7090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putInt(PREF_LLCP_OPT, val);
7102f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
7110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
7130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_LLCP_OPT, val);
7140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_A_VALUE)) {
7160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                boolean b = Boolean.parseBoolean(value);
7170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
7190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putBoolean(PREF_DISCOVERY_A, b);
7202f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
7210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
7230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_A, b ? 1 : 0);
7240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_B_VALUE)) {
7260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                boolean b = Boolean.parseBoolean(value);
7270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
7290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putBoolean(PREF_DISCOVERY_B, b);
7302f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
7310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
7330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_B, b ? 1 : 0);
7340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_F_VALUE)) {
7360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                boolean b = Boolean.parseBoolean(value);
7370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
7390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putBoolean(PREF_DISCOVERY_F, b);
7402f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
7410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
7430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_F, b ? 1 : 0);
7440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_15693_VALUE)) {
7460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                boolean b = Boolean.parseBoolean(value);
7470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
7490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putBoolean(PREF_DISCOVERY_15693, b);
7502f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
7510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
7530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_15693, b ? 1 : 0);
7540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_NFCIP_VALUE)) {
7560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                boolean b = Boolean.parseBoolean(value);
7570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
7590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putBoolean(PREF_DISCOVERY_NFCIP, b);
7602f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
7610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
7630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_NFCIP, b ? 1 : 0);
7640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
765f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
7660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_INVALID_PARAM;
767f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
7680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return ErrorCodes.SUCCESS;
770f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
771f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
7723ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton        @Override
7730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public NdefMessage localGet() throws RemoteException {
7743ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton            synchronized (this) {
7753ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                return mLocalMessage;
7763ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton            }
7770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
7780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7793ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton        @Override
7800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public void localSet(NdefMessage message) throws RemoteException {
7813ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton            synchronized (this) {
7823ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                mLocalMessage = message;
7833ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                // Send a message to the UI thread to show or hide the icon so the requests are
7843ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                // serialized and the icon can't get out of sync with reality.
7853ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                if (message != null) {
7863ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                    sendMessage(MSG_SHOW_MY_TAG_ICON, null);
7873ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                } else {
7883ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                    sendMessage(MSG_HIDE_MY_TAG_ICON, null);
7893ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                }
7903ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton            }
7910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
7920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    };
7930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private final ILlcpSocket mLlcpSocket = new ILlcpSocket.Stub() {
7950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        private final int CONNECT_FLAG = 0x01;
7970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        private final int CLOSE_FLAG   = 0x02;
7980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        private final int RECV_FLAG    = 0x04;
7990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        private final int SEND_FLAG    = 0x08;
8000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        private int concurrencyFlags;
8020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        private Object sync;
8030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int close(int nativeHandle) throws RemoteException {
805bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
806bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
807f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpSocket socket = null;
8080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
809f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
810f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
811f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
812f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
813f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
814f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
815f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
816f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
817f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
8180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
8190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    isSuccess = socket.doClose();
8200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (isSuccess) {
8210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Remove the socket closed from the hmap */
8220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        RemoveSocket(nativeHandle);
8230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Update mNbSocketCreated */
8240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        mNbSocketCreated--;
8250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.SUCCESS;
8260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    } else {
8270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_IO;
8280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
829f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
8300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Remove the socket closed from the hmap */
8310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    RemoveSocket(nativeHandle);
8320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Remove registered socket from the list */
8340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    RemoveRegisteredSocket(nativeHandle);
8350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Update mNbSocketCreated */
8370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mNbSocketCreated--;
8380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.SUCCESS;
840f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
841f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
8420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_IO;
843f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
844f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
845f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
8460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int connect(int nativeHandle, int sap) throws RemoteException {
847bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
848bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
849f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpSocket socket = null;
8500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
851f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
852f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
853f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
854f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
855f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
856f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
857f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
858f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
859f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
8600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                isSuccess = socket.doConnect(sap, socket.getConnectTimeout());
8610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (isSuccess) {
8620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.SUCCESS;
863f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
864f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return ErrorCodes.ERROR_IO;
865f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
866f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
867f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_IO;
868f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
8690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
870f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
871f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
8720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int connectByName(int nativeHandle, String sn) throws RemoteException {
873bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
874bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
875f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpSocket socket = null;
876f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            boolean isSuccess = false;
877f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
878f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
879f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
880f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
881f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
882f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
883f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
884f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
885f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
8860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                isSuccess = socket.doConnectBy(sn, socket.getConnectTimeout());
887f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                if (isSuccess) {
888f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return ErrorCodes.SUCCESS;
889f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
890f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return ErrorCodes.ERROR_IO;
891f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
892f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
893f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_IO;
894f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
8950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
896f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
897f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
8980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getConnectTimeout(int nativeHandle) throws RemoteException {
899bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
900bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
901f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpSocket socket = null;
902f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
9030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
9040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
9050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
9060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
9070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
908f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
909f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
910f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
9110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return socket.getConnectTimeout();
9120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else {
9130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return 0;
914f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
915f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
916f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
9170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getLocalSap(int nativeHandle) throws RemoteException {
918bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
919bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
9200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket socket = null;
921f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
922f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
923f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
924f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
925f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
926f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
9270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the socket in the hmap */
9280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
9290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (socket != null) {
9300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return socket.getSap();
931f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
9320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return 0;
933f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
934f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
935f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
9360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getLocalSocketMiu(int nativeHandle) throws RemoteException {
937bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
938bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
9390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket socket = null;
940f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
941f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
942f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
9430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
944f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
945f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
946f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
9470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
948f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
9490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return socket.getMiu();
9500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else {
9510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return 0;
952f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
953f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
954f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
9550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getLocalSocketRw(int nativeHandle) throws RemoteException {
956bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
957bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
9580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket socket = null;
959f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
960f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
961f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
962f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
963f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
964f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
965f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
9660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
9670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (socket != null) {
9680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return socket.getRw();
9690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else {
9700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return 0;
9710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
9720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
9730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
9740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getRemoteSocketMiu(int nativeHandle) throws RemoteException {
9750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
9760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
9770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket socket = null;
9780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
9790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
9800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
9810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
9820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
9830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
9840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the socket in the hmap */
9850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
9860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (socket != null) {
9870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (socket.doGetRemoteSocketMiu() != 0) {
9880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return socket.doGetRemoteSocketMiu();
9890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
9900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED;
9910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
9920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else {
9930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED;
9940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
9950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
9960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
9970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getRemoteSocketRw(int nativeHandle) throws RemoteException {
9980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
9990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket socket = null;
10010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
10030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
10040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
10050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
10060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the socket in the hmap */
10080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
10090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (socket != null) {
10100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (socket.doGetRemoteSocketRw() != 0) {
10110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return socket.doGetRemoteSocketRw();
10120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
10130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED;
10140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
10150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else {
10160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED;
10170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
10180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
10190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int receive(int nativeHandle, byte[] receiveBuffer) throws RemoteException {
10210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
10220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket socket = null;
10240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            int receiveLength = 0;
10250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
10270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
10280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
10290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
10300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the socket in the hmap */
10320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
10330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (socket != null) {
10340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                receiveLength = socket.doReceive(receiveBuffer);
10350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (receiveLength != 0) {
10360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return receiveLength;
10370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
10380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_IO;
10390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
10400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else {
10410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_IO;
10420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
10430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
10440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int send(int nativeHandle, byte[] data) throws RemoteException {
10460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
10470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket socket = null;
10490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
10500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
10520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
10530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
10540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
10550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the socket in the hmap */
10570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
10580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (socket != null) {
10590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                isSuccess = socket.doSend(data);
10600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (isSuccess) {
10610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.SUCCESS;
10620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
10630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_IO;
10640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
10650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else {
10660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_IO;
10670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
10680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
10690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public void setConnectTimeout(int nativeHandle, int timeout) throws RemoteException {
10710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
10720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket socket = null;
10740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the socket in the hmap */
10760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
10770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (socket != null) {
10780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                socket.setConnectTimeout(timeout);
10790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
10800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
10810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    };
10830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private final ILlcpServiceSocket mLlcpServerSocketService = new ILlcpServiceSocket.Stub() {
10850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int accept(int nativeHandle) throws RemoteException {
10870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
10880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpServiceSocket socket = null;
10900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket clientSocket = null;
10910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
10930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
10940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
10950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
10960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mNbSocketCreated < LLCP_SOCKET_NB_MAX) {
10980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* find the socket in the hmap */
10990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                socket = (NativeLlcpServiceSocket) findSocket(nativeHandle);
11000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (socket != null) {
11010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    clientSocket = socket.doAccept(socket.getAcceptTimeout(), socket.getMiu(),
11020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            socket.getRw(), socket.getLinearBufferLength());
11030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (clientSocket != null) {
11040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Add the socket into the socket map */
11052f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        synchronized(this) {
11062f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mSocketMap.put(clientSocket.getHandle(), clientSocket);
11072f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mNbSocketCreated++;
11082f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        }
11090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return clientSocket.getHandle();
11100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    } else {
11110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_IO;
11120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
11130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
11140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_IO;
11150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
11160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else {
11170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES;
11180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
11190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
11210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public void close(int nativeHandle) throws RemoteException {
11230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
11240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpServiceSocket socket = null;
11260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
11270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
11290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
11300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return;
11310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
11320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the socket in the hmap */
11340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpServiceSocket) findSocket(nativeHandle);
11350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (socket != null) {
11360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
11370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    isSuccess = socket.doClose();
11380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (isSuccess) {
11390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Remove the socket closed from the hmap */
11400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        RemoveSocket(nativeHandle);
11410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Update mNbSocketCreated */
11420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        mNbSocketCreated--;
11430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
11440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
11450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Remove the socket closed from the hmap */
11460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    RemoveSocket(nativeHandle);
11470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Remove registered socket from the list */
11490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    RemoveRegisteredSocket(nativeHandle);
11500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Update mNbSocketCreated */
11520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mNbSocketCreated--;
11530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
11540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
11550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
11560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getAcceptTimeout(int nativeHandle) throws RemoteException {
11580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
11590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpServiceSocket socket = null;
11610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
11630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
11640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
11650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
11660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the socket in the hmap */
11680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpServiceSocket) findSocket(nativeHandle);
1169f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
1170f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return socket.getAcceptTimeout();
1171f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
1172f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return 0;
1173f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1174f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1175f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1176f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public void setAcceptTimeout(int nativeHandle, int timeout) throws RemoteException {
1177bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
1178bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1179f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpServiceSocket socket = null;
1180f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1181f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
1182f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpServiceSocket) findSocket(nativeHandle);
1183f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
1184f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                socket.setAcceptTimeout(timeout);
1185f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1186f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1187f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    };
1188f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1189f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private final ILlcpConnectionlessSocket mLlcpConnectionlessSocketService = new ILlcpConnectionlessSocket.Stub() {
1190f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1191f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public void close(int nativeHandle) throws RemoteException {
1192bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
1193bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1194f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpConnectionlessSocket socket = null;
1195f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            boolean isSuccess = false;
1196f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1197f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1198f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1199f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return;
1200f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1201f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1202f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
1203f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpConnectionlessSocket) findSocket(nativeHandle);
1204f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
1205f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
1206f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    isSuccess = socket.doClose();
1207f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    if (isSuccess) {
1208f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                        /* Remove the socket closed from the hmap */
1209f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                        RemoveSocket(nativeHandle);
1210f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                        /* Update mNbSocketCreated */
1211f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                        mNbSocketCreated--;
1212f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    }
1213f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
1214f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    /* Remove the socket closed from the hmap */
1215f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    RemoveSocket(nativeHandle);
1216f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1217f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    /* Remove registered socket from the list */
1218f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    RemoveRegisteredSocket(nativeHandle);
1219f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1220f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    /* Update mNbSocketCreated */
1221f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    mNbSocketCreated--;
1222f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
1223f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1224f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1225f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1226f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public int getSap(int nativeHandle) throws RemoteException {
1227bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
1228bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1229f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpConnectionlessSocket socket = null;
1230f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1231f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1232f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1233f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
1234f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1235f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1236f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
1237f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpConnectionlessSocket) findSocket(nativeHandle);
1238f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
1239f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return socket.getSap();
1240f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
1241f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return 0;
1242f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1243f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1244f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1245f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public LlcpPacket receiveFrom(int nativeHandle) throws RemoteException {
1246bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
1247bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1248f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpConnectionlessSocket socket = null;
1249f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            LlcpPacket packet;
1250f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1251f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1252f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1253f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return null;
1254f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1255f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1256f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
1257f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpConnectionlessSocket) findSocket(nativeHandle);
1258f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
1259f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                packet = socket.doReceiveFrom(socket.getLinkMiu());
1260f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                if (packet != null) {
1261f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return packet;
1262f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
1263f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return null;
1264f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
1265f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return null;
1266f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1267f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1268f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1269f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public int sendTo(int nativeHandle, LlcpPacket packet) throws RemoteException {
1270bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
1271bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1272f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpConnectionlessSocket socket = null;
1273f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            boolean isSuccess = false;
1274f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1275f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1276f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1277f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
1278f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1279f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1280f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
1281f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpConnectionlessSocket) findSocket(nativeHandle);
1282f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
1283f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                isSuccess = socket.doSendTo(packet.getRemoteSap(), packet.getDataBuffer());
1284f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                if (isSuccess) {
1285f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return ErrorCodes.SUCCESS;
1286f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
1287f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return ErrorCodes.ERROR_IO;
1288f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
1289f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
1290f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_IO;
1291f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1292f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1293f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    };
1294f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1295f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private final INfcTag mNfcTagService = new INfcTag.Stub() {
1296f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1297f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public int close(int nativeHandle) throws RemoteException {
1298bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
1299bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1300f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeNfcTag tag = null;
1301f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1302f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1303f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1304f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
1305f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1306f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1307f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1308f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1309f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (tag != null) {
1310b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                /* Remove the device from the hmap */
1311b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                unregisterObject(nativeHandle);
1312b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                tag.asyncDisconnect();
1313b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                return ErrorCodes.SUCCESS;
1314f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1315f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* Restart polling loop for notification */
131665945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            maybeEnableDiscovery();
1317f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mOpenPending = false;
1318f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return ErrorCodes.ERROR_DISCONNECT;
1319f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1320f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1321f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public int connect(int nativeHandle) throws RemoteException {
1322bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
1323bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1324f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeNfcTag tag = null;
1325f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1326f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1327f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1328f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
1329f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1330f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1331f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1332f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1333b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            if (tag == null) {
1334b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                return ErrorCodes.ERROR_DISCONNECT;
1335f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1336b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            // TODO: register the tag as being locked rather than really connect
1337b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            return ErrorCodes.SUCCESS;
1338f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1339f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1340f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public String getType(int nativeHandle) throws RemoteException {
1341bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
1342bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1343f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeNfcTag tag = null;
1344f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            String type;
1345f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1346f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1347f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1348f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return null;
1349f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1350f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1351f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1352f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1353f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (tag != null) {
1354f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                type = tag.getType();
1355f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return type;
1356f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1357f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return null;
1358f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1359f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1360f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public byte[] getUid(int nativeHandle) throws RemoteException {
1361f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeNfcTag tag = null;
1362f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            byte[] uid;
1363f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1364f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1365f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1366f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return null;
1367f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1368f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1369f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1370f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1371f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (tag != null) {
1372f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                uid = tag.getUid();
1373f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return uid;
1374f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1375f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return null;
1376f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1377f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1378b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        public boolean isPresent(int nativeHandle) throws RemoteException {
1379b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            NativeNfcTag tag = null;
1380b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
1381b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            // Check if NFC is enabled
1382b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            if (!mIsNfcEnabled) {
1383b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                return false;
1384b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            }
1385b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
1386b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            /* find the tag in the hmap */
1387b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            tag = (NativeNfcTag) findObject(nativeHandle);
1388b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            if (tag == null) {
1389b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                return false;
1390b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            }
1391b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
1392b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            return tag.presenceCheck();
1393b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        }
1394b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
1395f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public boolean isNdef(int nativeHandle) throws RemoteException {
1396f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeNfcTag tag = null;
1397f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            boolean isSuccess = false;
1398f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1399f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1400f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1401f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return isSuccess;
1402f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1403f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1404f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1405f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1406f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (tag != null) {
1407b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                isSuccess = tag.checkNdef();
1408f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1409f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return isSuccess;
1410f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1411f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1412f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public byte[] transceive(int nativeHandle, byte[] data) throws RemoteException {
1413bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
1414bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1415f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeNfcTag tag = null;
1416f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            byte[] response;
1417f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1418f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1419f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1420f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return null;
1421f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1422f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1423f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1424f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1425f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (tag != null) {
1426b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                response = tag.transceive(data);
1427f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return response;
1428f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1429f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return null;
1430f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1431f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1432f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public NdefMessage read(int nativeHandle) throws RemoteException {
1433bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
1434bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1435f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeNfcTag tag;
1436f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1437f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1438f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1439f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return null;
1440f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1441f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1442f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1443f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1444f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (tag != null) {
1445b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                byte[] buf = tag.read();
1446f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                if (buf == null)
1447f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return null;
1448f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1449f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                /* Create an NdefMessage */
1450f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                try {
1451f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return new NdefMessage(buf);
1452f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } catch (FormatException e) {
1453f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return null;
1454f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
1455f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1456f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return null;
1457f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1458f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1459f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public int write(int nativeHandle, NdefMessage msg) throws RemoteException {
1460bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
1461bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1462f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeNfcTag tag;
1463f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1464f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1465f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1466f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
1467f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1468f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1469f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1470f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1471f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (tag == null) {
1472f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_IO;
1473f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1474f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1475b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            if (tag.write(msg.toByteArray())) {
1476f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.SUCCESS;
1477f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1478f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            else {
1479f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_IO;
1480f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1481f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1482f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1483f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1484f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public int getLastError(int nativeHandle) throws RemoteException {
1485f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // TODO Auto-generated method stub
14860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return 0;
1487f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1488f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
14890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getModeHint(int nativeHandle) throws RemoteException {
14900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // TODO Auto-generated method stub
14910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return 0;
1492f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1493f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
14940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int makeReadOnly(int nativeHandle) throws RemoteException {
14950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // TODO Auto-generated method stub
14960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return 0;
1497f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1498f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1499f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    };
1501f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private final IP2pInitiator mP2pInitiatorService = new IP2pInitiator.Stub() {
1503f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public byte[] getGeneralBytes(int nativeHandle) throws RemoteException {
15050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
1506f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
1508f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
15100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
15110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return null;
15120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
1513f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
15150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
15160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
15170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                byte[] buff = device.getGeneralBytes();
15180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (buff == null)
15190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return null;
15200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return buff;
15210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
15220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return null;
15230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
1524f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getMode(int nativeHandle) throws RemoteException {
15260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
1527f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
1529f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
15310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
15320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
15330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
1534f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
15360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
15370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
15380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return device.getMode();
15390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
1540f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return ErrorCodes.ERROR_INVALID_PARAM;
1541f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1542f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public byte[] receive(int nativeHandle) throws RemoteException {
15440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
1545f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
1547f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
15490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
15500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return null;
15510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
1552f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
15540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
15550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
15560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                byte[] buff = device.doReceive();
15570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (buff == null)
15580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return null;
15590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return buff;
15600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
15610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* Restart polling loop for notification */
156265945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            maybeEnableDiscovery();
15630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mOpenPending = false;
15640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return null;
15650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
1566f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public boolean send(int nativeHandle, byte[] data) throws RemoteException {
15680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
1569f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
15710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
1572f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
15740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
15750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return isSuccess;
15760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
1577f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
15790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
15800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
15810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                isSuccess = device.doSend(data);
15820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
15830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return isSuccess;
15840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
15850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    };
1586f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private final IP2pTarget mP2pTargetService = new IP2pTarget.Stub() {
1588f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int connect(int nativeHandle) throws RemoteException {
15900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
1591f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
1593f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
15950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
15960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
15970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
1598f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
16000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
16010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
16020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (device.doConnect()) {
16030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.SUCCESS;
16040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
16050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
16060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return ErrorCodes.ERROR_CONNECT;
16070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
1608f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public boolean disconnect(int nativeHandle) throws RemoteException {
16100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
1611f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
16130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
1614f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
16160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
16170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return isSuccess;
16180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
1619f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
16210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
16220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
16230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (isSuccess = device.doDisconnect()) {
16240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mOpenPending = false;
16250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* remove the device from the hmap */
1626b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                    unregisterObject(nativeHandle);
16270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Restart polling loop for notification */
162865945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly                    maybeEnableDiscovery();
16290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
1630f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
16310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return isSuccess;
1632f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
1634f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public byte[] getGeneralBytes(int nativeHandle) throws RemoteException {
16360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
1637f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
16390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
16400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
16410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
16420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return null;
1643f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1644f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
16460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
16470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
16480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                byte[] buff = device.getGeneralBytes();
16490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (buff == null)
16500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return null;
16510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return buff;
16520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
16530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return null;
16540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
1655f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getMode(int nativeHandle) throws RemoteException {
16570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
1658f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
1660f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
16620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
16630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
1664f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1665f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
16670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
16680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
16690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return device.getMode();
16700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
16710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return ErrorCodes.ERROR_INVALID_PARAM;
16720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
1673f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public byte[] transceive(int nativeHandle, byte[] data) throws RemoteException {
16750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
1676f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
1678f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
16800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
16810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return null;
1682f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1683f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
16850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
16860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
16870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                byte[] buff = device.doTransceive(data);
16880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (buff == null)
16890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return null;
16900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return buff;
16910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
16920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return null;
16930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
16940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    };
1695f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private boolean _enable(boolean oldEnabledState) {
16970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        boolean isSuccess = mManager.initialize();
16980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        if (isSuccess) {
1699f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly            applyProperties();
1700f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly
17010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* Check Secure Element setting */
17020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mNfcSecureElementState = mPrefs.getBoolean(PREF_SECURE_ELEMENT_ON,
17030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    SECURE_ELEMENT_ON_DEFAULT);
1704f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mNfcSecureElementState) {
17060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                int secureElementId = mPrefs.getInt(PREF_SECURE_ELEMENT_ID,
17070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        SECURE_ELEMENT_ID_DEFAULT);
17080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                int[] Se_list = mManager.doGetSecureElementList();
17090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (Se_list != null) {
17100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    for (int i = 0; i < Se_list.length; i++) {
17110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        if (Se_list[i] == secureElementId) {
17120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            mManager.doSelectSecureElement(Se_list[i]);
17130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            mSelectedSeId = Se_list[i];
17140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            break;
17150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        }
17160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
17170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
1718f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1719f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
172065945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            mIsNfcEnabled = true;
172165945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly
17220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* Start polling loop */
172365945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            maybeEnableDiscovery();
1724f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1725f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        } else {
17260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mIsNfcEnabled = false;
1727f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1728f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        updateNfcOnSetting(oldEnabledState);
1730f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        return isSuccess;
1732f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1733f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
173465945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly    /** Enable active tag discovery if screen is on and NFC is enabled */
173565945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly    private synchronized void maybeEnableDiscovery() {
173665945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly        if (mScreenOn && mIsNfcEnabled) {
173765945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            mManager.enableDiscovery(DISCOVERY_MODE_READER);
173865945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly        }
173965945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly    }
174065945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly
174165945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly    /** Disable active tag discovery if necessary */
174265945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly    private synchronized void maybeDisableDiscovery() {
174365945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly        if (mIsNfcEnabled) {
174465945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            mManager.disableDiscovery();
174565945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly        }
174665945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly    }
174765945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly
1748f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly    private void applyProperties() {
1749f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_LLCP_LTO, mPrefs.getInt(PREF_LLCP_LTO, LLCP_LTO_DEFAULT));
1750f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_LLCP_MIU, mPrefs.getInt(PREF_LLCP_MIU, LLCP_MIU_DEFAULT));
1751f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_LLCP_WKS, mPrefs.getInt(PREF_LLCP_WKS, LLCP_WKS_DEFAULT));
1752f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_LLCP_OPT, mPrefs.getInt(PREF_LLCP_OPT, LLCP_OPT_DEFAULT));
1753f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_A,
1754f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly                mPrefs.getBoolean(PREF_DISCOVERY_A, DISCOVERY_A_DEFAULT) ? 1 : 0);
1755f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_B,
1756f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly                mPrefs.getBoolean(PREF_DISCOVERY_B, DISCOVERY_B_DEFAULT) ? 1 : 0);
1757f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_F,
1758f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly                mPrefs.getBoolean(PREF_DISCOVERY_F, DISCOVERY_F_DEFAULT) ? 1 : 0);
1759f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_15693,
1760f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly                mPrefs.getBoolean(PREF_DISCOVERY_15693, DISCOVERY_15693_DEFAULT) ? 1 : 0);
1761f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_NFCIP,
1762f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly                mPrefs.getBoolean(PREF_DISCOVERY_NFCIP, DISCOVERY_NFCIP_DEFAULT) ? 1 : 0);
1763f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly     }
1764f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly
17650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private void updateNfcOnSetting(boolean oldEnabledState) {
17660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        int state;
1767f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mPrefsEditor.putBoolean(PREF_NFC_ON, mIsNfcEnabled);
17692f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick        mPrefsEditor.apply();
17700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
17712f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly        synchronized(this) {
17722f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly            if (mBootComplete && oldEnabledState != mIsNfcEnabled) {
17732f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                Intent intent = new Intent(NfcAdapter.ACTION_ADAPTER_STATE_CHANGE);
17742f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                intent.putExtra(NfcAdapter.EXTRA_NEW_BOOLEAN_STATE, mIsNfcEnabled);
17752f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                mContext.sendBroadcast(intent);
17762f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly            }
17770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
1778f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1779f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1780f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    // Reset all internals
17812f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    private synchronized void reset() {
178274180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick        // TODO: none of these appear to be synchronized but are
178374180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick        // read/written from different threads (notably Binder threads)...
1784f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1785f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        // Clear tables
1786f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mObjectMap.clear();
1787f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mSocketMap.clear();
1788f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mRegisteredSocketList.clear();
1789f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1790f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        // Reset variables
1791f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mLlcpLinkState = NfcAdapter.LLCP_LINK_STATE_DEACTIVATED;
1792f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mNbSocketCreated = 0;
1793f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mIsNfcEnabled = false;
1794f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mSelectedSeId = 0;
1795f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mTimeout = 0;
1796f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mOpenPending = false;
1797f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1798f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17992f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    private synchronized Object findObject(int key) {
1800f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        Object device = null;
1801f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1802f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        device = mObjectMap.get(key);
1803f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        if (device == null) {
1804f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            Log.w(TAG, "Handle not found !");
1805f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1806f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1807f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        return device;
1808f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1809f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
18102f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    synchronized void registerTagObject(NativeNfcTag nativeTag) {
1811b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        mObjectMap.put(nativeTag.getHandle(), nativeTag);
1812b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    }
1813b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
18142f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    synchronized void unregisterObject(int handle) {
1815b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        mObjectMap.remove(handle);
1816f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1817f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
18182f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    private synchronized Object findSocket(int key) {
1819f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        Object socket = null;
1820f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1821f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        socket = mSocketMap.get(key);
1822f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1823f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        return socket;
1824f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1825f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1826f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private void RemoveSocket(int key) {
1827f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mSocketMap.remove(key);
1828f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1829f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1830f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private boolean CheckSocketSap(int sap) {
1831f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        /* List of sockets registered */
1832f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        ListIterator<RegisteredSocket> it = mRegisteredSocketList.listIterator();
1833f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1834f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        while (it.hasNext()) {
1835f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            RegisteredSocket registeredSocket = it.next();
1836f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1837f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (sap == registeredSocket.mSap) {
1838f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                /* SAP already used */
1839f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return false;
1840f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1841f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1842f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        return true;
1843f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1844f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1845f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private boolean CheckSocketOptions(int miu, int rw, int linearBufferlength) {
1846f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
18470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        if (rw > LLCP_RW_MAX_VALUE || miu < LLCP_MIU_DEFAULT || linearBufferlength < miu) {
1848f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return false;
1849f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1850f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        return true;
1851f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1852f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1853f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private boolean CheckSocketServiceName(String sn) {
1854f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1855f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        /* List of sockets registered */
1856f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        ListIterator<RegisteredSocket> it = mRegisteredSocketList.listIterator();
1857f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1858f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        while (it.hasNext()) {
1859f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            RegisteredSocket registeredSocket = it.next();
1860f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1861f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (sn.equals(registeredSocket.mServiceName)) {
1862f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                /* Service Name already used */
1863f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return false;
1864f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1865f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1866f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        return true;
1867f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1868f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1869f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private void RemoveRegisteredSocket(int nativeHandle) {
1870f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        /* check if sockets are registered */
1871f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        ListIterator<RegisteredSocket> it = mRegisteredSocketList.listIterator();
1872f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1873f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        while (it.hasNext()) {
1874f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            RegisteredSocket registeredSocket = it.next();
1875f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (registeredSocket.mHandle == nativeHandle) {
1876f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                /* remove the registered socket from the list */
1877f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                it.remove();
1878f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                Log.d(TAG, "socket removed");
1879f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1880f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1881f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1882f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1883f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    /*
1884f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly     * RegisteredSocket class to store the creation request of socket until the
1885f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly     * LLCP link in not activated
1886f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly     */
1887f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private class RegisteredSocket {
1888f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        private final int mType;
1889f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1890f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        private final int mHandle;
1891f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1892f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        private final int mSap;
1893f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1894f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        private int mMiu;
1895f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1896f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        private int mRw;
1897f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1898f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        private String mServiceName;
1899f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1900f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        private int mlinearBufferLength;
1901f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1902f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        RegisteredSocket(int type, int handle, int sap, String sn, int miu, int rw,
1903f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                int linearBufferLength) {
1904f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mType = type;
1905f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mHandle = handle;
1906f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mSap = sap;
1907f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mServiceName = sn;
1908f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mRw = rw;
1909f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mMiu = miu;
1910f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mlinearBufferLength = linearBufferLength;
1911f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1912f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1913f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        RegisteredSocket(int type, int handle, int sap, int miu, int rw, int linearBufferLength) {
1914f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mType = type;
1915f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mHandle = handle;
1916f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mSap = sap;
1917f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mRw = rw;
1918f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mMiu = miu;
1919f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mlinearBufferLength = linearBufferLength;
1920f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1921f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1922f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        RegisteredSocket(int type, int handle, int sap) {
1923f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mType = type;
1924f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mHandle = handle;
1925f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mSap = sap;
1926f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1927f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1928f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
19290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private void activateLlcpLink() {
19300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        /* check if sockets are registered */
19310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        ListIterator<RegisteredSocket> it = mRegisteredSocketList.listIterator();
1932f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
19330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        Log.d(TAG, "Nb socket resgistered = " + mRegisteredSocketList.size());
1934f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
19350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        while (it.hasNext()) {
19360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            RegisteredSocket registeredSocket = it.next();
1937f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
19380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            switch (registeredSocket.mType) {
19390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            case LLCP_SERVICE_SOCKET_TYPE:
19400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                Log.d(TAG, "Registered Llcp Service Socket");
19410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                NativeLlcpServiceSocket serviceSocket;
19420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
19430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                serviceSocket = mManager.doCreateLlcpServiceSocket(
19440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        registeredSocket.mSap, registeredSocket.mServiceName,
19450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        registeredSocket.mMiu, registeredSocket.mRw,
19460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        registeredSocket.mlinearBufferLength);
19470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
19480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (serviceSocket != null) {
19490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Add the socket into the socket map */
19502f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    synchronized(NfcService.this) {
19512f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mSocketMap.put(registeredSocket.mHandle, serviceSocket);
19522f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    }
19530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
19540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* socket creation error - update the socket
19550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                     * handle counter */
19560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mGeneratedSocketHandle -= 1;
19570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
19580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                break;
19590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
19600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            case LLCP_SOCKET_TYPE:
19610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                Log.d(TAG, "Registered Llcp Socket");
19620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                NativeLlcpSocket clientSocket;
19630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                clientSocket = mManager.doCreateLlcpSocket(registeredSocket.mSap,
19640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        registeredSocket.mMiu, registeredSocket.mRw,
19650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        registeredSocket.mlinearBufferLength);
19660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (clientSocket != null) {
19670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Add the socket into the socket map */
19682f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    synchronized(NfcService.this) {
19692f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mSocketMap.put(registeredSocket.mHandle, clientSocket);
19702f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    }
19710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
19720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* socket creation error - update the socket
19730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                     * handle counter */
19740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mGeneratedSocketHandle -= 1;
19750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
19760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                break;
19770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
19780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            case LLCP_CONNECTIONLESS_SOCKET_TYPE:
19790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                Log.d(TAG, "Registered Llcp Connectionless Socket");
19800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                NativeLlcpConnectionlessSocket connectionlessSocket;
19810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                connectionlessSocket = mManager.doCreateLlcpConnectionlessSocket(
19820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        registeredSocket.mSap);
19830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (connectionlessSocket != null) {
19840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Add the socket into the socket map */
19852f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    synchronized(NfcService.this) {
19862f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mSocketMap.put(registeredSocket.mHandle, connectionlessSocket);
19872f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    }
19880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
19890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* socket creation error - update the socket
19900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                     * handle counter */
19910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mGeneratedSocketHandle -= 1;
19920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
19930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                break;
1994f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
19950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
1996f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
19970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        /* Remove all registered socket from the list */
19980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mRegisteredSocketList.clear();
1999f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
20000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        /* Broadcast Intent Link LLCP activated */
20010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        Intent LlcpLinkIntent = new Intent();
20020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        LlcpLinkIntent.setAction(NfcAdapter.ACTION_LLCP_LINK_STATE_CHANGED);
2003f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
20040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        LlcpLinkIntent.putExtra(NfcAdapter.EXTRA_LLCP_LINK_STATE_CHANGED,
20050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                NfcAdapter.LLCP_LINK_STATE_ACTIVATED);
2006f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
20070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        Log.d(TAG, "Broadcasting LLCP activation");
20080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mContext.sendOrderedBroadcast(LlcpLinkIntent, NFC_PERM);
20090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    }
2010f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2011b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    void sendMessage(int what, Object obj) {
2012b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        Message msg = mHandler.obtainMessage();
2013b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        msg.what = what;
2014b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        msg.obj = obj;
2015b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        mHandler.sendMessage(msg);
2016b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    }
2017b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
20181cf8ba9546ba5204af08b8de2c542b6a1bf8f8a0Nick Pelly
2019b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    private final Handler mHandler = new Handler() {
2020b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        @Override
2021b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        public void handleMessage(Message msg) {
2022f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           switch (msg.what) {
2023f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           case MSG_NDEF_TAG:
2024f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.d(TAG, "Tag detected, notifying applications");
2025f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               NativeNfcTag nativeTag = (NativeNfcTag) msg.obj;
2026f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               if (nativeTag.connect()) {
2027f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   if (nativeTag.checkNdef()) {
2028f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       byte[] buff = nativeTag.read();
2029f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       if (buff != null) {
2030f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           NdefMessage[] msgNdef = new NdefMessage[1];
2031f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           try {
2032f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               msgNdef[0] = new NdefMessage(buff);
2033f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               NdefTag tag = new NdefTag(nativeTag.getUid(),
20341cf8ba9546ba5204af08b8de2c542b6a1bf8f8a0Nick Pelly                                       TagTarget.internalTypeToRawTargets(nativeTag.getType()),
2035f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                                       null, null, nativeTag.getHandle(),
2036f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                                       TagTarget.internalTypeToNdefTargets(nativeTag.getType()),
2037f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                                       new NdefMessage[][] {msgNdef});
2038f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               Intent intent = new Intent();
2039f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               intent.setAction(NfcAdapter.ACTION_NDEF_TAG_DISCOVERED);
2040b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                               intent.putExtra(NfcAdapter.EXTRA_TAG, tag);
2041b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                               intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2042f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               Log.d(TAG, "NDEF tag found, starting corresponding activity");
20431cf8ba9546ba5204af08b8de2c542b6a1bf8f8a0Nick Pelly                               Log.d(TAG, tag.toString());
2044b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                               try {
2045b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                                   mContext.startActivity(intent);
2046b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                               } catch (ActivityNotFoundException e) {
2047b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                                   Log.w(TAG, "No activity found, disconnecting");
2048b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                                   nativeTag.asyncDisconnect();
2049b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                               }
2050f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           } catch (FormatException e) {
2051f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               Log.w(TAG, "Unable to create NDEF message object (tag empty or not well formated)");
2052f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               nativeTag.asyncDisconnect();
2053b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                           }
2054b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                       } else {
2055f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           Log.w(TAG, "Unable to read NDEF message (tag empty or not well formated)");
2056b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                           nativeTag.asyncDisconnect();
2057b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                       }
2058f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   } else {
2059f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       Intent intent = new Intent();
2060f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       Tag tag = new Tag(nativeTag.getUid(), false,
2061f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               TagTarget.internalTypeToRawTargets(nativeTag.getType()),
2062f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               null, null, nativeTag.getHandle());
2063f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       intent.setAction(NfcAdapter.ACTION_TAG_DISCOVERED);
2064f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       intent.putExtra(NfcAdapter.EXTRA_TAG, tag);
2065f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2066f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       Log.d(TAG, "Non-NDEF tag found, starting corresponding activity");
2067f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       Log.d(TAG, tag.toString());
2068f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       try {
2069f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           mContext.startActivity(intent);
2070f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       } catch (ActivityNotFoundException e) {
2071f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           Log.w(TAG, "No activity found, disconnecting");
2072f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           nativeTag.asyncDisconnect();
2073f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       }
2074f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   }
2075f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               } else {
2076f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   Log.w(TAG, "Failed to connect to tag");
2077f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   nativeTag.asyncDisconnect();
2078f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               }
2079f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               break;
2080f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           case MSG_CARD_EMULATION:
2081f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.d(TAG, "Card Emulation message");
2082f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               byte[] aid = (byte[]) msg.obj;
2083f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               /* Send broadcast ordered */
2084f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Intent TransactionIntent = new Intent();
2085f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               TransactionIntent.setAction(NfcAdapter.ACTION_TRANSACTION_DETECTED);
2086f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               TransactionIntent.putExtra(NfcAdapter.EXTRA_AID, aid);
2087f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.d(TAG, "Broadcasting Card Emulation event");
2088f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               mContext.sendOrderedBroadcast(TransactionIntent, NFC_PERM);
2089f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               break;
2090f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly
2091f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           case MSG_LLCP_LINK_ACTIVATION:
2092f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               NativeP2pDevice device = (NativeP2pDevice) msg.obj;
2093f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly
2094f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.d(TAG, "LLCP Activation message");
2095f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly
2096f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               if (device.getMode() == NativeP2pDevice.MODE_P2P_TARGET) {
2097f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   if (device.doConnect()) {
2098f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       /* Check Llcp compliancy */
2099f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       if (mManager.doCheckLlcp()) {
2100f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           /* Activate Llcp Link */
2101f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           if (mManager.doActivateLlcp()) {
2102f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               Log.d(TAG, "Initiator Activate LLCP OK");
2103f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               /* Broadcast Intent Link LLCP activated */
2104f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               Intent LlcpLinkIntent = new Intent();
2105f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               LlcpLinkIntent
2106f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                                       .setAction(mManager.INTERNAL_LLCP_LINK_STATE_CHANGED_ACTION);
2107f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               LlcpLinkIntent.putExtra(
2108f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                                       mManager.INTERNAL_LLCP_LINK_STATE_CHANGED_EXTRA,
2109f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                                       NfcAdapter.LLCP_LINK_STATE_ACTIVATED);
2110f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               Log.d(TAG, "Broadcasting internal LLCP activation");
2111f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               mContext.sendBroadcast(LlcpLinkIntent);
2112b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                           }
2113b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
2114f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       } else {
2115f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           device.doDisconnect();
2116b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                       }
2117f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly
2118f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   }
2119f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly
2120f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               } else if (device.getMode() == NativeP2pDevice.MODE_P2P_INITIATOR) {
2121f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   /* Check Llcp compliancy */
2122f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   if (mManager.doCheckLlcp()) {
2123f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       /* Activate Llcp Link */
2124f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       if (mManager.doActivateLlcp()) {
2125f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           Log.d(TAG, "Target Activate LLCP OK");
2126f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           /* Broadcast Intent Link LLCP activated */
2127f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           Intent LlcpLinkIntent = new Intent();
2128f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           LlcpLinkIntent
2129f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                                   .setAction(mManager.INTERNAL_LLCP_LINK_STATE_CHANGED_ACTION);
2130f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           LlcpLinkIntent.putExtra(mManager.INTERNAL_LLCP_LINK_STATE_CHANGED_EXTRA,
2131f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                                   NfcAdapter.LLCP_LINK_STATE_ACTIVATED);
2132f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           Log.d(TAG, "Broadcasting internal LLCP activation");
2133f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           mContext.sendBroadcast(LlcpLinkIntent);
2134f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       }
2135f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   }
2136b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau               }
2137f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               break;
2138f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly
2139f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           case MSG_LLCP_LINK_DEACTIVATED:
2140f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               /* Broadcast Intent Link LLCP activated */
2141f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.d(TAG, "LLCP Link Deactivated message");
2142f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Intent LlcpLinkIntent = new Intent();
2143f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               LlcpLinkIntent.setAction(NfcAdapter.ACTION_LLCP_LINK_STATE_CHANGED);
2144f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               LlcpLinkIntent.putExtra(NfcAdapter.EXTRA_LLCP_LINK_STATE_CHANGED,
2145f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       NfcAdapter.LLCP_LINK_STATE_DEACTIVATED);
2146f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.d(TAG, "Broadcasting LLCP deactivation");
2147f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               mContext.sendOrderedBroadcast(LlcpLinkIntent, NFC_PERM);
2148f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               break;
2149f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly
2150f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           case MSG_TARGET_DESELECTED:
2151f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               /* Broadcast Intent Target Deselected */
2152f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.d(TAG, "Target Deselected");
2153f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Intent TargetDeselectedIntent = new Intent();
2154f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               TargetDeselectedIntent.setAction(mManager.INTERNAL_TARGET_DESELECTED_ACTION);
2155f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.d(TAG, "Broadcasting Intent");
2156f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               mContext.sendOrderedBroadcast(TargetDeselectedIntent, NFC_PERM);
2157f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               break;
2158f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly
21593ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton           case MSG_SHOW_MY_TAG_ICON: {
21603ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton               StatusBarManager sb = (StatusBarManager) getSystemService(
21613ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                       Context.STATUS_BAR_SERVICE);
21623ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton               sb.setIcon("nfc", R.drawable.stat_sys_nfc, 0);
21633ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton               break;
21643ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton           }
21653ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton
21663ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton           case MSG_HIDE_MY_TAG_ICON: {
21673ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton               StatusBarManager sb = (StatusBarManager) getSystemService(
21683ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                       Context.STATUS_BAR_SERVICE);
21693ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton               sb.removeIcon("nfc");
21703ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton               break;
21713ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton           }
21723ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton
2173f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           default:
2174f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.e(TAG, "Unknown message received");
2175f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               break;
2176f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           }
2177b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        }
2178b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    };
2179b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
21800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
21810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        @Override
21820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public void onReceive(Context context, Intent intent) {
21830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (intent.getAction().equals(NfcAdapter.ACTION_LLCP_LINK_STATE_CHANGED)) {
21840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                Log.d(TAG, "LLCP_LINK_STATE_CHANGED");
2185f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
21860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mLlcpLinkState = intent.getIntExtra(
21870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        NfcAdapter.EXTRA_LLCP_LINK_STATE_CHANGED,
21880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        NfcAdapter.LLCP_LINK_STATE_DEACTIVATED);
2189f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
21900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_DEACTIVATED) {
21910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* restart polling loop */
219265945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly                    maybeEnableDiscovery();
21930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
21940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    activateLlcpLink();
2195f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
21960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (intent.getAction().equals(
2197f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION)) {
21980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                Log.d(TAG, "INERNAL_TARGET_DESELECTED_ACTION");
21990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
22000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mOpenPending = false;
2201f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                /* Restart polling loop for notification */
220265945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly                maybeEnableDiscovery();
2203f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
22040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
22052f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                Log.i(TAG, "Boot complete");
22060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
22072f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                synchronized(this) {
22082f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    mBootComplete = true;
22092f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly
22102f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    // now its safe to send the NFC state
22112f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    Intent sendIntent = new Intent(NfcAdapter.ACTION_ADAPTER_STATE_CHANGE);
22122f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    sendIntent.putExtra(NfcAdapter.EXTRA_NEW_BOOLEAN_STATE, mIsNfcEnabled);
22132f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    mContext.sendBroadcast(sendIntent);
22142f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                }
221565945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
221665945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly                synchronized (NfcService.this) {
221765945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly                    mScreenOn = true;
221865945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly                    maybeEnableDiscovery();
221965945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly                }
222065945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly
222165945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            } else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
222265945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly                synchronized (NfcService.this) {
222365945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly                    mScreenOn = false;
222465945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly                    maybeDisableDiscovery();
222565945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly                }
2226f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
2227f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
2228f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    };
222974180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick}
2230