NfcService.java revision 7c034a7fe7d36b1ab039af2c44717812ea02657e
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
19d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamiltonimport com.android.internal.nfc.LlcpServiceSocket;
20d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamiltonimport com.android.internal.nfc.LlcpSocket;
21d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamiltonimport com.android.nfc.mytag.MyTagClient;
22d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamiltonimport com.android.nfc.mytag.MyTagServer;
23d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
242f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pellyimport android.app.Application;
253ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamiltonimport android.app.StatusBarManager;
26b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneauimport android.content.ActivityNotFoundException;
2713d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellyimport android.content.BroadcastReceiver;
2813d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellyimport android.content.Context;
2913d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellyimport android.content.Intent;
3013d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellyimport android.content.IntentFilter;
310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pellyimport android.content.SharedPreferences;
32f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.ErrorCodes;
33f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.FormatException;
34f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.ILlcpConnectionlessSocket;
35f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.ILlcpServiceSocket;
36f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.ILlcpSocket;
370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pellyimport android.nfc.INfcAdapter;
38f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.INfcTag;
39f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.IP2pInitiator;
40f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.IP2pTarget;
41f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.LlcpPacket;
42f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.NdefMessage;
43b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneauimport android.nfc.NdefTag;
44f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.NfcAdapter;
450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pellyimport android.nfc.Tag;
467c034a7fe7d36b1ab039af2c44717812ea02657eNick Pellyimport android.os.AsyncTask;
47b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneauimport android.os.Handler;
48b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneauimport android.os.Message;
49f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.os.RemoteException;
5013d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellyimport android.os.ServiceManager;
51f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.util.Log;
52f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
533ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamiltonimport java.util.HashMap;
543ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamiltonimport java.util.LinkedList;
553ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamiltonimport java.util.ListIterator;
563ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton
572f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pellypublic class NfcService extends Application {
5813d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly    static {
5913d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly        System.loadLibrary("nfc_jni");
6013d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly    }
6113d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly
62d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    public static final String SERVICE_NAME = "nfc";
63d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
64f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final String TAG = "NfcService";
65f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
66bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly    private static final String NFC_PERM = android.Manifest.permission.NFC;
67bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly    private static final String NFC_PERM_ERROR = "NFC permission required";
68bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly    private static final String ADMIN_PERM = android.Manifest.permission.WRITE_SECURE_SETTINGS;
69bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly    private static final String ADMIN_PERM_ERROR = "WRITE_SECURE_SETTINGS permission required";
70bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF = "NfcServicePrefs";
72f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_NFC_ON = "nfc_on";
740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final boolean NFC_ON_DEFAULT = true;
75f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_SECURE_ELEMENT_ON = "secure_element_on";
770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final boolean SECURE_ELEMENT_ON_DEFAULT = false;
78f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_SECURE_ELEMENT_ID = "secure_element_id";
800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int SECURE_ELEMENT_ID_DEFAULT = 0;
81f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_LLCP_LTO = "llcp_lto";
830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_LTO_DEFAULT = 150;
840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_LTO_MAX = 255;
85f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    /** Maximum Information Unit */
870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_LLCP_MIU = "llcp_miu";
880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_MIU_DEFAULT = 128;
890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_MIU_MAX = 2176;
90f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    /** Well Known Service List */
920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_LLCP_WKS = "llcp_wks";
930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_WKS_DEFAULT = 1;
940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_WKS_MAX = 15;
95f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_LLCP_OPT = "llcp_opt";
970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_OPT_DEFAULT = 0;
980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_OPT_MAX = 3;
99f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_DISCOVERY_A = "discovery_a";
1010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final boolean DISCOVERY_A_DEFAULT = true;
102f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_DISCOVERY_B = "discovery_b";
1040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final boolean DISCOVERY_B_DEFAULT = true;
105f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_DISCOVERY_F = "discovery_f";
1070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final boolean DISCOVERY_F_DEFAULT = true;
108f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_DISCOVERY_15693 = "discovery_15693";
1100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final boolean DISCOVERY_15693_DEFAULT = true;
111f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_DISCOVERY_NFCIP = "discovery_nfcip";
1130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final boolean DISCOVERY_NFCIP_DEFAULT = true;
114f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    /** NFC Reader Discovery mode for enableDiscovery() */
1160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int DISCOVERY_MODE_READER = 0;
117f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    /** Card Emulation Discovery mode for enableDiscovery() */
1190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int DISCOVERY_MODE_CARD_EMULATION = 2;
120f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_SERVICE_SOCKET_TYPE = 0;
1220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_SOCKET_TYPE = 1;
1230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_CONNECTIONLESS_SOCKET_TYPE = 2;
1240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_SOCKET_NB_MAX = 5;  // Maximum number of socket managed
1250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_RW_MAX_VALUE = 15;  // Receive Window
126f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
127f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final int PROPERTY_LLCP_LTO = 0;
128f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final String PROPERTY_LLCP_LTO_VALUE = "llcp.lto";
1290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int PROPERTY_LLCP_MIU = 1;
130f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final String PROPERTY_LLCP_MIU_VALUE = "llcp.miu";
1310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int PROPERTY_LLCP_WKS = 2;
132f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final String PROPERTY_LLCP_WKS_VALUE = "llcp.wks";
1330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int PROPERTY_LLCP_OPT = 3;
134f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final String PROPERTY_LLCP_OPT_VALUE = "llcp.opt";
135f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final int PROPERTY_NFC_DISCOVERY_A = 4;
136f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final String PROPERTY_NFC_DISCOVERY_A_VALUE = "discovery.iso14443A";
1370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int PROPERTY_NFC_DISCOVERY_B = 5;
138f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final String PROPERTY_NFC_DISCOVERY_B_VALUE = "discovery.iso14443B";
1390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int PROPERTY_NFC_DISCOVERY_F = 6;
140f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final String PROPERTY_NFC_DISCOVERY_F_VALUE = "discovery.felica";
1410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int PROPERTY_NFC_DISCOVERY_15693 = 7;
142f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final String PROPERTY_NFC_DISCOVERY_15693_VALUE = "discovery.iso15693";
1430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int PROPERTY_NFC_DISCOVERY_NFCIP = 8;
144f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final String PROPERTY_NFC_DISCOVERY_NFCIP_VALUE = "discovery.nfcip";
145f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
146b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    static final int MSG_NDEF_TAG = 0;
147b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    static final int MSG_CARD_EMULATION = 1;
148b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    static final int MSG_LLCP_LINK_ACTIVATION = 2;
149b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    static final int MSG_LLCP_LINK_DEACTIVATED = 3;
150b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    static final int MSG_TARGET_DESELECTED = 4;
1513ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton    static final int MSG_SHOW_MY_TAG_ICON = 5;
1523ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton    static final int MSG_HIDE_MY_TAG_ICON = 6;
153d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    static final int MSG_MOCK_NDEF_TAG = 7;
154b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
15574180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick    // TODO: none of these appear to be synchronized but are
15674180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick    // read/written from different threads (notably Binder threads)...
157f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private final LinkedList<RegisteredSocket> mRegisteredSocketList = new LinkedList<RegisteredSocket>();
158f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private int mLlcpLinkState = NfcAdapter.LLCP_LINK_STATE_DEACTIVATED;
159f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private int mGeneratedSocketHandle = 0;
160f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private int mNbSocketCreated = 0;
16174180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick    private volatile boolean mIsNfcEnabled = false;
162f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private int mSelectedSeId = 0;
1630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private boolean mNfcSecureElementState;
164f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private boolean mOpenPending = false;
165f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1662f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    // fields below are used in multiple threads and protected by synchronized(this)
1672f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    private final HashMap<Integer, Object> mObjectMap = new HashMap<Integer, Object>();
1682f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    private final HashMap<Integer, Object> mSocketMap = new HashMap<Integer, Object>();
1692f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    private int mTimeout = 0;
1702f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    private boolean mBootComplete = false;
17165945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly    private boolean mScreenOn;
1722f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly
1732f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    // fields below are final after onCreate()
1740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private Context mContext;
1750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private NativeNfcManager mManager;
1760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private SharedPreferences mPrefs;
1770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private SharedPreferences.Editor mPrefsEditor;
178d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    private MyTagServer mMyTagServer;
179d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    private MyTagClient mMyTagClient;
180d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
181d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    private static NfcService sService;
182d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
183d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    public static NfcService getInstance() {
184d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        return sService;
185d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    }
186f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    @Override
1880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    public void onCreate() {
1892f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly        super.onCreate();
1902f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly
1912f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly        Log.i(TAG, "Starting NFC service");
1922f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly
193d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        sService = this;
194d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
1950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mContext = this;
196b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        mManager = new NativeNfcManager(mContext, this);
1970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mManager.initializeNativeStructure();
19874180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick
199d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        mMyTagServer = new MyTagServer();
200d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        mMyTagClient = new MyTagClient(this);
201d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton//        mMyTagServer.start();
202d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
2030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mPrefs = mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE);
2040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mPrefsEditor = mPrefs.edit();
205f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
206d6fdd3fbb880f1503d56616608e6823b51320dc3Nick Pelly        mIsNfcEnabled = false;  // real preference read later
20765945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly        mScreenOn = true;  // assume screen is on during boot
208f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
209d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        ServiceManager.addService(SERVICE_NAME, mNfcAdapter);
210f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        IntentFilter filter = new IntentFilter(NfcAdapter.ACTION_LLCP_LINK_STATE_CHANGED);
2120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        filter.addAction(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION);
2132f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly        filter.addAction(Intent.ACTION_BOOT_COMPLETED);
21465945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly        filter.addAction(Intent.ACTION_SCREEN_OFF);
21565945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly        filter.addAction(Intent.ACTION_SCREEN_ON);
2160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mContext.registerReceiver(mReceiver, filter);
2170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
2180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        Thread t = new Thread() {
2190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            @Override
2200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            public void run() {
2210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                boolean nfc_on = mPrefs.getBoolean(PREF_NFC_ON, NFC_ON_DEFAULT);
2220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (nfc_on) {
2230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    _enable(false);
224f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
225f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
2260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        };
2270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        t.start();
2280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    }
2290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
2300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    @Override
2312f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    public void onTerminate() {
2322f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly        super.onTerminate();
2332f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly        // NFC application is persistent, it should not be destroyed by framework
2340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        Log.wtf(TAG, "NFC service is under attack!");
2350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    }
2360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
2370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private final INfcAdapter.Stub mNfcAdapter = new INfcAdapter.Stub() {
2383ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton        /** Protected by "this" */
2393ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton        // TODO read this from permanent storage at boot time
2403ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton        NdefMessage mLocalMessage = null;
2413ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton
2420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public boolean enable() throws RemoteException {
243d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
2440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
2450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
2460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean previouslyEnabled = isEnabled();
2470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!previouslyEnabled) {
2480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                reset();
2490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                isSuccess = _enable(previouslyEnabled);
250f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
2510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return isSuccess;
252f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
253f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public boolean disable() throws RemoteException {
2550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
256d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
2570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean previouslyEnabled = isEnabled();
2580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            Log.d(TAG, "Disabling NFC.  previous=" + previouslyEnabled);
2590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
2600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (previouslyEnabled) {
2610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                isSuccess = mManager.deinitialize();
2620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                Log.d(TAG, "NFC success of deinitialize = " + isSuccess);
2630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (isSuccess) {
2640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mIsNfcEnabled = false;
2650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
266f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
2670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
2680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            updateNfcOnSetting(previouslyEnabled);
2690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
2700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return isSuccess;
271f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
272f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int createLlcpConnectionlessSocket(int sap) throws RemoteException {
274d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
275bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
276f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
277f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
278f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
279f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
280f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* Check SAP is not already used */
2820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
2830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* Check nb socket created */
2840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mNbSocketCreated < LLCP_SOCKET_NB_MAX) {
2850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store the socket handle */
2860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                int sockeHandle = mGeneratedSocketHandle;
2870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
288f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
2890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    NativeLlcpConnectionlessSocket socket;
2900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
2910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    socket = mManager.doCreateLlcpConnectionlessSocket(sap);
2920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (socket != null) {
2932f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        synchronized(NfcService.this) {
2942f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            /* Update the number of socket created */
2952f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mNbSocketCreated++;
2960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
2972f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            /* Add the socket into the socket map */
2982f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mSocketMap.put(sockeHandle, socket);
2992f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        }
3000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return sockeHandle;
301f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    } else {
3020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /*
3030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                         * socket creation error - update the socket handle
3040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                         * generation
3050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                         */
3060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        mGeneratedSocketHandle -= 1;
3070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Get Error Status */
3090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        int errorStatus = mManager.doGetLastError();
3100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        switch (errorStatus) {
3120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            case ErrorCodes.ERROR_BUFFER_TO_SMALL:
3130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_BUFFER_TO_SMALL;
3140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES:
3150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES;
3160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            default:
3170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_SOCKET_CREATION;
3180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        }
319f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    }
320f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
3210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Check SAP is not already used */
3220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (!CheckSocketSap(sap)) {
3230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_SAP_USED;
3240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
325f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
3260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    NativeLlcpConnectionlessSocket socket = new NativeLlcpConnectionlessSocket(sap);
327f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
3282f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    synchronized(NfcService.this) {
3292f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        /* Add the socket into the socket map */
3302f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mSocketMap.put(sockeHandle, socket);
3310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3322f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        /* Update the number of socket created */
3332f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mNbSocketCreated++;
3342f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    }
3350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Create new registered socket */
3360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    RegisteredSocket registeredSocket = new RegisteredSocket(
3370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            LLCP_CONNECTIONLESS_SOCKET_TYPE, sockeHandle, sap);
3380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Put this socket into a list of registered socket */
3400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mRegisteredSocketList.add(registeredSocket);
341f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
3420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* update socket handle generation */
3440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mGeneratedSocketHandle++;
3450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return sockeHandle;
3470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
348f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
3490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* No socket available */
3500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES;
351f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
3520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
353f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
354f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
3550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int createLlcpServiceSocket(int sap, String sn, int miu, int rw, int linearBufferLength)
3560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                throws RemoteException {
357d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
358bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
359f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
360f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
361f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
362f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
363f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
3640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mNbSocketCreated < LLCP_SOCKET_NB_MAX) {
3650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                int sockeHandle = mGeneratedSocketHandle;
3660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
3680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    NativeLlcpServiceSocket socket;
3690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    socket = mManager.doCreateLlcpServiceSocket(sap, sn, miu, rw, linearBufferLength);
3710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (socket != null) {
3722f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        synchronized(NfcService.this) {
3732f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            /* Update the number of socket created */
3742f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mNbSocketCreated++;
3752f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            /* Add the socket into the socket map */
3762f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mSocketMap.put(sockeHandle, socket);
3772f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        }
3780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    } else {
3790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* socket creation error - update the socket handle counter */
3800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        mGeneratedSocketHandle -= 1;
3810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Get Error Status */
3830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        int errorStatus = mManager.doGetLastError();
3840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        switch (errorStatus) {
3860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            case ErrorCodes.ERROR_BUFFER_TO_SMALL:
3870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_BUFFER_TO_SMALL;
3880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES:
3890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES;
3900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            default:
3910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_SOCKET_CREATION;
3920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        }
3930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
394f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
3950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Check SAP is not already used */
3970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (!CheckSocketSap(sap)) {
3980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_SAP_USED;
3990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
4000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Service Name */
4020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (!CheckSocketServiceName(sn)) {
4030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_SERVICE_NAME_USED;
4040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
4050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Check socket options */
4070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (!CheckSocketOptions(miu, rw, linearBufferLength)) {
4080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_SOCKET_OPTIONS;
4090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
4100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    NativeLlcpServiceSocket socket = new NativeLlcpServiceSocket(sn);
4122f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    synchronized(NfcService.this) {
4132f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        /* Add the socket into the socket map */
4142f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mSocketMap.put(sockeHandle, socket);
4150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4162f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        /* Update the number of socket created */
4172f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mNbSocketCreated++;
4182f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    }
4190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Create new registered socket */
4200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    RegisteredSocket registeredSocket = new RegisteredSocket(LLCP_SERVICE_SOCKET_TYPE,
4210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            sockeHandle, sap, sn, miu, rw, linearBufferLength);
4220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Put this socket into a list of registered socket */
4240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mRegisteredSocketList.add(registeredSocket);
425f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
4260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* update socket handle generation */
4280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mGeneratedSocketHandle += 1;
4290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                Log.d(TAG, "Llcp Service Socket Handle =" + sockeHandle);
4310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return sockeHandle;
432f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
4330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* No socket available */
4340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES;
435f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
436f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
437f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
4380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int createLlcpSocket(int sap, int miu, int rw, int linearBufferLength)
4390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                throws RemoteException {
440d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
441bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
442f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
443f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
444f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
445f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
446f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
4470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mNbSocketCreated < LLCP_SOCKET_NB_MAX) {
4480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                int sockeHandle = mGeneratedSocketHandle;
4500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
4520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    NativeLlcpSocket socket;
4530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    socket = mManager.doCreateLlcpSocket(sap, miu, rw, linearBufferLength);
4550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (socket != null) {
4572f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        synchronized(NfcService.this) {
4582f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            /* Update the number of socket created */
4592f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mNbSocketCreated++;
4602f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            /* Add the socket into the socket map */
4612f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mSocketMap.put(sockeHandle, socket);
4622f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        }
4630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    } else {
4640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /*
4650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                         * socket creation error - update the socket handle
4660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                         * generation
4670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                         */
4680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        mGeneratedSocketHandle -= 1;
4690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Get Error Status */
4710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        int errorStatus = mManager.doGetLastError();
4720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        switch (errorStatus) {
4740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            case ErrorCodes.ERROR_BUFFER_TO_SMALL:
4750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_BUFFER_TO_SMALL;
4760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES:
4770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES;
4780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            default:
4790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_SOCKET_CREATION;
4800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        }
4810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
482f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
483f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
4840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Check SAP is not already used */
4850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (!CheckSocketSap(sap)) {
4860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_SAP_USED;
4870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
488f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
4890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Check Socket options */
4900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (!CheckSocketOptions(miu, rw, linearBufferLength)) {
4910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_SOCKET_OPTIONS;
4920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
493bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
4940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    NativeLlcpSocket socket = new NativeLlcpSocket(sap, miu, rw);
4952f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    synchronized(NfcService.this) {
4962f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        /* Add the socket into the socket map */
4972f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mSocketMap.put(sockeHandle, socket);
498f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
4992f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        /* Update the number of socket created */
5002f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mNbSocketCreated++;
5012f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    }
5020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Create new registered socket */
5030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    RegisteredSocket registeredSocket = new RegisteredSocket(LLCP_SOCKET_TYPE,
5040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            sockeHandle, sap, miu, rw, linearBufferLength);
5050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Put this socket into a list of registered socket */
5070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mRegisteredSocketList.add(registeredSocket);
5080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
5090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* update socket handle generation */
5110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mGeneratedSocketHandle++;
5120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return sockeHandle;
514f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
5150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* No socket available */
5160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES;
517f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
518f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
519f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
5200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int deselectSecureElement() throws RemoteException {
521d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
522f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
523f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
524f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
525f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
526f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
527f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
5280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mSelectedSeId == 0) {
5290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NO_SE_CONNECTED;
530f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
5310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mManager.doDeselectSecureElement(mSelectedSeId);
5330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mNfcSecureElementState = false;
5340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mSelectedSeId = 0;
5350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* store preference */
5370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mPrefsEditor.putBoolean(PREF_SECURE_ELEMENT_ON, false);
5380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mPrefsEditor.putInt(PREF_SECURE_ELEMENT_ID, 0);
5392f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick            mPrefsEditor.apply();
5400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return ErrorCodes.SUCCESS;
542f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
543f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
5440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public ILlcpConnectionlessSocket getLlcpConnectionlessInterface() throws RemoteException {
545d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
5460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mLlcpConnectionlessSocketService;
5470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
548bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
5490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public ILlcpSocket getLlcpInterface() throws RemoteException {
550d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
5510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mLlcpSocket;
5520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
553f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
5540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public ILlcpServiceSocket getLlcpServiceInterface() throws RemoteException {
555d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
5560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mLlcpServerSocketService;
5570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
558f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
5590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public INfcTag getNfcTagInterface() throws RemoteException {
560d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
5610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mNfcTagService;
5620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
5630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5642f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly        public synchronized int getOpenTimeout() throws RemoteException {
565d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
5660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mTimeout;
5670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
5680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public IP2pInitiator getP2pInitiatorInterface() throws RemoteException {
570d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
5710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mP2pInitiatorService;
5720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
5730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public IP2pTarget getP2pTargetInterface() throws RemoteException {
575d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
5760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mP2pTargetService;
5770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
5780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public String getProperties(String param) throws RemoteException {
580d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
5810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (param == null) {
5830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return null;
5840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
5850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (param.equals(PROPERTY_LLCP_LTO_VALUE)) {
5870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Integer.toString(mPrefs.getInt(PREF_LLCP_LTO, LLCP_LTO_DEFAULT));
5880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_LLCP_MIU_VALUE)) {
5890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Integer.toString(mPrefs.getInt(PREF_LLCP_MIU, LLCP_MIU_DEFAULT));
5900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_LLCP_WKS_VALUE)) {
5910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Integer.toString(mPrefs.getInt(PREF_LLCP_WKS, LLCP_WKS_DEFAULT));
5920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_LLCP_OPT_VALUE)) {
5930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Integer.toString(mPrefs.getInt(PREF_LLCP_OPT, LLCP_OPT_DEFAULT));
5940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_A_VALUE)) {
5950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_A, DISCOVERY_A_DEFAULT));
5960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_B_VALUE)) {
5970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_B, DISCOVERY_B_DEFAULT));
5980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_F_VALUE)) {
5990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_F, DISCOVERY_F_DEFAULT));
6000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_NFCIP_VALUE)) {
6010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_NFCIP, DISCOVERY_NFCIP_DEFAULT));
6020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_15693_VALUE)) {
6030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_15693, DISCOVERY_15693_DEFAULT));
604f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
6050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return "Unknown property";
606f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
607f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
608f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
6090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int[] getSecureElementList() throws RemoteException {
610d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
611bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
6120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            int[] list = null;
6130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mIsNfcEnabled == true) {
6140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                list = mManager.doGetSecureElementList();
6150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
6160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return list;
6170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
6180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getSelectedSecureElement() throws RemoteException {
620d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
6210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mSelectedSeId;
6230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
6240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public boolean isEnabled() throws RemoteException {
6260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mIsNfcEnabled;
6270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
6280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public void openTagConnection(Tag tag) throws RemoteException {
630b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            // TODO: Remove obsolete code
6310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
6320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int selectSecureElement(int seId) throws RemoteException {
634d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
635f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
636f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
637f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
638f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
639f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
640f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
6410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mSelectedSeId == seId) {
6420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_SE_ALREADY_SELECTED;
6430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
6440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mSelectedSeId != 0) {
6460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_SE_CONNECTED;
6470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
6480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mSelectedSeId = seId;
6500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mManager.doSelectSecureElement(mSelectedSeId);
6510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* store */
6530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mPrefsEditor.putBoolean(PREF_SECURE_ELEMENT_ON, true);
6540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mPrefsEditor.putInt(PREF_SECURE_ELEMENT_ID, mSelectedSeId);
6552f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick            mPrefsEditor.apply();
6560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mNfcSecureElementState = true;
6580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return ErrorCodes.SUCCESS;
6600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
6620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6632f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly        public synchronized void setOpenTimeout(int timeout) throws RemoteException {
664d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
6650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mTimeout = timeout;
6660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
6670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int setProperties(String param, String value) throws RemoteException {
669d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
6700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (isEnabled()) {
6720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NFC_ON;
6730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
6740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            int val;
6760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* Check params validity */
6780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (param == null || value == null) {
6790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_INVALID_PARAM;
6800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
6810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (param.equals(PROPERTY_LLCP_LTO_VALUE)) {
6830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                val = Integer.parseInt(value);
6840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Check params */
6860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (val > LLCP_LTO_MAX)
6870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_INVALID_PARAM;
6880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
6900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putInt(PREF_LLCP_LTO, val);
6912f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
6920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
6940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_LLCP_LTO, val);
6950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_LLCP_MIU_VALUE)) {
6970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                val = Integer.parseInt(value);
6980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Check params */
7000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if ((val < LLCP_MIU_DEFAULT) || (val > LLCP_MIU_MAX))
7010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_INVALID_PARAM;
7020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
7040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putInt(PREF_LLCP_MIU, val);
7052f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
7060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
7080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_LLCP_MIU, val);
7090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_LLCP_WKS_VALUE)) {
7110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                val = Integer.parseInt(value);
7120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Check params */
7140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (val > LLCP_WKS_MAX)
7150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_INVALID_PARAM;
7160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
7180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putInt(PREF_LLCP_WKS, val);
7192f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
7200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
7220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_LLCP_WKS, val);
7230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_LLCP_OPT_VALUE)) {
7250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                val = Integer.parseInt(value);
7260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Check params */
7280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (val > LLCP_OPT_MAX)
7290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_INVALID_PARAM;
7300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
7320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putInt(PREF_LLCP_OPT, val);
7332f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
7340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
7360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_LLCP_OPT, val);
7370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_A_VALUE)) {
7390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                boolean b = Boolean.parseBoolean(value);
7400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
7420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putBoolean(PREF_DISCOVERY_A, b);
7432f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
7440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
7460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_A, b ? 1 : 0);
7470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_B_VALUE)) {
7490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                boolean b = Boolean.parseBoolean(value);
7500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
7520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putBoolean(PREF_DISCOVERY_B, b);
7532f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
7540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
7560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_B, b ? 1 : 0);
7570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_F_VALUE)) {
7590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                boolean b = Boolean.parseBoolean(value);
7600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
7620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putBoolean(PREF_DISCOVERY_F, b);
7632f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
7640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
7660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_F, b ? 1 : 0);
7670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_15693_VALUE)) {
7690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                boolean b = Boolean.parseBoolean(value);
7700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
7720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putBoolean(PREF_DISCOVERY_15693, b);
7732f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
7740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
7760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_15693, b ? 1 : 0);
7770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_NFCIP_VALUE)) {
7790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                boolean b = Boolean.parseBoolean(value);
7800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
7820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putBoolean(PREF_DISCOVERY_NFCIP, b);
7832f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
7840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
7860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_NFCIP, b ? 1 : 0);
7870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
788f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
7890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_INVALID_PARAM;
790f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
7910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return ErrorCodes.SUCCESS;
793f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
794f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
7953ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton        @Override
7960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public NdefMessage localGet() throws RemoteException {
797d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
798d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
7993ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton            synchronized (this) {
8003ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                return mLocalMessage;
8013ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton            }
8020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
8030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8043ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton        @Override
8050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public void localSet(NdefMessage message) throws RemoteException {
806d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
807d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
8083ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton            synchronized (this) {
8093ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                mLocalMessage = message;
8103ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                // Send a message to the UI thread to show or hide the icon so the requests are
8113ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                // serialized and the icon can't get out of sync with reality.
8123ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                if (message != null) {
8133ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                    sendMessage(MSG_SHOW_MY_TAG_ICON, null);
8143ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                } else {
8153ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                    sendMessage(MSG_HIDE_MY_TAG_ICON, null);
8163ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                }
8173ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton            }
8180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
8190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    };
8200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private final ILlcpSocket mLlcpSocket = new ILlcpSocket.Stub() {
8220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        private final int CONNECT_FLAG = 0x01;
8240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        private final int CLOSE_FLAG   = 0x02;
8250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        private final int RECV_FLAG    = 0x04;
8260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        private final int SEND_FLAG    = 0x08;
8270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        private int concurrencyFlags;
8290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        private Object sync;
8300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int close(int nativeHandle) throws RemoteException {
832d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
833bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
834f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpSocket socket = null;
8350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
836f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
837f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
838f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
839f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
840f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
841f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
842f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
843f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
844f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
8450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
8460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    isSuccess = socket.doClose();
8470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (isSuccess) {
8480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Remove the socket closed from the hmap */
8490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        RemoveSocket(nativeHandle);
8500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Update mNbSocketCreated */
8510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        mNbSocketCreated--;
8520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.SUCCESS;
8530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    } else {
8540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_IO;
8550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
856f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
8570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Remove the socket closed from the hmap */
8580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    RemoveSocket(nativeHandle);
8590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Remove registered socket from the list */
8610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    RemoveRegisteredSocket(nativeHandle);
8620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Update mNbSocketCreated */
8640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mNbSocketCreated--;
8650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.SUCCESS;
867f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
868f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
8690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_IO;
870f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
871f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
872f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
8730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int connect(int nativeHandle, int sap) throws RemoteException {
874d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
875bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
876f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpSocket socket = null;
8770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
878f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
879f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
880f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
881f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
882f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
883f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
884f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
885f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
886f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
8870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                isSuccess = socket.doConnect(sap, socket.getConnectTimeout());
8880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (isSuccess) {
8890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.SUCCESS;
890f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
891f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return ErrorCodes.ERROR_IO;
892f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
893f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
894f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_IO;
895f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
8960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
897f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
898f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
8990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int connectByName(int nativeHandle, String sn) throws RemoteException {
900d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
901bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
902f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpSocket socket = null;
903f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            boolean isSuccess = false;
904f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
905f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
906f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
907f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
908f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
909f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
910f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
911f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
912f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
9130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                isSuccess = socket.doConnectBy(sn, socket.getConnectTimeout());
914f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                if (isSuccess) {
915f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return ErrorCodes.SUCCESS;
916f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
917f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return ErrorCodes.ERROR_IO;
918f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
919f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
920f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_IO;
921f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
9220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
923f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
924f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
9250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getConnectTimeout(int nativeHandle) throws RemoteException {
926d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
927bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
928f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpSocket socket = null;
929f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
9300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
9310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
9320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
9330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
9340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
935f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
936f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
937f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
9380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return socket.getConnectTimeout();
9390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else {
9400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return 0;
941f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
942f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
943f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
9440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getLocalSap(int nativeHandle) throws RemoteException {
945d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
946bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
9470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket socket = null;
948f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
949f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
950f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
951f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
952f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
953f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
9540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the socket in the hmap */
9550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
9560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (socket != null) {
9570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return socket.getSap();
958f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
9590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return 0;
960f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
961f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
962f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
9630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getLocalSocketMiu(int nativeHandle) throws RemoteException {
964d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
965bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
9660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket socket = null;
967f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
968f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
969f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
9700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
971f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
972f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
973f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
9740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
975f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
9760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return socket.getMiu();
9770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else {
9780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return 0;
979f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
980f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
981f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
9820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getLocalSocketRw(int nativeHandle) throws RemoteException {
983d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
984bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
9850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket socket = null;
986f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
987f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
988f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
989f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
990f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
991f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
992f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
9930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
9940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (socket != null) {
9950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return socket.getRw();
9960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else {
9970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return 0;
9980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
9990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
10000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getRemoteSocketMiu(int nativeHandle) throws RemoteException {
1002d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
10030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket socket = null;
10050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
10070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
10080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
10090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
10100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the socket in the hmap */
10120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
10130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (socket != null) {
10140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (socket.doGetRemoteSocketMiu() != 0) {
10150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return socket.doGetRemoteSocketMiu();
10160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
10170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED;
10180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
10190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else {
10200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED;
10210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
10220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
10230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getRemoteSocketRw(int nativeHandle) throws RemoteException {
1025d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
10260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket socket = null;
10280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
10300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
10310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
10320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
10330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the socket in the hmap */
10350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
10360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (socket != null) {
10370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (socket.doGetRemoteSocketRw() != 0) {
10380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return socket.doGetRemoteSocketRw();
10390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
10400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED;
10410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
10420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else {
10430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED;
10440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
10450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
10460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int receive(int nativeHandle, byte[] receiveBuffer) throws RemoteException {
1048d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
10490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket socket = null;
10510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            int receiveLength = 0;
10520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
10540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
10550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
10560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
10570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the socket in the hmap */
10590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
10600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (socket != null) {
10610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                receiveLength = socket.doReceive(receiveBuffer);
10620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (receiveLength != 0) {
10630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return receiveLength;
10640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
10650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_IO;
10660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
10670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else {
10680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_IO;
10690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
10700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
10710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int send(int nativeHandle, byte[] data) throws RemoteException {
1073d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
10740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket socket = null;
10760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
10770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
10790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
10800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
10810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
10820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the socket in the hmap */
10840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
10850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (socket != null) {
10860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                isSuccess = socket.doSend(data);
10870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (isSuccess) {
10880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.SUCCESS;
10890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
10900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_IO;
10910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
10920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else {
10930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_IO;
10940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
10950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
10960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public void setConnectTimeout(int nativeHandle, int timeout) throws RemoteException {
1098d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
10990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket socket = null;
11010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the socket in the hmap */
11030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
11040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (socket != null) {
11050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                socket.setConnectTimeout(timeout);
11060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
11070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
11080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    };
11100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private final ILlcpServiceSocket mLlcpServerSocketService = new ILlcpServiceSocket.Stub() {
11120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int accept(int nativeHandle) throws RemoteException {
1114d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
11150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpServiceSocket socket = null;
11170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket clientSocket = null;
11180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
11200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
11210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
11220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
11230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mNbSocketCreated < LLCP_SOCKET_NB_MAX) {
11250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* find the socket in the hmap */
11260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                socket = (NativeLlcpServiceSocket) findSocket(nativeHandle);
11270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (socket != null) {
11280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    clientSocket = socket.doAccept(socket.getAcceptTimeout(), socket.getMiu(),
11290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            socket.getRw(), socket.getLinearBufferLength());
11300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (clientSocket != null) {
11310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Add the socket into the socket map */
11322f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        synchronized(this) {
11332f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mSocketMap.put(clientSocket.getHandle(), clientSocket);
11342f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mNbSocketCreated++;
11352f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        }
11360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return clientSocket.getHandle();
11370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    } else {
11380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_IO;
11390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
11400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
11410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_IO;
11420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
11430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else {
11440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES;
11450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
11460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
11480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public void close(int nativeHandle) throws RemoteException {
1150d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
11510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpServiceSocket socket = null;
11530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
11540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
11560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
11570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return;
11580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
11590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the socket in the hmap */
11610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpServiceSocket) findSocket(nativeHandle);
11620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (socket != null) {
11630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
11640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    isSuccess = socket.doClose();
11650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (isSuccess) {
11660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Remove the socket closed from the hmap */
11670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        RemoveSocket(nativeHandle);
11680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Update mNbSocketCreated */
11690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        mNbSocketCreated--;
11700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
11710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
11720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Remove the socket closed from the hmap */
11730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    RemoveSocket(nativeHandle);
11740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Remove registered socket from the list */
11760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    RemoveRegisteredSocket(nativeHandle);
11770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Update mNbSocketCreated */
11790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mNbSocketCreated--;
11800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
11810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
11820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
11830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getAcceptTimeout(int nativeHandle) throws RemoteException {
1185d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
11860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpServiceSocket socket = null;
11880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
11900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
11910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
11920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
11930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the socket in the hmap */
11950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpServiceSocket) findSocket(nativeHandle);
1196f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
1197f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return socket.getAcceptTimeout();
1198f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
1199f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return 0;
1200f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1201f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1202f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1203f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public void setAcceptTimeout(int nativeHandle, int timeout) throws RemoteException {
1204d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1205bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1206f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpServiceSocket socket = null;
1207f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1208f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
1209f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpServiceSocket) findSocket(nativeHandle);
1210f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
1211f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                socket.setAcceptTimeout(timeout);
1212f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1213f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1214f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    };
1215f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1216f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private final ILlcpConnectionlessSocket mLlcpConnectionlessSocketService = new ILlcpConnectionlessSocket.Stub() {
1217f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1218f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public void close(int nativeHandle) throws RemoteException {
1219d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1220bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1221f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpConnectionlessSocket socket = null;
1222f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            boolean isSuccess = false;
1223f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1224f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1225f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1226f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return;
1227f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1228f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1229f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
1230f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpConnectionlessSocket) findSocket(nativeHandle);
1231f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
1232f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
1233f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    isSuccess = socket.doClose();
1234f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    if (isSuccess) {
1235f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                        /* Remove the socket closed from the hmap */
1236f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                        RemoveSocket(nativeHandle);
1237f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                        /* Update mNbSocketCreated */
1238f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                        mNbSocketCreated--;
1239f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    }
1240f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
1241f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    /* Remove the socket closed from the hmap */
1242f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    RemoveSocket(nativeHandle);
1243f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1244f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    /* Remove registered socket from the list */
1245f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    RemoveRegisteredSocket(nativeHandle);
1246f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1247f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    /* Update mNbSocketCreated */
1248f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    mNbSocketCreated--;
1249f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
1250f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1251f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1252f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1253f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public int getSap(int nativeHandle) throws RemoteException {
1254d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1255bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1256f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpConnectionlessSocket socket = null;
1257f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1258f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1259f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1260f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
1261f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1262f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1263f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
1264f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpConnectionlessSocket) findSocket(nativeHandle);
1265f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
1266f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return socket.getSap();
1267f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
1268f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return 0;
1269f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1270f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1271f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1272f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public LlcpPacket receiveFrom(int nativeHandle) throws RemoteException {
1273d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1274bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1275f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpConnectionlessSocket socket = null;
1276f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            LlcpPacket packet;
1277f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1278f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1279f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1280f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return null;
1281f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1282f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1283f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
1284f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpConnectionlessSocket) findSocket(nativeHandle);
1285f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
1286f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                packet = socket.doReceiveFrom(socket.getLinkMiu());
1287f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                if (packet != null) {
1288f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return packet;
1289f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
1290f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return null;
1291f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
1292f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return null;
1293f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1294f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1295f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1296f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public int sendTo(int nativeHandle, LlcpPacket packet) throws RemoteException {
1297d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1298bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1299f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpConnectionlessSocket socket = null;
1300f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            boolean isSuccess = false;
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 socket in the hmap */
1308f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpConnectionlessSocket) findSocket(nativeHandle);
1309f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
1310f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                isSuccess = socket.doSendTo(packet.getRemoteSap(), packet.getDataBuffer());
1311f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                if (isSuccess) {
1312f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return ErrorCodes.SUCCESS;
1313f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
1314f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return ErrorCodes.ERROR_IO;
1315f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
1316f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
1317f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_IO;
1318f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1319f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1320f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    };
1321f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1322f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private final INfcTag mNfcTagService = new INfcTag.Stub() {
1323f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1324f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public int close(int nativeHandle) throws RemoteException {
1325d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1326bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1327f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeNfcTag tag = null;
1328f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1329f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1330f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1331f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
1332f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1333f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1334f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1335f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1336f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (tag != null) {
1337b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                /* Remove the device from the hmap */
1338b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                unregisterObject(nativeHandle);
1339b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                tag.asyncDisconnect();
1340b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                return ErrorCodes.SUCCESS;
1341f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1342f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* Restart polling loop for notification */
134365945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            maybeEnableDiscovery();
1344f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mOpenPending = false;
1345f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return ErrorCodes.ERROR_DISCONNECT;
1346f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1347f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1348f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public int connect(int nativeHandle) throws RemoteException {
1349d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1350bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1351f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeNfcTag tag = null;
1352f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1353f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1354f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1355f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
1356f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1357f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1358f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1359f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1360b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            if (tag == null) {
1361b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                return ErrorCodes.ERROR_DISCONNECT;
1362f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1363b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            // TODO: register the tag as being locked rather than really connect
1364b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            return ErrorCodes.SUCCESS;
1365f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1366f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1367f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public String getType(int nativeHandle) throws RemoteException {
1368d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1369bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1370f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeNfcTag tag = null;
1371f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            String type;
1372f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1373f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1374f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1375f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return null;
1376f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1377f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1378f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1379f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1380f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (tag != null) {
1381f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                type = tag.getType();
1382f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return type;
1383f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1384f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return null;
1385f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1386f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1387f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public byte[] getUid(int nativeHandle) throws RemoteException {
1388f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeNfcTag tag = null;
1389f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            byte[] uid;
1390f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1391f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1392f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1393f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return null;
1394f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1395f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1396f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1397f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1398f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (tag != null) {
1399f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                uid = tag.getUid();
1400f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return uid;
1401f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1402f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return null;
1403f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1404f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1405b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        public boolean isPresent(int nativeHandle) throws RemoteException {
1406b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            NativeNfcTag tag = null;
1407b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
1408b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            // Check if NFC is enabled
1409b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            if (!mIsNfcEnabled) {
1410b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                return false;
1411b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            }
1412b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
1413b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            /* find the tag in the hmap */
1414b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            tag = (NativeNfcTag) findObject(nativeHandle);
1415b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            if (tag == null) {
1416b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                return false;
1417b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            }
1418b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
1419b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            return tag.presenceCheck();
1420b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        }
1421b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
1422f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public boolean isNdef(int nativeHandle) throws RemoteException {
1423f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeNfcTag tag = null;
1424f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            boolean isSuccess = false;
1425f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1426f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1427f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1428f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return isSuccess;
1429f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1430f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1431f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1432f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1433f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (tag != null) {
1434b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                isSuccess = tag.checkNdef();
1435f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1436f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return isSuccess;
1437f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1438f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1439f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public byte[] transceive(int nativeHandle, byte[] data) throws RemoteException {
1440d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1441bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1442f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeNfcTag tag = null;
1443f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            byte[] response;
1444f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1445f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1446f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1447f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return null;
1448f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1449f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1450f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1451f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1452f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (tag != null) {
1453b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                response = tag.transceive(data);
1454f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return response;
1455f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1456f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return null;
1457f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1458f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1459f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public NdefMessage read(int nativeHandle) throws RemoteException {
1460d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(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 null;
1467f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1468f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1469f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1470f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1471f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (tag != null) {
1472b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                byte[] buf = tag.read();
1473f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                if (buf == null)
1474f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return null;
1475f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1476f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                /* Create an NdefMessage */
1477f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                try {
1478f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return new NdefMessage(buf);
1479f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } catch (FormatException e) {
1480f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return null;
1481f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
1482f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1483f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return null;
1484f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1485f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1486f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public int write(int nativeHandle, NdefMessage msg) throws RemoteException {
1487d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1488bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1489f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeNfcTag tag;
1490f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1491f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1492f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1493f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
1494f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1495f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1496f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1497f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1498f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (tag == null) {
1499f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_IO;
1500f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1501f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1502b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            if (tag.write(msg.toByteArray())) {
1503f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.SUCCESS;
1504f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1505f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            else {
1506f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_IO;
1507f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1508f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1509f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1510f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1511f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public int getLastError(int nativeHandle) throws RemoteException {
1512f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // TODO Auto-generated method stub
15130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return 0;
1514f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1515f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getModeHint(int nativeHandle) throws RemoteException {
15170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // TODO Auto-generated method stub
15180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return 0;
1519f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1520f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int makeReadOnly(int nativeHandle) throws RemoteException {
15220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // TODO Auto-generated method stub
15230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return 0;
1524f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1525f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1526f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    };
1528f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private final IP2pInitiator mP2pInitiatorService = new IP2pInitiator.Stub() {
1530f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public byte[] getGeneralBytes(int nativeHandle) throws RemoteException {
1532d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1533f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
1535f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
15370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
15380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return null;
15390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
1540f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
15420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
15430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
15440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                byte[] buff = device.getGeneralBytes();
15450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (buff == null)
15460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return null;
15470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return buff;
15480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
15490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return null;
15500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
1551f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getMode(int nativeHandle) throws RemoteException {
1553d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1554f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
1556f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
15580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
15590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
15600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
1561f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
15630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
15640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
15650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return device.getMode();
15660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
1567f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return ErrorCodes.ERROR_INVALID_PARAM;
1568f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1569f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public byte[] receive(int nativeHandle) throws RemoteException {
1571d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1572f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
1574f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
15760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
15770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return null;
15780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
1579f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
15810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
15820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
15830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                byte[] buff = device.doReceive();
15840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (buff == null)
15850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return null;
15860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return buff;
15870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
15880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* Restart polling loop for notification */
158965945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            maybeEnableDiscovery();
15900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mOpenPending = false;
15910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return null;
15920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
1593f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public boolean send(int nativeHandle, byte[] data) throws RemoteException {
1595d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1596f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
15980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
1599f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
16010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
16020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return isSuccess;
16030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
1604f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
16060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
16070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
16080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                isSuccess = device.doSend(data);
16090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
16100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return isSuccess;
16110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
16120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    };
1613f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private final IP2pTarget mP2pTargetService = new IP2pTarget.Stub() {
1615f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int connect(int nativeHandle) throws RemoteException {
1617d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1618f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
1620f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
16220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
16230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
16240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
1625f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
16270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
16280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
16290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (device.doConnect()) {
16300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.SUCCESS;
16310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
16320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
16330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return ErrorCodes.ERROR_CONNECT;
16340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
1635f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public boolean disconnect(int nativeHandle) throws RemoteException {
1637d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1638f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
16400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
1641f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
16430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
16440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return isSuccess;
16450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
1646f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
16480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
16490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
16500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (isSuccess = device.doDisconnect()) {
16510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mOpenPending = false;
16520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* remove the device from the hmap */
1653b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                    unregisterObject(nativeHandle);
16540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Restart polling loop for notification */
165565945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly                    maybeEnableDiscovery();
16560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
1657f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
16580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return isSuccess;
1659f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
1661f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public byte[] getGeneralBytes(int nativeHandle) throws RemoteException {
1663d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1664f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
16660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
16670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
16680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
16690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return null;
1670f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1671f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
16730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
16740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
16750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                byte[] buff = device.getGeneralBytes();
16760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (buff == null)
16770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return null;
16780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return buff;
16790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
16800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return null;
16810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
1682f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getMode(int nativeHandle) throws RemoteException {
1684d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1685f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
1687f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
16890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
16900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
1691f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1692f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
16940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
16950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
16960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return device.getMode();
16970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
16980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return ErrorCodes.ERROR_INVALID_PARAM;
16990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
1700f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public byte[] transceive(int nativeHandle, byte[] data) throws RemoteException {
1702d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1703f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
1705f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
17070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
17080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return null;
1709f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1710f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
17120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
17130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
17140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                byte[] buff = device.doTransceive(data);
17150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (buff == null)
17160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return null;
17170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return buff;
17180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
17190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return null;
17200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
17210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    };
1722f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private boolean _enable(boolean oldEnabledState) {
17240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        boolean isSuccess = mManager.initialize();
17250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        if (isSuccess) {
1726f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly            applyProperties();
1727f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly
17280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* Check Secure Element setting */
17290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mNfcSecureElementState = mPrefs.getBoolean(PREF_SECURE_ELEMENT_ON,
17300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    SECURE_ELEMENT_ON_DEFAULT);
1731f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mNfcSecureElementState) {
17330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                int secureElementId = mPrefs.getInt(PREF_SECURE_ELEMENT_ID,
17340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        SECURE_ELEMENT_ID_DEFAULT);
17350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                int[] Se_list = mManager.doGetSecureElementList();
17360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (Se_list != null) {
17370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    for (int i = 0; i < Se_list.length; i++) {
17380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        if (Se_list[i] == secureElementId) {
17390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            mManager.doSelectSecureElement(Se_list[i]);
17400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            mSelectedSeId = Se_list[i];
17410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            break;
17420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        }
17430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
17440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
1745f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1746f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
174765945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            mIsNfcEnabled = true;
174865945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly
17490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* Start polling loop */
175065945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            maybeEnableDiscovery();
1751f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1752f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        } else {
17530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mIsNfcEnabled = false;
1754f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1755f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        updateNfcOnSetting(oldEnabledState);
1757f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        return isSuccess;
1759f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1760f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
176165945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly    /** Enable active tag discovery if screen is on and NFC is enabled */
176265945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly    private synchronized void maybeEnableDiscovery() {
176365945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly        if (mScreenOn && mIsNfcEnabled) {
176465945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            mManager.enableDiscovery(DISCOVERY_MODE_READER);
1765d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton//            mMyTagServer.start();
176665945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly        }
176765945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly    }
176865945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly
176965945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly    /** Disable active tag discovery if necessary */
177065945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly    private synchronized void maybeDisableDiscovery() {
177165945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly        if (mIsNfcEnabled) {
177265945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            mManager.disableDiscovery();
1773d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton//            mMyTagServer.stop();
177465945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly        }
177565945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly    }
177665945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly
1777f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly    private void applyProperties() {
1778f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_LLCP_LTO, mPrefs.getInt(PREF_LLCP_LTO, LLCP_LTO_DEFAULT));
1779f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_LLCP_MIU, mPrefs.getInt(PREF_LLCP_MIU, LLCP_MIU_DEFAULT));
1780f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_LLCP_WKS, mPrefs.getInt(PREF_LLCP_WKS, LLCP_WKS_DEFAULT));
1781f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_LLCP_OPT, mPrefs.getInt(PREF_LLCP_OPT, LLCP_OPT_DEFAULT));
1782f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_A,
1783f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly                mPrefs.getBoolean(PREF_DISCOVERY_A, DISCOVERY_A_DEFAULT) ? 1 : 0);
1784f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_B,
1785f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly                mPrefs.getBoolean(PREF_DISCOVERY_B, DISCOVERY_B_DEFAULT) ? 1 : 0);
1786f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_F,
1787f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly                mPrefs.getBoolean(PREF_DISCOVERY_F, DISCOVERY_F_DEFAULT) ? 1 : 0);
1788f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_15693,
1789f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly                mPrefs.getBoolean(PREF_DISCOVERY_15693, DISCOVERY_15693_DEFAULT) ? 1 : 0);
1790f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_NFCIP,
1791f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly                mPrefs.getBoolean(PREF_DISCOVERY_NFCIP, DISCOVERY_NFCIP_DEFAULT) ? 1 : 0);
1792f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly     }
1793f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly
17940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private void updateNfcOnSetting(boolean oldEnabledState) {
17950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        int state;
1796f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mPrefsEditor.putBoolean(PREF_NFC_ON, mIsNfcEnabled);
17982f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick        mPrefsEditor.apply();
17990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
18002f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly        synchronized(this) {
18012f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly            if (mBootComplete && oldEnabledState != mIsNfcEnabled) {
18022f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                Intent intent = new Intent(NfcAdapter.ACTION_ADAPTER_STATE_CHANGE);
18032f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                intent.putExtra(NfcAdapter.EXTRA_NEW_BOOLEAN_STATE, mIsNfcEnabled);
18042f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                mContext.sendBroadcast(intent);
18052f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly            }
18060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
1807f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1808f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1809f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    // Reset all internals
18102f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    private synchronized void reset() {
181174180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick        // TODO: none of these appear to be synchronized but are
181274180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick        // read/written from different threads (notably Binder threads)...
1813f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1814f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        // Clear tables
1815f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mObjectMap.clear();
1816f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mSocketMap.clear();
1817f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mRegisteredSocketList.clear();
1818f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1819f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        // Reset variables
1820f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mLlcpLinkState = NfcAdapter.LLCP_LINK_STATE_DEACTIVATED;
1821f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mNbSocketCreated = 0;
1822f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mIsNfcEnabled = false;
1823f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mSelectedSeId = 0;
1824f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mTimeout = 0;
1825f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mOpenPending = false;
1826f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1827f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
18282f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    private synchronized Object findObject(int key) {
1829f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        Object device = null;
1830f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1831f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        device = mObjectMap.get(key);
1832f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        if (device == null) {
1833f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            Log.w(TAG, "Handle not found !");
1834f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1835f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1836f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        return device;
1837f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1838f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
18392f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    synchronized void registerTagObject(NativeNfcTag nativeTag) {
1840b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        mObjectMap.put(nativeTag.getHandle(), nativeTag);
1841b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    }
1842b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
18432f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    synchronized void unregisterObject(int handle) {
1844b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        mObjectMap.remove(handle);
1845f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1846f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
18472f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    private synchronized Object findSocket(int key) {
1848f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        Object socket = null;
1849f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1850f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        socket = mSocketMap.get(key);
1851f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1852f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        return socket;
1853f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1854f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1855f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private void RemoveSocket(int key) {
1856f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mSocketMap.remove(key);
1857f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1858f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1859f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private boolean CheckSocketSap(int sap) {
1860f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        /* List of sockets registered */
1861f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        ListIterator<RegisteredSocket> it = mRegisteredSocketList.listIterator();
1862f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1863f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        while (it.hasNext()) {
1864f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            RegisteredSocket registeredSocket = it.next();
1865f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1866f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (sap == registeredSocket.mSap) {
1867f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                /* SAP already used */
1868f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return false;
1869f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1870f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1871f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        return true;
1872f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1873f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1874f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private boolean CheckSocketOptions(int miu, int rw, int linearBufferlength) {
1875f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
18760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        if (rw > LLCP_RW_MAX_VALUE || miu < LLCP_MIU_DEFAULT || linearBufferlength < miu) {
1877f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return false;
1878f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1879f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        return true;
1880f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1881f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1882f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private boolean CheckSocketServiceName(String sn) {
1883f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1884f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        /* List of sockets registered */
1885f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        ListIterator<RegisteredSocket> it = mRegisteredSocketList.listIterator();
1886f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1887f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        while (it.hasNext()) {
1888f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            RegisteredSocket registeredSocket = it.next();
1889f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1890f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (sn.equals(registeredSocket.mServiceName)) {
1891f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                /* Service Name already used */
1892f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return false;
1893f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1894f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1895f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        return true;
1896f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1897f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1898f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private void RemoveRegisteredSocket(int nativeHandle) {
1899f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        /* check if sockets are registered */
1900f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        ListIterator<RegisteredSocket> it = mRegisteredSocketList.listIterator();
1901f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1902f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        while (it.hasNext()) {
1903f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            RegisteredSocket registeredSocket = it.next();
1904f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (registeredSocket.mHandle == nativeHandle) {
1905f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                /* remove the registered socket from the list */
1906f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                it.remove();
1907f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                Log.d(TAG, "socket removed");
1908f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1909f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1910f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1911f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1912f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    /*
1913f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly     * RegisteredSocket class to store the creation request of socket until the
1914f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly     * LLCP link in not activated
1915f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly     */
1916f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private class RegisteredSocket {
1917f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        private final int mType;
1918f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1919f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        private final int mHandle;
1920f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1921f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        private final int mSap;
1922f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1923f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        private int mMiu;
1924f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1925f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        private int mRw;
1926f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1927f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        private String mServiceName;
1928f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1929f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        private int mlinearBufferLength;
1930f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1931f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        RegisteredSocket(int type, int handle, int sap, String sn, int miu, int rw,
1932f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                int linearBufferLength) {
1933f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mType = type;
1934f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mHandle = handle;
1935f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mSap = sap;
1936f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mServiceName = sn;
1937f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mRw = rw;
1938f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mMiu = miu;
1939f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mlinearBufferLength = linearBufferLength;
1940f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1941f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1942f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        RegisteredSocket(int type, int handle, int sap, int miu, int rw, int linearBufferLength) {
1943f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mType = type;
1944f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mHandle = handle;
1945f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mSap = sap;
1946f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mRw = rw;
1947f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mMiu = miu;
1948f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mlinearBufferLength = linearBufferLength;
1949f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1950f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1951f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        RegisteredSocket(int type, int handle, int sap) {
1952f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mType = type;
1953f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mHandle = handle;
1954f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mSap = sap;
1955f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1956f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1957f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1958d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    /** For use by code in this process */
1959d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    public LlcpSocket createLlcpSocket(int sap, int miu, int rw, int linearBufferLength) {
1960d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        try {
1961d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            int handle = mNfcAdapter.createLlcpSocket(sap, miu, rw, linearBufferLength);
1962d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            return new LlcpSocket(mLlcpSocket, handle);
1963d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        } catch (RemoteException e) {
1964d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            // This will never happen since the code is calling into it's own process
1965d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            throw new IllegalStateException("unable to talk to myself", e);
1966d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        }
1967d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    }
1968d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
1969d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    /** For use by code in this process */
1970d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    public LlcpServiceSocket createLlcpServiceSocket(int sap, String sn, int miu, int rw,
1971d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            int linearBufferLength) {
1972d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        try {
1973d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            int handle = mNfcAdapter.createLlcpServiceSocket(sap, sn, miu, rw, linearBufferLength);
1974d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            return new LlcpServiceSocket(mLlcpServerSocketService, mLlcpSocket, handle);
1975d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        } catch (RemoteException e) {
1976d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            // This will never happen since the code is calling into it's own process
1977d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            throw new IllegalStateException("unable to talk to myself", e);
1978d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        }
1979d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    }
1980d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
19810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private void activateLlcpLink() {
19820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        /* check if sockets are registered */
19830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        ListIterator<RegisteredSocket> it = mRegisteredSocketList.listIterator();
1984f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
19850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        Log.d(TAG, "Nb socket resgistered = " + mRegisteredSocketList.size());
1986f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
19870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        while (it.hasNext()) {
19880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            RegisteredSocket registeredSocket = it.next();
1989f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
19900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            switch (registeredSocket.mType) {
19910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            case LLCP_SERVICE_SOCKET_TYPE:
19920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                Log.d(TAG, "Registered Llcp Service Socket");
19930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                NativeLlcpServiceSocket serviceSocket;
19940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
19950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                serviceSocket = mManager.doCreateLlcpServiceSocket(
19960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        registeredSocket.mSap, registeredSocket.mServiceName,
19970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        registeredSocket.mMiu, registeredSocket.mRw,
19980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        registeredSocket.mlinearBufferLength);
19990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
20000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (serviceSocket != null) {
20010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Add the socket into the socket map */
20022f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    synchronized(NfcService.this) {
20032f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mSocketMap.put(registeredSocket.mHandle, serviceSocket);
20042f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    }
20050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
20060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* socket creation error - update the socket
20070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                     * handle counter */
20080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mGeneratedSocketHandle -= 1;
20090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
20100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                break;
20110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
20120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            case LLCP_SOCKET_TYPE:
20130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                Log.d(TAG, "Registered Llcp Socket");
20140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                NativeLlcpSocket clientSocket;
20150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                clientSocket = mManager.doCreateLlcpSocket(registeredSocket.mSap,
20160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        registeredSocket.mMiu, registeredSocket.mRw,
20170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        registeredSocket.mlinearBufferLength);
20180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (clientSocket != null) {
20190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Add the socket into the socket map */
20202f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    synchronized(NfcService.this) {
20212f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mSocketMap.put(registeredSocket.mHandle, clientSocket);
20222f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    }
20230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
20240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* socket creation error - update the socket
20250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                     * handle counter */
20260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mGeneratedSocketHandle -= 1;
20270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
20280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                break;
20290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
20300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            case LLCP_CONNECTIONLESS_SOCKET_TYPE:
20310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                Log.d(TAG, "Registered Llcp Connectionless Socket");
20320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                NativeLlcpConnectionlessSocket connectionlessSocket;
20330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                connectionlessSocket = mManager.doCreateLlcpConnectionlessSocket(
20340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        registeredSocket.mSap);
20350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (connectionlessSocket != null) {
20360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Add the socket into the socket map */
20372f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    synchronized(NfcService.this) {
20382f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mSocketMap.put(registeredSocket.mHandle, connectionlessSocket);
20392f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    }
20400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
20410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* socket creation error - update the socket
20420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                     * handle counter */
20430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mGeneratedSocketHandle -= 1;
20440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
20450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                break;
2046f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
20470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
2048f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
20490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        /* Remove all registered socket from the list */
20500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mRegisteredSocketList.clear();
2051f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
20520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        /* Broadcast Intent Link LLCP activated */
20530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        Intent LlcpLinkIntent = new Intent();
20540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        LlcpLinkIntent.setAction(NfcAdapter.ACTION_LLCP_LINK_STATE_CHANGED);
2055f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
20560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        LlcpLinkIntent.putExtra(NfcAdapter.EXTRA_LLCP_LINK_STATE_CHANGED,
20570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                NfcAdapter.LLCP_LINK_STATE_ACTIVATED);
2058f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
20590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        Log.d(TAG, "Broadcasting LLCP activation");
20600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mContext.sendOrderedBroadcast(LlcpLinkIntent, NFC_PERM);
20610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    }
2062f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2063d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    public void sendMockNdefTag(NdefMessage msg) {
2064d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        NdefTag tag = NdefTag.createMockNdefTag(new byte[] { 0x00 },
2065d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton                new String[] { Tag.TARGET_OTHER },
2066d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton                null, null, new String[] { NdefTag.TARGET_OTHER },
2067d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton                new NdefMessage[][] { new NdefMessage[] { msg } });
2068d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        sendMessage(MSG_MOCK_NDEF_TAG, tag);
2069d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    }
2070d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
2071b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    void sendMessage(int what, Object obj) {
2072b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        Message msg = mHandler.obtainMessage();
2073b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        msg.what = what;
2074b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        msg.obj = obj;
2075b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        mHandler.sendMessage(msg);
2076b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    }
2077b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
2078b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    private final Handler mHandler = new Handler() {
2079b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        @Override
2080b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        public void handleMessage(Message msg) {
2081f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           switch (msg.what) {
2082d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton           case MSG_MOCK_NDEF_TAG: {
2083d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton               NdefTag tag = (NdefTag) msg.obj;
2084d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton               Intent intent = buildNdefTagIntent(tag);
2085d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton               Log.d(TAG, "mock NDEF tag, starting corresponding activity");
2086d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton               Log.d(TAG, tag.toString());
2087d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton               try {
2088d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton                   mContext.startActivity(intent);
2089d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton               } catch (ActivityNotFoundException e) {
2090d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton                   Log.w(TAG, "No activity found for mock tag");
2091d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton               }
2092d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton           }
2093d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
2094f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           case MSG_NDEF_TAG:
2095f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.d(TAG, "Tag detected, notifying applications");
2096f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               NativeNfcTag nativeTag = (NativeNfcTag) msg.obj;
2097f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               if (nativeTag.connect()) {
2098f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   if (nativeTag.checkNdef()) {
2099f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       byte[] buff = nativeTag.read();
2100f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       if (buff != null) {
2101f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           NdefMessage[] msgNdef = new NdefMessage[1];
2102f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           try {
2103f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               msgNdef[0] = new NdefMessage(buff);
2104f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               NdefTag tag = new NdefTag(nativeTag.getUid(),
21051cf8ba9546ba5204af08b8de2c542b6a1bf8f8a0Nick Pelly                                       TagTarget.internalTypeToRawTargets(nativeTag.getType()),
2106f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                                       null, null, nativeTag.getHandle(),
2107f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                                       TagTarget.internalTypeToNdefTargets(nativeTag.getType()),
2108f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                                       new NdefMessage[][] {msgNdef});
2109d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton                               Intent intent = buildNdefTagIntent(tag);
2110f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               Log.d(TAG, "NDEF tag found, starting corresponding activity");
21111cf8ba9546ba5204af08b8de2c542b6a1bf8f8a0Nick Pelly                               Log.d(TAG, tag.toString());
2112b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                               try {
2113b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                                   mContext.startActivity(intent);
2114b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                               } catch (ActivityNotFoundException e) {
2115b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                                   Log.w(TAG, "No activity found, disconnecting");
2116b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                                   nativeTag.asyncDisconnect();
2117b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                               }
2118f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           } catch (FormatException e) {
2119f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               Log.w(TAG, "Unable to create NDEF message object (tag empty or not well formated)");
2120f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               nativeTag.asyncDisconnect();
2121b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                           }
2122b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                       } else {
2123f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           Log.w(TAG, "Unable to read NDEF message (tag empty or not well formated)");
2124b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                           nativeTag.asyncDisconnect();
2125b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                       }
2126f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   } else {
2127f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       Intent intent = new Intent();
2128f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       Tag tag = new Tag(nativeTag.getUid(), false,
2129f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               TagTarget.internalTypeToRawTargets(nativeTag.getType()),
2130f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               null, null, nativeTag.getHandle());
2131f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       intent.setAction(NfcAdapter.ACTION_TAG_DISCOVERED);
2132f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       intent.putExtra(NfcAdapter.EXTRA_TAG, tag);
2133f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2134f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       Log.d(TAG, "Non-NDEF tag found, starting corresponding activity");
2135f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       Log.d(TAG, tag.toString());
2136f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       try {
2137f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           mContext.startActivity(intent);
2138f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       } catch (ActivityNotFoundException e) {
2139f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           Log.w(TAG, "No activity found, disconnecting");
2140f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           nativeTag.asyncDisconnect();
2141f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       }
2142f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   }
2143f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               } else {
2144f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   Log.w(TAG, "Failed to connect to tag");
2145f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   nativeTag.asyncDisconnect();
2146f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               }
2147f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               break;
2148f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           case MSG_CARD_EMULATION:
2149f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.d(TAG, "Card Emulation message");
2150f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               byte[] aid = (byte[]) msg.obj;
2151f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               /* Send broadcast ordered */
2152f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Intent TransactionIntent = new Intent();
2153f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               TransactionIntent.setAction(NfcAdapter.ACTION_TRANSACTION_DETECTED);
2154f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               TransactionIntent.putExtra(NfcAdapter.EXTRA_AID, aid);
2155f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.d(TAG, "Broadcasting Card Emulation event");
2156f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               mContext.sendOrderedBroadcast(TransactionIntent, NFC_PERM);
2157f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               break;
2158f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly
2159f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           case MSG_LLCP_LINK_ACTIVATION:
2160f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               NativeP2pDevice device = (NativeP2pDevice) msg.obj;
2161f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly
2162f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.d(TAG, "LLCP Activation message");
2163f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly
2164f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               if (device.getMode() == NativeP2pDevice.MODE_P2P_TARGET) {
2165f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   if (device.doConnect()) {
2166f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       /* Check Llcp compliancy */
2167f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       if (mManager.doCheckLlcp()) {
2168f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           /* Activate Llcp Link */
2169f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           if (mManager.doActivateLlcp()) {
2170f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               Log.d(TAG, "Initiator Activate LLCP OK");
2171f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               /* Broadcast Intent Link LLCP activated */
2172f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               Intent LlcpLinkIntent = new Intent();
2173f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               LlcpLinkIntent
2174f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                                       .setAction(mManager.INTERNAL_LLCP_LINK_STATE_CHANGED_ACTION);
2175f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               LlcpLinkIntent.putExtra(
2176f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                                       mManager.INTERNAL_LLCP_LINK_STATE_CHANGED_EXTRA,
2177f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                                       NfcAdapter.LLCP_LINK_STATE_ACTIVATED);
2178f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               Log.d(TAG, "Broadcasting internal LLCP activation");
2179f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               mContext.sendBroadcast(LlcpLinkIntent);
2180b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                           }
2181b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
2182f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       } else {
2183f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           device.doDisconnect();
2184b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                       }
2185f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly
2186f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   }
2187f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly
2188f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               } else if (device.getMode() == NativeP2pDevice.MODE_P2P_INITIATOR) {
2189f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   /* Check Llcp compliancy */
2190f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   if (mManager.doCheckLlcp()) {
2191f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       /* Activate Llcp Link */
2192f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       if (mManager.doActivateLlcp()) {
2193f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           Log.d(TAG, "Target Activate LLCP OK");
2194f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           /* Broadcast Intent Link LLCP activated */
2195f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           Intent LlcpLinkIntent = new Intent();
2196f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           LlcpLinkIntent
2197f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                                   .setAction(mManager.INTERNAL_LLCP_LINK_STATE_CHANGED_ACTION);
2198f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           LlcpLinkIntent.putExtra(mManager.INTERNAL_LLCP_LINK_STATE_CHANGED_EXTRA,
2199f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                                   NfcAdapter.LLCP_LINK_STATE_ACTIVATED);
2200f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           Log.d(TAG, "Broadcasting internal LLCP activation");
2201f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           mContext.sendBroadcast(LlcpLinkIntent);
2202f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       }
2203f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   }
2204b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau               }
2205f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               break;
2206f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly
2207f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           case MSG_LLCP_LINK_DEACTIVATED:
2208f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               /* Broadcast Intent Link LLCP activated */
2209f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.d(TAG, "LLCP Link Deactivated message");
2210f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Intent LlcpLinkIntent = new Intent();
2211f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               LlcpLinkIntent.setAction(NfcAdapter.ACTION_LLCP_LINK_STATE_CHANGED);
2212f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               LlcpLinkIntent.putExtra(NfcAdapter.EXTRA_LLCP_LINK_STATE_CHANGED,
2213f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       NfcAdapter.LLCP_LINK_STATE_DEACTIVATED);
2214f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.d(TAG, "Broadcasting LLCP deactivation");
2215f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               mContext.sendOrderedBroadcast(LlcpLinkIntent, NFC_PERM);
2216f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               break;
2217f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly
2218f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           case MSG_TARGET_DESELECTED:
2219f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               /* Broadcast Intent Target Deselected */
2220f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.d(TAG, "Target Deselected");
2221f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Intent TargetDeselectedIntent = new Intent();
2222f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               TargetDeselectedIntent.setAction(mManager.INTERNAL_TARGET_DESELECTED_ACTION);
2223f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.d(TAG, "Broadcasting Intent");
2224f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               mContext.sendOrderedBroadcast(TargetDeselectedIntent, NFC_PERM);
2225f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               break;
2226f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly
22273ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton           case MSG_SHOW_MY_TAG_ICON: {
22283ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton               StatusBarManager sb = (StatusBarManager) getSystemService(
22293ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                       Context.STATUS_BAR_SERVICE);
22303ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton               sb.setIcon("nfc", R.drawable.stat_sys_nfc, 0);
22313ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton               break;
22323ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton           }
22333ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton
22343ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton           case MSG_HIDE_MY_TAG_ICON: {
22353ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton               StatusBarManager sb = (StatusBarManager) getSystemService(
22363ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                       Context.STATUS_BAR_SERVICE);
22373ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton               sb.removeIcon("nfc");
22383ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton               break;
22393ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton           }
22403ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton
2241f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           default:
2242f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.e(TAG, "Unknown message received");
2243f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               break;
2244f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           }
2245b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        }
2246d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
2247d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        private Intent buildNdefTagIntent(NdefTag tag) {
2248d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            Intent intent = new Intent();
2249d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton               intent.setAction(NfcAdapter.ACTION_NDEF_TAG_DISCOVERED);
2250d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton               intent.putExtra(NfcAdapter.EXTRA_TAG, tag);
2251d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton               intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2252d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            return intent;
2253d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        }
2254b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    };
2255b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
22567c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly    private class EnableDisableDiscoveryTask extends AsyncTask<Boolean, Void, Void> {
22577c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly        protected Void doInBackground(Boolean... enable) {
22587c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly            if (enable.length < 0 || enable[1]) {
22597c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly                maybeEnableDiscovery();
22607c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly            } else {
22617c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly                maybeDisableDiscovery();
22627c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly            }
22637c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly            return null;
22647c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly        }
22657c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly    }
22667c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly
22670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
22680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        @Override
22690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public void onReceive(Context context, Intent intent) {
22700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (intent.getAction().equals(NfcAdapter.ACTION_LLCP_LINK_STATE_CHANGED)) {
22710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                Log.d(TAG, "LLCP_LINK_STATE_CHANGED");
2272f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
22730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mLlcpLinkState = intent.getIntExtra(
22740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        NfcAdapter.EXTRA_LLCP_LINK_STATE_CHANGED,
22750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        NfcAdapter.LLCP_LINK_STATE_DEACTIVATED);
2276f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
22770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_DEACTIVATED) {
22780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* restart polling loop */
227965945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly                    maybeEnableDiscovery();
22800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
22810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    activateLlcpLink();
2282f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
22830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (intent.getAction().equals(
2284f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION)) {
22850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                Log.d(TAG, "INERNAL_TARGET_DESELECTED_ACTION");
22860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
22870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mOpenPending = false;
2288f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                /* Restart polling loop for notification */
228965945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly                maybeEnableDiscovery();
2290f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
22910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
22922f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                Log.i(TAG, "Boot complete");
22930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
22942f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                synchronized(this) {
22952f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    mBootComplete = true;
22962f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly
22972f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    // now its safe to send the NFC state
22982f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    Intent sendIntent = new Intent(NfcAdapter.ACTION_ADAPTER_STATE_CHANGE);
22992f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    sendIntent.putExtra(NfcAdapter.EXTRA_NEW_BOOLEAN_STATE, mIsNfcEnabled);
23002f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    mContext.sendBroadcast(sendIntent);
23012f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                }
230265945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
230365945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly                synchronized (NfcService.this) {
230465945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly                    mScreenOn = true;
230565945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly                }
23067c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly                // Perform discovery enable in thread to protect against ANR when the
23077c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly                // NFC stack wedges. This is *not* the correct way to fix this issue -
23087c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly                // configuration of the local NFC adapter should be very quick and should
23097c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly                // be safe on the main thread, and the NFC stack should not wedge.
23107c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly                new EnableDisableDiscoveryTask().execute(true);
231165945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            } else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
231265945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly                synchronized (NfcService.this) {
231365945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly                    mScreenOn = false;
231465945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly                }
23157c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly                // Perform discovery disable in thread to protect against ANR when the
23167c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly                // NFC stack wedges. This is *not* the correct way to fix this issue -
23177c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly                // configuration of the local NFC adapter should be very quick and should
23187c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly                // be safe on the main thread, and the NFC stack should not wedge.
23197c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly                new EnableDisableDiscoveryTask().execute(false);
2320f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
2321f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
2322f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    };
232374180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick}
2324