NfcService.java revision fa746bcc16d57ff12d373b9139558f5bc7164b30
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
53fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parksimport java.io.ByteArrayOutputStream;
54fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parksimport java.io.FileInputStream;
55fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parksimport java.io.FileNotFoundException;
56fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parksimport java.io.FileOutputStream;
57fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parksimport java.io.IOException;
583ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamiltonimport java.util.HashMap;
593ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamiltonimport java.util.LinkedList;
603ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamiltonimport java.util.ListIterator;
613ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton
622f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pellypublic class NfcService extends Application {
63fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks    private static final String MY_TAG_FILE_NAME = "mytag";
64fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks
6513d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly    static {
6613d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly        System.loadLibrary("nfc_jni");
6713d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly    }
6813d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly
69d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    public static final String SERVICE_NAME = "nfc";
70fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks
71f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final String TAG = "NfcService";
72f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
73bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly    private static final String NFC_PERM = android.Manifest.permission.NFC;
74bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly    private static final String NFC_PERM_ERROR = "NFC permission required";
75bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly    private static final String ADMIN_PERM = android.Manifest.permission.WRITE_SECURE_SETTINGS;
76bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly    private static final String ADMIN_PERM_ERROR = "WRITE_SECURE_SETTINGS permission required";
77bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF = "NfcServicePrefs";
79f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_NFC_ON = "nfc_on";
810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final boolean NFC_ON_DEFAULT = true;
82f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_SECURE_ELEMENT_ON = "secure_element_on";
840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final boolean SECURE_ELEMENT_ON_DEFAULT = false;
85f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_SECURE_ELEMENT_ID = "secure_element_id";
870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int SECURE_ELEMENT_ID_DEFAULT = 0;
88f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_LLCP_LTO = "llcp_lto";
90eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton    private static final int LLCP_LTO_DEFAULT = 250;
910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_LTO_MAX = 255;
92f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    /** Maximum Information Unit */
940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_LLCP_MIU = "llcp_miu";
950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_MIU_DEFAULT = 128;
960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_MIU_MAX = 2176;
97f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    /** Well Known Service List */
990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_LLCP_WKS = "llcp_wks";
1000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_WKS_DEFAULT = 1;
1010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_WKS_MAX = 15;
102f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_LLCP_OPT = "llcp_opt";
1040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_OPT_DEFAULT = 0;
1050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_OPT_MAX = 3;
106f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_DISCOVERY_A = "discovery_a";
1080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final boolean DISCOVERY_A_DEFAULT = true;
109f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_DISCOVERY_B = "discovery_b";
1110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final boolean DISCOVERY_B_DEFAULT = true;
112f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_DISCOVERY_F = "discovery_f";
1140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final boolean DISCOVERY_F_DEFAULT = true;
115f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_DISCOVERY_15693 = "discovery_15693";
1170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final boolean DISCOVERY_15693_DEFAULT = true;
118f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final String PREF_DISCOVERY_NFCIP = "discovery_nfcip";
1200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final boolean DISCOVERY_NFCIP_DEFAULT = true;
121f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    /** NFC Reader Discovery mode for enableDiscovery() */
1230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int DISCOVERY_MODE_READER = 0;
124f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    /** Card Emulation Discovery mode for enableDiscovery() */
1260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int DISCOVERY_MODE_CARD_EMULATION = 2;
127f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_SERVICE_SOCKET_TYPE = 0;
1290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_SOCKET_TYPE = 1;
1300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_CONNECTIONLESS_SOCKET_TYPE = 2;
1310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_SOCKET_NB_MAX = 5;  // Maximum number of socket managed
1320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int LLCP_RW_MAX_VALUE = 15;  // Receive Window
133f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
134f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final int PROPERTY_LLCP_LTO = 0;
135f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final String PROPERTY_LLCP_LTO_VALUE = "llcp.lto";
1360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int PROPERTY_LLCP_MIU = 1;
137f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final String PROPERTY_LLCP_MIU_VALUE = "llcp.miu";
1380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int PROPERTY_LLCP_WKS = 2;
139f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final String PROPERTY_LLCP_WKS_VALUE = "llcp.wks";
1400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int PROPERTY_LLCP_OPT = 3;
141f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final String PROPERTY_LLCP_OPT_VALUE = "llcp.opt";
142f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final int PROPERTY_NFC_DISCOVERY_A = 4;
143f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final String PROPERTY_NFC_DISCOVERY_A_VALUE = "discovery.iso14443A";
1440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int PROPERTY_NFC_DISCOVERY_B = 5;
145f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final String PROPERTY_NFC_DISCOVERY_B_VALUE = "discovery.iso14443B";
1460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int PROPERTY_NFC_DISCOVERY_F = 6;
147f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final String PROPERTY_NFC_DISCOVERY_F_VALUE = "discovery.felica";
1480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int PROPERTY_NFC_DISCOVERY_15693 = 7;
149f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final String PROPERTY_NFC_DISCOVERY_15693_VALUE = "discovery.iso15693";
1500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private static final int PROPERTY_NFC_DISCOVERY_NFCIP = 8;
151f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private static final String PROPERTY_NFC_DISCOVERY_NFCIP_VALUE = "discovery.nfcip";
152f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
153b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    static final int MSG_NDEF_TAG = 0;
154b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    static final int MSG_CARD_EMULATION = 1;
155b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    static final int MSG_LLCP_LINK_ACTIVATION = 2;
156b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    static final int MSG_LLCP_LINK_DEACTIVATED = 3;
157b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    static final int MSG_TARGET_DESELECTED = 4;
1583ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton    static final int MSG_SHOW_MY_TAG_ICON = 5;
1593ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton    static final int MSG_HIDE_MY_TAG_ICON = 6;
160d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    static final int MSG_MOCK_NDEF_TAG = 7;
161b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
16274180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick    // TODO: none of these appear to be synchronized but are
16374180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick    // read/written from different threads (notably Binder threads)...
164f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private final LinkedList<RegisteredSocket> mRegisteredSocketList = new LinkedList<RegisteredSocket>();
165f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private int mLlcpLinkState = NfcAdapter.LLCP_LINK_STATE_DEACTIVATED;
166f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private int mGeneratedSocketHandle = 0;
167f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private int mNbSocketCreated = 0;
16874180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick    private volatile boolean mIsNfcEnabled = false;
169f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private int mSelectedSeId = 0;
1700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private boolean mNfcSecureElementState;
171f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private boolean mOpenPending = false;
172f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1732f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    // fields below are used in multiple threads and protected by synchronized(this)
1742f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    private final HashMap<Integer, Object> mObjectMap = new HashMap<Integer, Object>();
1752f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    private final HashMap<Integer, Object> mSocketMap = new HashMap<Integer, Object>();
1762f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    private int mTimeout = 0;
17765945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly    private boolean mScreenOn;
1782f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly
1792f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    // fields below are final after onCreate()
1800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private Context mContext;
1810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private NativeNfcManager mManager;
1820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private SharedPreferences mPrefs;
1830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private SharedPreferences.Editor mPrefsEditor;
184fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks    private MyTagServer mMyTagServer;
185d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    private MyTagClient mMyTagClient;
186d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
187d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    private static NfcService sService;
188d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
189d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    public static NfcService getInstance() {
190d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        return sService;
191d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    }
192f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    @Override
1940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    public void onCreate() {
1952f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly        super.onCreate();
1962f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly
1972f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly        Log.i(TAG, "Starting NFC service");
1982f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly
199d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        sService = this;
200d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
2010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mContext = this;
202b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        mManager = new NativeNfcManager(mContext, this);
2030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mManager.initializeNativeStructure();
20474180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick
205d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        mMyTagServer = new MyTagServer();
206d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        mMyTagClient = new MyTagClient(this);
207d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
2080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mPrefs = mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE);
2090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mPrefsEditor = mPrefs.edit();
210f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
211d6fdd3fbb880f1503d56616608e6823b51320dc3Nick Pelly        mIsNfcEnabled = false;  // real preference read later
21265945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly        mScreenOn = true;  // assume screen is on during boot
213f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
214d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        ServiceManager.addService(SERVICE_NAME, mNfcAdapter);
215f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
216eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton        IntentFilter filter = new IntentFilter(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION);
21765945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly        filter.addAction(Intent.ACTION_SCREEN_OFF);
21865945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly        filter.addAction(Intent.ACTION_SCREEN_ON);
2190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mContext.registerReceiver(mReceiver, filter);
2200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
2210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        Thread t = new Thread() {
2220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            @Override
2230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            public void run() {
2240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                boolean nfc_on = mPrefs.getBoolean(PREF_NFC_ON, NFC_ON_DEFAULT);
2250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (nfc_on) {
2260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    _enable(false);
227f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
228f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
2290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        };
2300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        t.start();
231fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks
232fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        Context context = getApplicationContext();
233fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks
234fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        // Set this to null by default. If there isn't a tag on disk or if there
235fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        // was an error reading the tag then this will cause the status bar icon
236fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        // to be removed.
237fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        NdefMessage myTag = null;
238fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks
239fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        FileInputStream input = null;
240fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks
241fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        try {
242fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            input = context.openFileInput(MY_TAG_FILE_NAME);
243fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            ByteArrayOutputStream bytes = new ByteArrayOutputStream();
244fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks
245fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            byte[] buffer = new byte[4096];
246fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            int read = 0;
247fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            while ((read = input.read(buffer)) > 0) {
248fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                bytes.write(buffer, 0, read);
249fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            }
250fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks
251fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            myTag = new NdefMessage(bytes.toByteArray());
252fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        } catch (FileNotFoundException e) {
253fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            // Ignore.
254fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        } catch (IOException e) {
255fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            Log.e(TAG, "Could not read mytag file: ", e);
256fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            context.deleteFile(MY_TAG_FILE_NAME);
257fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        } catch (FormatException e) {
258fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            Log.e(TAG, "Invalid NdefMessage for mytag", e);
259fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            context.deleteFile(MY_TAG_FILE_NAME);
260fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        } finally {
261fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            try {
262fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                if (input != null) {
263fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                    input.close();
264fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                }
265fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            } catch (IOException e) {
266fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                // Ignore
267fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            }
268fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        }
269fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks
270fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        try {
271fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            mNfcAdapter.localSet(myTag);
272fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        } catch (RemoteException e) {
273fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            // Ignore
274fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        }
2750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    }
2760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
2770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    @Override
2782f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    public void onTerminate() {
2792f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly        super.onTerminate();
2802f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly        // NFC application is persistent, it should not be destroyed by framework
2810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        Log.wtf(TAG, "NFC service is under attack!");
2820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    }
2830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
2840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private final INfcAdapter.Stub mNfcAdapter = new INfcAdapter.Stub() {
2853ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton        /** Protected by "this" */
2863ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton        NdefMessage mLocalMessage = null;
2874acf84356e35861f7df6d07a2b9ff84842a9f221Nick Pelly
288fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
2890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public boolean enable() throws RemoteException {
290d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
2910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
2920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
2930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean previouslyEnabled = isEnabled();
2940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!previouslyEnabled) {
2950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                reset();
2960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                isSuccess = _enable(previouslyEnabled);
297f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
2980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return isSuccess;
299f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
300f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
301fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
3020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public boolean disable() throws RemoteException {
3030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
304d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
3050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean previouslyEnabled = isEnabled();
3060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            Log.d(TAG, "Disabling NFC.  previous=" + previouslyEnabled);
3070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (previouslyEnabled) {
3096f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton                /* tear down the my tag server */
3106f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton                mMyTagServer.stop();
3110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                isSuccess = mManager.deinitialize();
3120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                Log.d(TAG, "NFC success of deinitialize = " + isSuccess);
3130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (isSuccess) {
3140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mIsNfcEnabled = false;
3150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
316f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
3170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            updateNfcOnSetting(previouslyEnabled);
3190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return isSuccess;
321f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
322f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
323fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
3240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int createLlcpConnectionlessSocket(int sap) throws RemoteException {
325d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
326bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
327f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
328f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
329f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
330f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
331f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
3320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* Check SAP is not already used */
3330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* Check nb socket created */
3350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mNbSocketCreated < LLCP_SOCKET_NB_MAX) {
3360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store the socket handle */
3370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                int sockeHandle = mGeneratedSocketHandle;
3380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
339f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
3400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    NativeLlcpConnectionlessSocket socket;
3410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    socket = mManager.doCreateLlcpConnectionlessSocket(sap);
3430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (socket != null) {
3442f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        synchronized(NfcService.this) {
3452f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            /* Update the number of socket created */
3462f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mNbSocketCreated++;
3470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3482f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            /* Add the socket into the socket map */
3492f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mSocketMap.put(sockeHandle, socket);
3502f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        }
3510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return sockeHandle;
352f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    } else {
3530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /*
3540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                         * socket creation error - update the socket handle
3550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                         * generation
3560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                         */
3570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        mGeneratedSocketHandle -= 1;
3580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Get Error Status */
3600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        int errorStatus = mManager.doGetLastError();
3610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        switch (errorStatus) {
3630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            case ErrorCodes.ERROR_BUFFER_TO_SMALL:
3640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_BUFFER_TO_SMALL;
3650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES:
3660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES;
3670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            default:
3680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_SOCKET_CREATION;
3690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        }
370f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    }
371f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
3720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Check SAP is not already used */
3730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (!CheckSocketSap(sap)) {
3740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_SAP_USED;
3750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
376f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
3770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    NativeLlcpConnectionlessSocket socket = new NativeLlcpConnectionlessSocket(sap);
378f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
3792f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    synchronized(NfcService.this) {
3802f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        /* Add the socket into the socket map */
3812f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mSocketMap.put(sockeHandle, socket);
3820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3832f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        /* Update the number of socket created */
3842f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mNbSocketCreated++;
3852f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    }
3860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Create new registered socket */
3870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    RegisteredSocket registeredSocket = new RegisteredSocket(
3880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            LLCP_CONNECTIONLESS_SOCKET_TYPE, sockeHandle, sap);
3890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Put this socket into a list of registered socket */
3910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mRegisteredSocketList.add(registeredSocket);
392f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
3930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* update socket handle generation */
3950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mGeneratedSocketHandle++;
3960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return sockeHandle;
3980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
399f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
4000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* No socket available */
4010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES;
402f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
4030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
404f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
405f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
406fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
4070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int createLlcpServiceSocket(int sap, String sn, int miu, int rw, int linearBufferLength)
4080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                throws RemoteException {
409d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
410bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
411f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
412f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
413f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
414f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
415f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
4160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mNbSocketCreated < LLCP_SOCKET_NB_MAX) {
4170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                int sockeHandle = mGeneratedSocketHandle;
4180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
4200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    NativeLlcpServiceSocket socket;
4210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    socket = mManager.doCreateLlcpServiceSocket(sap, sn, miu, rw, linearBufferLength);
4230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (socket != null) {
4242f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        synchronized(NfcService.this) {
4252f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            /* Update the number of socket created */
4262f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mNbSocketCreated++;
4272f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            /* Add the socket into the socket map */
4282f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mSocketMap.put(sockeHandle, socket);
4292f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        }
4300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    } else {
4310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* socket creation error - update the socket handle counter */
4320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        mGeneratedSocketHandle -= 1;
4330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Get Error Status */
4350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        int errorStatus = mManager.doGetLastError();
4360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        switch (errorStatus) {
4380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            case ErrorCodes.ERROR_BUFFER_TO_SMALL:
4390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_BUFFER_TO_SMALL;
4400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES:
4410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES;
4420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            default:
4430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_SOCKET_CREATION;
4440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        }
4450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
446f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
4470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Check SAP is not already used */
4490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (!CheckSocketSap(sap)) {
4500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_SAP_USED;
4510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
4520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Service Name */
4540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (!CheckSocketServiceName(sn)) {
4550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_SERVICE_NAME_USED;
4560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
4570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Check socket options */
4590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (!CheckSocketOptions(miu, rw, linearBufferLength)) {
4600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_SOCKET_OPTIONS;
4610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
4620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    NativeLlcpServiceSocket socket = new NativeLlcpServiceSocket(sn);
4642f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    synchronized(NfcService.this) {
4652f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        /* Add the socket into the socket map */
4662f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mSocketMap.put(sockeHandle, socket);
4670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4682f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        /* Update the number of socket created */
4692f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mNbSocketCreated++;
4702f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    }
4710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Create new registered socket */
4720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    RegisteredSocket registeredSocket = new RegisteredSocket(LLCP_SERVICE_SOCKET_TYPE,
4730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            sockeHandle, sap, sn, miu, rw, linearBufferLength);
4740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Put this socket into a list of registered socket */
4760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mRegisteredSocketList.add(registeredSocket);
477f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
4780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* update socket handle generation */
4800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mGeneratedSocketHandle += 1;
4810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                Log.d(TAG, "Llcp Service Socket Handle =" + sockeHandle);
4830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return sockeHandle;
484f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
4850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* No socket available */
4860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES;
487f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
488f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
489f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
490fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
4910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int createLlcpSocket(int sap, int miu, int rw, int linearBufferLength)
4920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                throws RemoteException {
493d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
494bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
495f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
496f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
497f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
498f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
499f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
5000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mNbSocketCreated < LLCP_SOCKET_NB_MAX) {
5010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                int sockeHandle = mGeneratedSocketHandle;
5030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
5056f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton                    Log.d(TAG, "creating llcp socket while activated");
5060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    NativeLlcpSocket socket;
5070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    socket = mManager.doCreateLlcpSocket(sap, miu, rw, linearBufferLength);
5090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (socket != null) {
5112f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        synchronized(NfcService.this) {
5122f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            /* Update the number of socket created */
5132f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mNbSocketCreated++;
5142f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            /* Add the socket into the socket map */
5152f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mSocketMap.put(sockeHandle, socket);
5162f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        }
5170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    } else {
5180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /*
5190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                         * socket creation error - update the socket handle
5200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                         * generation
5210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                         */
5220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        mGeneratedSocketHandle -= 1;
5230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Get Error Status */
5250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        int errorStatus = mManager.doGetLastError();
5260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5276f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton                        Log.d(TAG, "failed to create llcp socket: " + ErrorCodes.asString(errorStatus));
5286f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton
5290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        switch (errorStatus) {
5300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            case ErrorCodes.ERROR_BUFFER_TO_SMALL:
5310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_BUFFER_TO_SMALL;
5320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES:
5330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES;
5340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            default:
5350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_SOCKET_CREATION;
5360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        }
5370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
538f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
5396f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton                    Log.d(TAG, "registering llcp socket while not activated");
540f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
5410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Check SAP is not already used */
5420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (!CheckSocketSap(sap)) {
5430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_SAP_USED;
5440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
545f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
5460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Check Socket options */
5470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (!CheckSocketOptions(miu, rw, linearBufferLength)) {
5480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_SOCKET_OPTIONS;
5490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
550bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
5510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    NativeLlcpSocket socket = new NativeLlcpSocket(sap, miu, rw);
5522f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    synchronized(NfcService.this) {
5532f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        /* Add the socket into the socket map */
5542f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mSocketMap.put(sockeHandle, socket);
555f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
5562f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        /* Update the number of socket created */
5572f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mNbSocketCreated++;
5582f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    }
5590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Create new registered socket */
5600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    RegisteredSocket registeredSocket = new RegisteredSocket(LLCP_SOCKET_TYPE,
5610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            sockeHandle, sap, miu, rw, linearBufferLength);
5620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Put this socket into a list of registered socket */
5640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mRegisteredSocketList.add(registeredSocket);
5650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
5660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* update socket handle generation */
5680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mGeneratedSocketHandle++;
5690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return sockeHandle;
571f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
5720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* No socket available */
5730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES;
574f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
575f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
576f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
577fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
5780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int deselectSecureElement() throws RemoteException {
579d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
580f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
581f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
582f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
583f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
584f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
585f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
5860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mSelectedSeId == 0) {
5870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NO_SE_CONNECTED;
588f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
5890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mManager.doDeselectSecureElement(mSelectedSeId);
5910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mNfcSecureElementState = false;
5920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mSelectedSeId = 0;
5930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* store preference */
5950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mPrefsEditor.putBoolean(PREF_SECURE_ELEMENT_ON, false);
5960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mPrefsEditor.putInt(PREF_SECURE_ELEMENT_ID, 0);
5972f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick            mPrefsEditor.apply();
5980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return ErrorCodes.SUCCESS;
600f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
601f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
602fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
6030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public ILlcpConnectionlessSocket getLlcpConnectionlessInterface() throws RemoteException {
604d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
6050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mLlcpConnectionlessSocketService;
6060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
607bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
608fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
6090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public ILlcpSocket getLlcpInterface() throws RemoteException {
610d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
6110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mLlcpSocket;
6120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
613f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
614fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
6150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public ILlcpServiceSocket getLlcpServiceInterface() throws RemoteException {
616d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
6170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mLlcpServerSocketService;
6180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
619f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
620fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
6210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public INfcTag getNfcTagInterface() throws RemoteException {
622d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
6230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mNfcTagService;
6240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
6250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6262f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly        public synchronized int getOpenTimeout() throws RemoteException {
627d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
6280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mTimeout;
6290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
6300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
631fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
6320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public IP2pInitiator getP2pInitiatorInterface() throws RemoteException {
633d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
6340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mP2pInitiatorService;
6350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
6360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
637fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
6380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public IP2pTarget getP2pTargetInterface() throws RemoteException {
639d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
6400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mP2pTargetService;
6410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
6420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
643fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
6440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public String getProperties(String param) throws RemoteException {
645d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
6460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (param == null) {
6480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return null;
6490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
6500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (param.equals(PROPERTY_LLCP_LTO_VALUE)) {
6520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Integer.toString(mPrefs.getInt(PREF_LLCP_LTO, LLCP_LTO_DEFAULT));
6530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_LLCP_MIU_VALUE)) {
6540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Integer.toString(mPrefs.getInt(PREF_LLCP_MIU, LLCP_MIU_DEFAULT));
6550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_LLCP_WKS_VALUE)) {
6560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Integer.toString(mPrefs.getInt(PREF_LLCP_WKS, LLCP_WKS_DEFAULT));
6570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_LLCP_OPT_VALUE)) {
6580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Integer.toString(mPrefs.getInt(PREF_LLCP_OPT, LLCP_OPT_DEFAULT));
6590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_A_VALUE)) {
6600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_A, DISCOVERY_A_DEFAULT));
6610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_B_VALUE)) {
6620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_B, DISCOVERY_B_DEFAULT));
6630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_F_VALUE)) {
6640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_F, DISCOVERY_F_DEFAULT));
6650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_NFCIP_VALUE)) {
6660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_NFCIP, DISCOVERY_NFCIP_DEFAULT));
6670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_15693_VALUE)) {
6680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_15693, DISCOVERY_15693_DEFAULT));
669f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
6700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return "Unknown property";
671f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
672f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
673f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
674fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
6750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int[] getSecureElementList() throws RemoteException {
676d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
677bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
6780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            int[] list = null;
6790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mIsNfcEnabled == true) {
6800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                list = mManager.doGetSecureElementList();
6810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
6820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return list;
6830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
6840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
685fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
6860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getSelectedSecureElement() throws RemoteException {
687d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
6880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mSelectedSeId;
6900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
6910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
692fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
6930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public boolean isEnabled() throws RemoteException {
6940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mIsNfcEnabled;
6950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
6960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
697fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
6980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public void openTagConnection(Tag tag) throws RemoteException {
699b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            // TODO: Remove obsolete code
7000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
7010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
702fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
7030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int selectSecureElement(int seId) throws RemoteException {
704d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
705f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
706f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
707f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
708f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
709f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
710f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
7110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mSelectedSeId == seId) {
7120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_SE_ALREADY_SELECTED;
7130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
7140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mSelectedSeId != 0) {
7160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_SE_CONNECTED;
7170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
7180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mSelectedSeId = seId;
7200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mManager.doSelectSecureElement(mSelectedSeId);
7210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* store */
7230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mPrefsEditor.putBoolean(PREF_SECURE_ELEMENT_ON, true);
7240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mPrefsEditor.putInt(PREF_SECURE_ELEMENT_ID, mSelectedSeId);
7252f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick            mPrefsEditor.apply();
7260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mNfcSecureElementState = true;
7280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return ErrorCodes.SUCCESS;
7300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
7320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7332f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly        public synchronized void setOpenTimeout(int timeout) throws RemoteException {
734d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
7350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mTimeout = timeout;
7360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
7370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
738fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
7390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int setProperties(String param, String value) throws RemoteException {
740d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
7410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (isEnabled()) {
7430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NFC_ON;
7440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
7450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            int val;
7470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* Check params validity */
7490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (param == null || value == null) {
7500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_INVALID_PARAM;
7510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
7520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (param.equals(PROPERTY_LLCP_LTO_VALUE)) {
7540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                val = Integer.parseInt(value);
7550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Check params */
7570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (val > LLCP_LTO_MAX)
7580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_INVALID_PARAM;
7590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
7610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putInt(PREF_LLCP_LTO, val);
7622f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
7630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
7650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_LLCP_LTO, val);
7660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_LLCP_MIU_VALUE)) {
7680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                val = Integer.parseInt(value);
7690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Check params */
7710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if ((val < LLCP_MIU_DEFAULT) || (val > LLCP_MIU_MAX))
7720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_INVALID_PARAM;
7730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
7750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putInt(PREF_LLCP_MIU, val);
7762f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
7770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
7790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_LLCP_MIU, val);
7800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_LLCP_WKS_VALUE)) {
7820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                val = Integer.parseInt(value);
7830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Check params */
7850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (val > LLCP_WKS_MAX)
7860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_INVALID_PARAM;
7870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
7890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putInt(PREF_LLCP_WKS, val);
7902f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
7910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
7930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_LLCP_WKS, val);
7940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_LLCP_OPT_VALUE)) {
7960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                val = Integer.parseInt(value);
7970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Check params */
7990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (val > LLCP_OPT_MAX)
8000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_INVALID_PARAM;
8010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
8030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putInt(PREF_LLCP_OPT, val);
8042f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
8050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
8070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_LLCP_OPT, val);
8080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_A_VALUE)) {
8100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                boolean b = Boolean.parseBoolean(value);
8110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
8130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putBoolean(PREF_DISCOVERY_A, b);
8142f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
8150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
8170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_A, b ? 1 : 0);
8180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_B_VALUE)) {
8200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                boolean b = Boolean.parseBoolean(value);
8210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
8230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putBoolean(PREF_DISCOVERY_B, b);
8242f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
8250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
8270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_B, b ? 1 : 0);
8280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_F_VALUE)) {
8300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                boolean b = Boolean.parseBoolean(value);
8310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
8330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putBoolean(PREF_DISCOVERY_F, b);
8342f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
8350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
8370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_F, b ? 1 : 0);
8380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_15693_VALUE)) {
8400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                boolean b = Boolean.parseBoolean(value);
8410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
8430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putBoolean(PREF_DISCOVERY_15693, b);
8442f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
8450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
8470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_15693, b ? 1 : 0);
8480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_NFCIP_VALUE)) {
8500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                boolean b = Boolean.parseBoolean(value);
8510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
8530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putBoolean(PREF_DISCOVERY_NFCIP, b);
8542f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
8550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
8570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_NFCIP, b ? 1 : 0);
8580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
859f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
8600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_INVALID_PARAM;
861f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
8620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return ErrorCodes.SUCCESS;
864f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
865f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
8663ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton        @Override
8670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public NdefMessage localGet() throws RemoteException {
868d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
869d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
8703ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton            synchronized (this) {
8713ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                return mLocalMessage;
8723ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton            }
8730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
8740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8753ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton        @Override
8760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public void localSet(NdefMessage message) throws RemoteException {
877d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
878d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
8793ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton            synchronized (this) {
8803ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                mLocalMessage = message;
881fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                Context context = NfcService.this.getApplicationContext();
882fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks
8833ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                // Send a message to the UI thread to show or hide the icon so the requests are
8843ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                // serialized and the icon can't get out of sync with reality.
8853ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                if (message != null) {
886fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                    FileOutputStream out = null;
887fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks
888fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                    try {
889fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                        out = context.openFileOutput(MY_TAG_FILE_NAME, Context.MODE_PRIVATE);
890fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                        out.write(message.toByteArray());
891fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                    } catch (IOException e) {
892fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                        Log.e(TAG, "Could not write mytag file", e);
893fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                    } finally {
894fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                        try {
895fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                            if (out != null) {
896fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                                out.flush();
897fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                                out.close();
898fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                            }
899fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                        } catch (IOException e) {
900fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                            // Ignore
901fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                        }
902fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                    }
903fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks
9043ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                    sendMessage(MSG_SHOW_MY_TAG_ICON, null);
9053ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                } else {
906fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                    context.deleteFile(MY_TAG_FILE_NAME);
9073ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                    sendMessage(MSG_HIDE_MY_TAG_ICON, null);
9083ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                }
9093ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton            }
9100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
9110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    };
9120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
9130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private final ILlcpSocket mLlcpSocket = new ILlcpSocket.Stub() {
9140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
9150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        private final int CONNECT_FLAG = 0x01;
9160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        private final int CLOSE_FLAG   = 0x02;
9170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        private final int RECV_FLAG    = 0x04;
9180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        private final int SEND_FLAG    = 0x08;
9190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
9200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        private int concurrencyFlags;
9210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        private Object sync;
9220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
923fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
9240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int close(int nativeHandle) throws RemoteException {
925d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
926bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
927f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpSocket socket = null;
9280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
929f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
930f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
931f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
932f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
933f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
934f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
935f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
936f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
937f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
9380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
9390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    isSuccess = socket.doClose();
9400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (isSuccess) {
9410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Remove the socket closed from the hmap */
9420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        RemoveSocket(nativeHandle);
9430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Update mNbSocketCreated */
9440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        mNbSocketCreated--;
9450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.SUCCESS;
9460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    } else {
9470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_IO;
9480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
949f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
9500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Remove the socket closed from the hmap */
9510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    RemoveSocket(nativeHandle);
9520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
9530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Remove registered socket from the list */
9540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    RemoveRegisteredSocket(nativeHandle);
9550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
9560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Update mNbSocketCreated */
9570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mNbSocketCreated--;
9580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
9590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.SUCCESS;
960f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
961f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
9620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_IO;
963f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
964f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
965f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
966fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
9670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int connect(int nativeHandle, int sap) throws RemoteException {
968d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
969bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
970f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpSocket socket = null;
9710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
972f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
973f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
974f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
975f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
976f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
977f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
978f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
979f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
980f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
9810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                isSuccess = socket.doConnect(sap, socket.getConnectTimeout());
9820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (isSuccess) {
9830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.SUCCESS;
984f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
985f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return ErrorCodes.ERROR_IO;
986f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
987f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
988f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_IO;
989f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
9900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
991f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
992f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
993fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
9940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int connectByName(int nativeHandle, String sn) throws RemoteException {
995d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
996bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
997f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpSocket socket = null;
998f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            boolean isSuccess = false;
999f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1000f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1001f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1002f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
1003f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1004f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1005f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
1006f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
1007f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
10080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                isSuccess = socket.doConnectBy(sn, socket.getConnectTimeout());
1009f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                if (isSuccess) {
1010f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return ErrorCodes.SUCCESS;
1011f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
1012f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return ErrorCodes.ERROR_IO;
1013f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
1014f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
1015f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_IO;
1016f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
10170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
1018f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1019f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1020fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
10210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getConnectTimeout(int nativeHandle) throws RemoteException {
1022d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1023bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1024f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpSocket socket = null;
1025f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
10260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
10270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
10280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
10290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
10300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
1031f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
1032f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
1033f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
10340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return socket.getConnectTimeout();
10350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else {
10360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return 0;
1037f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1038f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1039f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1040fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
10410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getLocalSap(int nativeHandle) throws RemoteException {
1042d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1043bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
10440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket socket = null;
1045f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1046f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1047f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1048f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
1049f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1050f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
10510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the socket in the hmap */
10520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
10530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (socket != null) {
10540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return socket.getSap();
1055f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
10560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return 0;
1057f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1058f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1059f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1060fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
10610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getLocalSocketMiu(int nativeHandle) throws RemoteException {
1062d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1063bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
10640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket socket = null;
1065f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1066f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1067f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
10680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
1069f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1070f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1071f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
10720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
1073f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
10740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return socket.getMiu();
10750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else {
10760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return 0;
1077f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1078f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1079f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1080fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
10810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getLocalSocketRw(int nativeHandle) throws RemoteException {
1082d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1083bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
10840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket socket = null;
1085f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1086f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1087f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1088f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
1089f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1090f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1091f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
10920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
10930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (socket != null) {
10940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return socket.getRw();
10950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else {
10960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return 0;
10970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
10980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
10990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
1100fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
11010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getRemoteSocketMiu(int nativeHandle) throws RemoteException {
1102d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
11030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket socket = null;
11050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
11070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
11080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
11090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
11100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the socket in the hmap */
11120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
11130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (socket != null) {
11140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (socket.doGetRemoteSocketMiu() != 0) {
11150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return socket.doGetRemoteSocketMiu();
11160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
11170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED;
11180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
11190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else {
11200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED;
11210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
11220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
11230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
1124fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
11250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getRemoteSocketRw(int nativeHandle) throws RemoteException {
1126d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
11270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket socket = null;
11290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
11310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
11320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
11330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
11340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the socket in the hmap */
11360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
11370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (socket != null) {
11380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (socket.doGetRemoteSocketRw() != 0) {
11390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return socket.doGetRemoteSocketRw();
11400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
11410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED;
11420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
11430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else {
11440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED;
11450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
11460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
11470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
1148fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
11490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int receive(int nativeHandle, byte[] receiveBuffer) throws RemoteException {
1150d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
11510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket socket = null;
11530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            int receiveLength = 0;
11540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
11560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
11570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
11580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
11590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the socket in the hmap */
11610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
11620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (socket != null) {
11630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                receiveLength = socket.doReceive(receiveBuffer);
11640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (receiveLength != 0) {
11650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return receiveLength;
11660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
11670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_IO;
11680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
11690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else {
11700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_IO;
11710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
11720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
11730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
1174fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
11750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int send(int nativeHandle, byte[] data) throws RemoteException {
1176d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
11770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket socket = null;
11790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
11800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
11820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
11830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
11840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
11850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the socket in the hmap */
11870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
11880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (socket != null) {
11890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                isSuccess = socket.doSend(data);
11900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (isSuccess) {
11910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.SUCCESS;
11920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
11930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_IO;
11940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
11950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else {
11960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_IO;
11970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
11980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
11990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
1200fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
12010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public void setConnectTimeout(int nativeHandle, int timeout) throws RemoteException {
1202d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
12030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
12040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket socket = null;
12050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
12060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the socket in the hmap */
12070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
12080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (socket != null) {
12090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                socket.setConnectTimeout(timeout);
12100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
12110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
12120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
12130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    };
12140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
12150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private final ILlcpServiceSocket mLlcpServerSocketService = new ILlcpServiceSocket.Stub() {
12160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
1217fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
12180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int accept(int nativeHandle) throws RemoteException {
1219d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
12200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
12210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpServiceSocket socket = null;
12220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket clientSocket = null;
12230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
12240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
12250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
12260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
12270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
12280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
12290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mNbSocketCreated < LLCP_SOCKET_NB_MAX) {
12300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* find the socket in the hmap */
12310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                socket = (NativeLlcpServiceSocket) findSocket(nativeHandle);
12320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (socket != null) {
12330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    clientSocket = socket.doAccept(socket.getAcceptTimeout(), socket.getMiu(),
12340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            socket.getRw(), socket.getLinearBufferLength());
12350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (clientSocket != null) {
12360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Add the socket into the socket map */
12372f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        synchronized(this) {
12382f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mSocketMap.put(clientSocket.getHandle(), clientSocket);
12392f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mNbSocketCreated++;
12402f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        }
12410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return clientSocket.getHandle();
12420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    } else {
12430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_IO;
12440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
12450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
12460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_IO;
12470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
12480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else {
12490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES;
12500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
12510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
12520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
12530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
1254fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
12550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public void close(int nativeHandle) throws RemoteException {
1256d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
12570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
12580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpServiceSocket socket = null;
12590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
12600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
12610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
12620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
12630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return;
12640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
12650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
12660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the socket in the hmap */
12670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpServiceSocket) findSocket(nativeHandle);
12680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (socket != null) {
12690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
12700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    isSuccess = socket.doClose();
12710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (isSuccess) {
12720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Remove the socket closed from the hmap */
12730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        RemoveSocket(nativeHandle);
12740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Update mNbSocketCreated */
12750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        mNbSocketCreated--;
12760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
12770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
12780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Remove the socket closed from the hmap */
12790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    RemoveSocket(nativeHandle);
12800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
12810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Remove registered socket from the list */
12820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    RemoveRegisteredSocket(nativeHandle);
12830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
12840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Update mNbSocketCreated */
12850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mNbSocketCreated--;
12860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
12870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
12880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
12890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
1290fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
12910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getAcceptTimeout(int nativeHandle) throws RemoteException {
1292d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
12930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
12940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpServiceSocket socket = null;
12950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
12960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
12970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
12980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
12990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
13000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
13010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the socket in the hmap */
13020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpServiceSocket) findSocket(nativeHandle);
1303f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
1304f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return socket.getAcceptTimeout();
1305f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
1306f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return 0;
1307f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1308f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1309f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1310fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
1311f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public void setAcceptTimeout(int nativeHandle, int timeout) throws RemoteException {
1312d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1313bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1314f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpServiceSocket socket = null;
1315f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1316f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
1317f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpServiceSocket) findSocket(nativeHandle);
1318f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
1319f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                socket.setAcceptTimeout(timeout);
1320f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1321f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1322f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    };
1323f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1324f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private final ILlcpConnectionlessSocket mLlcpConnectionlessSocketService = new ILlcpConnectionlessSocket.Stub() {
1325f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1326fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
1327f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public void close(int nativeHandle) throws RemoteException {
1328d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1329bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1330f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpConnectionlessSocket socket = null;
1331f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            boolean isSuccess = false;
1332f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1333f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1334f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1335f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return;
1336f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1337f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1338f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
1339f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpConnectionlessSocket) findSocket(nativeHandle);
1340f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
1341f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
1342f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    isSuccess = socket.doClose();
1343f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    if (isSuccess) {
1344f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                        /* Remove the socket closed from the hmap */
1345f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                        RemoveSocket(nativeHandle);
1346f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                        /* Update mNbSocketCreated */
1347f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                        mNbSocketCreated--;
1348f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    }
1349f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
1350f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    /* Remove the socket closed from the hmap */
1351f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    RemoveSocket(nativeHandle);
1352f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1353f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    /* Remove registered socket from the list */
1354f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    RemoveRegisteredSocket(nativeHandle);
1355f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1356f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    /* Update mNbSocketCreated */
1357f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    mNbSocketCreated--;
1358f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
1359f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1360f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1361f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1362fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
1363f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public int getSap(int nativeHandle) throws RemoteException {
1364d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1365bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1366f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpConnectionlessSocket socket = null;
1367f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1368f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1369f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1370f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
1371f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1372f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1373f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
1374f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpConnectionlessSocket) findSocket(nativeHandle);
1375f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
1376f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return socket.getSap();
1377f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
1378f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return 0;
1379f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1380f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1381f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1382fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
1383f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public LlcpPacket receiveFrom(int nativeHandle) throws RemoteException {
1384d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1385bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1386f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpConnectionlessSocket socket = null;
1387f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            LlcpPacket packet;
1388f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1389f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1390f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1391f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return null;
1392f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1393f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1394f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
1395f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpConnectionlessSocket) findSocket(nativeHandle);
1396f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
1397f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                packet = socket.doReceiveFrom(socket.getLinkMiu());
1398f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                if (packet != null) {
1399f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return packet;
1400f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
1401f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return null;
1402f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
1403f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return null;
1404f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1405f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1406f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1407fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
1408f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public int sendTo(int nativeHandle, LlcpPacket packet) throws RemoteException {
1409d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1410bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1411f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpConnectionlessSocket socket = null;
1412f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            boolean isSuccess = false;
1413f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1414f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1415f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1416f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
1417f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1418f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1419f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
1420f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpConnectionlessSocket) findSocket(nativeHandle);
1421f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
1422f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                isSuccess = socket.doSendTo(packet.getRemoteSap(), packet.getDataBuffer());
1423f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                if (isSuccess) {
1424f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return ErrorCodes.SUCCESS;
1425f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
1426f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return ErrorCodes.ERROR_IO;
1427f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
1428f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
1429f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_IO;
1430f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1431f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1432f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    };
1433f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1434f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private final INfcTag mNfcTagService = new INfcTag.Stub() {
1435f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1436fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
1437f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public int close(int nativeHandle) throws RemoteException {
1438d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1439bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1440f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeNfcTag tag = null;
1441f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1442f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1443f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1444f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
1445f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1446f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1447f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1448f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1449f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (tag != null) {
1450b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                /* Remove the device from the hmap */
1451b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                unregisterObject(nativeHandle);
1452b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                tag.asyncDisconnect();
1453b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                return ErrorCodes.SUCCESS;
1454f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1455f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* Restart polling loop for notification */
145665945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            maybeEnableDiscovery();
1457f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mOpenPending = false;
1458f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return ErrorCodes.ERROR_DISCONNECT;
1459f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1460f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1461fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
1462f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public int connect(int nativeHandle) throws RemoteException {
1463d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1464bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1465f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeNfcTag tag = null;
1466f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1467f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1468f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1469f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
1470f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1471f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1472f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1473f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1474b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            if (tag == null) {
1475b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                return ErrorCodes.ERROR_DISCONNECT;
1476f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1477b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            // TODO: register the tag as being locked rather than really connect
1478b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            return ErrorCodes.SUCCESS;
1479f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1480f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1481fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
1482f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public String getType(int nativeHandle) throws RemoteException {
1483d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1484bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1485f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeNfcTag tag = null;
1486f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            String type;
1487f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1488f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1489f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1490f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return null;
1491f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1492f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1493f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1494f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1495f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (tag != null) {
1496f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                type = tag.getType();
1497f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return type;
1498f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1499f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return null;
1500f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1501f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1502fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
1503f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public byte[] getUid(int nativeHandle) throws RemoteException {
1504f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeNfcTag tag = null;
1505f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            byte[] uid;
1506f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1507f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1508f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1509f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return null;
1510f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1511f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1512f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1513f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1514f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (tag != null) {
1515f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                uid = tag.getUid();
1516f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return uid;
1517f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1518f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return null;
1519f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1520f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1521fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
1522b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        public boolean isPresent(int nativeHandle) throws RemoteException {
1523b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            NativeNfcTag tag = null;
1524b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
1525b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            // Check if NFC is enabled
1526b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            if (!mIsNfcEnabled) {
1527b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                return false;
1528b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            }
1529b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
1530b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            /* find the tag in the hmap */
1531b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            tag = (NativeNfcTag) findObject(nativeHandle);
1532b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            if (tag == null) {
1533b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                return false;
1534b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            }
1535b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
1536b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            return tag.presenceCheck();
1537b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        }
1538b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
1539fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
1540f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public boolean isNdef(int nativeHandle) throws RemoteException {
1541f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeNfcTag tag = null;
1542f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            boolean isSuccess = false;
1543f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1544f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1545f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1546f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return isSuccess;
1547f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1548f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1549f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1550f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1551f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (tag != null) {
1552b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                isSuccess = tag.checkNdef();
1553f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1554f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return isSuccess;
1555f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1556f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1557fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
1558f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public byte[] transceive(int nativeHandle, byte[] data) throws RemoteException {
1559d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1560bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1561f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeNfcTag tag = null;
1562f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            byte[] response;
1563f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1564f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1565f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1566f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return null;
1567f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1568f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1569f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1570f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1571f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (tag != null) {
1572b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                response = tag.transceive(data);
1573f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return response;
1574f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1575f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return null;
1576f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1577f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1578fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
1579f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public NdefMessage read(int nativeHandle) throws RemoteException {
1580d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1581bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1582f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeNfcTag tag;
1583f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1584f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1585f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1586f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return null;
1587f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1588f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1589f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1590f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1591f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (tag != null) {
1592b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                byte[] buf = tag.read();
1593f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                if (buf == null)
1594f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return null;
1595f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1596f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                /* Create an NdefMessage */
1597f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                try {
1598f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return new NdefMessage(buf);
1599f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } catch (FormatException e) {
1600f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return null;
1601f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
1602f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1603f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return null;
1604f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1605f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1606fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
1607f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public int write(int nativeHandle, NdefMessage msg) throws RemoteException {
1608d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1609bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1610f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeNfcTag tag;
1611f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1612f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1613f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1614f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
1615f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1616f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1617f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1618f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1619f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (tag == null) {
1620f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_IO;
1621f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1622f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1623b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            if (tag.write(msg.toByteArray())) {
1624f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.SUCCESS;
1625f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1626f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            else {
1627f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_IO;
1628f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1629f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1630f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1631f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1632fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
1633f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public int getLastError(int nativeHandle) throws RemoteException {
1634f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // TODO Auto-generated method stub
16350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return 0;
1636f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1637f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1638fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
16390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getModeHint(int nativeHandle) throws RemoteException {
16400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // TODO Auto-generated method stub
16410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return 0;
1642f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1643f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1644fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
16450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int makeReadOnly(int nativeHandle) throws RemoteException {
16460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // TODO Auto-generated method stub
16470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return 0;
1648f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1649f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1650f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    };
1652f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private final IP2pInitiator mP2pInitiatorService = new IP2pInitiator.Stub() {
1654f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1655fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
16560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public byte[] getGeneralBytes(int nativeHandle) throws RemoteException {
1657d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1658f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
1660f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
16620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
16630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return null;
16640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
1665f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
16670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
16680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
16690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                byte[] buff = device.getGeneralBytes();
16700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (buff == null)
16710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return null;
16720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return buff;
16730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
16740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return null;
16750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
1676f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1677fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
16780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getMode(int nativeHandle) throws RemoteException {
1679d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1680f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
1682f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
16840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
16850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
16860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
1687f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
16890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
16900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
16910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return device.getMode();
16920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
1693f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return ErrorCodes.ERROR_INVALID_PARAM;
1694f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1695f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1696fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
16970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public byte[] receive(int nativeHandle) throws RemoteException {
1698d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1699f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
1701f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
17030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
17040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return null;
17050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
1706f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
17080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
17090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
17100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                byte[] buff = device.doReceive();
17110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (buff == null)
17120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return null;
17130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return buff;
17140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
17150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* Restart polling loop for notification */
171665945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            maybeEnableDiscovery();
17170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mOpenPending = false;
17180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return null;
17190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
1720f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1721fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
17220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public boolean send(int nativeHandle, byte[] data) throws RemoteException {
1723d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1724f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
17260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
1727f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
17290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
17300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return isSuccess;
17310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
1732f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
17340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
17350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
17360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                isSuccess = device.doSend(data);
17370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
17380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return isSuccess;
17390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
17400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    };
1741f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private final IP2pTarget mP2pTargetService = new IP2pTarget.Stub() {
1743f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1744fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
17450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int connect(int nativeHandle) throws RemoteException {
1746d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1747f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
1749f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
17510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
17520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
17530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
1754f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
17560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
17570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
17580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (device.doConnect()) {
17590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.SUCCESS;
17600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
17610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
17620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return ErrorCodes.ERROR_CONNECT;
17630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
1764f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1765fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
17660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public boolean disconnect(int nativeHandle) throws RemoteException {
1767d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1768f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
17700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
1771f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
17730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
17740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return isSuccess;
17750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
1776f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
17780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
17790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
17800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (isSuccess = device.doDisconnect()) {
17810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mOpenPending = false;
17820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* remove the device from the hmap */
1783b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                    unregisterObject(nativeHandle);
17840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Restart polling loop for notification */
178565945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly                    maybeEnableDiscovery();
17860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
1787f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
17880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return isSuccess;
1789f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
1791f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1792fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
17930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public byte[] getGeneralBytes(int nativeHandle) throws RemoteException {
1794d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1795f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
17970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
17980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
17990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
18000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return null;
1801f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1802f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
18030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
18040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
18050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
18060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                byte[] buff = device.getGeneralBytes();
18070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (buff == null)
18080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return null;
18090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return buff;
18100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
18110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return null;
18120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
1813f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1814fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
18150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getMode(int nativeHandle) throws RemoteException {
1816d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1817f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
18180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
1819f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
18200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
18210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
18220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
1823f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1824f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
18250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
18260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
18270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
18280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return device.getMode();
18290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
18300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return ErrorCodes.ERROR_INVALID_PARAM;
18310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
1832f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1833fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
18340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public byte[] transceive(int nativeHandle, byte[] data) throws RemoteException {
1835d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1836f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
18370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
1838f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
18390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
18400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
18410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return null;
1842f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1843f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
18440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
18450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
18460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
18470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                byte[] buff = device.doTransceive(data);
18480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (buff == null)
18490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return null;
18500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return buff;
18510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
18520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return null;
18530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
18540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    };
1855f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
18560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private boolean _enable(boolean oldEnabledState) {
18570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        boolean isSuccess = mManager.initialize();
18580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        if (isSuccess) {
1859f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly            applyProperties();
1860f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly
18610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* Check Secure Element setting */
18620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mNfcSecureElementState = mPrefs.getBoolean(PREF_SECURE_ELEMENT_ON,
18630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    SECURE_ELEMENT_ON_DEFAULT);
1864f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
18650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mNfcSecureElementState) {
18660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                int secureElementId = mPrefs.getInt(PREF_SECURE_ELEMENT_ID,
18670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        SECURE_ELEMENT_ID_DEFAULT);
18680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                int[] Se_list = mManager.doGetSecureElementList();
18690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (Se_list != null) {
18700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    for (int i = 0; i < Se_list.length; i++) {
18710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        if (Se_list[i] == secureElementId) {
18720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            mManager.doSelectSecureElement(Se_list[i]);
18730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            mSelectedSeId = Se_list[i];
18740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            break;
18750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        }
18760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
18770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
1878f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1879f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
188065945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            mIsNfcEnabled = true;
188165945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly
18820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* Start polling loop */
188365945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            maybeEnableDiscovery();
1884f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
18856f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton            /* bring up the my tag server */
18866f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton            //mMyTagServer.start();
18876f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton
1888f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        } else {
18890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mIsNfcEnabled = false;
1890f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1891f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
18920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        updateNfcOnSetting(oldEnabledState);
1893f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
18940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        return isSuccess;
1895f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1896f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
189765945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly    /** Enable active tag discovery if screen is on and NFC is enabled */
189865945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly    private synchronized void maybeEnableDiscovery() {
189965945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly        if (mScreenOn && mIsNfcEnabled) {
190065945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            mManager.enableDiscovery(DISCOVERY_MODE_READER);
190165945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly        }
190265945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly    }
190365945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly
190465945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly    /** Disable active tag discovery if necessary */
190565945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly    private synchronized void maybeDisableDiscovery() {
190665945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly        if (mIsNfcEnabled) {
190765945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            mManager.disableDiscovery();
190865945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly        }
190965945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly    }
191065945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly
1911f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly    private void applyProperties() {
1912f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_LLCP_LTO, mPrefs.getInt(PREF_LLCP_LTO, LLCP_LTO_DEFAULT));
1913f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_LLCP_MIU, mPrefs.getInt(PREF_LLCP_MIU, LLCP_MIU_DEFAULT));
1914f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_LLCP_WKS, mPrefs.getInt(PREF_LLCP_WKS, LLCP_WKS_DEFAULT));
1915f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_LLCP_OPT, mPrefs.getInt(PREF_LLCP_OPT, LLCP_OPT_DEFAULT));
1916f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_A,
1917f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly                mPrefs.getBoolean(PREF_DISCOVERY_A, DISCOVERY_A_DEFAULT) ? 1 : 0);
1918f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_B,
1919f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly                mPrefs.getBoolean(PREF_DISCOVERY_B, DISCOVERY_B_DEFAULT) ? 1 : 0);
1920f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_F,
1921f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly                mPrefs.getBoolean(PREF_DISCOVERY_F, DISCOVERY_F_DEFAULT) ? 1 : 0);
1922f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_15693,
1923f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly                mPrefs.getBoolean(PREF_DISCOVERY_15693, DISCOVERY_15693_DEFAULT) ? 1 : 0);
1924f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_NFCIP,
1925f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly                mPrefs.getBoolean(PREF_DISCOVERY_NFCIP, DISCOVERY_NFCIP_DEFAULT) ? 1 : 0);
1926f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly     }
1927f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly
19280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private void updateNfcOnSetting(boolean oldEnabledState) {
19290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        int state;
1930f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
19310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mPrefsEditor.putBoolean(PREF_NFC_ON, mIsNfcEnabled);
19322f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick        mPrefsEditor.apply();
19330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
19342f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly        synchronized(this) {
19354acf84356e35861f7df6d07a2b9ff84842a9f221Nick Pelly            if (oldEnabledState != mIsNfcEnabled) {
19362f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                Intent intent = new Intent(NfcAdapter.ACTION_ADAPTER_STATE_CHANGE);
19374acf84356e35861f7df6d07a2b9ff84842a9f221Nick Pelly                intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
19382f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                intent.putExtra(NfcAdapter.EXTRA_NEW_BOOLEAN_STATE, mIsNfcEnabled);
19392f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                mContext.sendBroadcast(intent);
19402f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly            }
19410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
1942f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1943f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1944f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    // Reset all internals
19452f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    private synchronized void reset() {
194674180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick        // TODO: none of these appear to be synchronized but are
194774180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick        // read/written from different threads (notably Binder threads)...
1948f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1949f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        // Clear tables
1950f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mObjectMap.clear();
1951f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mSocketMap.clear();
1952f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mRegisteredSocketList.clear();
1953f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1954f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        // Reset variables
1955f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mLlcpLinkState = NfcAdapter.LLCP_LINK_STATE_DEACTIVATED;
1956f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mNbSocketCreated = 0;
1957f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mIsNfcEnabled = false;
1958f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mSelectedSeId = 0;
1959f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mTimeout = 0;
1960f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mOpenPending = false;
1961f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1962f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
19632f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    private synchronized Object findObject(int key) {
1964f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        Object device = null;
1965f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1966f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        device = mObjectMap.get(key);
1967f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        if (device == null) {
1968f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            Log.w(TAG, "Handle not found !");
1969f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1970f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1971f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        return device;
1972f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1973f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
19742f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    synchronized void registerTagObject(NativeNfcTag nativeTag) {
1975b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        mObjectMap.put(nativeTag.getHandle(), nativeTag);
1976b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    }
1977b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
19782f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    synchronized void unregisterObject(int handle) {
1979b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        mObjectMap.remove(handle);
1980f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1981f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
19822f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    private synchronized Object findSocket(int key) {
1983f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        Object socket = null;
1984f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1985f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        socket = mSocketMap.get(key);
1986f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1987f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        return socket;
1988f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1989f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1990f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private void RemoveSocket(int key) {
1991f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mSocketMap.remove(key);
1992f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1993f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1994f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private boolean CheckSocketSap(int sap) {
1995f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        /* List of sockets registered */
1996f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        ListIterator<RegisteredSocket> it = mRegisteredSocketList.listIterator();
1997f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1998f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        while (it.hasNext()) {
1999f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            RegisteredSocket registeredSocket = it.next();
2000f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2001f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (sap == registeredSocket.mSap) {
2002f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                /* SAP already used */
2003f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return false;
2004f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
2005f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
2006f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        return true;
2007f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
2008f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2009f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private boolean CheckSocketOptions(int miu, int rw, int linearBufferlength) {
2010f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
20110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        if (rw > LLCP_RW_MAX_VALUE || miu < LLCP_MIU_DEFAULT || linearBufferlength < miu) {
2012f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return false;
2013f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
2014f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        return true;
2015f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
2016f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2017f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private boolean CheckSocketServiceName(String sn) {
2018f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2019f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        /* List of sockets registered */
2020f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        ListIterator<RegisteredSocket> it = mRegisteredSocketList.listIterator();
2021f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2022f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        while (it.hasNext()) {
2023f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            RegisteredSocket registeredSocket = it.next();
2024f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2025f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (sn.equals(registeredSocket.mServiceName)) {
2026f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                /* Service Name already used */
2027f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return false;
2028f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
2029f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
2030f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        return true;
2031f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
2032f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2033f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private void RemoveRegisteredSocket(int nativeHandle) {
2034f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        /* check if sockets are registered */
2035f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        ListIterator<RegisteredSocket> it = mRegisteredSocketList.listIterator();
2036f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2037f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        while (it.hasNext()) {
2038f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            RegisteredSocket registeredSocket = it.next();
2039f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (registeredSocket.mHandle == nativeHandle) {
2040f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                /* remove the registered socket from the list */
2041f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                it.remove();
2042f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                Log.d(TAG, "socket removed");
2043f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
2044f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
2045f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
2046f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2047f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    /*
2048f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly     * RegisteredSocket class to store the creation request of socket until the
2049f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly     * LLCP link in not activated
2050f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly     */
2051f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private class RegisteredSocket {
2052f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        private final int mType;
2053f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2054f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        private final int mHandle;
2055f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2056f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        private final int mSap;
2057f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2058f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        private int mMiu;
2059f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2060f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        private int mRw;
2061f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2062f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        private String mServiceName;
2063f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2064f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        private int mlinearBufferLength;
2065f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2066f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        RegisteredSocket(int type, int handle, int sap, String sn, int miu, int rw,
2067f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                int linearBufferLength) {
2068f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mType = type;
2069f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mHandle = handle;
2070f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mSap = sap;
2071f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mServiceName = sn;
2072f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mRw = rw;
2073f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mMiu = miu;
2074f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mlinearBufferLength = linearBufferLength;
2075f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
2076f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2077f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        RegisteredSocket(int type, int handle, int sap, int miu, int rw, int linearBufferLength) {
2078f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mType = type;
2079f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mHandle = handle;
2080f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mSap = sap;
2081f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mRw = rw;
2082f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mMiu = miu;
2083f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mlinearBufferLength = linearBufferLength;
2084f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
2085f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2086f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        RegisteredSocket(int type, int handle, int sap) {
2087f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mType = type;
2088f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mHandle = handle;
2089f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mSap = sap;
2090f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
2091f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
2092f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2093d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    /** For use by code in this process */
2094d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    public LlcpSocket createLlcpSocket(int sap, int miu, int rw, int linearBufferLength) {
2095d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        try {
2096d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            int handle = mNfcAdapter.createLlcpSocket(sap, miu, rw, linearBufferLength);
20971be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton            if (ErrorCodes.isError(handle)) {
20981be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton                Log.e(TAG, "unable to create socket: " + ErrorCodes.asString(handle));
20991be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton                return null;
21001be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton            }
2101d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            return new LlcpSocket(mLlcpSocket, handle);
2102d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        } catch (RemoteException e) {
2103d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            // This will never happen since the code is calling into it's own process
2104d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            throw new IllegalStateException("unable to talk to myself", e);
2105d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        }
2106d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    }
2107d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
2108d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    /** For use by code in this process */
2109d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    public LlcpServiceSocket createLlcpServiceSocket(int sap, String sn, int miu, int rw,
2110d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            int linearBufferLength) {
2111d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        try {
2112d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            int handle = mNfcAdapter.createLlcpServiceSocket(sap, sn, miu, rw, linearBufferLength);
21131be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton            if (ErrorCodes.isError(handle)) {
21141be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton                Log.e(TAG, "unable to create socket: " + ErrorCodes.asString(handle));
21151be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton                return null;
21161be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton            }
2117d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            return new LlcpServiceSocket(mLlcpServerSocketService, mLlcpSocket, handle);
2118d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        } catch (RemoteException e) {
2119d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            // This will never happen since the code is calling into it's own process
2120d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            throw new IllegalStateException("unable to talk to myself", e);
2121d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        }
2122d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    }
2123d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
21240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private void activateLlcpLink() {
21250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        /* check if sockets are registered */
21260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        ListIterator<RegisteredSocket> it = mRegisteredSocketList.listIterator();
2127f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
21280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        Log.d(TAG, "Nb socket resgistered = " + mRegisteredSocketList.size());
2129f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2130b3cdb6612a057373a61521171d99ce4f24b84e1fJeff Hamilton        /* Mark the link state */
2131b3cdb6612a057373a61521171d99ce4f24b84e1fJeff Hamilton        mLlcpLinkState = NfcAdapter.LLCP_LINK_STATE_ACTIVATED;
2132b3cdb6612a057373a61521171d99ce4f24b84e1fJeff Hamilton
21330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        while (it.hasNext()) {
21340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            RegisteredSocket registeredSocket = it.next();
2135f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
21360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            switch (registeredSocket.mType) {
21370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            case LLCP_SERVICE_SOCKET_TYPE:
21380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                Log.d(TAG, "Registered Llcp Service Socket");
2139b3cdb6612a057373a61521171d99ce4f24b84e1fJeff Hamilton                Log.d(TAG, "SAP: " + registeredSocket.mSap + ", SN: " + registeredSocket.mServiceName);
21400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                NativeLlcpServiceSocket serviceSocket;
21410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
21420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                serviceSocket = mManager.doCreateLlcpServiceSocket(
21430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        registeredSocket.mSap, registeredSocket.mServiceName,
21440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        registeredSocket.mMiu, registeredSocket.mRw,
21450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        registeredSocket.mlinearBufferLength);
21460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
21470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (serviceSocket != null) {
21486f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton                    Log.d(TAG, "service socket created");
21490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Add the socket into the socket map */
21502f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    synchronized(NfcService.this) {
21512f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mSocketMap.put(registeredSocket.mHandle, serviceSocket);
21522f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    }
21530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
21546f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton                    Log.d(TAG, "FAILED to create service socket");
21550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* socket creation error - update the socket
21560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                     * handle counter */
21570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mGeneratedSocketHandle -= 1;
21580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
21590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                break;
21600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
21610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            case LLCP_SOCKET_TYPE:
21620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                Log.d(TAG, "Registered Llcp Socket");
21630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                NativeLlcpSocket clientSocket;
21640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                clientSocket = mManager.doCreateLlcpSocket(registeredSocket.mSap,
21650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        registeredSocket.mMiu, registeredSocket.mRw,
21660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        registeredSocket.mlinearBufferLength);
21670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (clientSocket != null) {
21686f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton                    Log.d(TAG, "socket created");
21690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Add the socket into the socket map */
21702f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    synchronized(NfcService.this) {
21712f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mSocketMap.put(registeredSocket.mHandle, clientSocket);
21722f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    }
21730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
21746f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton                    Log.d(TAG, "FAILED to create service socket");
21750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* socket creation error - update the socket
21760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                     * handle counter */
21770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mGeneratedSocketHandle -= 1;
21780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
21790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                break;
21800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
21810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            case LLCP_CONNECTIONLESS_SOCKET_TYPE:
21820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                Log.d(TAG, "Registered Llcp Connectionless Socket");
21830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                NativeLlcpConnectionlessSocket connectionlessSocket;
21840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                connectionlessSocket = mManager.doCreateLlcpConnectionlessSocket(
21850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        registeredSocket.mSap);
21860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (connectionlessSocket != null) {
21876f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton                    Log.d(TAG, "connectionless socket created");
21880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Add the socket into the socket map */
21892f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    synchronized(NfcService.this) {
21902f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mSocketMap.put(registeredSocket.mHandle, connectionlessSocket);
21912f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    }
21920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
21936f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton                    Log.d(TAG, "FAILED to create service socket");
21940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* socket creation error - update the socket
21950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                     * handle counter */
21960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mGeneratedSocketHandle -= 1;
21970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
21980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                break;
2199f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
22000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
2201f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
22020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        /* Remove all registered socket from the list */
22030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mRegisteredSocketList.clear();
2204f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
22050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        /* Broadcast Intent Link LLCP activated */
22060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        Intent LlcpLinkIntent = new Intent();
22070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        LlcpLinkIntent.setAction(NfcAdapter.ACTION_LLCP_LINK_STATE_CHANGED);
2208f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
22090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        LlcpLinkIntent.putExtra(NfcAdapter.EXTRA_LLCP_LINK_STATE_CHANGED,
22100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                NfcAdapter.LLCP_LINK_STATE_ACTIVATED);
2211f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
22120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        Log.d(TAG, "Broadcasting LLCP activation");
22130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mContext.sendOrderedBroadcast(LlcpLinkIntent, NFC_PERM);
22140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    }
2215f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2216d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    public void sendMockNdefTag(NdefMessage msg) {
2217d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        NdefTag tag = NdefTag.createMockNdefTag(new byte[] { 0x00 },
2218d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton                new String[] { Tag.TARGET_OTHER },
2219d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton                null, null, new String[] { NdefTag.TARGET_OTHER },
2220d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton                new NdefMessage[][] { new NdefMessage[] { msg } });
2221d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        sendMessage(MSG_MOCK_NDEF_TAG, tag);
2222d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    }
2223d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
2224b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    void sendMessage(int what, Object obj) {
2225b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        Message msg = mHandler.obtainMessage();
2226b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        msg.what = what;
2227b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        msg.obj = obj;
2228b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        mHandler.sendMessage(msg);
2229b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    }
2230b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
2231b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    private final Handler mHandler = new Handler() {
2232b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        @Override
2233b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        public void handleMessage(Message msg) {
2234f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           switch (msg.what) {
2235d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton           case MSG_MOCK_NDEF_TAG: {
2236d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton               NdefTag tag = (NdefTag) msg.obj;
2237d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton               Intent intent = buildNdefTagIntent(tag);
2238d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton               Log.d(TAG, "mock NDEF tag, starting corresponding activity");
2239d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton               Log.d(TAG, tag.toString());
2240d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton               try {
2241d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton                   mContext.startActivity(intent);
2242d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton               } catch (ActivityNotFoundException e) {
2243d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton                   Log.w(TAG, "No activity found for mock tag");
2244d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton               }
2245d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton           }
2246d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
2247f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           case MSG_NDEF_TAG:
2248f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.d(TAG, "Tag detected, notifying applications");
2249f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               NativeNfcTag nativeTag = (NativeNfcTag) msg.obj;
2250f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               if (nativeTag.connect()) {
2251f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   if (nativeTag.checkNdef()) {
2252f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       byte[] buff = nativeTag.read();
2253f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       if (buff != null) {
2254f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           NdefMessage[] msgNdef = new NdefMessage[1];
2255f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           try {
2256f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               msgNdef[0] = new NdefMessage(buff);
2257f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               NdefTag tag = new NdefTag(nativeTag.getUid(),
22581cf8ba9546ba5204af08b8de2c542b6a1bf8f8a0Nick Pelly                                       TagTarget.internalTypeToRawTargets(nativeTag.getType()),
2259f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                                       null, null, nativeTag.getHandle(),
2260f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                                       TagTarget.internalTypeToNdefTargets(nativeTag.getType()),
2261f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                                       new NdefMessage[][] {msgNdef});
2262d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton                               Intent intent = buildNdefTagIntent(tag);
2263f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               Log.d(TAG, "NDEF tag found, starting corresponding activity");
22641cf8ba9546ba5204af08b8de2c542b6a1bf8f8a0Nick Pelly                               Log.d(TAG, tag.toString());
2265b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                               try {
2266b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                                   mContext.startActivity(intent);
2267db7d865e53c4db049bab20a0bcc7cb596e450d9aSylvain Fonteneau                                   registerTagObject(nativeTag);
2268b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                               } catch (ActivityNotFoundException e) {
2269b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                                   Log.w(TAG, "No activity found, disconnecting");
2270b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                                   nativeTag.asyncDisconnect();
2271b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                               }
2272f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           } catch (FormatException e) {
2273f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               Log.w(TAG, "Unable to create NDEF message object (tag empty or not well formated)");
2274f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               nativeTag.asyncDisconnect();
2275b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                           }
2276b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                       } else {
2277f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           Log.w(TAG, "Unable to read NDEF message (tag empty or not well formated)");
2278b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                           nativeTag.asyncDisconnect();
2279b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                       }
2280f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   } else {
2281f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       Intent intent = new Intent();
2282f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       Tag tag = new Tag(nativeTag.getUid(), false,
2283f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               TagTarget.internalTypeToRawTargets(nativeTag.getType()),
2284f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               null, null, nativeTag.getHandle());
2285f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       intent.setAction(NfcAdapter.ACTION_TAG_DISCOVERED);
2286f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       intent.putExtra(NfcAdapter.EXTRA_TAG, tag);
22872407a9d01fdc8e48f778d2ef070e75a74d3863c4Nick Pelly                       intent.putExtra(NfcAdapter.EXTRA_ID, tag.getId());
2288f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2289f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       Log.d(TAG, "Non-NDEF tag found, starting corresponding activity");
2290f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       Log.d(TAG, tag.toString());
2291f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       try {
2292f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           mContext.startActivity(intent);
2293db7d865e53c4db049bab20a0bcc7cb596e450d9aSylvain Fonteneau                           registerTagObject(nativeTag);
2294f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       } catch (ActivityNotFoundException e) {
2295f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           Log.w(TAG, "No activity found, disconnecting");
2296f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           nativeTag.asyncDisconnect();
2297f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       }
2298f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   }
2299f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               } else {
2300f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   Log.w(TAG, "Failed to connect to tag");
2301f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   nativeTag.asyncDisconnect();
2302f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               }
2303f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               break;
2304f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           case MSG_CARD_EMULATION:
2305f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.d(TAG, "Card Emulation message");
2306f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               byte[] aid = (byte[]) msg.obj;
2307f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               /* Send broadcast ordered */
2308f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Intent TransactionIntent = new Intent();
2309f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               TransactionIntent.setAction(NfcAdapter.ACTION_TRANSACTION_DETECTED);
2310f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               TransactionIntent.putExtra(NfcAdapter.EXTRA_AID, aid);
2311f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.d(TAG, "Broadcasting Card Emulation event");
2312f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               mContext.sendOrderedBroadcast(TransactionIntent, NFC_PERM);
2313f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               break;
2314f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly
2315f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           case MSG_LLCP_LINK_ACTIVATION:
2316f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               NativeP2pDevice device = (NativeP2pDevice) msg.obj;
2317f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly
2318f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.d(TAG, "LLCP Activation message");
2319f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly
2320f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               if (device.getMode() == NativeP2pDevice.MODE_P2P_TARGET) {
23216f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton                   Log.d(TAG, "NativeP2pDevice.MODE_P2P_TARGET");
2322f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   if (device.doConnect()) {
2323f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       /* Check Llcp compliancy */
2324f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       if (mManager.doCheckLlcp()) {
2325f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           /* Activate Llcp Link */
2326f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           if (mManager.doActivateLlcp()) {
2327f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               Log.d(TAG, "Initiator Activate LLCP OK");
2328eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton                               activateLlcpLink();
2329eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton                           } else {
2330eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton                               /* should not happen */
2331eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton                               Log.w(TAG, "Initiator Activate LLCP NOK. Disconnect.");
2332eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton                               device.doDisconnect();
2333b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                           }
2334b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
2335f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       } else {
2336eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton                           Log.d(TAG, "Remote Target does not support LLCP. Disconnect.");
2337f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           device.doDisconnect();
2338b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                       }
2339eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton                   } else {
2340eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton                       Log.d(TAG, "Cannot connect remote Target. Restart polling loop.");
2341eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton                       /* resume should be done in doConnect */
2342f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   }
2343f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly
2344f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               } else if (device.getMode() == NativeP2pDevice.MODE_P2P_INITIATOR) {
23456f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton                   Log.d(TAG, "NativeP2pDevice.MODE_P2P_INITIATOR");
2346f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   /* Check Llcp compliancy */
2347f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   if (mManager.doCheckLlcp()) {
2348f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       /* Activate Llcp Link */
2349f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       if (mManager.doActivateLlcp()) {
2350f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           Log.d(TAG, "Target Activate LLCP OK");
2351eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton                           activateLlcpLink();
2352eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton                      }
23536f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton                   } else {
23546f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton                       Log.d(TAG, "checkLlcp failed");
2355f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   }
2356b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau               }
2357f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               break;
2358f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly
2359f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           case MSG_LLCP_LINK_DEACTIVATED:
2360eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton               device = (NativeP2pDevice) msg.obj;
2361eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton
2362eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton               Log.d(TAG, "LLCP Link Deactivated message. Restart polling loop.");
2363eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton               /* Restart polling loop */
2364eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton               device.doDisconnect();
2365eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton
2366b3cdb6612a057373a61521171d99ce4f24b84e1fJeff Hamilton               /* Mark the link state */
2367b3cdb6612a057373a61521171d99ce4f24b84e1fJeff Hamilton               mLlcpLinkState = NfcAdapter.LLCP_LINK_STATE_DEACTIVATED;
2368b3cdb6612a057373a61521171d99ce4f24b84e1fJeff Hamilton
2369f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               /* Broadcast Intent Link LLCP activated */
2370f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Intent LlcpLinkIntent = new Intent();
2371f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               LlcpLinkIntent.setAction(NfcAdapter.ACTION_LLCP_LINK_STATE_CHANGED);
2372f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               LlcpLinkIntent.putExtra(NfcAdapter.EXTRA_LLCP_LINK_STATE_CHANGED,
2373f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       NfcAdapter.LLCP_LINK_STATE_DEACTIVATED);
2374f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.d(TAG, "Broadcasting LLCP deactivation");
2375f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               mContext.sendOrderedBroadcast(LlcpLinkIntent, NFC_PERM);
2376f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               break;
2377f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly
2378f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           case MSG_TARGET_DESELECTED:
2379f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               /* Broadcast Intent Target Deselected */
2380f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.d(TAG, "Target Deselected");
2381f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Intent TargetDeselectedIntent = new Intent();
2382f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               TargetDeselectedIntent.setAction(mManager.INTERNAL_TARGET_DESELECTED_ACTION);
2383f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.d(TAG, "Broadcasting Intent");
2384f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               mContext.sendOrderedBroadcast(TargetDeselectedIntent, NFC_PERM);
2385f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               break;
2386f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly
23873ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton           case MSG_SHOW_MY_TAG_ICON: {
23883ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton               StatusBarManager sb = (StatusBarManager) getSystemService(
23893ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                       Context.STATUS_BAR_SERVICE);
23903ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton               sb.setIcon("nfc", R.drawable.stat_sys_nfc, 0);
23913ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton               break;
23923ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton           }
23933ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton
23943ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton           case MSG_HIDE_MY_TAG_ICON: {
23953ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton               StatusBarManager sb = (StatusBarManager) getSystemService(
23963ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                       Context.STATUS_BAR_SERVICE);
23973ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton               sb.removeIcon("nfc");
23983ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton               break;
23993ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton           }
24003ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton
2401f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           default:
2402f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.e(TAG, "Unknown message received");
2403f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               break;
2404f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           }
2405b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        }
2406d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
2407d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        private Intent buildNdefTagIntent(NdefTag tag) {
2408d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            Intent intent = new Intent();
24092407a9d01fdc8e48f778d2ef070e75a74d3863c4Nick Pelly               intent.setAction(NfcAdapter.ACTION_TAG_DISCOVERED);
2410d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton               intent.putExtra(NfcAdapter.EXTRA_TAG, tag);
24112407a9d01fdc8e48f778d2ef070e75a74d3863c4Nick Pelly               intent.putExtra(NfcAdapter.EXTRA_ID, tag.getId());
24122407a9d01fdc8e48f778d2ef070e75a74d3863c4Nick Pelly               intent.putExtra(NfcAdapter.EXTRA_NDEF_MESSAGES, tag.getNdefMessages());
2413d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton               intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2414d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            return intent;
2415d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        }
2416b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    };
2417b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
24187c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly    private class EnableDisableDiscoveryTask extends AsyncTask<Boolean, Void, Void> {
2419fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
24207c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly        protected Void doInBackground(Boolean... enable) {
2421df4e65b5dacb313e7d68bad797a843a175febbedNick Pelly            if (enable != null && enable.length > 0 && enable[0]) {
2422161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly                synchronized (NfcService.this) {
2423161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly                    mScreenOn = true;
2424161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly                    maybeEnableDiscovery();
2425161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly                }
24267c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly            } else {
2427161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly                synchronized (NfcService.this) {
2428161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly                    mScreenOn = false;
2429161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly                    maybeDisableDiscovery();
2430161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly                }
24317c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly            }
24327c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly            return null;
24337c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly        }
24347c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly    }
24357c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly
24360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
24370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        @Override
24380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public void onReceive(Context context, Intent intent) {
2439eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton            if (intent.getAction().equals(
2440f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION)) {
24410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                Log.d(TAG, "INERNAL_TARGET_DESELECTED_ACTION");
24420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
24430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mOpenPending = false;
2444f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                /* Restart polling loop for notification */
244565945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly                maybeEnableDiscovery();
2446f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
244765945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
24487c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly                // Perform discovery enable in thread to protect against ANR when the
24497c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly                // NFC stack wedges. This is *not* the correct way to fix this issue -
24507c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly                // configuration of the local NFC adapter should be very quick and should
24517c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly                // be safe on the main thread, and the NFC stack should not wedge.
2452df4e65b5dacb313e7d68bad797a843a175febbedNick Pelly                new EnableDisableDiscoveryTask().execute(new Boolean(true));
245365945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            } else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
24547c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly                // Perform discovery disable in thread to protect against ANR when the
24557c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly                // NFC stack wedges. This is *not* the correct way to fix this issue -
24567c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly                // configuration of the local NFC adapter should be very quick and should
24577c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly                // be safe on the main thread, and the NFC stack should not wedge.
2458df4e65b5dacb313e7d68bad797a843a175febbedNick Pelly                new EnableDisableDiscoveryTask().execute(new Boolean(false));
2459f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
2460f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
2461f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    };
246274180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick}
2463