NfcService.java revision cdab1112486288ee6ccc9eb5c55456f9618f6b9c
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
1722f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    // fields below are used in multiple threads and protected by synchronized(this)
1732f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    private final HashMap<Integer, Object> mObjectMap = new HashMap<Integer, Object>();
1742f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    private final HashMap<Integer, Object> mSocketMap = new HashMap<Integer, Object>();
17565945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly    private boolean mScreenOn;
1762f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly
1772f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    // fields below are final after onCreate()
1780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private Context mContext;
1790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private NativeNfcManager mManager;
1800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private SharedPreferences mPrefs;
1810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private SharedPreferences.Editor mPrefsEditor;
182fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks    private MyTagServer mMyTagServer;
183d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    private MyTagClient mMyTagClient;
184d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
185d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    private static NfcService sService;
186d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
187d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    public static NfcService getInstance() {
188d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        return sService;
189d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    }
190f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    @Override
1920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    public void onCreate() {
1932f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly        super.onCreate();
1942f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly
1952f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly        Log.i(TAG, "Starting NFC service");
1962f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly
197d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        sService = this;
198d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
1990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mContext = this;
200b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        mManager = new NativeNfcManager(mContext, this);
2010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mManager.initializeNativeStructure();
20274180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick
203d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        mMyTagServer = new MyTagServer();
204d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        mMyTagClient = new MyTagClient(this);
205d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
2060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mPrefs = mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE);
2070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mPrefsEditor = mPrefs.edit();
208f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
209d6fdd3fbb880f1503d56616608e6823b51320dc3Nick Pelly        mIsNfcEnabled = false;  // real preference read later
21065945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly        mScreenOn = true;  // assume screen is on during boot
211f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
212d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        ServiceManager.addService(SERVICE_NAME, mNfcAdapter);
213f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
214eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton        IntentFilter filter = new IntentFilter(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION);
21565945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly        filter.addAction(Intent.ACTION_SCREEN_OFF);
21665945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly        filter.addAction(Intent.ACTION_SCREEN_ON);
2170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mContext.registerReceiver(mReceiver, filter);
2180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
2190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        Thread t = new Thread() {
2200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            @Override
2210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            public void run() {
2220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                boolean nfc_on = mPrefs.getBoolean(PREF_NFC_ON, NFC_ON_DEFAULT);
2230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (nfc_on) {
2240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    _enable(false);
225f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
226f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
2270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        };
2280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        t.start();
229fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks
230fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        Context context = getApplicationContext();
231fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks
232fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        // Set this to null by default. If there isn't a tag on disk or if there
233fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        // was an error reading the tag then this will cause the status bar icon
234fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        // to be removed.
235fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        NdefMessage myTag = null;
236fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks
237fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        FileInputStream input = null;
238fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks
239fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        try {
240fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            input = context.openFileInput(MY_TAG_FILE_NAME);
241fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            ByteArrayOutputStream bytes = new ByteArrayOutputStream();
242fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks
243fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            byte[] buffer = new byte[4096];
244fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            int read = 0;
245fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            while ((read = input.read(buffer)) > 0) {
246fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                bytes.write(buffer, 0, read);
247fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            }
248fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks
249fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            myTag = new NdefMessage(bytes.toByteArray());
250fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        } catch (FileNotFoundException e) {
251fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            // Ignore.
252fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        } catch (IOException e) {
253fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            Log.e(TAG, "Could not read mytag file: ", e);
254fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            context.deleteFile(MY_TAG_FILE_NAME);
255fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        } catch (FormatException e) {
256fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            Log.e(TAG, "Invalid NdefMessage for mytag", e);
257fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            context.deleteFile(MY_TAG_FILE_NAME);
258fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        } finally {
259fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            try {
260fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                if (input != null) {
261fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                    input.close();
262fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                }
263fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            } catch (IOException e) {
264fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                // Ignore
265fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            }
266fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        }
267fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks
268fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        try {
269fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            mNfcAdapter.localSet(myTag);
270fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        } catch (RemoteException e) {
271fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks            // Ignore
272fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        }
2730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    }
2740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
2750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    @Override
2762f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    public void onTerminate() {
2772f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly        super.onTerminate();
2782f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly        // NFC application is persistent, it should not be destroyed by framework
2790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        Log.wtf(TAG, "NFC service is under attack!");
2800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    }
2810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
2820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private final INfcAdapter.Stub mNfcAdapter = new INfcAdapter.Stub() {
2833ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton        /** Protected by "this" */
2843ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton        NdefMessage mLocalMessage = null;
2854acf84356e35861f7df6d07a2b9ff84842a9f221Nick Pelly
286fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
2870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public boolean enable() throws RemoteException {
288d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
2890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
2900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
2910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean previouslyEnabled = isEnabled();
2920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!previouslyEnabled) {
2930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                reset();
2940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                isSuccess = _enable(previouslyEnabled);
295f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
2960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return isSuccess;
297f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
298f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
299fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
3000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public boolean disable() throws RemoteException {
3010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
302d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
3030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean previouslyEnabled = isEnabled();
3040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            Log.d(TAG, "Disabling NFC.  previous=" + previouslyEnabled);
3050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (previouslyEnabled) {
3076f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton                /* tear down the my tag server */
3086f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton                mMyTagServer.stop();
3090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                isSuccess = mManager.deinitialize();
3100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                Log.d(TAG, "NFC success of deinitialize = " + isSuccess);
3110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (isSuccess) {
3120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mIsNfcEnabled = false;
3130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
314f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
3150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            updateNfcOnSetting(previouslyEnabled);
3170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return isSuccess;
319f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
320f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
321fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
3220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int createLlcpConnectionlessSocket(int sap) throws RemoteException {
323d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
324bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
325f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
326f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
327f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
328f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
329f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
3300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* Check SAP is not already used */
3310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* Check nb socket created */
3330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mNbSocketCreated < LLCP_SOCKET_NB_MAX) {
3340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store the socket handle */
3350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                int sockeHandle = mGeneratedSocketHandle;
3360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
337f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
3380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    NativeLlcpConnectionlessSocket socket;
3390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    socket = mManager.doCreateLlcpConnectionlessSocket(sap);
3410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (socket != null) {
3422f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        synchronized(NfcService.this) {
3432f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            /* Update the number of socket created */
3442f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mNbSocketCreated++;
3450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3462f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            /* Add the socket into the socket map */
3472f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mSocketMap.put(sockeHandle, socket);
3482f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        }
3490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return sockeHandle;
350f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    } else {
3510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /*
3520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                         * socket creation error - update the socket handle
3530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                         * generation
3540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                         */
3550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        mGeneratedSocketHandle -= 1;
3560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Get Error Status */
3580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        int errorStatus = mManager.doGetLastError();
3590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        switch (errorStatus) {
3610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            case ErrorCodes.ERROR_BUFFER_TO_SMALL:
3620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_BUFFER_TO_SMALL;
3630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES:
3640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES;
3650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            default:
3660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_SOCKET_CREATION;
3670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        }
368f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    }
369f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
3700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Check SAP is not already used */
3710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (!CheckSocketSap(sap)) {
3720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_SAP_USED;
3730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
374f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
3750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    NativeLlcpConnectionlessSocket socket = new NativeLlcpConnectionlessSocket(sap);
376f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
3772f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    synchronized(NfcService.this) {
3782f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        /* Add the socket into the socket map */
3792f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mSocketMap.put(sockeHandle, socket);
3800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3812f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        /* Update the number of socket created */
3822f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mNbSocketCreated++;
3832f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    }
3840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Create new registered socket */
3850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    RegisteredSocket registeredSocket = new RegisteredSocket(
3860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            LLCP_CONNECTIONLESS_SOCKET_TYPE, sockeHandle, sap);
3870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Put this socket into a list of registered socket */
3890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mRegisteredSocketList.add(registeredSocket);
390f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
3910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* update socket handle generation */
3930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mGeneratedSocketHandle++;
3940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
3950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return sockeHandle;
3960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
397f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
3980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* No socket available */
3990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES;
400f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
4010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
402f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
403f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
404fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
4050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int createLlcpServiceSocket(int sap, String sn, int miu, int rw, int linearBufferLength)
4060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                throws RemoteException {
407d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
408bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
409f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
410f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
411f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
412f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
413f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
4140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mNbSocketCreated < LLCP_SOCKET_NB_MAX) {
4150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                int sockeHandle = mGeneratedSocketHandle;
4160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
4180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    NativeLlcpServiceSocket socket;
4190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    socket = mManager.doCreateLlcpServiceSocket(sap, sn, miu, rw, linearBufferLength);
4210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (socket != null) {
4222f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        synchronized(NfcService.this) {
4232f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            /* Update the number of socket created */
4242f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mNbSocketCreated++;
4252f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            /* Add the socket into the socket map */
4262f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mSocketMap.put(sockeHandle, socket);
4272f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        }
4280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    } else {
4290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* socket creation error - update the socket handle counter */
4300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        mGeneratedSocketHandle -= 1;
4310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Get Error Status */
4330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        int errorStatus = mManager.doGetLastError();
4340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        switch (errorStatus) {
4360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            case ErrorCodes.ERROR_BUFFER_TO_SMALL:
4370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_BUFFER_TO_SMALL;
4380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES:
4390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES;
4400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            default:
4410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_SOCKET_CREATION;
4420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        }
4430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
444f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
4450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Check SAP is not already used */
4470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (!CheckSocketSap(sap)) {
4480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_SAP_USED;
4490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
4500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Service Name */
4520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (!CheckSocketServiceName(sn)) {
4530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_SERVICE_NAME_USED;
4540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
4550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Check socket options */
4570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (!CheckSocketOptions(miu, rw, linearBufferLength)) {
4580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_SOCKET_OPTIONS;
4590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
4600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
46115151d5453f9b9b3680cb254ccea42458cc51f33Jeff Hamilton                    NativeLlcpServiceSocket socket = new NativeLlcpServiceSocket(sap, sn, miu, rw,
46215151d5453f9b9b3680cb254ccea42458cc51f33Jeff Hamilton                            linearBufferLength);
4632f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    synchronized(NfcService.this) {
4642f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        /* Add the socket into the socket map */
4652f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mSocketMap.put(sockeHandle, socket);
4660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4672f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        /* Update the number of socket created */
4682f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mNbSocketCreated++;
4692f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    }
4700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Create new registered socket */
4710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    RegisteredSocket registeredSocket = new RegisteredSocket(LLCP_SERVICE_SOCKET_TYPE,
4720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            sockeHandle, sap, sn, miu, rw, linearBufferLength);
4730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Put this socket into a list of registered socket */
4750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mRegisteredSocketList.add(registeredSocket);
476f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
4770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* update socket handle generation */
4790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mGeneratedSocketHandle += 1;
4800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
4810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                Log.d(TAG, "Llcp Service Socket Handle =" + sockeHandle);
4820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return sockeHandle;
483f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
4840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* No socket available */
4850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES;
486f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
487f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
488f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
489fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
4900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int createLlcpSocket(int sap, int miu, int rw, int linearBufferLength)
4910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                throws RemoteException {
492d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
493bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
494f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
495f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
496f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
497f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
498f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
4990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mNbSocketCreated < LLCP_SOCKET_NB_MAX) {
5000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                int sockeHandle = mGeneratedSocketHandle;
5020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
5046f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton                    Log.d(TAG, "creating llcp socket while activated");
5050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    NativeLlcpSocket socket;
5060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    socket = mManager.doCreateLlcpSocket(sap, miu, rw, linearBufferLength);
5080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (socket != null) {
5102f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        synchronized(NfcService.this) {
5112f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            /* Update the number of socket created */
5122f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mNbSocketCreated++;
5132f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            /* Add the socket into the socket map */
5142f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mSocketMap.put(sockeHandle, socket);
5152f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        }
5160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    } else {
5170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /*
5180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                         * socket creation error - update the socket handle
5190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                         * generation
5200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                         */
5210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        mGeneratedSocketHandle -= 1;
5220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Get Error Status */
5240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        int errorStatus = mManager.doGetLastError();
5250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5266f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton                        Log.d(TAG, "failed to create llcp socket: " + ErrorCodes.asString(errorStatus));
5276f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton
5280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        switch (errorStatus) {
5290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            case ErrorCodes.ERROR_BUFFER_TO_SMALL:
5300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_BUFFER_TO_SMALL;
5310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES:
5320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES;
5330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            default:
5340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                                return ErrorCodes.ERROR_SOCKET_CREATION;
5350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        }
5360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
537f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
5386f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton                    Log.d(TAG, "registering llcp socket while not activated");
539f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
5400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Check SAP is not already used */
5410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (!CheckSocketSap(sap)) {
5420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_SAP_USED;
5430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
544f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
5450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Check Socket options */
5460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (!CheckSocketOptions(miu, rw, linearBufferLength)) {
5470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_SOCKET_OPTIONS;
5480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
549bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
5500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    NativeLlcpSocket socket = new NativeLlcpSocket(sap, miu, rw);
5512f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    synchronized(NfcService.this) {
5522f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        /* Add the socket into the socket map */
5532f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mSocketMap.put(sockeHandle, socket);
554f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
5552f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        /* Update the number of socket created */
5562f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mNbSocketCreated++;
5572f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    }
5580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Create new registered socket */
5590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    RegisteredSocket registeredSocket = new RegisteredSocket(LLCP_SOCKET_TYPE,
5600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            sockeHandle, sap, miu, rw, linearBufferLength);
5610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Put this socket into a list of registered socket */
5630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mRegisteredSocketList.add(registeredSocket);
5640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
5650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* update socket handle generation */
5670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mGeneratedSocketHandle++;
5680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return sockeHandle;
570f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
5710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* No socket available */
5720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES;
573f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
574f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
575f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
576fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
5770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int deselectSecureElement() throws RemoteException {
578d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
579f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
580f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
581f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
582f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
583f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
584f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
5850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mSelectedSeId == 0) {
5860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NO_SE_CONNECTED;
587f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
5880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mManager.doDeselectSecureElement(mSelectedSeId);
5900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mNfcSecureElementState = false;
5910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mSelectedSeId = 0;
5920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* store preference */
5940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mPrefsEditor.putBoolean(PREF_SECURE_ELEMENT_ON, false);
5950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mPrefsEditor.putInt(PREF_SECURE_ELEMENT_ID, 0);
5962f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick            mPrefsEditor.apply();
5970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
5980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return ErrorCodes.SUCCESS;
599f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
600f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
601fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
6020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public ILlcpConnectionlessSocket getLlcpConnectionlessInterface() throws RemoteException {
603d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
6040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mLlcpConnectionlessSocketService;
6050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
606bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
607fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
6080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public ILlcpSocket getLlcpInterface() throws RemoteException {
609d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
6100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mLlcpSocket;
6110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
612f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
613fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
6140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public ILlcpServiceSocket getLlcpServiceInterface() throws RemoteException {
615d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
6160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mLlcpServerSocketService;
6170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
618f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
619fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
6200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public INfcTag getNfcTagInterface() throws RemoteException {
621d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
6220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mNfcTagService;
6230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
6240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
625fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
6260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public IP2pInitiator getP2pInitiatorInterface() throws RemoteException {
627d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
6280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mP2pInitiatorService;
6290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
6300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
631fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
6320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public IP2pTarget getP2pTargetInterface() throws RemoteException {
633d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
6340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mP2pTargetService;
6350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
6360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
637fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
6380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public String getProperties(String param) throws RemoteException {
639d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
6400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (param == null) {
6420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return null;
6430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
6440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (param.equals(PROPERTY_LLCP_LTO_VALUE)) {
6460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Integer.toString(mPrefs.getInt(PREF_LLCP_LTO, LLCP_LTO_DEFAULT));
6470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_LLCP_MIU_VALUE)) {
6480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Integer.toString(mPrefs.getInt(PREF_LLCP_MIU, LLCP_MIU_DEFAULT));
6490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_LLCP_WKS_VALUE)) {
6500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Integer.toString(mPrefs.getInt(PREF_LLCP_WKS, LLCP_WKS_DEFAULT));
6510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_LLCP_OPT_VALUE)) {
6520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Integer.toString(mPrefs.getInt(PREF_LLCP_OPT, LLCP_OPT_DEFAULT));
6530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_A_VALUE)) {
6540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_A, DISCOVERY_A_DEFAULT));
6550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_B_VALUE)) {
6560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_B, DISCOVERY_B_DEFAULT));
6570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_F_VALUE)) {
6580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_F, DISCOVERY_F_DEFAULT));
6590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_NFCIP_VALUE)) {
6600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_NFCIP, DISCOVERY_NFCIP_DEFAULT));
6610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_15693_VALUE)) {
6620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_15693, DISCOVERY_15693_DEFAULT));
663f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
6640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return "Unknown property";
665f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
666f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
667f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
668fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
6690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int[] getSecureElementList() throws RemoteException {
670d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
671bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
6720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            int[] list = null;
6730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mIsNfcEnabled == true) {
6740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                list = mManager.doGetSecureElementList();
6750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
6760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return list;
6770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
6780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
679fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
6800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getSelectedSecureElement() throws RemoteException {
681d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
6820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
6830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mSelectedSeId;
6840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
6850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
686fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
6870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public boolean isEnabled() throws RemoteException {
6880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return mIsNfcEnabled;
6890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
6900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
691fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
6920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public void openTagConnection(Tag tag) throws RemoteException {
693b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            // TODO: Remove obsolete code
6940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
6950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
696fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
6970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int selectSecureElement(int seId) throws RemoteException {
698d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
699f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
700f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
701f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
702f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
703f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
704f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
7050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mSelectedSeId == seId) {
7060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_SE_ALREADY_SELECTED;
7070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
7080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mSelectedSeId != 0) {
7100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_SE_CONNECTED;
7110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
7120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mSelectedSeId = seId;
7140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mManager.doSelectSecureElement(mSelectedSeId);
7150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* store */
7170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mPrefsEditor.putBoolean(PREF_SECURE_ELEMENT_ON, true);
7180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mPrefsEditor.putInt(PREF_SECURE_ELEMENT_ID, mSelectedSeId);
7192f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick            mPrefsEditor.apply();
7200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mNfcSecureElementState = true;
7220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return ErrorCodes.SUCCESS;
7240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
7260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
727fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
7280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int setProperties(String param, String value) throws RemoteException {
729d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
7300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (isEnabled()) {
7320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NFC_ON;
7330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
7340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            int val;
7360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* Check params validity */
7380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (param == null || value == null) {
7390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_INVALID_PARAM;
7400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
7410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (param.equals(PROPERTY_LLCP_LTO_VALUE)) {
7430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                val = Integer.parseInt(value);
7440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Check params */
7460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (val > LLCP_LTO_MAX)
7470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_INVALID_PARAM;
7480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
7500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putInt(PREF_LLCP_LTO, val);
7512f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
7520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
7540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_LLCP_LTO, val);
7550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_LLCP_MIU_VALUE)) {
7570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                val = Integer.parseInt(value);
7580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Check params */
7600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if ((val < LLCP_MIU_DEFAULT) || (val > LLCP_MIU_MAX))
7610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_INVALID_PARAM;
7620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
7640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putInt(PREF_LLCP_MIU, val);
7652f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
7660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
7680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_LLCP_MIU, val);
7690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_LLCP_WKS_VALUE)) {
7710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                val = Integer.parseInt(value);
7720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Check params */
7740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (val > LLCP_WKS_MAX)
7750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_INVALID_PARAM;
7760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
7780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putInt(PREF_LLCP_WKS, val);
7792f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
7800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
7820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_LLCP_WKS, val);
7830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_LLCP_OPT_VALUE)) {
7850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                val = Integer.parseInt(value);
7860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Check params */
7880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (val > LLCP_OPT_MAX)
7890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_INVALID_PARAM;
7900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
7920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putInt(PREF_LLCP_OPT, val);
7932f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
7940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
7960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_LLCP_OPT, val);
7970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
7980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_A_VALUE)) {
7990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                boolean b = Boolean.parseBoolean(value);
8000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
8020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putBoolean(PREF_DISCOVERY_A, b);
8032f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
8040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
8060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_A, b ? 1 : 0);
8070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_B_VALUE)) {
8090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                boolean b = Boolean.parseBoolean(value);
8100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
8120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putBoolean(PREF_DISCOVERY_B, b);
8132f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
8140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
8160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_B, b ? 1 : 0);
8170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_F_VALUE)) {
8190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                boolean b = Boolean.parseBoolean(value);
8200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
8220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putBoolean(PREF_DISCOVERY_F, b);
8232f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
8240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
8260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_F, b ? 1 : 0);
8270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_15693_VALUE)) {
8290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                boolean b = Boolean.parseBoolean(value);
8300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
8320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putBoolean(PREF_DISCOVERY_15693, b);
8332f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
8340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
8360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_15693, b ? 1 : 0);
8370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else if (param.equals(PROPERTY_NFC_DISCOVERY_NFCIP_VALUE)) {
8390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                boolean b = Boolean.parseBoolean(value);
8400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Store value */
8420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mPrefsEditor.putBoolean(PREF_DISCOVERY_NFCIP, b);
8432f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick                mPrefsEditor.apply();
8440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* Update JNI */
8460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_NFCIP, b ? 1 : 0);
8470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
848f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
8490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_INVALID_PARAM;
850f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
8510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return ErrorCodes.SUCCESS;
853f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
854f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
8553ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton        @Override
8560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public NdefMessage localGet() throws RemoteException {
857d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
858d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
8593ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton            synchronized (this) {
8603ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                return mLocalMessage;
8613ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton            }
8620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
8630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
8643ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton        @Override
8650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public void localSet(NdefMessage message) throws RemoteException {
866d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
867d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
8683ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton            synchronized (this) {
8693ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                mLocalMessage = message;
870fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                Context context = NfcService.this.getApplicationContext();
871fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks
8723ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                // Send a message to the UI thread to show or hide the icon so the requests are
8733ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                // serialized and the icon can't get out of sync with reality.
8743ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                if (message != null) {
875fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                    FileOutputStream out = null;
876fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks
877fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                    try {
878fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                        out = context.openFileOutput(MY_TAG_FILE_NAME, Context.MODE_PRIVATE);
87988f552a4ac37af91db1e0c848df347267fcfb26aJason parks                        byte[] bytes = message.toByteArray();
88088f552a4ac37af91db1e0c848df347267fcfb26aJason parks                        if (bytes.length == 0) {
88188f552a4ac37af91db1e0c848df347267fcfb26aJason parks                            Log.w(TAG, "Setting a empty mytag");
88288f552a4ac37af91db1e0c848df347267fcfb26aJason parks                        }
88388f552a4ac37af91db1e0c848df347267fcfb26aJason parks
88488f552a4ac37af91db1e0c848df347267fcfb26aJason parks                        out.write(bytes);
885fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                    } catch (IOException e) {
886fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                        Log.e(TAG, "Could not write mytag file", e);
887fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                    } finally {
888fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                        try {
889fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                            if (out != null) {
890fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                                out.flush();
891fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                                out.close();
892fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                            }
893fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                        } catch (IOException e) {
894fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                            // Ignore
895fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                        }
896fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                    }
897fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks
8983ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                    sendMessage(MSG_SHOW_MY_TAG_ICON, null);
8993ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                } else {
900fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks                    context.deleteFile(MY_TAG_FILE_NAME);
9013ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                    sendMessage(MSG_HIDE_MY_TAG_ICON, null);
9023ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                }
9033ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton            }
9040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
9050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    };
9060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
9070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private final ILlcpSocket mLlcpSocket = new ILlcpSocket.Stub() {
9080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
9090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        private final int CONNECT_FLAG = 0x01;
9100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        private final int CLOSE_FLAG   = 0x02;
9110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        private final int RECV_FLAG    = 0x04;
9120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        private final int SEND_FLAG    = 0x08;
9130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
9140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        private int concurrencyFlags;
9150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        private Object sync;
9160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
917fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
9180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int close(int nativeHandle) throws RemoteException {
919d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
920bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
921f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpSocket socket = null;
9220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
923f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
924f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
925f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
926f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
927f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
928f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
929f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
930f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
931f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
9320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
9330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    isSuccess = socket.doClose();
9340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (isSuccess) {
9350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Remove the socket closed from the hmap */
9360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        RemoveSocket(nativeHandle);
9370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Update mNbSocketCreated */
9380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        mNbSocketCreated--;
9390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.SUCCESS;
9400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    } else {
9410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_IO;
9420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
943f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
9440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Remove the socket closed from the hmap */
9450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    RemoveSocket(nativeHandle);
9460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
9470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Remove registered socket from the list */
9480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    RemoveRegisteredSocket(nativeHandle);
9490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
9500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Update mNbSocketCreated */
9510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mNbSocketCreated--;
9520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
9530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.SUCCESS;
954f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
955f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
9560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_IO;
957f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
958f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
959f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
960fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
9610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int connect(int nativeHandle, int sap) throws RemoteException {
962d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
963bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
964f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpSocket socket = null;
9650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
966f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
967f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
968f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
969f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
970f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
971f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
972f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
973f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
974f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
97593915e1c6fe6d5d16fcebeda610782bf5812c9b4Nick Pelly                isSuccess = socket.doConnect(sap);
9760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (isSuccess) {
9770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.SUCCESS;
978f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
979f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return ErrorCodes.ERROR_IO;
980f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
981f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
982f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_IO;
983f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
9840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
985f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
986f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
987fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
9880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int connectByName(int nativeHandle, String sn) throws RemoteException {
989d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
990bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
991f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpSocket socket = null;
992f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            boolean isSuccess = false;
993f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
994f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
995f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
996f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
997f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
998f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
999f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
1000f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
1001f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
100293915e1c6fe6d5d16fcebeda610782bf5812c9b4Nick Pelly                isSuccess = socket.doConnectBy(sn);
1003f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                if (isSuccess) {
1004f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return ErrorCodes.SUCCESS;
1005f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
1006f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return ErrorCodes.ERROR_IO;
1007f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
1008f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
1009f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_IO;
1010f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
10110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
1012f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1013f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1014fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
10150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getLocalSap(int nativeHandle) throws RemoteException {
1016d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1017bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
10180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket socket = null;
1019f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1020f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1021f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1022f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
1023f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1024f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
10250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the socket in the hmap */
10260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
10270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (socket != null) {
10280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return socket.getSap();
1029f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
10300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return 0;
1031f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1032f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1033f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1034fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
10350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getLocalSocketMiu(int nativeHandle) throws RemoteException {
1036d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1037bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
10380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket socket = null;
1039f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1040f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1041f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
10420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
1043f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1044f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1045f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
10460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
1047f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
10480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return socket.getMiu();
10490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else {
10500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return 0;
1051f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1052f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1053f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1054fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
10550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getLocalSocketRw(int nativeHandle) throws RemoteException {
1056d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1057bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
10580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket socket = null;
1059f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1060f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1061f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1062f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
1063f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1064f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1065f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
10660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
10670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (socket != null) {
10680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return socket.getRw();
10690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else {
10700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return 0;
10710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
10720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
10730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
1074fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
10750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getRemoteSocketMiu(int nativeHandle) throws RemoteException {
1076d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
10770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket socket = null;
10790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
10810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
10820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
10830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
10840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
10850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the socket in the hmap */
10860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
10870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (socket != null) {
10880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (socket.doGetRemoteSocketMiu() != 0) {
10890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return socket.doGetRemoteSocketMiu();
10900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
10910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED;
10920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
10930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else {
10940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED;
10950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
10960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
10970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
1098fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
10990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getRemoteSocketRw(int nativeHandle) throws RemoteException {
1100d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
11010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket socket = null;
11030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
11050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
11060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
11070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
11080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the socket in the hmap */
11100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
11110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (socket != null) {
11120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (socket.doGetRemoteSocketRw() != 0) {
11130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return socket.doGetRemoteSocketRw();
11140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
11150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED;
11160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
11170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else {
11180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED;
11190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
11200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
11210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
1122fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
11230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int receive(int nativeHandle, byte[] receiveBuffer) throws RemoteException {
1124d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
11250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket socket = null;
11270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            int receiveLength = 0;
11280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
11300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
11310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
11320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
11330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the socket in the hmap */
11350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpSocket) findSocket(nativeHandle);
11360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (socket != null) {
11370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                receiveLength = socket.doReceive(receiveBuffer);
11380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (receiveLength != 0) {
11390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return receiveLength;
11400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
11410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_IO;
11420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
11430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else {
11440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_IO;
11450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
11460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
11470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
1148fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
11490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int send(int nativeHandle, byte[] data) throws RemoteException {
1150d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
11510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket socket = null;
11530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
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                isSuccess = socket.doSend(data);
11640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (isSuccess) {
11650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.SUCCESS;
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    };
11740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private final ILlcpServiceSocket mLlcpServerSocketService = new ILlcpServiceSocket.Stub() {
11760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
1177fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
11780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int accept(int nativeHandle) throws RemoteException {
1179d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
11800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpServiceSocket socket = null;
11820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpSocket clientSocket = null;
11830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
11850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
11860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
11870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
11880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
11890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mNbSocketCreated < LLCP_SOCKET_NB_MAX) {
11900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                /* find the socket in the hmap */
11910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                socket = (NativeLlcpServiceSocket) findSocket(nativeHandle);
11920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (socket != null) {
119393915e1c6fe6d5d16fcebeda610782bf5812c9b4Nick Pelly                    clientSocket = socket.doAccept(socket.getMiu(),
11940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            socket.getRw(), socket.getLinearBufferLength());
11950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (clientSocket != null) {
11960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Add the socket into the socket map */
11972f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        synchronized(this) {
11982f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mSocketMap.put(clientSocket.getHandle(), clientSocket);
11992f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                            mNbSocketCreated++;
12002f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        }
12010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return clientSocket.getHandle();
12020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    } else {
12030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        return ErrorCodes.ERROR_IO;
12040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
12050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
12060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.ERROR_IO;
12070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
12080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            } else {
12090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES;
12100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
12110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
12120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
12130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
1214fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
12150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public void close(int nativeHandle) throws RemoteException {
1216d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
12170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
12180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeLlcpServiceSocket socket = null;
12190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
12200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
12210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
12220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
12230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return;
12240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
12250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
12260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the socket in the hmap */
12270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            socket = (NativeLlcpServiceSocket) findSocket(nativeHandle);
12280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (socket != null) {
12290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
12300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    isSuccess = socket.doClose();
12310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    if (isSuccess) {
12320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Remove the socket closed from the hmap */
12330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        RemoveSocket(nativeHandle);
12340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        /* Update mNbSocketCreated */
12350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        mNbSocketCreated--;
12360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
12370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
12380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Remove the socket closed from the hmap */
12390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    RemoveSocket(nativeHandle);
12400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
12410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Remove registered socket from the list */
12420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    RemoveRegisteredSocket(nativeHandle);
12430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
12440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Update mNbSocketCreated */
12450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mNbSocketCreated--;
12460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
12470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
12480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
1249f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    };
1250f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1251f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private final ILlcpConnectionlessSocket mLlcpConnectionlessSocketService = new ILlcpConnectionlessSocket.Stub() {
1252f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1253fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
1254f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public void close(int nativeHandle) throws RemoteException {
1255d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1256bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1257f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpConnectionlessSocket socket = null;
1258f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            boolean isSuccess = false;
1259f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1260f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1261f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1262f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return;
1263f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1264f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1265f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
1266f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpConnectionlessSocket) findSocket(nativeHandle);
1267f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
1268f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
1269f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    isSuccess = socket.doClose();
1270f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    if (isSuccess) {
1271f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                        /* Remove the socket closed from the hmap */
1272f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                        RemoveSocket(nativeHandle);
1273f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                        /* Update mNbSocketCreated */
1274f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                        mNbSocketCreated--;
1275f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    }
1276f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
1277f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    /* Remove the socket closed from the hmap */
1278f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    RemoveSocket(nativeHandle);
1279f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1280f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    /* Remove registered socket from the list */
1281f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    RemoveRegisteredSocket(nativeHandle);
1282f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1283f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    /* Update mNbSocketCreated */
1284f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    mNbSocketCreated--;
1285f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
1286f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1287f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1288f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1289fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
1290f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public int getSap(int nativeHandle) throws RemoteException {
1291d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1292bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1293f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpConnectionlessSocket socket = null;
1294f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1295f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1296f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1297f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
1298f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1299f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1300f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
1301f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpConnectionlessSocket) findSocket(nativeHandle);
1302f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
1303f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return socket.getSap();
1304f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
1305f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return 0;
1306f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1307f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1308f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1309fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
1310f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public LlcpPacket receiveFrom(int nativeHandle) throws RemoteException {
1311d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1312bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1313f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpConnectionlessSocket socket = null;
1314f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            LlcpPacket packet;
1315f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1316f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1317f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1318f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return null;
1319f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1320f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1321f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
1322f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpConnectionlessSocket) findSocket(nativeHandle);
1323f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
1324f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                packet = socket.doReceiveFrom(socket.getLinkMiu());
1325f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                if (packet != null) {
1326f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return packet;
1327f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
1328f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return null;
1329f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
1330f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return null;
1331f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1332f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1333f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1334fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
1335f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public int sendTo(int nativeHandle, LlcpPacket packet) throws RemoteException {
1336d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1337bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1338f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeLlcpConnectionlessSocket socket = null;
1339f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            boolean isSuccess = false;
1340f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1341f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1342f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1343f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
1344f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1345f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1346f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the socket in the hmap */
1347f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            socket = (NativeLlcpConnectionlessSocket) findSocket(nativeHandle);
1348f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (socket != null) {
1349f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                isSuccess = socket.doSendTo(packet.getRemoteSap(), packet.getDataBuffer());
1350f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                if (isSuccess) {
1351f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return ErrorCodes.SUCCESS;
1352f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } else {
1353f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return ErrorCodes.ERROR_IO;
1354f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
1355f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            } else {
1356f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_IO;
1357f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1358f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1359f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    };
1360f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1361f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private final INfcTag mNfcTagService = new INfcTag.Stub() {
1362f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1363fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
1364f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public int close(int nativeHandle) throws RemoteException {
1365d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1366bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1367f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeNfcTag tag = null;
1368f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1369f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1370f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1371f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
1372f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1373f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1374f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1375f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1376f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (tag != null) {
1377b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                /* Remove the device from the hmap */
1378b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                unregisterObject(nativeHandle);
137921545af22f9b913ec9cb124287aab2fcb0cf2b3bNick Pelly                tag.disconnect();
1380b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                return ErrorCodes.SUCCESS;
1381f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1382f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* Restart polling loop for notification */
138365945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            maybeEnableDiscovery();
1384f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return ErrorCodes.ERROR_DISCONNECT;
1385f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1386f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1387fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
1388f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public int connect(int nativeHandle) throws RemoteException {
1389d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1390bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1391f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeNfcTag tag = null;
1392f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1393f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1394f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1395f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
1396f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1397f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1398f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1399f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1400b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            if (tag == null) {
1401b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                return ErrorCodes.ERROR_DISCONNECT;
1402f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1403b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            // TODO: register the tag as being locked rather than really connect
1404b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            return ErrorCodes.SUCCESS;
1405f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1406f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1407fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
1408f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public String getType(int nativeHandle) throws RemoteException {
1409d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1410bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1411f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeNfcTag tag = null;
1412f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            String type;
1413f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1414f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1415f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1416f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return null;
1417f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1418f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1419f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1420f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1421f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (tag != null) {
1422f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                type = tag.getType();
1423f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return type;
1424f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1425f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return null;
1426f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1427f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1428fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
1429f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public byte[] getUid(int nativeHandle) throws RemoteException {
1430f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeNfcTag tag = null;
1431f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            byte[] uid;
1432f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1433f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1434f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1435f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return null;
1436f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1437f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1438f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1439f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1440f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (tag != null) {
1441f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                uid = tag.getUid();
1442f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return uid;
1443f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1444f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return null;
1445f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1446f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1447fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
1448b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        public boolean isPresent(int nativeHandle) throws RemoteException {
1449b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            NativeNfcTag tag = null;
1450b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
1451b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            // Check if NFC is enabled
1452b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            if (!mIsNfcEnabled) {
1453b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                return false;
1454b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            }
1455b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
1456b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            /* find the tag in the hmap */
1457b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            tag = (NativeNfcTag) findObject(nativeHandle);
1458b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            if (tag == null) {
1459b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                return false;
1460b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            }
1461b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
1462b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            return tag.presenceCheck();
1463b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        }
1464b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
1465fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
1466f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public boolean isNdef(int nativeHandle) throws RemoteException {
1467f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeNfcTag tag = null;
1468f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            boolean isSuccess = false;
1469f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1470f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1471f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1472f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return isSuccess;
1473f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1474f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1475f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1476f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1477f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (tag != null) {
1478b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                isSuccess = tag.checkNdef();
1479f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1480f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return isSuccess;
1481f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1482f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1483fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
1484f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public byte[] transceive(int nativeHandle, byte[] data) throws RemoteException {
1485d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1486bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1487f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeNfcTag tag = null;
1488f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            byte[] response;
1489f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1490f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1491f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1492f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return null;
1493f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1494f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1495f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1496f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1497f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (tag != null) {
1498b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                response = tag.transceive(data);
1499f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return response;
1500f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1501f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return null;
1502f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1503f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1504fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
1505f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public NdefMessage read(int nativeHandle) throws RemoteException {
1506d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1507bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1508f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeNfcTag tag;
1509f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1510f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1511f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1512f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return null;
1513f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1514f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1515f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1516f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1517f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (tag != null) {
1518b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                byte[] buf = tag.read();
1519f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                if (buf == null)
1520f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return null;
1521f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1522f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                /* Create an NdefMessage */
1523f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                try {
1524f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return new NdefMessage(buf);
1525f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                } catch (FormatException e) {
1526f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    return null;
1527f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                }
1528f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1529f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return null;
1530f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1531f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1532fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
1533f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public int write(int nativeHandle, NdefMessage msg) throws RemoteException {
1534d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1535bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly
1536f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            NativeNfcTag tag;
1537f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1538f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // Check if NFC is enabled
1539f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (!mIsNfcEnabled) {
1540f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
1541f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1542f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1543f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            /* find the tag in the hmap */
1544f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            tag = (NativeNfcTag) findObject(nativeHandle);
1545f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (tag == null) {
1546f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_IO;
1547f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1548f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1549b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau            if (tag.write(msg.toByteArray())) {
1550f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.SUCCESS;
1551f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1552f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            else {
1553f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return ErrorCodes.ERROR_IO;
1554f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1555f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1556f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1557f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1558fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
1559f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        public int getLastError(int nativeHandle) throws RemoteException {
1560f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            // TODO Auto-generated method stub
15610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return 0;
1562f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1563f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1564fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
15650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getModeHint(int nativeHandle) throws RemoteException {
15660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // TODO Auto-generated method stub
15670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return 0;
1568f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1569f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1570fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
15710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int makeReadOnly(int nativeHandle) throws RemoteException {
15720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // TODO Auto-generated method stub
15730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return 0;
1574f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1575f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1576f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    };
1578f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private final IP2pInitiator mP2pInitiatorService = new IP2pInitiator.Stub() {
1580f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1581fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
15820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public byte[] getGeneralBytes(int nativeHandle) throws RemoteException {
1583d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1584f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
1586f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
15880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
15890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return null;
15900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
1591f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
15920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
15930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
15940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
15950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                byte[] buff = device.getGeneralBytes();
15960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (buff == null)
15970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return null;
15980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return buff;
15990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
16000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return null;
16010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
1602f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1603fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
16040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getMode(int nativeHandle) throws RemoteException {
1605d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1606f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
1608f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
16100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
16110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
16120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
1613f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
16150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
16160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
16170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return device.getMode();
16180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
1619f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return ErrorCodes.ERROR_INVALID_PARAM;
1620f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1621f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1622fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
16230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public byte[] receive(int nativeHandle) throws RemoteException {
1624d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1625f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
1627f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
16290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
16300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return null;
16310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
1632f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
16340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
16350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
16360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                byte[] buff = device.doReceive();
16370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (buff == null)
16380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return null;
16390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return buff;
16400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
16410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* Restart polling loop for notification */
164265945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            maybeEnableDiscovery();
16430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return null;
16440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
1645f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1646fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
16470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public boolean send(int nativeHandle, byte[] data) throws RemoteException {
1648d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1649f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
16510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
1652f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
16540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
16550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return isSuccess;
16560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
1657f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
16590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
16600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
16610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                isSuccess = device.doSend(data);
16620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
16630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return isSuccess;
16640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
16650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    };
1666f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private final IP2pTarget mP2pTargetService = new IP2pTarget.Stub() {
1668f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1669fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
16700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int connect(int nativeHandle) throws RemoteException {
1671d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1672f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
1674f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
16760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
16770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
16780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
1679f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
16810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
16820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
16830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (device.doConnect()) {
16840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return ErrorCodes.SUCCESS;
16850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
16860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
16870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return ErrorCodes.ERROR_CONNECT;
16880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
1689f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1690fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
16910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public boolean disconnect(int nativeHandle) throws RemoteException {
1692d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1693f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
16950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            boolean isSuccess = false;
1696f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
16970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
16980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
16990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return isSuccess;
17000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
1701f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
17030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
17040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
17050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (isSuccess = device.doDisconnect()) {
17060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* remove the device from the hmap */
1707b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                    unregisterObject(nativeHandle);
17080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Restart polling loop for notification */
170965945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly                    maybeEnableDiscovery();
17100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
1711f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
17120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return isSuccess;
1713f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
1715f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1716fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
17170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public byte[] getGeneralBytes(int nativeHandle) throws RemoteException {
1718d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1719f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
17210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
17220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
17230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
17240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return null;
1725f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1726f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
17280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
17290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
17300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                byte[] buff = device.getGeneralBytes();
17310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (buff == null)
17320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return null;
17330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return buff;
17340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
17350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return null;
17360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
1737f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1738fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
17390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public int getMode(int nativeHandle) throws RemoteException {
1740d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1741f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
1743f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
17450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
17460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return ErrorCodes.ERROR_NOT_INITIALIZED;
1747f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1748f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
17500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
17510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
17520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return device.getMode();
17530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
17540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return ErrorCodes.ERROR_INVALID_PARAM;
17550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
1756f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1757fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
17580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public byte[] transceive(int nativeHandle, byte[] data) throws RemoteException {
1759d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
1760f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            NativeP2pDevice device;
1762f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            // Check if NFC is enabled
17640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (!mIsNfcEnabled) {
17650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return null;
1766f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1767f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* find the device in the hmap */
17690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            device = (NativeP2pDevice) findObject(nativeHandle);
17700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (device != null) {
17710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                byte[] buff = device.doTransceive(data);
17720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (buff == null)
17730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    return null;
17740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                return buff;
17750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            }
17760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            return null;
17770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
17780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    };
1779f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private boolean _enable(boolean oldEnabledState) {
17810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        boolean isSuccess = mManager.initialize();
17820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        if (isSuccess) {
1783f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly            applyProperties();
1784f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly
17850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* Check Secure Element setting */
17860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mNfcSecureElementState = mPrefs.getBoolean(PREF_SECURE_ELEMENT_ON,
17870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    SECURE_ELEMENT_ON_DEFAULT);
1788f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
17890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            if (mNfcSecureElementState) {
17900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                int secureElementId = mPrefs.getInt(PREF_SECURE_ELEMENT_ID,
17910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        SECURE_ELEMENT_ID_DEFAULT);
17920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                int[] Se_list = mManager.doGetSecureElementList();
17930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (Se_list != null) {
17940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    for (int i = 0; i < Se_list.length; i++) {
17950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        if (Se_list[i] == secureElementId) {
17960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            mManager.doSelectSecureElement(Se_list[i]);
17970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            mSelectedSeId = Se_list[i];
17980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                            break;
17990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        }
18000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    }
18010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
1802f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1803f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
180465945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            mIsNfcEnabled = true;
180565945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly
18060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            /* Start polling loop */
180765945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            maybeEnableDiscovery();
1808f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
18096f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton            /* bring up the my tag server */
18106f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton            //mMyTagServer.start();
18116f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton
1812f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        } else {
18130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            mIsNfcEnabled = false;
1814f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1815f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
18160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        updateNfcOnSetting(oldEnabledState);
1817f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
18180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        return isSuccess;
1819f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1820f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
182165945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly    /** Enable active tag discovery if screen is on and NFC is enabled */
182265945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly    private synchronized void maybeEnableDiscovery() {
182365945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly        if (mScreenOn && mIsNfcEnabled) {
182465945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            mManager.enableDiscovery(DISCOVERY_MODE_READER);
182565945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly        }
182665945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly    }
182765945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly
182865945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly    /** Disable active tag discovery if necessary */
182965945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly    private synchronized void maybeDisableDiscovery() {
183065945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly        if (mIsNfcEnabled) {
183165945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            mManager.disableDiscovery();
183265945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly        }
183365945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly    }
183465945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly
1835f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly    private void applyProperties() {
1836f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_LLCP_LTO, mPrefs.getInt(PREF_LLCP_LTO, LLCP_LTO_DEFAULT));
1837f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_LLCP_MIU, mPrefs.getInt(PREF_LLCP_MIU, LLCP_MIU_DEFAULT));
1838f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_LLCP_WKS, mPrefs.getInt(PREF_LLCP_WKS, LLCP_WKS_DEFAULT));
1839f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_LLCP_OPT, mPrefs.getInt(PREF_LLCP_OPT, LLCP_OPT_DEFAULT));
1840f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_A,
1841f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly                mPrefs.getBoolean(PREF_DISCOVERY_A, DISCOVERY_A_DEFAULT) ? 1 : 0);
1842f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_B,
1843f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly                mPrefs.getBoolean(PREF_DISCOVERY_B, DISCOVERY_B_DEFAULT) ? 1 : 0);
1844f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_F,
1845f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly                mPrefs.getBoolean(PREF_DISCOVERY_F, DISCOVERY_F_DEFAULT) ? 1 : 0);
1846f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_15693,
1847f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly                mPrefs.getBoolean(PREF_DISCOVERY_15693, DISCOVERY_15693_DEFAULT) ? 1 : 0);
1848f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly        mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_NFCIP,
1849f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly                mPrefs.getBoolean(PREF_DISCOVERY_NFCIP, DISCOVERY_NFCIP_DEFAULT) ? 1 : 0);
1850f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly     }
1851f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly
18520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private void updateNfcOnSetting(boolean oldEnabledState) {
18530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        int state;
1854f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
18550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mPrefsEditor.putBoolean(PREF_NFC_ON, mIsNfcEnabled);
18562f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick        mPrefsEditor.apply();
18570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
18582f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly        synchronized(this) {
18594acf84356e35861f7df6d07a2b9ff84842a9f221Nick Pelly            if (oldEnabledState != mIsNfcEnabled) {
18602f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                Intent intent = new Intent(NfcAdapter.ACTION_ADAPTER_STATE_CHANGE);
18614acf84356e35861f7df6d07a2b9ff84842a9f221Nick Pelly                intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
18622f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                intent.putExtra(NfcAdapter.EXTRA_NEW_BOOLEAN_STATE, mIsNfcEnabled);
18632f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                mContext.sendBroadcast(intent);
18642f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly            }
18650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
1866f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1867f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1868f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    // Reset all internals
18692f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    private synchronized void reset() {
187074180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick        // TODO: none of these appear to be synchronized but are
187174180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick        // read/written from different threads (notably Binder threads)...
1872f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1873f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        // Clear tables
1874f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mObjectMap.clear();
1875f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mSocketMap.clear();
1876f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mRegisteredSocketList.clear();
1877f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1878f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        // Reset variables
1879f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mLlcpLinkState = NfcAdapter.LLCP_LINK_STATE_DEACTIVATED;
1880f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mNbSocketCreated = 0;
1881f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mIsNfcEnabled = false;
1882f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mSelectedSeId = 0;
1883f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1884f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
18852f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    private synchronized Object findObject(int key) {
1886f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        Object device = null;
1887f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1888f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        device = mObjectMap.get(key);
1889f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        if (device == null) {
1890f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            Log.w(TAG, "Handle not found !");
1891f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1892f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1893f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        return device;
1894f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1895f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
18962f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    synchronized void registerTagObject(NativeNfcTag nativeTag) {
1897b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        mObjectMap.put(nativeTag.getHandle(), nativeTag);
1898b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    }
1899b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
19002f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    synchronized void unregisterObject(int handle) {
1901b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        mObjectMap.remove(handle);
1902f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1903f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
19042f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly    private synchronized Object findSocket(int key) {
1905f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        Object socket = null;
1906f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1907f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        socket = mSocketMap.get(key);
1908f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1909f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        return socket;
1910f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1911f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1912f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private void RemoveSocket(int key) {
1913f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        mSocketMap.remove(key);
1914f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1915f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1916f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private boolean CheckSocketSap(int sap) {
1917f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        /* List of sockets registered */
1918f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        ListIterator<RegisteredSocket> it = mRegisteredSocketList.listIterator();
1919f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1920f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        while (it.hasNext()) {
1921f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            RegisteredSocket registeredSocket = it.next();
1922f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1923f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (sap == registeredSocket.mSap) {
1924f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                /* SAP already used */
1925f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return false;
1926f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1927f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1928f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        return true;
1929f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1930f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1931f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private boolean CheckSocketOptions(int miu, int rw, int linearBufferlength) {
1932f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
19330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        if (rw > LLCP_RW_MAX_VALUE || miu < LLCP_MIU_DEFAULT || linearBufferlength < miu) {
1934f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            return false;
1935f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1936f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        return true;
1937f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1938f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1939f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private boolean CheckSocketServiceName(String sn) {
1940f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1941f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        /* List of sockets registered */
1942f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        ListIterator<RegisteredSocket> it = mRegisteredSocketList.listIterator();
1943f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1944f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        while (it.hasNext()) {
1945f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            RegisteredSocket registeredSocket = it.next();
1946f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1947f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (sn.equals(registeredSocket.mServiceName)) {
1948f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                /* Service Name already used */
1949f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                return false;
1950f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1951f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1952f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        return true;
1953f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1954f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1955f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private void RemoveRegisteredSocket(int nativeHandle) {
1956f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        /* check if sockets are registered */
1957f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        ListIterator<RegisteredSocket> it = mRegisteredSocketList.listIterator();
1958f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1959f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        while (it.hasNext()) {
1960f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            RegisteredSocket registeredSocket = it.next();
1961f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            if (registeredSocket.mHandle == nativeHandle) {
1962f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                /* remove the registered socket from the list */
1963f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                it.remove();
1964f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                Log.d(TAG, "socket removed");
1965f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
1966f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1967f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
1968f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1969f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    /*
1970f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly     * RegisteredSocket class to store the creation request of socket until the
1971f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly     * LLCP link in not activated
1972f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly     */
1973f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    private class RegisteredSocket {
1974f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        private final int mType;
1975f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1976f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        private final int mHandle;
1977f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1978f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        private final int mSap;
1979f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1980f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        private int mMiu;
1981f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1982f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        private int mRw;
1983f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1984f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        private String mServiceName;
1985f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1986f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        private int mlinearBufferLength;
1987f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1988f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        RegisteredSocket(int type, int handle, int sap, String sn, int miu, int rw,
1989f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                int linearBufferLength) {
1990f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mType = type;
1991f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mHandle = handle;
1992f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mSap = sap;
1993f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mServiceName = sn;
1994f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mRw = rw;
1995f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mMiu = miu;
1996f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mlinearBufferLength = linearBufferLength;
1997f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
1998f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1999f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        RegisteredSocket(int type, int handle, int sap, int miu, int rw, int linearBufferLength) {
2000f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mType = type;
2001f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mHandle = handle;
2002f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mSap = sap;
2003f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mRw = rw;
2004f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mMiu = miu;
2005f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mlinearBufferLength = linearBufferLength;
2006f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
2007f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2008f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        RegisteredSocket(int type, int handle, int sap) {
2009f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mType = type;
2010f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mHandle = handle;
2011f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            mSap = sap;
2012f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
2013f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    }
2014f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2015d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    /** For use by code in this process */
2016d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    public LlcpSocket createLlcpSocket(int sap, int miu, int rw, int linearBufferLength) {
2017d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        try {
2018d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            int handle = mNfcAdapter.createLlcpSocket(sap, miu, rw, linearBufferLength);
20191be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton            if (ErrorCodes.isError(handle)) {
20201be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton                Log.e(TAG, "unable to create socket: " + ErrorCodes.asString(handle));
20211be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton                return null;
20221be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton            }
2023d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            return new LlcpSocket(mLlcpSocket, handle);
2024d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        } catch (RemoteException e) {
2025d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            // This will never happen since the code is calling into it's own process
2026d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            throw new IllegalStateException("unable to talk to myself", e);
2027d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        }
2028d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    }
2029d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
2030d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    /** For use by code in this process */
2031d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    public LlcpServiceSocket createLlcpServiceSocket(int sap, String sn, int miu, int rw,
2032d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            int linearBufferLength) {
2033d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        try {
2034d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            int handle = mNfcAdapter.createLlcpServiceSocket(sap, sn, miu, rw, linearBufferLength);
20351be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton            if (ErrorCodes.isError(handle)) {
20361be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton                Log.e(TAG, "unable to create socket: " + ErrorCodes.asString(handle));
20371be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton                return null;
20381be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton            }
2039d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            return new LlcpServiceSocket(mLlcpServerSocketService, mLlcpSocket, handle);
2040d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        } catch (RemoteException e) {
2041d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            // This will never happen since the code is calling into it's own process
2042d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            throw new IllegalStateException("unable to talk to myself", e);
2043d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        }
2044d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    }
2045d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
20460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private void activateLlcpLink() {
20470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        /* check if sockets are registered */
20480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        ListIterator<RegisteredSocket> it = mRegisteredSocketList.listIterator();
2049f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
20500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        Log.d(TAG, "Nb socket resgistered = " + mRegisteredSocketList.size());
2051f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2052b3cdb6612a057373a61521171d99ce4f24b84e1fJeff Hamilton        /* Mark the link state */
2053b3cdb6612a057373a61521171d99ce4f24b84e1fJeff Hamilton        mLlcpLinkState = NfcAdapter.LLCP_LINK_STATE_ACTIVATED;
2054b3cdb6612a057373a61521171d99ce4f24b84e1fJeff Hamilton
20550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        while (it.hasNext()) {
20560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            RegisteredSocket registeredSocket = it.next();
2057f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
20580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            switch (registeredSocket.mType) {
20590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            case LLCP_SERVICE_SOCKET_TYPE:
20600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                Log.d(TAG, "Registered Llcp Service Socket");
2061b3cdb6612a057373a61521171d99ce4f24b84e1fJeff Hamilton                Log.d(TAG, "SAP: " + registeredSocket.mSap + ", SN: " + registeredSocket.mServiceName);
20620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                NativeLlcpServiceSocket serviceSocket;
20630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
20640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                serviceSocket = mManager.doCreateLlcpServiceSocket(
20650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        registeredSocket.mSap, registeredSocket.mServiceName,
20660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        registeredSocket.mMiu, registeredSocket.mRw,
20670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        registeredSocket.mlinearBufferLength);
20680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
20690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (serviceSocket != null) {
20706f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton                    Log.d(TAG, "service socket created");
20710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Add the socket into the socket map */
20722f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    synchronized(NfcService.this) {
20732f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mSocketMap.put(registeredSocket.mHandle, serviceSocket);
20742f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    }
20750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
20766f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton                    Log.d(TAG, "FAILED to create service socket");
20770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* socket creation error - update the socket
20780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                     * handle counter */
20790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mGeneratedSocketHandle -= 1;
20800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
20810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                break;
20820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
20830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            case LLCP_SOCKET_TYPE:
20840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                Log.d(TAG, "Registered Llcp Socket");
20850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                NativeLlcpSocket clientSocket;
20860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                clientSocket = mManager.doCreateLlcpSocket(registeredSocket.mSap,
20870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        registeredSocket.mMiu, registeredSocket.mRw,
20880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        registeredSocket.mlinearBufferLength);
20890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (clientSocket != null) {
20906f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton                    Log.d(TAG, "socket created");
20910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Add the socket into the socket map */
20922f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    synchronized(NfcService.this) {
20932f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mSocketMap.put(registeredSocket.mHandle, clientSocket);
20942f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    }
20950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
20966f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton                    Log.d(TAG, "FAILED to create service socket");
20970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* socket creation error - update the socket
20980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                     * handle counter */
20990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mGeneratedSocketHandle -= 1;
21000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
21010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                break;
21020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
21030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly            case LLCP_CONNECTIONLESS_SOCKET_TYPE:
21040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                Log.d(TAG, "Registered Llcp Connectionless Socket");
21050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                NativeLlcpConnectionlessSocket connectionlessSocket;
21060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                connectionlessSocket = mManager.doCreateLlcpConnectionlessSocket(
21070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                        registeredSocket.mSap);
21080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                if (connectionlessSocket != null) {
21096f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton                    Log.d(TAG, "connectionless socket created");
21100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* Add the socket into the socket map */
21112f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    synchronized(NfcService.this) {
21122f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                        mSocketMap.put(registeredSocket.mHandle, connectionlessSocket);
21132f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly                    }
21140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                } else {
21156f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton                    Log.d(TAG, "FAILED to create service socket");
21160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    /* socket creation error - update the socket
21170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                     * handle counter */
21180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                    mGeneratedSocketHandle -= 1;
21190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                }
21200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                break;
2121f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
21220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        }
2123f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
21240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        /* Remove all registered socket from the list */
21250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mRegisteredSocketList.clear();
2126f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
21270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        /* Broadcast Intent Link LLCP activated */
21280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        Intent LlcpLinkIntent = new Intent();
21290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        LlcpLinkIntent.setAction(NfcAdapter.ACTION_LLCP_LINK_STATE_CHANGED);
2130f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
21310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        LlcpLinkIntent.putExtra(NfcAdapter.EXTRA_LLCP_LINK_STATE_CHANGED,
21320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                NfcAdapter.LLCP_LINK_STATE_ACTIVATED);
2133f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
21340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        Log.d(TAG, "Broadcasting LLCP activation");
21350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        mContext.sendOrderedBroadcast(LlcpLinkIntent, NFC_PERM);
21360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    }
2137f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2138d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    public void sendMockNdefTag(NdefMessage msg) {
2139d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        NdefTag tag = NdefTag.createMockNdefTag(new byte[] { 0x00 },
2140d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton                new String[] { Tag.TARGET_OTHER },
2141d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton                null, null, new String[] { NdefTag.TARGET_OTHER },
2142d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton                new NdefMessage[][] { new NdefMessage[] { msg } });
2143d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        sendMessage(MSG_MOCK_NDEF_TAG, tag);
2144d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton    }
2145d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
2146b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    void sendMessage(int what, Object obj) {
2147b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        Message msg = mHandler.obtainMessage();
2148b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        msg.what = what;
2149b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        msg.obj = obj;
2150b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        mHandler.sendMessage(msg);
2151b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    }
2152b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
2153b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    private final Handler mHandler = new Handler() {
2154b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        @Override
2155b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        public void handleMessage(Message msg) {
2156f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           switch (msg.what) {
2157d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton           case MSG_MOCK_NDEF_TAG: {
2158d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton               NdefTag tag = (NdefTag) msg.obj;
2159d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton               Intent intent = buildNdefTagIntent(tag);
2160d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton               Log.d(TAG, "mock NDEF tag, starting corresponding activity");
2161d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton               Log.d(TAG, tag.toString());
2162d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton               try {
2163d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton                   mContext.startActivity(intent);
2164d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton               } catch (ActivityNotFoundException e) {
2165d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton                   Log.w(TAG, "No activity found for mock tag");
2166d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton               }
216715151d5453f9b9b3680cb254ccea42458cc51f33Jeff Hamilton               break;
2168d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton           }
2169d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
2170f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           case MSG_NDEF_TAG:
2171f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.d(TAG, "Tag detected, notifying applications");
2172f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               NativeNfcTag nativeTag = (NativeNfcTag) msg.obj;
2173f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               if (nativeTag.connect()) {
2174f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   if (nativeTag.checkNdef()) {
2175d3c57c0c2419d595b8de940254814b5935932b28Martijn Coenen                       boolean generateEmptyIntent = false;
2176f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       byte[] buff = nativeTag.read();
2177f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       if (buff != null) {
2178f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           NdefMessage[] msgNdef = new NdefMessage[1];
2179f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           try {
2180f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               msgNdef[0] = new NdefMessage(buff);
2181f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               NdefTag tag = new NdefTag(nativeTag.getUid(),
21821cf8ba9546ba5204af08b8de2c542b6a1bf8f8a0Nick Pelly                                       TagTarget.internalTypeToRawTargets(nativeTag.getType()),
2183f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                                       null, null, nativeTag.getHandle(),
2184f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                                       TagTarget.internalTypeToNdefTargets(nativeTag.getType()),
2185f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                                       new NdefMessage[][] {msgNdef});
2186d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton                               Intent intent = buildNdefTagIntent(tag);
2187f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               Log.d(TAG, "NDEF tag found, starting corresponding activity");
21881cf8ba9546ba5204af08b8de2c542b6a1bf8f8a0Nick Pelly                               Log.d(TAG, tag.toString());
2189b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                               try {
2190b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                                   mContext.startActivity(intent);
2191db7d865e53c4db049bab20a0bcc7cb596e450d9aSylvain Fonteneau                                   registerTagObject(nativeTag);
2192b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                               } catch (ActivityNotFoundException e) {
2193b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                                   Log.w(TAG, "No activity found, disconnecting");
219421545af22f9b913ec9cb124287aab2fcb0cf2b3bNick Pelly                                   nativeTag.disconnect();
2195b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                               }
2196f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           } catch (FormatException e) {
2197d3c57c0c2419d595b8de940254814b5935932b28Martijn Coenen                               // Create an intent anyway, without NDEF messages
2198d3c57c0c2419d595b8de940254814b5935932b28Martijn Coenen                               generateEmptyIntent = true;
2199b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                           }
2200b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                       } else {
2201d3c57c0c2419d595b8de940254814b5935932b28Martijn Coenen                           // Create an intent anyway, without NDEF messages
2202d3c57c0c2419d595b8de940254814b5935932b28Martijn Coenen                           generateEmptyIntent = true;
2203d3c57c0c2419d595b8de940254814b5935932b28Martijn Coenen                       }
2204d3c57c0c2419d595b8de940254814b5935932b28Martijn Coenen                       if (generateEmptyIntent) {
2205d3c57c0c2419d595b8de940254814b5935932b28Martijn Coenen                           // Create an intent with an empty ndef message array
2206d3c57c0c2419d595b8de940254814b5935932b28Martijn Coenen                           NdefTag tag = new NdefTag(nativeTag.getUid(),
2207d3c57c0c2419d595b8de940254814b5935932b28Martijn Coenen                                   TagTarget.internalTypeToRawTargets(nativeTag.getType()),
2208d3c57c0c2419d595b8de940254814b5935932b28Martijn Coenen                                   null, null, nativeTag.getHandle(),
2209d3c57c0c2419d595b8de940254814b5935932b28Martijn Coenen                                   TagTarget.internalTypeToNdefTargets(nativeTag.getType()),
2210d3c57c0c2419d595b8de940254814b5935932b28Martijn Coenen                                   new NdefMessage[][] { {} });
2211d3c57c0c2419d595b8de940254814b5935932b28Martijn Coenen                           Intent intent = buildNdefTagIntent(tag);
2212d3c57c0c2419d595b8de940254814b5935932b28Martijn Coenen                           Log.d(TAG, "NDEF tag found, but length 0 or invalid format, starting corresponding activity");
2213d3c57c0c2419d595b8de940254814b5935932b28Martijn Coenen                           try {
2214d3c57c0c2419d595b8de940254814b5935932b28Martijn Coenen                               mContext.startActivity(intent);
2215d3c57c0c2419d595b8de940254814b5935932b28Martijn Coenen                               registerTagObject(nativeTag);
2216d3c57c0c2419d595b8de940254814b5935932b28Martijn Coenen                           } catch (ActivityNotFoundException e) {
2217d3c57c0c2419d595b8de940254814b5935932b28Martijn Coenen                               Log.w(TAG, "No activity found, disconnecting");
2218d3c57c0c2419d595b8de940254814b5935932b28Martijn Coenen                               nativeTag.disconnect();
2219d3c57c0c2419d595b8de940254814b5935932b28Martijn Coenen                           }
2220b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                       }
2221f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   } else {
2222f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       Intent intent = new Intent();
2223f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       Tag tag = new Tag(nativeTag.getUid(), false,
2224f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               TagTarget.internalTypeToRawTargets(nativeTag.getType()),
2225f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               null, null, nativeTag.getHandle());
2226f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       intent.setAction(NfcAdapter.ACTION_TAG_DISCOVERED);
2227f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       intent.putExtra(NfcAdapter.EXTRA_TAG, tag);
22282407a9d01fdc8e48f778d2ef070e75a74d3863c4Nick Pelly                       intent.putExtra(NfcAdapter.EXTRA_ID, tag.getId());
2229f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2230f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       Log.d(TAG, "Non-NDEF tag found, starting corresponding activity");
2231f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       Log.d(TAG, tag.toString());
2232f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       try {
2233f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           mContext.startActivity(intent);
2234db7d865e53c4db049bab20a0bcc7cb596e450d9aSylvain Fonteneau                           registerTagObject(nativeTag);
2235f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       } catch (ActivityNotFoundException e) {
2236f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           Log.w(TAG, "No activity found, disconnecting");
223721545af22f9b913ec9cb124287aab2fcb0cf2b3bNick Pelly                           nativeTag.disconnect();
2238f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       }
2239f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   }
2240f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               } else {
2241f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   Log.w(TAG, "Failed to connect to tag");
224221545af22f9b913ec9cb124287aab2fcb0cf2b3bNick Pelly                   nativeTag.disconnect();
2243f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               }
2244f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               break;
2245f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           case MSG_CARD_EMULATION:
2246f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.d(TAG, "Card Emulation message");
2247f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               byte[] aid = (byte[]) msg.obj;
2248f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               /* Send broadcast ordered */
2249f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Intent TransactionIntent = new Intent();
2250f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               TransactionIntent.setAction(NfcAdapter.ACTION_TRANSACTION_DETECTED);
2251f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               TransactionIntent.putExtra(NfcAdapter.EXTRA_AID, aid);
2252f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.d(TAG, "Broadcasting Card Emulation event");
2253f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               mContext.sendOrderedBroadcast(TransactionIntent, NFC_PERM);
2254f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               break;
2255f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly
2256f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           case MSG_LLCP_LINK_ACTIVATION:
2257f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               NativeP2pDevice device = (NativeP2pDevice) msg.obj;
2258f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly
2259f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.d(TAG, "LLCP Activation message");
2260f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly
2261f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               if (device.getMode() == NativeP2pDevice.MODE_P2P_TARGET) {
22626f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton                   Log.d(TAG, "NativeP2pDevice.MODE_P2P_TARGET");
2263f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   if (device.doConnect()) {
2264f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       /* Check Llcp compliancy */
2265f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       if (mManager.doCheckLlcp()) {
2266f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           /* Activate Llcp Link */
2267f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           if (mManager.doActivateLlcp()) {
2268f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                               Log.d(TAG, "Initiator Activate LLCP OK");
2269eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton                               activateLlcpLink();
2270eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton                           } else {
2271eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton                               /* should not happen */
2272eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton                               Log.w(TAG, "Initiator Activate LLCP NOK. Disconnect.");
2273eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton                               device.doDisconnect();
2274b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                           }
2275b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
2276f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       } else {
2277eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton                           Log.d(TAG, "Remote Target does not support LLCP. Disconnect.");
2278f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           device.doDisconnect();
2279b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau                       }
2280eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton                   } else {
2281eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton                       Log.d(TAG, "Cannot connect remote Target. Restart polling loop.");
2282eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton                       /* resume should be done in doConnect */
2283f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   }
2284f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly
2285f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               } else if (device.getMode() == NativeP2pDevice.MODE_P2P_INITIATOR) {
22866f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton                   Log.d(TAG, "NativeP2pDevice.MODE_P2P_INITIATOR");
2287f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   /* Check Llcp compliancy */
2288f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   if (mManager.doCheckLlcp()) {
2289f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       /* Activate Llcp Link */
2290f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       if (mManager.doActivateLlcp()) {
2291f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                           Log.d(TAG, "Target Activate LLCP OK");
2292eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton                           activateLlcpLink();
2293eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton                      }
22946f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton                   } else {
22956f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton                       Log.d(TAG, "checkLlcp failed");
2296f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                   }
2297b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau               }
2298f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               break;
2299f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly
2300f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           case MSG_LLCP_LINK_DEACTIVATED:
2301eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton               device = (NativeP2pDevice) msg.obj;
2302eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton
2303eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton               Log.d(TAG, "LLCP Link Deactivated message. Restart polling loop.");
2304cdab1112486288ee6ccc9eb5c55456f9618f6b9cJeff Hamilton               if (device.getMode() == NativeP2pDevice.MODE_P2P_TARGET) {
2305cdab1112486288ee6ccc9eb5c55456f9618f6b9cJeff Hamilton                   Log.d(TAG, "disconnecting from target");
2306cdab1112486288ee6ccc9eb5c55456f9618f6b9cJeff Hamilton                   /* Restart polling loop */
2307cdab1112486288ee6ccc9eb5c55456f9618f6b9cJeff Hamilton                   device.doDisconnect();
2308cdab1112486288ee6ccc9eb5c55456f9618f6b9cJeff Hamilton               } else {
2309cdab1112486288ee6ccc9eb5c55456f9618f6b9cJeff Hamilton                   Log.d(TAG, "not disconnecting from initiator");
2310cdab1112486288ee6ccc9eb5c55456f9618f6b9cJeff Hamilton               }
2311eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton
2312b3cdb6612a057373a61521171d99ce4f24b84e1fJeff Hamilton               /* Mark the link state */
2313b3cdb6612a057373a61521171d99ce4f24b84e1fJeff Hamilton               mLlcpLinkState = NfcAdapter.LLCP_LINK_STATE_DEACTIVATED;
2314b3cdb6612a057373a61521171d99ce4f24b84e1fJeff Hamilton
2315f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               /* Broadcast Intent Link LLCP activated */
2316f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Intent LlcpLinkIntent = new Intent();
2317f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               LlcpLinkIntent.setAction(NfcAdapter.ACTION_LLCP_LINK_STATE_CHANGED);
2318f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               LlcpLinkIntent.putExtra(NfcAdapter.EXTRA_LLCP_LINK_STATE_CHANGED,
2319f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly                       NfcAdapter.LLCP_LINK_STATE_DEACTIVATED);
2320f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.d(TAG, "Broadcasting LLCP deactivation");
2321f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               mContext.sendOrderedBroadcast(LlcpLinkIntent, NFC_PERM);
2322f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               break;
2323f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly
2324f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           case MSG_TARGET_DESELECTED:
2325f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               /* Broadcast Intent Target Deselected */
2326f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.d(TAG, "Target Deselected");
2327f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Intent TargetDeselectedIntent = new Intent();
2328f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               TargetDeselectedIntent.setAction(mManager.INTERNAL_TARGET_DESELECTED_ACTION);
2329f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.d(TAG, "Broadcasting Intent");
2330f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               mContext.sendOrderedBroadcast(TargetDeselectedIntent, NFC_PERM);
2331f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               break;
2332f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly
23333ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton           case MSG_SHOW_MY_TAG_ICON: {
23343ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton               StatusBarManager sb = (StatusBarManager) getSystemService(
23353ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                       Context.STATUS_BAR_SERVICE);
23363ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton               sb.setIcon("nfc", R.drawable.stat_sys_nfc, 0);
23373ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton               break;
23383ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton           }
23393ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton
23403ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton           case MSG_HIDE_MY_TAG_ICON: {
23413ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton               StatusBarManager sb = (StatusBarManager) getSystemService(
23423ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton                       Context.STATUS_BAR_SERVICE);
23433ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton               sb.removeIcon("nfc");
23443ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton               break;
23453ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton           }
23463ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton
2347f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           default:
2348f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               Log.e(TAG, "Unknown message received");
2349f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly               break;
2350f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly           }
2351b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau        }
2352d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton
2353d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        private Intent buildNdefTagIntent(NdefTag tag) {
2354d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            Intent intent = new Intent();
23552407a9d01fdc8e48f778d2ef070e75a74d3863c4Nick Pelly               intent.setAction(NfcAdapter.ACTION_TAG_DISCOVERED);
2356d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton               intent.putExtra(NfcAdapter.EXTRA_TAG, tag);
23572407a9d01fdc8e48f778d2ef070e75a74d3863c4Nick Pelly               intent.putExtra(NfcAdapter.EXTRA_ID, tag.getId());
23582407a9d01fdc8e48f778d2ef070e75a74d3863c4Nick Pelly               intent.putExtra(NfcAdapter.EXTRA_NDEF_MESSAGES, tag.getNdefMessages());
2359d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton               intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2360d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton            return intent;
2361d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton        }
2362b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau    };
2363b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
23647c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly    private class EnableDisableDiscoveryTask extends AsyncTask<Boolean, Void, Void> {
2365fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks        @Override
23667c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly        protected Void doInBackground(Boolean... enable) {
2367df4e65b5dacb313e7d68bad797a843a175febbedNick Pelly            if (enable != null && enable.length > 0 && enable[0]) {
2368161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly                synchronized (NfcService.this) {
2369161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly                    mScreenOn = true;
2370161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly                    maybeEnableDiscovery();
2371161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly                }
23727c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly            } else {
2373161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly                synchronized (NfcService.this) {
2374161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly                    mScreenOn = false;
2375161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly                    maybeDisableDiscovery();
2376161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly                }
23777c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly            }
23787c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly            return null;
23797c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly        }
23807c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly    }
23817c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly
23820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
23830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        @Override
23840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly        public void onReceive(Context context, Intent intent) {
2385eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton            if (intent.getAction().equals(
2386f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                    NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION)) {
23870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly                Log.d(TAG, "INERNAL_TARGET_DESELECTED_ACTION");
23880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly
2389f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                /* Restart polling loop for notification */
239065945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly                maybeEnableDiscovery();
2391f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
239265945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
23937c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly                // Perform discovery enable in thread to protect against ANR when the
23947c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly                // NFC stack wedges. This is *not* the correct way to fix this issue -
23957c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly                // configuration of the local NFC adapter should be very quick and should
23967c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly                // be safe on the main thread, and the NFC stack should not wedge.
2397df4e65b5dacb313e7d68bad797a843a175febbedNick Pelly                new EnableDisableDiscoveryTask().execute(new Boolean(true));
239865945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly            } else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
23997c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly                // Perform discovery disable in thread to protect against ANR when the
24007c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly                // NFC stack wedges. This is *not* the correct way to fix this issue -
24017c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly                // configuration of the local NFC adapter should be very quick and should
24027c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly                // be safe on the main thread, and the NFC stack should not wedge.
2403df4e65b5dacb313e7d68bad797a843a175febbedNick Pelly                new EnableDisableDiscoveryTask().execute(new Boolean(false));
2404f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly            }
2405f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly        }
2406f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly    };
240774180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick}
2408