NfcService.java revision d2d5dddf17ac2008547172cd72faa034a89d569b
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; 21f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamiltonimport com.android.nfc.DeviceHost.DeviceHostListener; 22f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamiltonimport com.android.nfc.DeviceHost.NfcDepEndpoint; 23f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamiltonimport com.android.nfc.DeviceHost.TagEndpoint; 2481c476dd93f059d4082c15369894d5d16fbea05dJeff Hamiltonimport com.android.nfc.nxp.NativeLlcpConnectionlessSocket; 2581c476dd93f059d4082c15369894d5d16fbea05dJeff Hamiltonimport com.android.nfc.nxp.NativeLlcpServiceSocket; 2681c476dd93f059d4082c15369894d5d16fbea05dJeff Hamiltonimport com.android.nfc.nxp.NativeLlcpSocket; 2781c476dd93f059d4082c15369894d5d16fbea05dJeff Hamiltonimport com.android.nfc.nxp.NativeNfcManager; 2881c476dd93f059d4082c15369894d5d16fbea05dJeff Hamiltonimport com.android.nfc.nxp.NativeNfcSecureElement; 298afd14d3b23d3124c48ee275ba2845aede6542a1Jeff Hamiltonimport com.android.nfc3.R; 30d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton 312f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pellyimport android.app.Application; 32275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parksimport android.app.KeyguardManager; 3305973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamiltonimport android.app.PendingIntent; 3413d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellyimport android.content.BroadcastReceiver; 3505973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamiltonimport android.content.ComponentName; 3613d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellyimport android.content.Context; 3713d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellyimport android.content.Intent; 3813d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellyimport android.content.IntentFilter; 390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pellyimport android.content.SharedPreferences; 4093d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamiltonimport android.content.pm.PackageManager; 41d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamiltonimport android.media.AudioManager; 42d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamiltonimport android.media.SoundPool; 433fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamiltonimport android.net.Uri; 44f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.ErrorCodes; 45f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.FormatException; 46f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.ILlcpConnectionlessSocket; 47f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.ILlcpServiceSocket; 48f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.ILlcpSocket; 492094515fca0cfa0ac87e9cc260d3953d416afe3eJason parksimport android.nfc.INdefPushCallback; 500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pellyimport android.nfc.INfcAdapter; 5149d53329a0c720a7e430220d77805bc1763545b1Nick Pellyimport android.nfc.INfcAdapterExtras; 52f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.INfcTag; 53f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.IP2pInitiator; 54f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.IP2pTarget; 55f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.LlcpPacket; 56f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.NdefMessage; 57f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.NfcAdapter; 580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pellyimport android.nfc.Tag; 5924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport android.nfc.TechListParcel; 609d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenenimport android.nfc.TransceiveResult; 61aca0d055a82da850c27f6872405602ad5f3fee7bJeff Hamiltonimport android.nfc.tech.Ndef; 6281c476dd93f059d4082c15369894d5d16fbea05dJeff Hamiltonimport android.nfc.tech.TagTechnology; 637c034a7fe7d36b1ab039af2c44717812ea02657eNick Pellyimport android.os.AsyncTask; 64b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamiltonimport android.os.Bundle; 65b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneauimport android.os.Handler; 6649d53329a0c720a7e430220d77805bc1763545b1Nick Pellyimport android.os.IBinder; 67b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneauimport android.os.Message; 68533043d1003de2f6a20a29201100d94c3c7bc9caNick Pellyimport android.os.PowerManager; 69f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.os.RemoteException; 7013d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellyimport android.os.ServiceManager; 71f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.util.Log; 72f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 73bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parksimport java.io.DataInputStream; 7457d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonimport java.io.FileInputStream; 7557d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonimport java.io.FileNotFoundException; 7657d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonimport java.io.IOException; 7724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport java.util.ArrayList; 783ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamiltonimport java.util.HashMap; 7984e1e0adc2516afd35ebab029a52e764e0490559Jason parksimport java.util.HashSet; 802436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Feririmport java.util.Iterator; 81bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parksimport java.util.List; 823ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton 83d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamiltoninterface P2pStatusListener { 84d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton void onP2pBegin(); 85d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton void onP2pEnd(); 86d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton void onP2pError(); 87d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton} 88d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton 89d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamiltonpublic class NfcService extends Application implements DeviceHostListener, P2pStatusListener { 90bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks private static final String ACTION_MASTER_CLEAR_NOTIFICATION = "android.intent.action.MASTER_CLEAR_NOTIFICATION"; 91bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 928d6a8dce6706c6c6b3158101f2f3e94a1e0ad946Ben Dodson static final boolean DBG = true; 9376a412f47ff57ce05d84fd51adbf8e72fd37a448Nick Pelly static final String TAG = "NfcService"; 94fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks 95a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly private static final String SE_RESET_SCRIPT_FILE_NAME = "/system/etc/se-reset-script"; 9657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 97d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton public static final String SERVICE_NAME = "nfc"; 98fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks 99bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly private static final String NFC_PERM = android.Manifest.permission.NFC; 100bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly private static final String NFC_PERM_ERROR = "NFC permission required"; 101bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly private static final String ADMIN_PERM = android.Manifest.permission.WRITE_SECURE_SETTINGS; 102bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly private static final String ADMIN_PERM_ERROR = "WRITE_SECURE_SETTINGS permission required"; 103a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly private static final String NFCEE_ADMIN_PERM = "com.android.nfc.permission.NFCEE_ADMIN"; 10493d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton private static final String NFCEE_ADMIN_PERM_ERROR = "NFCEE_ADMIN permission required"; 105bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 106225ae2587712b06a354b4ad4625aadc780fa4e80Martijn Coenen /*package*/ static final String PREF = "NfcServicePrefs"; 107f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_NFC_ON = "nfc_on"; 1090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final boolean NFC_ON_DEFAULT = true; 110d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen private static final String PREF_ZEROCLICK_ON = "zeroclick_on"; 111d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen private static final boolean ZEROCLICK_ON_DEFAULT = true; 112f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 113a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly private static final String PREF_FIRST_BOOT = "first_boot"; 114a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly 115b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau static final int MSG_NDEF_TAG = 0; 116b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau static final int MSG_CARD_EMULATION = 1; 117b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau static final int MSG_LLCP_LINK_ACTIVATION = 2; 118b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau static final int MSG_LLCP_LINK_DEACTIVATED = 3; 119b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau static final int MSG_TARGET_DESELECTED = 4; 120b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton static final int MSG_MOCK_NDEF = 7; 121c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas static final int MSG_SE_FIELD_ACTIVATED = 8; 122c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas static final int MSG_SE_FIELD_DEACTIVATED = 9; 1232c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas static final int MSG_SE_APDU_RECEIVED = 10; 1242c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas static final int MSG_SE_EMV_CARD_REMOVAL = 11; 1252c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas static final int MSG_SE_MIFARE_ACCESS = 12; 126b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 12749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly // Copied from com.android.nfc_extras to avoid library dependency 12849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly // Must keep in sync with com.android.nfc_extras 12949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly static final int ROUTE_OFF = 1; 13049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly static final int ROUTE_ON_WHEN_SCREEN_ON = 2; 1317efbf69a37134ccbd86a1f6b4121f16b4a80eaaeNick Pelly 13249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public static final String ACTION_RF_FIELD_ON_DETECTED = 13349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly "com.android.nfc_extras.action.RF_FIELD_ON_DETECTED"; 13449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public static final String ACTION_RF_FIELD_OFF_DETECTED = 13549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly "com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED"; 13649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public static final String ACTION_AID_SELECTED = 13749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly "com.android.nfc_extras.action.AID_SELECTED"; 13849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public static final String EXTRA_AID = "com.android.nfc_extras.extra.AID"; 13949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly 1402c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas public static final String ACTION_APDU_RECEIVED = 1412c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas "com.android.nfc_extras.action.APDU_RECEIVED"; 1422c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas public static final String EXTRA_APDU_BYTES = 1432c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas "com.android.nfc_extras.extra.APDU_BYTES"; 1442c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas 1452c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas public static final String ACTION_EMV_CARD_REMOVAL = 1462c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas "com.android.nfc_extras.action.EMV_CARD_REMOVAL"; 1472c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas 1482c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas public static final String ACTION_MIFARE_ACCESS_DETECTED = 1492c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas "com.android.nfc_extras.action.MIFARE_ACCESS_DETECTED"; 1502c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas public static final String EXTRA_MIFARE_BLOCK = 1512c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas "com.android.nfc_extras.extra.MIFARE_BLOCK"; 1522c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas 15374180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick // TODO: none of these appear to be synchronized but are 15474180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick // read/written from different threads (notably Binder threads)... 155f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private int mGeneratedSocketHandle = 0; 15674180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick private volatile boolean mIsNfcEnabled = false; 15749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private boolean mIsDiscoveryOn = false; 158d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen private boolean mZeroClickOn = false; 15949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly 16049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly // NFC Execution Environment 16149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly // fields below are protected by this 1620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas private NativeNfcSecureElement mSecureElement; 16349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private OpenSecureElement mOpenEe; // null when EE closed 16449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private int mEeRoutingState; // contactless interface routing 1650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 166d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton // fields below must be used only on the UI thread and therefore aren't synchronized 167d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton boolean mP2pStarted = false; 168d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton 1692f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly // fields below are used in multiple threads and protected by synchronized(this) 1702f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly private final HashMap<Integer, Object> mObjectMap = new HashMap<Integer, Object>(); 1712f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly private final HashMap<Integer, Object> mSocketMap = new HashMap<Integer, Object>(); 172275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks private boolean mScreenUnlocked; 17384e1e0adc2516afd35ebab029a52e764e0490559Jason parks private HashSet<String> mSePackages = new HashSet<String>(); 1742f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly 1752f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly // fields below are final after onCreate() 17605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton Context mContext; 177f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton private NativeNfcManager mDeviceHost; 1780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private SharedPreferences mPrefs; 1790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private SharedPreferences.Editor mPrefsEditor; 180533043d1003de2f6a20a29201100d94c3c7bc9caNick Pelly private PowerManager.WakeLock mWakeLock; 1812ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson NdefP2pManager mP2pManager; 182d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton int mStartSound; 183d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton int mEndSound; 184d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton int mErrorSound; 185d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton SoundPool mSoundPool; // playback synchronized on this 1862ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson 18776a412f47ff57ce05d84fd51adbf8e72fd37a448Nick Pelly private NfcDispatcher mNfcDispatcher; 188275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks private KeyguardManager mKeyguard; 189d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton 190d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton private static NfcService sService; 191d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton 19293d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton public static void enforceAdminPerm(Context context) { 19393d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton int admin = context.checkCallingOrSelfPermission(ADMIN_PERM); 19493d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton int nfcee = context.checkCallingOrSelfPermission(NFCEE_ADMIN_PERM); 19593d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton if (admin != PackageManager.PERMISSION_GRANTED 19693d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton && nfcee != PackageManager.PERMISSION_GRANTED) { 19793d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton throw new SecurityException(ADMIN_PERM_ERROR); 19893d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton } 19993d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton } 20093d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton 20193d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton public static void enforceNfceeAdminPerm(Context context) { 20293d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton context.enforceCallingOrSelfPermission(NFCEE_ADMIN_PERM, NFCEE_ADMIN_PERM_ERROR); 20393d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton } 20493d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton 205d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton public static NfcService getInstance() { 206d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton return sService; 207d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton } 208f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly @Override 210f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton public void onRemoteEndpointDiscovered(TagEndpoint tag) { 211f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton sendMessage(NfcService.MSG_NDEF_TAG, tag); 212f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton } 213f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton 214f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton /** 215f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton * Notifies transaction 216f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton */ 217d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton @Override 218f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton public void onCardEmulationDeselected() { 219f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton sendMessage(NfcService.MSG_TARGET_DESELECTED, null); 220f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton } 221f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton 222f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton /** 223f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton * Notifies transaction 224f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton */ 225d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton @Override 226f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton public void onCardEmulationAidSelected(byte[] aid) { 227f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton sendMessage(NfcService.MSG_CARD_EMULATION, aid); 228f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton } 229f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton 230f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton /** 231f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton * Notifies P2P Device detected, to activate LLCP link 232f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton */ 233f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton @Override 234f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton public void onLlcpLinkActivated(NfcDepEndpoint device) { 235f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton sendMessage(NfcService.MSG_LLCP_LINK_ACTIVATION, device); 236f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton } 237f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton 238f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton /** 239f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton * Notifies P2P Device detected, to activate LLCP link 240f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton */ 241d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton @Override 242f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton public void onLlcpLinkDeactivated(NfcDepEndpoint device) { 243f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton sendMessage(NfcService.MSG_LLCP_LINK_DEACTIVATED, device); 244f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton } 245f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton 246d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton @Override 247f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton public void onRemoteFieldActivated() { 248f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton sendMessage(NfcService.MSG_SE_FIELD_ACTIVATED, null); 249f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton } 250f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton 251d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton @Override 252f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton public void onRemoteFieldDeactivated() { 253f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton sendMessage(NfcService.MSG_SE_FIELD_DEACTIVATED, null); 254f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton } 255f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton 256f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton @Override 257442cad40a205a63ea8797fbccaee99b2e8ab89abNick Pelly public void onSeApduReceived(byte[] apdu) { 258442cad40a205a63ea8797fbccaee99b2e8ab89abNick Pelly sendMessage(NfcService.MSG_SE_APDU_RECEIVED, apdu); 259442cad40a205a63ea8797fbccaee99b2e8ab89abNick Pelly } 260442cad40a205a63ea8797fbccaee99b2e8ab89abNick Pelly 261442cad40a205a63ea8797fbccaee99b2e8ab89abNick Pelly @Override 262442cad40a205a63ea8797fbccaee99b2e8ab89abNick Pelly public void onSeEmvCardRemoval() { 263442cad40a205a63ea8797fbccaee99b2e8ab89abNick Pelly sendMessage(NfcService.MSG_SE_EMV_CARD_REMOVAL, null); 264442cad40a205a63ea8797fbccaee99b2e8ab89abNick Pelly } 265442cad40a205a63ea8797fbccaee99b2e8ab89abNick Pelly 266442cad40a205a63ea8797fbccaee99b2e8ab89abNick Pelly @Override 267442cad40a205a63ea8797fbccaee99b2e8ab89abNick Pelly public void onSeMifareAccess(byte[] block) { 268442cad40a205a63ea8797fbccaee99b2e8ab89abNick Pelly sendMessage(NfcService.MSG_SE_MIFARE_ACCESS, block); 269442cad40a205a63ea8797fbccaee99b2e8ab89abNick Pelly } 270442cad40a205a63ea8797fbccaee99b2e8ab89abNick Pelly 271442cad40a205a63ea8797fbccaee99b2e8ab89abNick Pelly @Override 2720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public void onCreate() { 2732f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly super.onCreate(); 2742f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly 2752f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly Log.i(TAG, "Starting NFC service"); 2762f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly 277d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton sService = this; 278d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton 279d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton mSoundPool = new SoundPool(1, AudioManager.STREAM_NOTIFICATION, 0); 280d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton mStartSound = mSoundPool.load(this, R.raw.start, 1); 281d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton mEndSound = mSoundPool.load(this, R.raw.end, 1); 282d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton mErrorSound = mSoundPool.load(this, R.raw.error, 1); 283d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton 2840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mContext = this; 285f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton mDeviceHost = new NativeNfcManager(this, this); 286f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton mDeviceHost.initializeNativeStructure(); 28774180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick 288d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton mP2pManager = new NdefP2pManager(this, this); 2892ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson mNfcDispatcher = new NfcDispatcher(this, mP2pManager); 29024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 2910bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas mSecureElement = new NativeNfcSecureElement(); 292eab09ad7204fe1f0feaca33efccf75c1bb388708Robert Tsai mEeRoutingState = ROUTE_OFF; 2930bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 294275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks mPrefs = getSharedPreferences(PREF, Context.MODE_PRIVATE); 2950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor = mPrefs.edit(); 296f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2977efbf69a37134ccbd86a1f6b4121f16b4a80eaaeNick Pelly mIsNfcEnabled = false; // load from preferences later 298f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 299275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); 300275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks 301533043d1003de2f6a20a29201100d94c3c7bc9caNick Pelly mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "NfcService"); 302275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks mKeyguard = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE); 303275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks mScreenUnlocked = !mKeyguard.isKeyguardLocked() && !mKeyguard.isKeyguardSecure(); 304533043d1003de2f6a20a29201100d94c3c7bc9caNick Pelly 305d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton ServiceManager.addService(SERVICE_NAME, mNfcAdapter); 306f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 307eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton IntentFilter filter = new IntentFilter(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION); 30865945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly filter.addAction(Intent.ACTION_SCREEN_OFF); 30965945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly filter.addAction(Intent.ACTION_SCREEN_ON); 310bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks filter.addAction(ACTION_MASTER_CLEAR_NOTIFICATION); 311275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks filter.addAction(Intent.ACTION_USER_PRESENT); 312275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks registerReceiver(mReceiver, filter); 313bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 314bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks filter = new IntentFilter(); 315bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks filter.addAction(Intent.ACTION_PACKAGE_REMOVED); 316bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks filter.addDataScheme("package"); 317bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 318275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks registerReceiver(mReceiver, filter); 3190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 3200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly Thread t = new Thread() { 3210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly @Override 3220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public void run() { 3230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean nfc_on = mPrefs.getBoolean(PREF_NFC_ON, NFC_ON_DEFAULT); 3240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (nfc_on) { 325e7a398f2f0256a4a80a4ee08b70d48dbfd8da6d2Nick Pelly _enable(false, true); 326f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 327a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly resetSeOnFirstBoot(); 328f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 3290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly }; 3300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly t.start(); 3310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 3320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 333d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton private void playSound(int sound) { 334d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton synchronized (this) { 335d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton mSoundPool.play(sound, 1.0f, 1.0f, 0, 0, 1.0f); 336d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton } 337d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton } 338d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton 3390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly @Override 340d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton public void onP2pBegin() { 341d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton if (!mP2pStarted) { 342d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton playSound(mStartSound); 343d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton mP2pStarted = true; 344d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton } 345d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton } 346d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton 347d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton @Override 348d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton public void onP2pEnd() { 349d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton if (mP2pStarted) { 350d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton playSound(mEndSound); 351d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton mP2pStarted = false; 352d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton } 353d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton } 354d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton 355d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton @Override 356d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton public void onP2pError() { 357d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton if (mP2pStarted) { 358d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton playSound(mErrorSound); 359d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton mP2pStarted = false; 360d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton } 361d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton } 362d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton 363d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton @Override 3642f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly public void onTerminate() { 3652f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly super.onTerminate(); 3662f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly // NFC application is persistent, it should not be destroyed by framework 3670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly Log.wtf(TAG, "NFC service is under attack!"); 3680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 3690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 3700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private final INfcAdapter.Stub mNfcAdapter = new INfcAdapter.Stub() { 3713ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton /** Protected by "this" */ 3723ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton NdefMessage mLocalMessage = null; 3734acf84356e35861f7df6d07a2b9ff84842a9f221Nick Pelly 374fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 3750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public boolean enable() throws RemoteException { 37693d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton NfcService.enforceAdminPerm(mContext); 3770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 3780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean isSuccess = false; 3790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean previouslyEnabled = isEnabled(); 3800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!previouslyEnabled) { 3810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly reset(); 382e7a398f2f0256a4a80a4ee08b70d48dbfd8da6d2Nick Pelly isSuccess = _enable(previouslyEnabled, true); 383f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 3840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return isSuccess; 385f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 386f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 387fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 3880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public boolean disable() throws RemoteException { 3890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean isSuccess = false; 39093d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton NfcService.enforceAdminPerm(mContext); 3910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean previouslyEnabled = isEnabled(); 392ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Disabling NFC. previous=" + previouslyEnabled); 3930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 3940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (previouslyEnabled) { 395e7a398f2f0256a4a80a4ee08b70d48dbfd8da6d2Nick Pelly isSuccess = _disable(previouslyEnabled, true); 396f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 3970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return isSuccess; 398f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 399f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 400fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 401d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen public boolean zeroClickEnabled() throws RemoteException { 402d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen return mZeroClickOn; 403d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen } 404d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen 405d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen @Override 406d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen public boolean enableZeroClick() throws RemoteException { 407d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen NfcService.enforceAdminPerm(mContext); 408d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen synchronized(NfcService.this) { 409d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen if (!mZeroClickOn) { 410d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen Log.e(TAG, "ENABLING 0-CLICK"); 411d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen mPrefsEditor.putBoolean(PREF_ZEROCLICK_ON, true); 412d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen mPrefsEditor.apply(); 413d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen mP2pManager.enableNdefServer(); 414d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen mZeroClickOn = true; 415d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen } 416d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen } 417d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen return true; 418d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen } 419d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen 420d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen @Override 421d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen public boolean disableZeroClick() throws RemoteException { 422d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen NfcService.enforceAdminPerm(mContext); 423d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen synchronized(NfcService.this) { 424d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen if (mZeroClickOn) { 425d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen Log.e(TAG, "DISABLING 0-CLICK"); 426d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen mPrefsEditor.putBoolean(PREF_ZEROCLICK_ON, false); 427d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen mPrefsEditor.apply(); 428d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen mP2pManager.disableNdefServer(); 429d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen mZeroClickOn = false; 430d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen } 431d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen } 432d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen return true; 433d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen } 434d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen 435d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen 436d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen @Override 43705973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton public void enableForegroundDispatch(ComponentName activity, PendingIntent intent, 43824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton IntentFilter[] filters, TechListParcel techListsParcel) { 439a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // Permission check 44005973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 441a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton 442a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // Argument validation 443a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (activity == null || intent == null) { 444ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton throw new IllegalArgumentException(); 445ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton } 446a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton 447a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // Validate the IntentFilters 448a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (filters != null) { 449a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (filters.length == 0) { 450a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton filters = null; 451a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } else { 452a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton for (IntentFilter filter : filters) { 453a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (filter == null) { 454a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton throw new IllegalArgumentException("null IntentFilter"); 455a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } 456a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } 457a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } 458a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } 459a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton 46024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // Validate the tech lists 46124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton String[][] techLists = null; 46224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (techListsParcel != null) { 46324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton techLists = techListsParcel.getTechLists(); 46424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 46549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly 46676a412f47ff57ce05d84fd51adbf8e72fd37a448Nick Pelly mNfcDispatcher.enableForegroundDispatch(intent, filters, techLists); 46705973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 46805973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton 46905973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton @Override 47005973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton public void disableForegroundDispatch(ComponentName activity) { 47105973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 47276a412f47ff57ce05d84fd51adbf8e72fd37a448Nick Pelly 47376a412f47ff57ce05d84fd51adbf8e72fd37a448Nick Pelly mNfcDispatcher.disableForegroundDispatch(); 47405973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 47505973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton 47605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton @Override 477ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton public void enableForegroundNdefPush(ComponentName activity, NdefMessage msg) { 478ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 479ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton if (activity == null || msg == null) { 480ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton throw new IllegalArgumentException(); 481ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton } 4822ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson if (mP2pManager.setForegroundMessage(msg)) { 483ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton Log.e(TAG, "Replacing active NDEF push message"); 484ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton } 485ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton } 486ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton 487ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton @Override 4882094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks public void enableForegroundNdefPushWithCallback(ComponentName activity, 4892094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks INdefPushCallback callback) { 4902094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 4912094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks if (activity == null || callback == null) { 4922094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks throw new IllegalArgumentException(); 4932094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks } 4942ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson if (mP2pManager.setForegroundCallback(callback)) { 4952094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks Log.e(TAG, "Replacing active NDEF push message"); 4962094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks } 4972094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks } 4982094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks 4992094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks @Override 500ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton public void disableForegroundNdefPush(ComponentName activity) { 501ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 5022ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson boolean hadMsg = mP2pManager.setForegroundMessage(null); 5032ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson boolean hadCallback = mP2pManager.setForegroundCallback(null); 5042094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks if (!hadMsg || !hadCallback) { 505ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton Log.e(TAG, "No active foreground NDEF push message"); 506ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton } 507ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton } 508ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton 509ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton @Override 5100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int createLlcpConnectionlessSocket(int sap) throws RemoteException { 511d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 512bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 513f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 514f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 515f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 516f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 517f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 5180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Check SAP is not already used */ 5190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 5201878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Store the socket handle */ 5211878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau int sockeHandle = mGeneratedSocketHandle; 5221878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau NativeLlcpConnectionlessSocket socket; 523f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 524f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton socket = mDeviceHost.doCreateLlcpConnectionlessSocket(sap); 5251878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau if (socket != null) { 5261878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau synchronized(NfcService.this) { 5271878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* update socket handle generation */ 5281878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mGeneratedSocketHandle++; 5290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 5301878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Add the socket into the socket map */ 5311878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mSocketMap.put(mGeneratedSocketHandle, socket); 5321878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return mGeneratedSocketHandle; 533f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 534f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 5351878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Get Error Status */ 536f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton int errorStatus = mDeviceHost.doGetLastError(); 5371878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau 5381878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau switch (errorStatus) { 5391878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau case ErrorCodes.ERROR_BUFFER_TO_SMALL: 5401878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_BUFFER_TO_SMALL; 5411878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES: 5421878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; 5431878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau default: 5441878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_SOCKET_CREATION; 5451878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau } 546f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 547f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 548f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 549fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 5500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int createLlcpServiceSocket(int sap, String sn, int miu, int rw, int linearBufferLength) 5510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly throws RemoteException { 552d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 553bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 554f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 555f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 556f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 557f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 558f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 5591878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau NativeLlcpServiceSocket socket; 5600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 561f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton socket = mDeviceHost.doCreateLlcpServiceSocket(sap, sn, miu, rw, linearBufferLength); 5621878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau if (socket != null) { 5631878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau synchronized(NfcService.this) { 5641878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* update socket handle generation */ 5651878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mGeneratedSocketHandle++; 5660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 5671878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Add the socket into the socket map */ 5681878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mSocketMap.put(mGeneratedSocketHandle, socket); 569f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton return mGeneratedSocketHandle; 570f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 571f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 5721878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Get Error Status */ 573f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton int errorStatus = mDeviceHost.doGetLastError(); 5741878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau 5751878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau switch (errorStatus) { 5761878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau case ErrorCodes.ERROR_BUFFER_TO_SMALL: 5771878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_BUFFER_TO_SMALL; 5781878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES: 5791878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; 5801878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau default: 5811878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_SOCKET_CREATION; 5821878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau } 583f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 584f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 585f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 586fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 5870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int createLlcpSocket(int sap, int miu, int rw, int linearBufferLength) 5880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly throws RemoteException { 589d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 590bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 591f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 592f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 593f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 594f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 595f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 5961878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau if (DBG) Log.d(TAG, "creating llcp socket"); 5971878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau NativeLlcpSocket socket; 598bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 599f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton socket = mDeviceHost.doCreateLlcpSocket(sap, miu, rw, linearBufferLength); 600f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 6011878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau if (socket != null) { 6021878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau synchronized(NfcService.this) { 6031878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* update socket handle generation */ 6041878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mGeneratedSocketHandle++; 6050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 6061878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Add the socket into the socket map */ 6071878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mSocketMap.put(mGeneratedSocketHandle, socket); 6081878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return mGeneratedSocketHandle; 6090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 610f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 6111878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Get Error Status */ 612f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton int errorStatus = mDeviceHost.doGetLastError(); 6131878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau 6141878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau Log.d(TAG, "failed to create llcp socket: " + ErrorCodes.asString(errorStatus)); 6151878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau 6161878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau switch (errorStatus) { 6171878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau case ErrorCodes.ERROR_BUFFER_TO_SMALL: 6181878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_BUFFER_TO_SMALL; 6191878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES: 6201878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; 6211878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau default: 6221878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_SOCKET_CREATION; 6231878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau } 624f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 625f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 626f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 627fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public ILlcpConnectionlessSocket getLlcpConnectionlessInterface() throws RemoteException { 629d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 6300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return mLlcpConnectionlessSocketService; 6310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 632bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 633fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public ILlcpSocket getLlcpInterface() throws RemoteException { 635d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 6360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return mLlcpSocket; 6370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 638f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 639fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public ILlcpServiceSocket getLlcpServiceInterface() throws RemoteException { 641d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 6420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return mLlcpServerSocketService; 6430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 644f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 645fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public INfcTag getNfcTagInterface() throws RemoteException { 647d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 6480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return mNfcTagService; 6490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 6500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 651fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public IP2pInitiator getP2pInitiatorInterface() throws RemoteException { 653d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 6540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return mP2pInitiatorService; 6550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 6560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 657fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public IP2pTarget getP2pTargetInterface() throws RemoteException { 659d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 6600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return mP2pTargetService; 6610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 6620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 663bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks @Override 66449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public INfcAdapterExtras getNfcAdapterExtrasInterface() { 66593d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton NfcService.enforceNfceeAdminPerm(mContext); 66649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly return mExtrasService; 6670bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 6680bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 669fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public boolean isEnabled() throws RemoteException { 6710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return mIsNfcEnabled; 6720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 6730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly }; 6740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 6750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private final ILlcpSocket mLlcpSocket = new ILlcpSocket.Stub() { 676f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau 677f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau private NativeLlcpSocket findSocket(int nativeHandle) { 678bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly Object socket = NfcService.this.findSocket(nativeHandle); 679bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly if (!(socket instanceof NativeLlcpSocket)) { 680f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau return null; 681f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau } 682bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly return (NativeLlcpSocket) socket; 683f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau } 684f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau 685fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int close(int nativeHandle) throws RemoteException { 687d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 688bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 689f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeLlcpSocket socket = null; 690f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 691f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 692f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 693f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 694f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 695f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 696f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 697f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 698f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 6991878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau socket.doClose(); 7001878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Remove the socket closed from the hmap */ 701f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton removeSocket(nativeHandle); 7021878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.SUCCESS; 703f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 7040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_IO; 705f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 706f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 707f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 708fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 7090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int connect(int nativeHandle, int sap) throws RemoteException { 710d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 711bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 712f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeLlcpSocket socket = null; 7130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean isSuccess = false; 714f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 715f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 716f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 717f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 718f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 719f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 720f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 721f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 722f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 72393915e1c6fe6d5d16fcebeda610782bf5812c9b4Nick Pelly isSuccess = socket.doConnect(sap); 7240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (isSuccess) { 7250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.SUCCESS; 726f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 727f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 728f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 729f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 730f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 731f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 7320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 733f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 734f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 735fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 7360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int connectByName(int nativeHandle, String sn) throws RemoteException { 737d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 738bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 739f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeLlcpSocket socket = null; 740f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly boolean isSuccess = false; 741f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 742f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 743f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 744f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 745f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 746f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 747f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 748f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 749f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 75093915e1c6fe6d5d16fcebeda610782bf5812c9b4Nick Pelly isSuccess = socket.doConnectBy(sn); 751f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (isSuccess) { 752f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.SUCCESS; 753f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 754f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 755f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 756f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 757f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 758f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 7590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 760f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 761f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 762fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 7630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int getLocalSap(int nativeHandle) throws RemoteException { 764d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 765bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 7660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket socket = null; 767f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 768f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 769f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 770f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 771f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 772f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 7730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the socket in the hmap */ 774f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 7750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 7760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return socket.getSap(); 777f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 7780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return 0; 779f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 780f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 781f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 782fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 7830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int getLocalSocketMiu(int nativeHandle) throws RemoteException { 784d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 785bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 7860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket socket = null; 787f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 788f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 789f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 7900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 791f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 792f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 793f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 794f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 795f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 7960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return socket.getMiu(); 7970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 7980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return 0; 799f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 800f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 801f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 802fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 8030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int getLocalSocketRw(int nativeHandle) throws RemoteException { 804d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 805bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 8060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket socket = null; 807f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 808f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 809f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 810f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 811f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 812f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 813f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 814f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 8150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 8160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return socket.getRw(); 8170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 8180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return 0; 8190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 8200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 8210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 822fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 8230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int getRemoteSocketMiu(int nativeHandle) throws RemoteException { 824d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 8250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket socket = null; 8270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 8290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 8300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 8310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 8320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the socket in the hmap */ 834f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 8350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 8360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket.doGetRemoteSocketMiu() != 0) { 8370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return socket.doGetRemoteSocketMiu(); 8380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 8390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED; 8400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 8410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 8420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED; 8430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 8440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 8450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 846fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 8470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int getRemoteSocketRw(int nativeHandle) throws RemoteException { 848d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 8490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket socket = null; 8510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 8530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 8540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 8550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 8560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the socket in the hmap */ 858f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 8590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 8600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket.doGetRemoteSocketRw() != 0) { 8610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return socket.doGetRemoteSocketRw(); 8620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 8630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED; 8640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 8650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 8660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED; 8670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 8680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 8690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 870fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 8710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int receive(int nativeHandle, byte[] receiveBuffer) throws RemoteException { 872d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 8730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket socket = null; 8750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 8770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 8780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 8790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 8800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the socket in the hmap */ 882f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 8830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 88428f72bd9880d0b00c486603489d3862733eb638fSylvain Fonteneau return socket.doReceive(receiveBuffer); 8850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 88628f72bd9880d0b00c486603489d3862733eb638fSylvain Fonteneau return 0; 8870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 8880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 8890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 890fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 8910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int send(int nativeHandle, byte[] data) throws RemoteException { 892d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 8930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket socket = null; 8950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean isSuccess = false; 8960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 8980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 8990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 9000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 9010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 9020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the socket in the hmap */ 903f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 9040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 9050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly isSuccess = socket.doSend(data); 9060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (isSuccess) { 9070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.SUCCESS; 9080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 9090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_IO; 9100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 9110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 9120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_IO; 9130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 9140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 9150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly }; 9160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 9170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private final ILlcpServiceSocket mLlcpServerSocketService = new ILlcpServiceSocket.Stub() { 9180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 919f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau private NativeLlcpServiceSocket findSocket(int nativeHandle) { 920bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly Object socket = NfcService.this.findSocket(nativeHandle); 921bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly if (!(socket instanceof NativeLlcpServiceSocket)) { 922f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau return null; 923f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau } 924bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly return (NativeLlcpServiceSocket) socket; 925f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau } 926f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau 927fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 9280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int accept(int nativeHandle) throws RemoteException { 929d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 9300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 9310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpServiceSocket socket = null; 9320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket clientSocket = null; 9330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 9340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 9350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 9360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 9370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 9380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 9390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the socket in the hmap */ 940f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 9410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 94293915e1c6fe6d5d16fcebeda610782bf5812c9b4Nick Pelly clientSocket = socket.doAccept(socket.getMiu(), 9430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly socket.getRw(), socket.getLinearBufferLength()); 9440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (clientSocket != null) { 9450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Add the socket into the socket map */ 9462f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly synchronized(this) { 9471878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mGeneratedSocketHandle++; 9481878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mSocketMap.put(mGeneratedSocketHandle, clientSocket); 9491878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return mGeneratedSocketHandle; 9502f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly } 9510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 9520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_IO; 9530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 9540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 9550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_IO; 9560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 9570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 9580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 959fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 9600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public void close(int nativeHandle) throws RemoteException { 961d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 9620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 9630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpServiceSocket socket = null; 9640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 9650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 9660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 9670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return; 9680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 9690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 9700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the socket in the hmap */ 971f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 9720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 9731878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau socket.doClose(); 974f63da5f0887eba86d877faaee41dc5dfb8fccd50Jeff Hamilton synchronized (this) { 9750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Remove the socket closed from the hmap */ 976f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton removeSocket(nativeHandle); 9770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 9780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 9790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 980f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly }; 981f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 982f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private final ILlcpConnectionlessSocket mLlcpConnectionlessSocketService = new ILlcpConnectionlessSocket.Stub() { 983f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 984f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau private NativeLlcpConnectionlessSocket findSocket(int nativeHandle) { 985bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly Object socket = NfcService.this.findSocket(nativeHandle); 986bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly if (!(socket instanceof NativeLlcpConnectionlessSocket)) { 987f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau return null; 988f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau } 989bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly return (NativeLlcpConnectionlessSocket) socket; 990f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau } 991f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau 992fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 993f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public void close(int nativeHandle) throws RemoteException { 994d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 995bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 996f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeLlcpConnectionlessSocket socket = null; 997f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 998f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 999f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1000f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return; 1001f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1002f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1003f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 1004f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 1005f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 10061878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau socket.doClose(); 10071878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Remove the socket closed from the hmap */ 1008f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton removeSocket(nativeHandle); 1009f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1010f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1011f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1012fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1013f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public int getSap(int nativeHandle) throws RemoteException { 1014d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1015bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1016f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeLlcpConnectionlessSocket socket = null; 1017f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1018f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1019f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1020f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 1021f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1022f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1023f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 1024f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 1025f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 1026f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return socket.getSap(); 1027f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 1028f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return 0; 1029f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1030f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1031f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1032fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1033f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public LlcpPacket receiveFrom(int nativeHandle) throws RemoteException { 1034d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1035bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1036f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeLlcpConnectionlessSocket socket = null; 1037f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly LlcpPacket packet; 1038f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1039f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1040f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1041f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1042f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1043f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1044f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 1045f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 1046f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 1047f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly packet = socket.doReceiveFrom(socket.getLinkMiu()); 1048f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (packet != null) { 1049f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return packet; 1050f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1051f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1052f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 1053f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1054f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1055f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1056f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1057fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1058f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public int sendTo(int nativeHandle, LlcpPacket packet) throws RemoteException { 1059d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1060bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1061f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeLlcpConnectionlessSocket socket = null; 1062f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly boolean isSuccess = false; 1063f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1064f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1065f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1066f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 1067f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1068f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1069f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 1070f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 1071f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 1072f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly isSuccess = socket.doSendTo(packet.getRemoteSap(), packet.getDataBuffer()); 1073f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (isSuccess) { 1074f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.SUCCESS; 1075f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 1076f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 1077f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1078f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 1079f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 1080f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1081f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1082f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly }; 1083f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1084f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private final INfcTag mNfcTagService = new INfcTag.Stub() { 1085f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1086fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1087f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public int close(int nativeHandle) throws RemoteException { 1088d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1089bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1090f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton TagEndpoint tag = null; 1091f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1092f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1093f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1094f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 1095f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1096f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1097f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1098f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton tag = (TagEndpoint) findObject(nativeHandle); 1099f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (tag != null) { 1100b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau /* Remove the device from the hmap */ 1101b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau unregisterObject(nativeHandle); 110221545af22f9b913ec9cb124287aab2fcb0cf2b3bNick Pelly tag.disconnect(); 1103b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau return ErrorCodes.SUCCESS; 1104f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1105f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* Restart polling loop for notification */ 110649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly applyRouting(); 1107f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_DISCONNECT; 1108f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1109f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1110fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1111ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen public int connect(int nativeHandle, int technology) throws RemoteException { 1112d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1113bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1114f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton TagEndpoint tag = null; 1115f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1116f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1117f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1118f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 1119f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1120f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1121f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1122f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton tag = (TagEndpoint) findObject(nativeHandle); 1123b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau if (tag == null) { 1124b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau return ErrorCodes.ERROR_DISCONNECT; 1125f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1126ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen 11271b1e68327701225b728d43226049ad7a5dee4bcdMartijn Coenen if (technology == TagTechnology.NFC_B) { 11281b1e68327701225b728d43226049ad7a5dee4bcdMartijn Coenen return ErrorCodes.ERROR_NOT_SUPPORTED; 11291b1e68327701225b728d43226049ad7a5dee4bcdMartijn Coenen } 11301b1e68327701225b728d43226049ad7a5dee4bcdMartijn Coenen 1131ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen // Note that on most tags, all technologies are behind a single 1132ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen // handle. This means that the connect at the lower levels 1133ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen // will do nothing, as the tag is already connected to that handle. 1134ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen if (tag.connect(technology)) { 1135ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen return ErrorCodes.SUCCESS; 1136ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen } else { 1137ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen return ErrorCodes.ERROR_DISCONNECT; 1138ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen } 1139f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1140f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1141fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1142aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen public int reconnect(int nativeHandle) throws RemoteException { 1143aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1144aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen 1145f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton TagEndpoint tag = null; 1146aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen 1147aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen // Check if NFC is enabled 1148aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen if (!mIsNfcEnabled) { 1149aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen return ErrorCodes.ERROR_NOT_INITIALIZED; 1150aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen } 1151aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen 1152aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen /* find the tag in the hmap */ 1153f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton tag = (TagEndpoint) findObject(nativeHandle); 1154aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen if (tag != null) { 1155aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen if (tag.reconnect()) { 1156aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen return ErrorCodes.SUCCESS; 1157aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen } else { 1158aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen return ErrorCodes.ERROR_DISCONNECT; 1159aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen } 1160aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen } 1161aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen return ErrorCodes.ERROR_DISCONNECT; 1162aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen } 1163aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen 1164aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen @Override 1165b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton public int[] getTechList(int nativeHandle) throws RemoteException { 1166d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1167bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1168f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1169f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1170f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1171f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1172f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1173f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1174f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton TagEndpoint tag = (TagEndpoint) findObject(nativeHandle); 1175f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (tag != null) { 1176b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton return tag.getTechList(); 1177f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1178f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1179f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1180f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1181fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1182f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public byte[] getUid(int nativeHandle) throws RemoteException { 1183f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton TagEndpoint tag = null; 1184f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly byte[] uid; 1185f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1186f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1187f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1188f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1189f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1190f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1191f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1192f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton tag = (TagEndpoint) findObject(nativeHandle); 1193f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (tag != null) { 1194f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly uid = tag.getUid(); 1195f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return uid; 1196f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1197f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1198f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1199f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1200fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1201b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau public boolean isPresent(int nativeHandle) throws RemoteException { 1202f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton TagEndpoint tag = null; 1203b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 1204b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau // Check if NFC is enabled 1205b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau if (!mIsNfcEnabled) { 1206b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau return false; 1207b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 1208b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 1209b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau /* find the tag in the hmap */ 1210f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton tag = (TagEndpoint) findObject(nativeHandle); 1211b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau if (tag == null) { 1212b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau return false; 1213b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 1214b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 1215ab2b44b97936d2c5dbf6eda1245ca793e840713fMartijn Coenen return tag.isPresent(); 1216b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 1217b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 1218fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1219f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public boolean isNdef(int nativeHandle) throws RemoteException { 1220f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton TagEndpoint tag = null; 1221f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly boolean isSuccess = false; 1222f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1223f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1224f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1225f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return isSuccess; 1226f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1227f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1228f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1229f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton tag = (TagEndpoint) findObject(nativeHandle); 12303ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen int[] ndefInfo = new int[2]; 1231f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (tag != null) { 12323ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen isSuccess = tag.checkNdef(ndefInfo); 1233f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1234f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return isSuccess; 1235f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1236f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1237fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 12389d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen public TransceiveResult transceive(int nativeHandle, byte[] data, boolean raw) 123997c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen throws RemoteException { 1240d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1241bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1242f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton TagEndpoint tag = null; 1243f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly byte[] response; 1244f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1245f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1246f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1247f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1248f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1249f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1250f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1251f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton tag = (TagEndpoint) findObject(nativeHandle); 1252f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (tag != null) { 12539d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen int[] targetLost = new int[1]; 12549d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen response = tag.transceive(data, raw, targetLost); 12559d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen TransceiveResult transResult = new TransceiveResult( 12569d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen (response != null) ? true : false, 12579d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen (targetLost[0] == 1) ? true : false, 12589d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen response); 12599d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen return transResult; 1260f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1261f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1262f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1263f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1264fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 12653fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton public NdefMessage ndefRead(int nativeHandle) throws RemoteException { 1266d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1267bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1268f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton TagEndpoint tag; 1269f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1270f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1271f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1272f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1273f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1274f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1275f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1276f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton tag = (TagEndpoint) findObject(nativeHandle); 1277f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (tag != null) { 1278f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton byte[] buf = tag.readNdef(); 1279f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton if (buf == null) { 1280f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1281f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton } 1282f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1283f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* Create an NdefMessage */ 1284f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly try { 1285f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return new NdefMessage(buf); 1286f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } catch (FormatException e) { 1287f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1288f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1289f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1290f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1291f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1292f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1293fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 12943fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton public int ndefWrite(int nativeHandle, NdefMessage msg) throws RemoteException { 1295d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1296bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1297f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton TagEndpoint tag; 1298f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1299f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1300f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1301f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 1302f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1303f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1304f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1305f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton tag = (TagEndpoint) findObject(nativeHandle); 1306f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (tag == null) { 1307f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 1308f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1309f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1310f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton if (tag.writeNdef(msg.toByteArray())) { 1311f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.SUCCESS; 1312f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton } else { 1313f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 1314f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1315f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1316f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1317f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1318fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1319f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public int getLastError(int nativeHandle) throws RemoteException { 1320f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton return(mDeviceHost.doGetLastError()); 1321f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1322f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1323fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 13243fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton public boolean ndefIsWritable(int nativeHandle) throws RemoteException { 13253fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton throw new UnsupportedOperationException(); 1326f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1327f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1328fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 13293fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton public int ndefMakeReadOnly(int nativeHandle) throws RemoteException { 133003ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 133103ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen 1332f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton TagEndpoint tag; 133303ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen 133403ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen // Check if NFC is enabled 133503ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen if (!mIsNfcEnabled) { 133603ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen return ErrorCodes.ERROR_NOT_INITIALIZED; 133703ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen } 133803ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen 133903ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen /* find the tag in the hmap */ 1340f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton tag = (TagEndpoint) findObject(nativeHandle); 134103ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen if (tag == null) { 134203ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen return ErrorCodes.ERROR_IO; 134303ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen } 134403ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen 1345f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton if (tag.makeReadOnly()) { 134603ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen return ErrorCodes.SUCCESS; 1347f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton } else { 134803ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen return ErrorCodes.ERROR_IO; 134903ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen } 1350f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1351f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 13520aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen @Override 13530aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen public int formatNdef(int nativeHandle, byte[] key) throws RemoteException { 13540aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 13550aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen 1356f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton TagEndpoint tag; 13570aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen 13580aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen // Check if NFC is enabled 13590aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen if (!mIsNfcEnabled) { 13600aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen return ErrorCodes.ERROR_NOT_INITIALIZED; 13610aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen } 13620aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen 13630aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen /* find the tag in the hmap */ 1364f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton tag = (TagEndpoint) findObject(nativeHandle); 13650aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen if (tag == null) { 13660aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen return ErrorCodes.ERROR_IO; 13670aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen } 13680aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen 13690aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen if (tag.formatNdef(key)) { 13700aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen return ErrorCodes.SUCCESS; 1371f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton } else { 13720aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen return ErrorCodes.ERROR_IO; 13730aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen } 13740aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen } 13750aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen 13761b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen @Override 13773fb14d0868594c78a777e805545209636814e223Martijn Coenen public Tag rediscover(int nativeHandle) throws RemoteException { 13783fb14d0868594c78a777e805545209636814e223Martijn Coenen mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 13793fb14d0868594c78a777e805545209636814e223Martijn Coenen 1380f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton TagEndpoint tag = null; 13813fb14d0868594c78a777e805545209636814e223Martijn Coenen 13823fb14d0868594c78a777e805545209636814e223Martijn Coenen // Check if NFC is enabled 13833fb14d0868594c78a777e805545209636814e223Martijn Coenen if (!mIsNfcEnabled) { 13843fb14d0868594c78a777e805545209636814e223Martijn Coenen return null; 13853fb14d0868594c78a777e805545209636814e223Martijn Coenen } 13863fb14d0868594c78a777e805545209636814e223Martijn Coenen 13873fb14d0868594c78a777e805545209636814e223Martijn Coenen /* find the tag in the hmap */ 1388f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton tag = (TagEndpoint) findObject(nativeHandle); 13893fb14d0868594c78a777e805545209636814e223Martijn Coenen if (tag != null) { 13903fb14d0868594c78a777e805545209636814e223Martijn Coenen // For now the prime usecase for rediscover() is to be able 13913fb14d0868594c78a777e805545209636814e223Martijn Coenen // to access the NDEF technology after formatting without 13923fb14d0868594c78a777e805545209636814e223Martijn Coenen // having to remove the tag from the field, or similar 13933fb14d0868594c78a777e805545209636814e223Martijn Coenen // to have access to NdefFormatable in case low-level commands 13943fb14d0868594c78a777e805545209636814e223Martijn Coenen // were used to remove NDEF. So instead of doing a full stack 13953fb14d0868594c78a777e805545209636814e223Martijn Coenen // rediscover (which is poorly supported at the moment anyway), 13963fb14d0868594c78a777e805545209636814e223Martijn Coenen // we simply remove these two technologies and detect them 13973fb14d0868594c78a777e805545209636814e223Martijn Coenen // again. 13983fb14d0868594c78a777e805545209636814e223Martijn Coenen tag.removeTechnology(TagTechnology.NDEF); 13993fb14d0868594c78a777e805545209636814e223Martijn Coenen tag.removeTechnology(TagTechnology.NDEF_FORMATABLE); 1400f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton NdefMessage[] msgs = tag.findAndReadNdef(); 14013fb14d0868594c78a777e805545209636814e223Martijn Coenen // Build a new Tag object to return 14023fb14d0868594c78a777e805545209636814e223Martijn Coenen Tag newTag = new Tag(tag.getUid(), tag.getTechList(), 14033fb14d0868594c78a777e805545209636814e223Martijn Coenen tag.getTechExtras(), tag.getHandle(), mNfcTagService); 14043fb14d0868594c78a777e805545209636814e223Martijn Coenen return newTag; 14053fb14d0868594c78a777e805545209636814e223Martijn Coenen } 14063fb14d0868594c78a777e805545209636814e223Martijn Coenen return null; 14073fb14d0868594c78a777e805545209636814e223Martijn Coenen } 14083fb14d0868594c78a777e805545209636814e223Martijn Coenen 14091b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen @Override 1410fbd90779b1525b254726eb58d07883ca74e1b21cMartijn Coenen public int setTimeout(int tech, int timeout) throws RemoteException { 14111b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1412f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton boolean success = mDeviceHost.setTimeout(tech, timeout); 1413fbd90779b1525b254726eb58d07883ca74e1b21cMartijn Coenen if (success) { 1414fbd90779b1525b254726eb58d07883ca74e1b21cMartijn Coenen return ErrorCodes.SUCCESS; 1415fbd90779b1525b254726eb58d07883ca74e1b21cMartijn Coenen } else { 1416fbd90779b1525b254726eb58d07883ca74e1b21cMartijn Coenen return ErrorCodes.ERROR_INVALID_PARAM; 1417fbd90779b1525b254726eb58d07883ca74e1b21cMartijn Coenen } 1418dfebdbf803bf01404255f964e571056aa84173caMartijn Coenen } 1419dfebdbf803bf01404255f964e571056aa84173caMartijn Coenen 1420dfebdbf803bf01404255f964e571056aa84173caMartijn Coenen @Override 1421358d8b6ad611aba11e69a3b1dd9d132dbc9a7605Martijn Coenen public int getTimeout(int tech) throws RemoteException { 1422358d8b6ad611aba11e69a3b1dd9d132dbc9a7605Martijn Coenen mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1423358d8b6ad611aba11e69a3b1dd9d132dbc9a7605Martijn Coenen 1424358d8b6ad611aba11e69a3b1dd9d132dbc9a7605Martijn Coenen return mDeviceHost.getTimeout(tech); 1425358d8b6ad611aba11e69a3b1dd9d132dbc9a7605Martijn Coenen } 1426358d8b6ad611aba11e69a3b1dd9d132dbc9a7605Martijn Coenen 1427358d8b6ad611aba11e69a3b1dd9d132dbc9a7605Martijn Coenen @Override 1428dfebdbf803bf01404255f964e571056aa84173caMartijn Coenen public void resetTimeouts() throws RemoteException { 1429dfebdbf803bf01404255f964e571056aa84173caMartijn Coenen mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1430dfebdbf803bf01404255f964e571056aa84173caMartijn Coenen 1431f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton mDeviceHost.resetTimeouts(); 14321b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen } 14330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly }; 1434f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 14350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private final IP2pInitiator mP2pInitiatorService = new IP2pInitiator.Stub() { 1436f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1437fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 14380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public byte[] getGeneralBytes(int nativeHandle) throws RemoteException { 1439d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1440f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1441f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton NfcDepEndpoint device; 1442f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 14430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 14440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 14450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 14460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1447f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 14480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 1449f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton device = (NfcDepEndpoint) findObject(nativeHandle); 14500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 14510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly byte[] buff = device.getGeneralBytes(); 14520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (buff == null) 14530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 14540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return buff; 14550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 14560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 14570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1458f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1459fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 14600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int getMode(int nativeHandle) throws RemoteException { 1461d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1462f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1463f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton NfcDepEndpoint device; 1464f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 14650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 14660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 14670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 14680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1469f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 14700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 1471f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton device = (NfcDepEndpoint) findObject(nativeHandle); 14720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 14730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return device.getMode(); 14740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1475f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_INVALID_PARAM; 1476f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1477f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1478fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 14790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public byte[] receive(int nativeHandle) throws RemoteException { 1480d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1481f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1482f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton NfcDepEndpoint device; 1483f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 14840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 14850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 14860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 14870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1488f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 14890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 1490f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton device = (NfcDepEndpoint) findObject(nativeHandle); 14910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 1492f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton byte[] buff = device.receive(); 1493f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton if (buff == null) { 14940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 1495f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton } 14960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return buff; 14970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 14980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Restart polling loop for notification */ 149949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly applyRouting(); 15000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 15010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1502f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1503fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 15040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public boolean send(int nativeHandle, byte[] data) throws RemoteException { 1505d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1506f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1507f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton NfcDepEndpoint device; 15080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean isSuccess = false; 1509f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 15100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 15110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 15120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return isSuccess; 15130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1514f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 15150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 1516f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton device = (NfcDepEndpoint) findObject(nativeHandle); 15170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 1518f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton isSuccess = device.send(data); 15190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 15200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return isSuccess; 15210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 15220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly }; 1523f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 15240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private final IP2pTarget mP2pTargetService = new IP2pTarget.Stub() { 1525f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1526fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 15270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int connect(int nativeHandle) throws RemoteException { 1528d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1529f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1530f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton NfcDepEndpoint device; 1531f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 15320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 15330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 15340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 15350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1536f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 15370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 1538f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton device = (NfcDepEndpoint) findObject(nativeHandle); 15390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 1540f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton if (device.connect()) { 15410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.SUCCESS; 15420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 15430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 15440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_CONNECT; 15450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1546f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1547fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 15480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public boolean disconnect(int nativeHandle) throws RemoteException { 1549d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1550f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1551f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton NfcDepEndpoint device; 15520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean isSuccess = false; 1553f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 15540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 15550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 15560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return isSuccess; 15570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1558f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 15590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 1560f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton device = (NfcDepEndpoint) findObject(nativeHandle); 15610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 1562f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton if (isSuccess = device.disconnect()) { 15630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* remove the device from the hmap */ 1564b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau unregisterObject(nativeHandle); 15650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Restart polling loop for notification */ 156649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly applyRouting(); 15670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1568f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 15690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return isSuccess; 1570f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 15710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1572f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1573fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 15740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public byte[] getGeneralBytes(int nativeHandle) throws RemoteException { 1575d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1576f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1577f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton NfcDepEndpoint device; 15780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 15790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 15800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 15810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 1582f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1583f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 15840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 1585f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton device = (NfcDepEndpoint) findObject(nativeHandle); 15860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 15870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly byte[] buff = device.getGeneralBytes(); 15880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (buff == null) 15890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 15900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return buff; 15910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 15920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 15930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1594f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1595fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 15960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int getMode(int nativeHandle) throws RemoteException { 1597d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1598f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1599f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton NfcDepEndpoint device; 1600f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 16020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 16030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 1604f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1605f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 1607f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton device = (NfcDepEndpoint) findObject(nativeHandle); 16080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 16090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return device.getMode(); 16100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 16110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_INVALID_PARAM; 16120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1613f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1614fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 161597c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen public byte[] transceive(int nativeHandle, byte[] data) 161697c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen throws RemoteException { 1617d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1618f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1619f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton NfcDepEndpoint device; 1620f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 16220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 16230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 1624f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1625f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 1627f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton device = (NfcDepEndpoint) findObject(nativeHandle); 16280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 1629f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton return device.transceive(data); 16300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 16310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 16320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 16330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly }; 1634f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1635dfac80d25dd2816ad5af74cc4131b74134cc81b7Nick Pelly private void _nfcEeClose(boolean checkPid, int callingPid) throws IOException { 1636dfac80d25dd2816ad5af74cc4131b74134cc81b7Nick Pelly // Blocks until a pending open() or transceive() times out. 1637dfac80d25dd2816ad5af74cc4131b74134cc81b7Nick Pelly //TODO: This is incorrect behavior - the close should interrupt pending 1638dfac80d25dd2816ad5af74cc4131b74134cc81b7Nick Pelly // operations. However this is not supported by current hardware. 1639dfac80d25dd2816ad5af74cc4131b74134cc81b7Nick Pelly 1640dfac80d25dd2816ad5af74cc4131b74134cc81b7Nick Pelly synchronized(NfcService.this) { 1641dfac80d25dd2816ad5af74cc4131b74134cc81b7Nick Pelly if (!mIsNfcEnabled) { 1642dfac80d25dd2816ad5af74cc4131b74134cc81b7Nick Pelly throw new IOException("NFC adapter is disabled"); 1643dfac80d25dd2816ad5af74cc4131b74134cc81b7Nick Pelly } 1644dfac80d25dd2816ad5af74cc4131b74134cc81b7Nick Pelly if (mOpenEe == null) { 1645dfac80d25dd2816ad5af74cc4131b74134cc81b7Nick Pelly throw new IOException("NFC EE closed"); 1646dfac80d25dd2816ad5af74cc4131b74134cc81b7Nick Pelly } 1647dfac80d25dd2816ad5af74cc4131b74134cc81b7Nick Pelly if (checkPid && mOpenEe.pid != -1 && callingPid != mOpenEe.pid) { 1648dfac80d25dd2816ad5af74cc4131b74134cc81b7Nick Pelly throw new SecurityException("Wrong PID"); 1649dfac80d25dd2816ad5af74cc4131b74134cc81b7Nick Pelly } 1650dfac80d25dd2816ad5af74cc4131b74134cc81b7Nick Pelly 1651f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton mDeviceHost.resetTimeouts(); 1652dfac80d25dd2816ad5af74cc4131b74134cc81b7Nick Pelly mSecureElement.doDisconnect(mOpenEe.handle); 1653dfac80d25dd2816ad5af74cc4131b74134cc81b7Nick Pelly mOpenEe = null; 1654dfac80d25dd2816ad5af74cc4131b74134cc81b7Nick Pelly 1655dfac80d25dd2816ad5af74cc4131b74134cc81b7Nick Pelly applyRouting(); 1656dfac80d25dd2816ad5af74cc4131b74134cc81b7Nick Pelly } 1657dfac80d25dd2816ad5af74cc4131b74134cc81b7Nick Pelly } 1658dfac80d25dd2816ad5af74cc4131b74134cc81b7Nick Pelly 165949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private INfcAdapterExtras mExtrasService = new INfcAdapterExtras.Stub() { 166049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private Bundle writeNoException() { 166149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Bundle p = new Bundle(); 166249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly p.putInt("e", 0); 166349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly return p; 166449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 166549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private Bundle writeIoException(IOException e) { 166649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Bundle p = new Bundle(); 166749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly p.putInt("e", -1); 166849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly p.putString("m", e.getMessage()); 166949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly return p; 167049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 16710bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 1672bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks @Override 167349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public Bundle open(IBinder b) throws RemoteException { 167493d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton NfcService.enforceNfceeAdminPerm(mContext); 1675bd555ee64250126b60b24814120a2049943920caNick Pelly 167649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Bundle result; 167749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly try { 167849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly _open(b); 167949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly result = writeNoException(); 168049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } catch (IOException e) { 168149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly result = writeIoException(e); 16820bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 168349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly return result; 168449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 16850bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 168649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private void _open(IBinder b) throws IOException, RemoteException { 168749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly synchronized(NfcService.this) { 168849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (!mIsNfcEnabled) { 168949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly throw new IOException("NFC adapter is disabled"); 169049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 169149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (mOpenEe != null) { 169249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly throw new IOException("NFC EE already open"); 169349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 16940bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 169549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly int handle = mSecureElement.doOpenSecureElementConnection(); 169649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (handle == 0) { 169749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly throw new IOException("NFC EE failed to open"); 169849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 1699f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton mDeviceHost.setTimeout(TagTechnology.ISO_DEP, 10000); 1700ba6401757f8017faeb77423f2d08fd51be1d1051Nick Pelly 170149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mOpenEe = new OpenSecureElement(getCallingPid(), handle); 170249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly try { 170349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly b.linkToDeath(mOpenEe, 0); 170449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } catch (RemoteException e) { 170549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mOpenEe.binderDied(); 170649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 170784e1e0adc2516afd35ebab029a52e764e0490559Jason parks 170884e1e0adc2516afd35ebab029a52e764e0490559Jason parks // Add the calling package to the list of packages that have accessed 170984e1e0adc2516afd35ebab029a52e764e0490559Jason parks // the secure element. 171084e1e0adc2516afd35ebab029a52e764e0490559Jason parks for (String packageName : getPackageManager().getPackagesForUid(getCallingUid())) { 171184e1e0adc2516afd35ebab029a52e764e0490559Jason parks mSePackages.add(packageName); 171284e1e0adc2516afd35ebab029a52e764e0490559Jason parks } 171349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 17140bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 17150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 1716bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks @Override 171749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public Bundle close() throws RemoteException { 171893d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton NfcService.enforceNfceeAdminPerm(mContext); 17190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 172049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Bundle result; 172149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly try { 1722dfac80d25dd2816ad5af74cc4131b74134cc81b7Nick Pelly _nfcEeClose(true, getCallingPid()); 172349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly result = writeNoException(); 172449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } catch (IOException e) { 172549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly result = writeIoException(e); 17260bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 172749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly return result; 172849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 17290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 1730bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks @Override 173149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public Bundle transceive(byte[] in) throws RemoteException { 173293d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton NfcService.enforceNfceeAdminPerm(mContext); 1733bd555ee64250126b60b24814120a2049943920caNick Pelly 173449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Bundle result; 173549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly byte[] out; 173649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly try { 173749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly out = _transceive(in); 173849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly result = writeNoException(); 173949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly result.putByteArray("out", out); 174049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } catch (IOException e) { 174149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly result = writeIoException(e); 17420bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 174349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly return result; 174449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 17450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 174649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private byte[] _transceive(byte[] data) throws IOException, RemoteException { 174749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly synchronized(NfcService.this) { 174849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (!mIsNfcEnabled) { 174949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly throw new IOException("NFC is not enabled"); 175049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 175149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (mOpenEe == null){ 175249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly throw new IOException("NFC EE is not open"); 175349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 175449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (getCallingPid() != mOpenEe.pid) { 175549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly throw new SecurityException("Wrong PID"); 175649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 17570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 17580bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 175949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly return mSecureElement.doTransceive(mOpenEe.handle, data); 17600bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 17610bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 1762bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks @Override 176349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public int getCardEmulationRoute() throws RemoteException { 176493d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton NfcService.enforceNfceeAdminPerm(mContext); 176549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly return mEeRoutingState; 17660bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 17670bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 1768bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks @Override 176949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public void setCardEmulationRoute(int route) throws RemoteException { 177093d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton NfcService.enforceNfceeAdminPerm(mContext); 177149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mEeRoutingState = route; 177249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly applyRouting(); 17730bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 1774bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 1775bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks @Override 17765a8844da9bc569aa7289426bf7b96e7eef90abf5Nick Pelly public void authenticate(byte[] token) throws RemoteException { 1777bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks NfcService.enforceNfceeAdminPerm(mContext); 1778bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 17790bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas }; 17800bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 178149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly /** resources kept while secure element is open */ 178249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private class OpenSecureElement implements IBinder.DeathRecipient { 178349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public int pid; // pid that opened SE 178449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public int handle; // low-level handle 178549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public OpenSecureElement(int pid, int handle) { 178649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly this.pid = pid; 178749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly this.handle = handle; 178849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 1789bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks @Override 179049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public void binderDied() { 179149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly synchronized (NfcService.this) { 179249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (DBG) Log.d(TAG, "Tracked app " + pid + " died"); 179349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly pid = -1; 17940bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas try { 1795dfac80d25dd2816ad5af74cc4131b74134cc81b7Nick Pelly _nfcEeClose(false, -1); 1796dfac80d25dd2816ad5af74cc4131b74134cc81b7Nick Pelly } catch (IOException e) { /* already closed */ } 17970bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 17980bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 17990bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 18000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 1801e7a398f2f0256a4a80a4ee08b70d48dbfd8da6d2Nick Pelly private boolean _enable(boolean oldEnabledState, boolean savePref) { 1802f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton boolean isSuccess = mDeviceHost.initialize(); 18030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (isSuccess) { 180465945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly mIsNfcEnabled = true; 180549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mIsDiscoveryOn = true; 180665945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly 18070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Start polling loop */ 180849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly applyRouting(); 1809e063132e40dc788f0b471ed3832f5fbaebd7e463Martijn Coenen synchronized(NfcService.this) { 1810e063132e40dc788f0b471ed3832f5fbaebd7e463Martijn Coenen boolean zeroclick_on = mPrefs.getBoolean(PREF_ZEROCLICK_ON, 1811e063132e40dc788f0b471ed3832f5fbaebd7e463Martijn Coenen ZEROCLICK_ON_DEFAULT); 1812e063132e40dc788f0b471ed3832f5fbaebd7e463Martijn Coenen if (zeroclick_on) { 1813e063132e40dc788f0b471ed3832f5fbaebd7e463Martijn Coenen /* bring up p2p ndef servers */ 1814e063132e40dc788f0b471ed3832f5fbaebd7e463Martijn Coenen mP2pManager.enableNdefServer(); 1815e063132e40dc788f0b471ed3832f5fbaebd7e463Martijn Coenen mZeroClickOn = true; 1816e063132e40dc788f0b471ed3832f5fbaebd7e463Martijn Coenen } 1817d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen } 1818f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 1819aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly Log.w(TAG, "Error enabling NFC"); 18200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mIsNfcEnabled = false; 1821f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1822f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1823e7a398f2f0256a4a80a4ee08b70d48dbfd8da6d2Nick Pelly if (savePref) { 1824e7a398f2f0256a4a80a4ee08b70d48dbfd8da6d2Nick Pelly updateNfcOnSetting(oldEnabledState); 1825e7a398f2f0256a4a80a4ee08b70d48dbfd8da6d2Nick Pelly } 1826f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 18270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return isSuccess; 1828f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1829f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1830e7a398f2f0256a4a80a4ee08b70d48dbfd8da6d2Nick Pelly private boolean _disable(boolean oldEnabledState, boolean savePref) { 18312083287b83a587d8f6e9ad829ea18041dc17d842Nick Pelly /* sometimes mDeviceHost.deinitialize() hangs, watch-dog it */ 18322edb3ee5e28ab719a3bb17b8d76b2b588405be9aNick Pelly WatchDogThread watchDog = new WatchDogThread(); 18332edb3ee5e28ab719a3bb17b8d76b2b588405be9aNick Pelly watchDog.start(); 18342edb3ee5e28ab719a3bb17b8d76b2b588405be9aNick Pelly 1835aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly boolean isSuccess; 1836aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly 18372ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson /* tear down the p2p server */ 1838e063132e40dc788f0b471ed3832f5fbaebd7e463Martijn Coenen synchronized(NfcService.this) { 1839e063132e40dc788f0b471ed3832f5fbaebd7e463Martijn Coenen if (mZeroClickOn) { 1840e063132e40dc788f0b471ed3832f5fbaebd7e463Martijn Coenen mP2pManager.disableNdefServer(); 1841e063132e40dc788f0b471ed3832f5fbaebd7e463Martijn Coenen mZeroClickOn = false; 1842e063132e40dc788f0b471ed3832f5fbaebd7e463Martijn Coenen } 1843d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen } 1844aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly // Stop watchdog if tag present 1845aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly // A convenient way to stop the watchdog properly consists of 1846aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly // disconnecting the tag. The polling loop shall be stopped before 1847aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly // to avoid the tag being discovered again. 1848aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly mIsDiscoveryOn = false; 1849aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly applyRouting(); 1850aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly maybeDisconnectTarget(); 1851aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly 1852f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton isSuccess = mDeviceHost.deinitialize(); 1853aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly if (DBG) Log.d(TAG, "NFC success of deinitialize = " + isSuccess); 1854aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly if (isSuccess) { 1855aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly mIsNfcEnabled = false; 18568586b104c1cf07c52c739c0afab0ded1bf151859Nick Pelly mNfcDispatcher.disableForegroundDispatch(); 18572ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson mP2pManager.setForegroundMessage(null); 1858aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly } 1859aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly 1860e7a398f2f0256a4a80a4ee08b70d48dbfd8da6d2Nick Pelly if (savePref) { 1861e7a398f2f0256a4a80a4ee08b70d48dbfd8da6d2Nick Pelly updateNfcOnSetting(oldEnabledState); 1862e7a398f2f0256a4a80a4ee08b70d48dbfd8da6d2Nick Pelly } 1863aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly 18642edb3ee5e28ab719a3bb17b8d76b2b588405be9aNick Pelly watchDog.cancel(); 1865aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly return isSuccess; 1866aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly } 1867aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly 18682edb3ee5e28ab719a3bb17b8d76b2b588405be9aNick Pelly private class WatchDogThread extends Thread { 18692edb3ee5e28ab719a3bb17b8d76b2b588405be9aNick Pelly boolean mWatchDogCanceled = false; 18702edb3ee5e28ab719a3bb17b8d76b2b588405be9aNick Pelly @Override 18712edb3ee5e28ab719a3bb17b8d76b2b588405be9aNick Pelly public void run() { 18722edb3ee5e28ab719a3bb17b8d76b2b588405be9aNick Pelly boolean slept = false; 18732edb3ee5e28ab719a3bb17b8d76b2b588405be9aNick Pelly while (!slept) { 18742edb3ee5e28ab719a3bb17b8d76b2b588405be9aNick Pelly try { 18752edb3ee5e28ab719a3bb17b8d76b2b588405be9aNick Pelly Thread.sleep(10000); 18762edb3ee5e28ab719a3bb17b8d76b2b588405be9aNick Pelly slept = true; 18772edb3ee5e28ab719a3bb17b8d76b2b588405be9aNick Pelly } catch (InterruptedException e) { } 18782edb3ee5e28ab719a3bb17b8d76b2b588405be9aNick Pelly } 18792edb3ee5e28ab719a3bb17b8d76b2b588405be9aNick Pelly synchronized (this) { 18802edb3ee5e28ab719a3bb17b8d76b2b588405be9aNick Pelly if (!mWatchDogCanceled) { 18812edb3ee5e28ab719a3bb17b8d76b2b588405be9aNick Pelly // Trigger watch-dog 18822edb3ee5e28ab719a3bb17b8d76b2b588405be9aNick Pelly Log.e(TAG, "Watch dog triggered"); 18832083287b83a587d8f6e9ad829ea18041dc17d842Nick Pelly mDeviceHost.doAbort(); 18842edb3ee5e28ab719a3bb17b8d76b2b588405be9aNick Pelly } 18852edb3ee5e28ab719a3bb17b8d76b2b588405be9aNick Pelly } 18862edb3ee5e28ab719a3bb17b8d76b2b588405be9aNick Pelly } 18872edb3ee5e28ab719a3bb17b8d76b2b588405be9aNick Pelly public synchronized void cancel() { 18882edb3ee5e28ab719a3bb17b8d76b2b588405be9aNick Pelly mWatchDogCanceled = true; 18892edb3ee5e28ab719a3bb17b8d76b2b588405be9aNick Pelly } 18902edb3ee5e28ab719a3bb17b8d76b2b588405be9aNick Pelly } 18912edb3ee5e28ab719a3bb17b8d76b2b588405be9aNick Pelly 189249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly /** apply NFC discovery and EE routing */ 189349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private synchronized void applyRouting() { 189449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (mIsNfcEnabled && mOpenEe == null) { 1895275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks if (mScreenUnlocked) { 189649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (mEeRoutingState == ROUTE_ON_WHEN_SCREEN_ON) { 189749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Log.d(TAG, "NFC-EE routing ON"); 1898f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton mDeviceHost.doSelectSecureElement(); 189949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } else { 190049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Log.d(TAG, "NFC-EE routing OFF"); 1901f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton mDeviceHost.doDeselectSecureElement(); 1902221b4d6ee301fbfe19402798f7d3c11e6878c888daniel_tomas } 190349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (mIsDiscoveryOn) { 190449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Log.d(TAG, "NFC-C discovery ON"); 1905f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton mDeviceHost.enableDiscovery(); 190649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } else { 190749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Log.d(TAG, "NFC-C discovery OFF"); 1908f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton mDeviceHost.disableDiscovery(); 1909221b4d6ee301fbfe19402798f7d3c11e6878c888daniel_tomas } 1910221b4d6ee301fbfe19402798f7d3c11e6878c888daniel_tomas } else { 191149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Log.d(TAG, "NFC-EE routing OFF"); 1912f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton mDeviceHost.doDeselectSecureElement(); 191349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Log.d(TAG, "NFC-C discovery OFF"); 1914f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton mDeviceHost.disableDiscovery(); 1915221b4d6ee301fbfe19402798f7d3c11e6878c888daniel_tomas } 191665945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly } 191765945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly } 191865945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly 19192436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir /** Disconnect any target if present */ 19202436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir private synchronized void maybeDisconnectTarget() { 19212436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir if (mIsNfcEnabled) { 19222436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir Iterator<?> iterator = mObjectMap.values().iterator(); 19232436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir while(iterator.hasNext()) { 19242436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir Object object = iterator.next(); 1925f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton if (object instanceof TagEndpoint) { 1926663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau // Disconnect from tags 1927f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton TagEndpoint tag = (TagEndpoint) object; 19282436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir tag.disconnect(); 1929f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton } else if(object instanceof NfcDepEndpoint) { 1930663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau // Disconnect from P2P devices 1931f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton NfcDepEndpoint device = (NfcDepEndpoint) object; 1932f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton if (device.getMode() == NfcDepEndpoint.MODE_P2P_TARGET) { 1933663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau // Remote peer is target, request disconnection 1934f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton device.disconnect(); 1935f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton } else { 1936663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau // Remote peer is initiator, we cannot disconnect 1937663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau // Just wait for field removal 1938663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau } 1939663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau } 1940663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau iterator.remove(); 19412436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir } 19422436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir } 19432436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir } 19442436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir 1945a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly //TODO: dont hardcode this 1946a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly private static final byte[][] SE_RESET_APDUS = { 1947a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly {(byte)0x00, (byte)0xa4, (byte)0x04, (byte)0x00, (byte)0x00}, 1948a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly {(byte)0x00, (byte)0xa4, (byte)0x04, (byte)0x00, (byte)0x07, (byte)0xa0, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x76, (byte)0x20, (byte)0x10, (byte)0x00}, 1949a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly {(byte)0x80, (byte)0xe2, (byte)0x01, (byte)0x03, (byte)0x00}, 1950a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly {(byte)0x00, (byte)0xa4, (byte)0x04, (byte)0x00, (byte)0x00}, 1951a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly {(byte)0x00, (byte)0xa4, (byte)0x04, (byte)0x00, (byte)0x07, (byte)0xa0, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x76, (byte)0x30, (byte)0x30, (byte)0x00}, 1952a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly {(byte)0x80, (byte)0xb4, (byte)0x00, (byte)0x00, (byte)0x00}, 1953a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly {(byte)0x00, (byte)0xa4, (byte)0x04, (byte)0x00, (byte)0x00}, 1954a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly }; 1955bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 1956a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly private void resetSeOnFirstBoot() { 1957a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly if (mPrefs.getBoolean(PREF_FIRST_BOOT, true)) { 1958a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly Log.i(TAG, "First Boot"); 1959a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly mPrefsEditor.putBoolean(PREF_FIRST_BOOT, false); 1960a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly mPrefsEditor.apply(); 19612edb3ee5e28ab719a3bb17b8d76b2b588405be9aNick Pelly executeSeReset(); 1962a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly } 1963a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly } 1964bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 1965a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly private synchronized void executeSeReset() { 1966a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly // TODO: read SE reset list from /system/etc 1967a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly //List<byte[]> apdus = readSeResetApdus(); 1968a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly byte[][]apdus = SE_RESET_APDUS; 1969a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly if (apdus == null) { 1970a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly return; 1971a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly } 1972aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly 1973aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly boolean tempEnable = !mIsNfcEnabled; 1974aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly if (tempEnable) { 1975e7a398f2f0256a4a80a4ee08b70d48dbfd8da6d2Nick Pelly if (!_enable(false, false)) { 1976aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly Log.w(TAG, "Could not enable NFC to reset EE!"); 1977aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly return; 1978aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly } 1979aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly } 1980aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly 1981a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly Log.i(TAG, "Executing SE Reset Script"); 1982a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly int handle = mSecureElement.doOpenSecureElementConnection(); 1983a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly if (handle == 0) { 1984a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly Log.e(TAG, "Could not open the secure element!"); 1985aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly if (tempEnable) { 1986e7a398f2f0256a4a80a4ee08b70d48dbfd8da6d2Nick Pelly _disable(true, false); 1987aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly } 1988a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly return; 1989a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly } 1990bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 1991ce77cf9b062cc749f488994cefd958e23994d60eNick Pelly mDeviceHost.setTimeout(TagTechnology.ISO_DEP, 10000); 199285a8366a75041491a22928f65357c69d112c9925Daniel Tomas 1993a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly for (byte[] cmd : apdus) { 1994a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly mSecureElement.doTransceive(handle, cmd); 1995bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 1996a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly 1997ce77cf9b062cc749f488994cefd958e23994d60eNick Pelly mDeviceHost.resetTimeouts(); 199885a8366a75041491a22928f65357c69d112c9925Daniel Tomas 1999a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly mSecureElement.doDisconnect(handle); 2000aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly 2001aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly if (tempEnable) { 2002e7a398f2f0256a4a80a4ee08b70d48dbfd8da6d2Nick Pelly _disable(true, false); 2003aa122139d77645149c09c9815fd45e7b87ce7170Nick Pelly } 2004bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2005bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2006a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly private List<byte[]> readSeResetApdus() { 2007a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly FileInputStream input = null; 2008a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly List<byte[]> apdus = null; 2009bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2010bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks try { 2011a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly input = openFileInput(SE_RESET_SCRIPT_FILE_NAME); 2012a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly DataInputStream stream = new DataInputStream(input); 2013bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2014a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly int commandsSize = stream.readInt(); 2015a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly apdus = new ArrayList<byte[]>(commandsSize); 2016bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2017a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly for (int i = 0 ; i < commandsSize ; i++) { 2018a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly int length = stream.readInt(); 2019bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2020a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly byte[] cmd = new byte[length]; 2021bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2022a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly stream.read(cmd); 2023a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly apdus.add(cmd); 2024bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2025bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2026a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly return apdus; 2027a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly } catch (FileNotFoundException e) { 2028a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly Log.e(TAG, "SE Reset Script not found: " + SE_RESET_SCRIPT_FILE_NAME); 2029bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } catch (IOException e) { 2030a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly Log.e(TAG, "SE Reset Script corrupt: ", e); 2031a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly apdus = null; 2032bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } finally { 2033bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks try { 2034a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly if (input != null) { 2035a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly input.close(); 2036bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2037bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } catch (IOException e) { 2038bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks // Ignore 2039bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2040bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2041a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly return apdus; 2042bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2043bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 20440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private void updateNfcOnSetting(boolean oldEnabledState) { 20450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putBoolean(PREF_NFC_ON, mIsNfcEnabled); 20462f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 20470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 20482f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly synchronized(this) { 20494acf84356e35861f7df6d07a2b9ff84842a9f221Nick Pelly if (oldEnabledState != mIsNfcEnabled) { 20502f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly Intent intent = new Intent(NfcAdapter.ACTION_ADAPTER_STATE_CHANGE); 20514acf84356e35861f7df6d07a2b9ff84842a9f221Nick Pelly intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 20522f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly intent.putExtra(NfcAdapter.EXTRA_NEW_BOOLEAN_STATE, mIsNfcEnabled); 20532f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly mContext.sendBroadcast(intent); 20542f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly } 20550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 2056f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2057f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2058f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Reset all internals 20592f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly private synchronized void reset() { 206074180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick // TODO: none of these appear to be synchronized but are 206174180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick // read/written from different threads (notably Binder threads)... 2062f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2063f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Clear tables 2064f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly mObjectMap.clear(); 2065f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly mSocketMap.clear(); 2066f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2067f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Reset variables 2068f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly mIsNfcEnabled = false; 2069f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2070f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 20712f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly private synchronized Object findObject(int key) { 2072f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly Object device = null; 2073f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2074f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly device = mObjectMap.get(key); 2075f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (device == null) { 2076f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly Log.w(TAG, "Handle not found !"); 2077f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2078f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2079f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return device; 2080f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2081f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2082f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton synchronized void registerTagObject(TagEndpoint tag) { 2083f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton mObjectMap.put(tag.getHandle(), tag); 2084b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 2085b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 20862f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly synchronized void unregisterObject(int handle) { 2087b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau mObjectMap.remove(handle); 2088f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2089f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 20902f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly private synchronized Object findSocket(int key) { 2091bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly if (mSocketMap == null) { 2092bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly return null; 2093bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly } 2094bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly return mSocketMap.get(key); 2095f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2096f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2097f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton private void removeSocket(int key) { 2098f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly mSocketMap.remove(key); 2099f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2100f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2101d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton /** For use by code in this process */ 2102d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton public LlcpSocket createLlcpSocket(int sap, int miu, int rw, int linearBufferLength) { 2103d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton try { 2104d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton int handle = mNfcAdapter.createLlcpSocket(sap, miu, rw, linearBufferLength); 21051be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton if (ErrorCodes.isError(handle)) { 21061be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton Log.e(TAG, "unable to create socket: " + ErrorCodes.asString(handle)); 21071be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton return null; 21081be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton } 2109d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton return new LlcpSocket(mLlcpSocket, handle); 2110d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton } catch (RemoteException e) { 2111d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton // This will never happen since the code is calling into it's own process 2112d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton throw new IllegalStateException("unable to talk to myself", e); 2113d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton } 2114d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton } 2115d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton 2116d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton /** For use by code in this process */ 2117d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton public LlcpServiceSocket createLlcpServiceSocket(int sap, String sn, int miu, int rw, 2118d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton int linearBufferLength) { 2119d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton try { 2120d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton int handle = mNfcAdapter.createLlcpServiceSocket(sap, sn, miu, rw, linearBufferLength); 21211be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton if (ErrorCodes.isError(handle)) { 21221be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton Log.e(TAG, "unable to create socket: " + ErrorCodes.asString(handle)); 21231be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton return null; 21241be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton } 2125d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton return new LlcpServiceSocket(mLlcpServerSocketService, mLlcpSocket, handle); 2126d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton } catch (RemoteException e) { 2127d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton // This will never happen since the code is calling into it's own process 2128d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton throw new IllegalStateException("unable to talk to myself", e); 2129d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton } 2130d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton } 2131d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton 213257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton public void sendMockNdefTag(NdefMessage msg) { 2133b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton sendMessage(MSG_MOCK_NDEF, msg); 213457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 213557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 21368d6a8dce6706c6c6b3158101f2f3e94a1e0ad946Ben Dodson public void sendMeProfile(NdefMessage target, NdefMessage profile) { 21378d6a8dce6706c6c6b3158101f2f3e94a1e0ad946Ben Dodson mP2pManager.sendMeProfile(target, profile); 21388d6a8dce6706c6c6b3158101f2f3e94a1e0ad946Ben Dodson } 21398d6a8dce6706c6c6b3158101f2f3e94a1e0ad946Ben Dodson 2140b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau void sendMessage(int what, Object obj) { 2141b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau Message msg = mHandler.obtainMessage(); 2142b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau msg.what = what; 2143b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau msg.obj = obj; 2144b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau mHandler.sendMessage(msg); 2145b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 2146b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 21473fb14d0868594c78a777e805545209636814e223Martijn Coenen final class NfcServiceHandler extends Handler { 2148232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen 2149b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau @Override 2150b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau public void handleMessage(Message msg) { 2151f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly switch (msg.what) { 2152b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton case MSG_MOCK_NDEF: { 2153b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton NdefMessage ndefMsg = (NdefMessage) msg.obj; 2154aca0d055a82da850c27f6872405602ad5f3fee7bJeff Hamilton Bundle extras = new Bundle(); 2155aca0d055a82da850c27f6872405602ad5f3fee7bJeff Hamilton extras.putParcelable(Ndef.EXTRA_NDEF_MSG, ndefMsg); 2156aca0d055a82da850c27f6872405602ad5f3fee7bJeff Hamilton extras.putInt(Ndef.EXTRA_NDEF_MAXLENGTH, 0); 2157aca0d055a82da850c27f6872405602ad5f3fee7bJeff Hamilton extras.putInt(Ndef.EXTRA_NDEF_CARDSTATE, Ndef.NDEF_MODE_READ_ONLY); 2158aca0d055a82da850c27f6872405602ad5f3fee7bJeff Hamilton extras.putInt(Ndef.EXTRA_NDEF_TYPE, Ndef.TYPE_OTHER); 2159b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton Tag tag = Tag.createMockTag(new byte[] { 0x00 }, 2160aca0d055a82da850c27f6872405602ad5f3fee7bJeff Hamilton new int[] { TagTechnology.NDEF }, 2161aca0d055a82da850c27f6872405602ad5f3fee7bJeff Hamilton new Bundle[] { extras }); 216257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Log.d(TAG, "mock NDEF tag, starting corresponding activity"); 216357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Log.d(TAG, tag.toString()); 2164d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton boolean delivered = mNfcDispatcher.dispatchTag(tag, new NdefMessage[] { ndefMsg }); 2165d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton if (delivered) { 2166d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton onP2pEnd(); 2167d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton } 216857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton break; 216957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 217057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 2171f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly case MSG_NDEF_TAG: 2172ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Tag detected, notifying applications"); 2173f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton TagEndpoint tag = (TagEndpoint) msg.obj; 2174d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton playSound(mStartSound); 2175f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton NdefMessage[] ndefMsgs = tag.findAndReadNdef(); 2176232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen 2177232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen if (ndefMsgs != null) { 2178f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton tag.startPresenceChecking(); 2179f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton dispatchTagEndpoint(tag, ndefMsgs); 2180232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } else { 2181232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen // No ndef found or connect failed, just try to reconnect and dispatch 2182f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton if (tag.reconnect()) { 2183f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton tag.startPresenceChecking(); 2184f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton dispatchTagEndpoint(tag, null); 2185232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } else { 2186232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen Log.w(TAG, "Failed to connect to tag"); 2187f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton tag.disconnect(); 2188d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton playSound(mErrorSound); 2189f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly } 2190f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly } 2191f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly break; 21923fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 2193f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly case MSG_CARD_EMULATION: 2194ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Card Emulation message"); 2195f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly byte[] aid = (byte[]) msg.obj; 219649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly /* Send broadcast */ 219749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Intent aidIntent = new Intent(); 219849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly aidIntent.setAction(ACTION_AID_SELECTED); 219949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly aidIntent.putExtra(EXTRA_AID, aid); 22002c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas if (DBG) Log.d(TAG, "Broadcasting " + ACTION_AID_SELECTED); 220193d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton mContext.sendBroadcast(aidIntent, NFCEE_ADMIN_PERM); 2202f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly break; 2203f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly 22042c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas case MSG_SE_EMV_CARD_REMOVAL: 22052c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas if (DBG) Log.d(TAG, "Card Removal message"); 22062c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas /* Send broadcast */ 22072c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas Intent cardRemovalIntent = new Intent(); 22082c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas cardRemovalIntent.setAction(ACTION_EMV_CARD_REMOVAL); 22092c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas if (DBG) Log.d(TAG, "Broadcasting " + ACTION_EMV_CARD_REMOVAL); 22102c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas mContext.sendBroadcast(cardRemovalIntent, NFCEE_ADMIN_PERM); 22112c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas break; 22122c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas 22132c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas case MSG_SE_APDU_RECEIVED: 22142c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas if (DBG) Log.d(TAG, "APDU Received message"); 22152c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas byte[] apduBytes = (byte[]) msg.obj; 22162c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas /* Send broadcast */ 22172c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas Intent apduReceivedIntent = new Intent(); 22182c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas apduReceivedIntent.setAction(ACTION_APDU_RECEIVED); 22192c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas if (apduBytes != null && apduBytes.length > 0) { 22202c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas apduReceivedIntent.putExtra(EXTRA_APDU_BYTES, apduBytes); 22212c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas } 22222c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas if (DBG) Log.d(TAG, "Broadcasting " + ACTION_APDU_RECEIVED); 22232c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas mContext.sendBroadcast(apduReceivedIntent, NFCEE_ADMIN_PERM); 22242c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas break; 22252c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas 22262c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas case MSG_SE_MIFARE_ACCESS: 22272c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas if (DBG) Log.d(TAG, "MIFARE access message"); 22282c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas /* Send broadcast */ 22292c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas byte[] mifareCmd = (byte[]) msg.obj; 22302c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas Intent mifareAccessIntent = new Intent(); 22312c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas mifareAccessIntent.setAction(ACTION_MIFARE_ACCESS_DETECTED); 22322c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas if (mifareCmd != null && mifareCmd.length > 1) { 22332c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas int mifareBlock = mifareCmd[1] & 0xff; 22342c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas if (DBG) Log.d(TAG, "Mifare Block=" + mifareBlock); 22352c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas mifareAccessIntent.putExtra(EXTRA_MIFARE_BLOCK, mifareBlock); 22362c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas } 22372c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas if (DBG) Log.d(TAG, "Broadcasting " + ACTION_MIFARE_ACCESS_DETECTED); 22382c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas mContext.sendBroadcast(mifareAccessIntent, NFCEE_ADMIN_PERM); 22392c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas break; 22402c37e6a839cecf5638911af357a2ea7aec6093a5Daniel Tomas 2241f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly case MSG_LLCP_LINK_ACTIVATION: 2242d2d5dddf17ac2008547172cd72faa034a89d569bJeff Hamilton llcpActivated((NfcDepEndpoint) msg.obj); 2243f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly break; 2244f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly 2245f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly case MSG_LLCP_LINK_DEACTIVATED: 2246d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton NfcDepEndpoint device = (NfcDepEndpoint) msg.obj; 2247eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton 2248eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton Log.d(TAG, "LLCP Link Deactivated message. Restart polling loop."); 2249663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau synchronized (NfcService.this) { 2250663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau /* Check if the device has been already unregistered */ 2251663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau if (mObjectMap.remove(device.getHandle()) != null) { 2252663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau /* Disconnect if we are initiator */ 2253f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton if (device.getMode() == NfcDepEndpoint.MODE_P2P_TARGET) { 2254663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau if (DBG) Log.d(TAG, "disconnecting from target"); 2255663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau /* Restart polling loop */ 2256f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton device.disconnect(); 2257663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau } else { 2258663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau if (DBG) Log.d(TAG, "not disconnecting from initiator"); 2259663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau } 2260663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau } 2261cdab1112486288ee6ccc9eb5c55456f9618f6b9cJeff Hamilton } 2262eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton 22632ef360deaff9f17aa72d5749ceee283cc80897afBen Dodson mP2pManager.llcpDeactivated(); 2264f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly break; 2265f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly 2266f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly case MSG_TARGET_DESELECTED: 2267f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly /* Broadcast Intent Target Deselected */ 2268ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Target Deselected"); 2269f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton Intent intent = new Intent(); 2270f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton intent.setAction(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION); 2271ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Broadcasting Intent"); 2272f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton mContext.sendOrderedBroadcast(intent, NFC_PERM); 2273f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly break; 2274f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly 2275c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas case MSG_SE_FIELD_ACTIVATED:{ 2276c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas if (DBG) Log.d(TAG, "SE FIELD ACTIVATED"); 2277c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas Intent eventFieldOnIntent = new Intent(); 227849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly eventFieldOnIntent.setAction(ACTION_RF_FIELD_ON_DETECTED); 227993d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton mContext.sendBroadcast(eventFieldOnIntent, NFCEE_ADMIN_PERM); 2280c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas break; 2281c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas } 2282c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas 2283c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas case MSG_SE_FIELD_DEACTIVATED:{ 2284c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas if (DBG) Log.d(TAG, "SE FIELD DEACTIVATED"); 2285c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas Intent eventFieldOffIntent = new Intent(); 228649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly eventFieldOffIntent.setAction(ACTION_RF_FIELD_OFF_DETECTED); 228793d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton mContext.sendBroadcast(eventFieldOffIntent, NFCEE_ADMIN_PERM); 2288c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas break; 2289c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas } 2290c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas 2291f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly default: 2292f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly Log.e(TAG, "Unknown message received"); 2293f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly break; 2294f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly } 2295b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 2296d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton 2297d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton private boolean llcpActivated(NfcDepEndpoint device) { 2298d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton Log.d(TAG, "LLCP Activation message"); 2299d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton 2300d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton if (device.getMode() == NfcDepEndpoint.MODE_P2P_TARGET) { 2301d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton if (DBG) Log.d(TAG, "NativeP2pDevice.MODE_P2P_TARGET"); 2302d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton if (device.connect()) { 2303d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton /* Check LLCP compliancy */ 2304d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton if (mDeviceHost.doCheckLlcp()) { 2305d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton /* Activate LLCP Link */ 2306d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton if (mDeviceHost.doActivateLlcp()) { 2307d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton if (DBG) Log.d(TAG, "Initiator Activate LLCP OK"); 2308d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton // Register P2P device 2309d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton mObjectMap.put(device.getHandle(), device); 2310d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen // TODO this should be done decently instead, not depend on the bool 2311d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen if (mZeroClickOn) { 2312d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen mP2pManager.llcpActivated(); 2313d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen } 2314d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton return true; 2315d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton } else { 2316d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton /* should not happen */ 2317d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton Log.w(TAG, "Initiator LLCP activation failed. Disconnect."); 2318d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton device.disconnect(); 2319d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton } 2320d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton } else { 2321d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton if (DBG) Log.d(TAG, "Remote Target does not support LLCP. Disconnect."); 2322d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton device.disconnect(); 2323d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton } 2324d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton } else { 2325d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton if (DBG) Log.d(TAG, "Cannot connect remote Target. Polling loop restarted."); 2326d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton /* 2327d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton * The polling loop should have been restarted in failing 2328d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton * doConnect 2329d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton */ 2330d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton } 2331d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton } else if (device.getMode() == NfcDepEndpoint.MODE_P2P_INITIATOR) { 2332d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton if (DBG) Log.d(TAG, "NativeP2pDevice.MODE_P2P_INITIATOR"); 2333d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton /* Check LLCP compliancy */ 2334d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton if (mDeviceHost.doCheckLlcp()) { 2335d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton /* Activate LLCP Link */ 2336d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton if (mDeviceHost.doActivateLlcp()) { 2337d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton if (DBG) Log.d(TAG, "Target Activate LLCP OK"); 2338d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton // Register P2P device 2339d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton mObjectMap.put(device.getHandle(), device); 2340d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen // TODO this should be done decently instead, not depend on the bool 2341d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen if (mZeroClickOn) { 2342d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen mP2pManager.llcpActivated(); 2343d9567994fefe21743131adc7390acdb97f81ed67Martijn Coenen } 2344d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton return true; 2345d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton } 2346d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton } else { 2347d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton Log.w(TAG, "checkLlcp failed"); 2348d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton } 2349d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton } 2350d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton 2351d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton return false; 2352d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton } 2353d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton 2354f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton private void dispatchTagEndpoint(TagEndpoint tagEndpoint, NdefMessage[] msgs) { 2355f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton Tag tag = new Tag(tagEndpoint.getUid(), tagEndpoint.getTechList(), 2356f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton tagEndpoint.getTechExtras(), tagEndpoint.getHandle(), mNfcTagService); 2357f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton registerTagObject(tagEndpoint); 235876a412f47ff57ce05d84fd51adbf8e72fd37a448Nick Pelly if (!mNfcDispatcher.dispatchTag(tag, msgs)) { 2359f6c56a2191d58e3f9f68e3e7d94908b04b9b66ffJeff Hamilton unregisterObject(tagEndpoint.getHandle()); 2360d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton playSound(mErrorSound); 2361d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton } else { 2362d704c298a5a1e783c71db6f39b2eef0a909b0e88Jeff Hamilton playSound(mEndSound); 23633fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 23643fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 2365b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton } 2366b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 2367b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton private NfcServiceHandler mHandler = new NfcServiceHandler(); 236849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly 23697c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly private class EnableDisableDiscoveryTask extends AsyncTask<Boolean, Void, Void> { 2370fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 2371275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks protected Void doInBackground(Boolean... params) { 2372275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks if (DBG) Log.d(TAG, "EnableDisableDiscoveryTask: enable = " + params[0]); 2373275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks 2374275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks if (params != null && params.length > 0 && params[0]) { 2375161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly synchronized (NfcService.this) { 2376275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks if (!mScreenUnlocked) { 2377275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks mScreenUnlocked = true; 2378275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks applyRouting(); 2379275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks } else { 2380275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks if (DBG) Log.d(TAG, "Ignoring enable request"); 2381275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks } 2382161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly } 23837c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly } else { 2384533043d1003de2f6a20a29201100d94c3c7bc9caNick Pelly mWakeLock.acquire(); 2385161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly synchronized (NfcService.this) { 2386275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks if (mScreenUnlocked) { 2387275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks mScreenUnlocked = false; 2388275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks applyRouting(); 2389275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks maybeDisconnectTarget(); 2390275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks } else { 2391275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks if (DBG) Log.d(TAG, "Ignoring disable request"); 2392275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks } 2393161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly } 2394533043d1003de2f6a20a29201100d94c3c7bc9caNick Pelly mWakeLock.release(); 23957c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly } 23967c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly return null; 23977c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly } 23987c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly } 23997c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly 24000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 24010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly @Override 24020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public void onReceive(Context context, Intent intent) { 2403eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton if (intent.getAction().equals( 2404f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION)) { 2405ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "INERNAL_TARGET_DESELECTED_ACTION"); 24060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 2407f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* Restart polling loop for notification */ 240849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly applyRouting(); 2409f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 241065945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) { 2411275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks // Only enable if the screen is unlocked. If the screen is locked 2412275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks // Intent.ACTION_USER_PRESENT will be broadcast when the screen is 2413275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks // unlocked. 24146ec87aa54aad2c340c4ea0247ba4a8e0d9f10573Nick Pelly boolean enable = !mKeyguard.isKeyguardSecure() || !mKeyguard.isKeyguardLocked(); 2415275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks 24166ec87aa54aad2c340c4ea0247ba4a8e0d9f10573Nick Pelly // Perform discovery enable in thread to protect against ANR when the 24176ec87aa54aad2c340c4ea0247ba4a8e0d9f10573Nick Pelly // NFC stack wedges. This is *not* the correct way to fix this issue - 24186ec87aa54aad2c340c4ea0247ba4a8e0d9f10573Nick Pelly // configuration of the local NFC adapter should be very quick and should 24196ec87aa54aad2c340c4ea0247ba4a8e0d9f10573Nick Pelly // be safe on the main thread, and the NFC stack should not wedge. 2420275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks new EnableDisableDiscoveryTask().execute(enable); 242165945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly } else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { 24227c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly // Perform discovery disable in thread to protect against ANR when the 24237c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly // NFC stack wedges. This is *not* the correct way to fix this issue - 24247c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly // configuration of the local NFC adapter should be very quick and should 24257c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly // be safe on the main thread, and the NFC stack should not wedge. 2426275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks new EnableDisableDiscoveryTask().execute(Boolean.FALSE); 2427275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks } else if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)) { 2428275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks // The user has unlocked the screen. Enabled! 2429275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks new EnableDisableDiscoveryTask().execute(Boolean.TRUE); 2430bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } else if (intent.getAction().equals(ACTION_MASTER_CLEAR_NOTIFICATION)) { 2431a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly executeSeReset(); 2432bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } else if (intent.getAction().equals(Intent.ACTION_PACKAGE_REMOVED)) { 24337a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton boolean dataRemoved = intent.getBooleanExtra(Intent.EXTRA_DATA_REMOVED, false); 24347a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton if (dataRemoved) { 24357a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton Uri data = intent.getData(); 24367a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton if (data == null) return; 24377a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton String packageName = data.getSchemeSpecificPart(); 24387a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton 24397a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton synchronized (NfcService.this) { 244084e1e0adc2516afd35ebab029a52e764e0490559Jason parks if (mSePackages.contains(packageName)) { 2441a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly executeSeReset(); 244284e1e0adc2516afd35ebab029a52e764e0490559Jason parks mSePackages.remove(packageName); 24437a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton } 2444bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2445bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2446f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2447f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2448f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly }; 244974180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick} 2450