NfcService.java revision 2094515fca0cfa0ac87e9cc260d3953d416afe3e
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; 2124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport com.android.nfc.RegisteredComponentCache.ComponentInfo; 22ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamiltonimport com.android.nfc.ndefpush.NdefPushClient; 23ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamiltonimport com.android.nfc.ndefpush.NdefPushServer; 248afd14d3b23d3124c48ee275ba2845aede6542a1Jeff Hamiltonimport com.android.nfc3.R; 25d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton 2605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamiltonimport android.app.Activity; 271a9eca5f84036d7dd3e28000290caa2f641856deNick Pellyimport android.app.ActivityManagerNative; 282f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pellyimport android.app.Application; 2924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport android.app.IActivityManager; 3005973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamiltonimport android.app.PendingIntent; 3193d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamiltonimport android.app.PendingIntent.CanceledException; 32bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parksimport android.app.StatusBarManager; 33b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneauimport android.content.ActivityNotFoundException; 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; 4124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport android.content.pm.ResolveInfo; 423fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamiltonimport android.net.Uri; 43bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parksimport android.nfc.ApduList; 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; 573fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamiltonimport android.nfc.NdefRecord; 58f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.NfcAdapter; 590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pellyimport android.nfc.Tag; 6024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport android.nfc.TechListParcel; 619d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenenimport android.nfc.TransceiveResult; 627c034a7fe7d36b1ab039af2c44717812ea02657eNick Pellyimport android.os.AsyncTask; 63b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamiltonimport android.os.Bundle; 64b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneauimport android.os.Handler; 6549d53329a0c720a7e430220d77805bc1763545b1Nick Pellyimport android.os.IBinder; 66b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneauimport android.os.Message; 67533043d1003de2f6a20a29201100d94c3c7bc9caNick Pellyimport android.os.PowerManager; 68f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.os.RemoteException; 6913d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellyimport android.os.ServiceManager; 70f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.util.Log; 71f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 7257d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonimport java.io.ByteArrayOutputStream; 73bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parksimport java.io.DataInputStream; 74bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parksimport java.io.DataOutputStream; 7557d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonimport java.io.FileInputStream; 7657d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonimport java.io.FileNotFoundException; 7757d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonimport java.io.FileOutputStream; 7857d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonimport java.io.IOException; 793fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamiltonimport java.nio.charset.Charsets; 8024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport java.util.ArrayList; 813fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamiltonimport java.util.Arrays; 823ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamiltonimport java.util.HashMap; 832436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Feririmport java.util.Iterator; 84bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parksimport java.util.List; 853ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton 862f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pellypublic class NfcService extends Application { 87bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks private static final String ACTION_MASTER_CLEAR_NOTIFICATION = "android.intent.action.MASTER_CLEAR_NOTIFICATION"; 88bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 89ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton static final boolean DBG = false; 90fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks 9157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton private static final String MY_TAG_FILE_NAME = "mytag"; 92bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks private static final String TEAR_DOWN_SCRIPTS_FILE_NAME = "teardowns"; 9357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 9413d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly static { 9513d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly System.loadLibrary("nfc_jni"); 9613d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly } 9713d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly 983fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton /** 993fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton * NFC Forum "URI Record Type Definition" 1003fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton * 1013fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton * This is a mapping of "URI Identifier Codes" to URI string prefixes, 1023fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton * per section 3.2.2 of the NFC Forum URI Record Type Definition document. 1033fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton */ 1043fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton private static final String[] URI_PREFIX_MAP = new String[] { 1053fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "", // 0x00 1063fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "http://www.", // 0x01 1073fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "https://www.", // 0x02 1083fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "http://", // 0x03 1093fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "https://", // 0x04 1103fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "tel:", // 0x05 1113fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "mailto:", // 0x06 1123fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "ftp://anonymous:anonymous@", // 0x07 1133fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "ftp://ftp.", // 0x08 1143fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "ftps://", // 0x09 1153fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "sftp://", // 0x0A 1163fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "smb://", // 0x0B 1173fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "nfs://", // 0x0C 1183fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "ftp://", // 0x0D 1193fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "dav://", // 0x0E 1203fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "news:", // 0x0F 1213fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "telnet://", // 0x10 1223fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "imap:", // 0x11 1233fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "rtsp://", // 0x12 1243fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "urn:", // 0x13 1253fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "pop:", // 0x14 1263fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "sip:", // 0x15 1273fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "sips:", // 0x16 1283fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "tftp:", // 0x17 1293fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "btspp://", // 0x18 1303fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "btl2cap://", // 0x19 1313fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "btgoep://", // 0x1A 1323fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "tcpobex://", // 0x1B 1333fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "irdaobex://", // 0x1C 1343fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "file://", // 0x1D 1353fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "urn:epc:id:", // 0x1E 1363fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "urn:epc:tag:", // 0x1F 1373fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "urn:epc:pat:", // 0x20 1383fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "urn:epc:raw:", // 0x21 1393fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "urn:epc:", // 0x22 1403fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton }; 1413fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 142d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton public static final String SERVICE_NAME = "nfc"; 143fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks 144f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final String TAG = "NfcService"; 145f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 146bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly private static final String NFC_PERM = android.Manifest.permission.NFC; 147bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly private static final String NFC_PERM_ERROR = "NFC permission required"; 148bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly private static final String ADMIN_PERM = android.Manifest.permission.WRITE_SECURE_SETTINGS; 149bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly private static final String ADMIN_PERM_ERROR = "WRITE_SECURE_SETTINGS permission required"; 15093d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton // STOPSHIP: This needs to be updated to the line below 15193d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton// private static final String NFCEE_ADMIN_PERM = "com.android.nfc.permission.NFCEE_ADMIN"; 15293d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton private static final String NFCEE_ADMIN_PERM = NFC_PERM; 15393d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton private static final String NFCEE_ADMIN_PERM_ERROR = "NFCEE_ADMIN permission required"; 154bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF = "NfcServicePrefs"; 156f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_NFC_ON = "nfc_on"; 1580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final boolean NFC_ON_DEFAULT = true; 159f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_LLCP_LTO = "llcp_lto"; 161e1fac398523a97e3bcf513393a91478d79a8763fSylvain Fonteneau private static final int LLCP_LTO_DEFAULT = 150; 1620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int LLCP_LTO_MAX = 255; 163f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /** Maximum Information Unit */ 1650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_LLCP_MIU = "llcp_miu"; 1660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int LLCP_MIU_DEFAULT = 128; 1670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int LLCP_MIU_MAX = 2176; 168f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /** Well Known Service List */ 1700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_LLCP_WKS = "llcp_wks"; 1710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int LLCP_WKS_DEFAULT = 1; 1720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int LLCP_WKS_MAX = 15; 173f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_LLCP_OPT = "llcp_opt"; 1750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int LLCP_OPT_DEFAULT = 0; 1760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int LLCP_OPT_MAX = 3; 177f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_DISCOVERY_A = "discovery_a"; 1790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final boolean DISCOVERY_A_DEFAULT = true; 180f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_DISCOVERY_B = "discovery_b"; 1820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final boolean DISCOVERY_B_DEFAULT = true; 183f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_DISCOVERY_F = "discovery_f"; 1850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final boolean DISCOVERY_F_DEFAULT = true; 186f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_DISCOVERY_15693 = "discovery_15693"; 1880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final boolean DISCOVERY_15693_DEFAULT = true; 189f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_DISCOVERY_NFCIP = "discovery_nfcip"; 191a989351c7383aa6b3a6086b10f32c39c1d28fa5dJeff Hamilton private static final boolean DISCOVERY_NFCIP_DEFAULT = true; 192f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /** NFC Reader Discovery mode for enableDiscovery() */ 1940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int DISCOVERY_MODE_READER = 0; 195f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 196f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final int PROPERTY_LLCP_LTO = 0; 197f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final String PROPERTY_LLCP_LTO_VALUE = "llcp.lto"; 1980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int PROPERTY_LLCP_MIU = 1; 199f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final String PROPERTY_LLCP_MIU_VALUE = "llcp.miu"; 2000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int PROPERTY_LLCP_WKS = 2; 201f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final String PROPERTY_LLCP_WKS_VALUE = "llcp.wks"; 2020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int PROPERTY_LLCP_OPT = 3; 203f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final String PROPERTY_LLCP_OPT_VALUE = "llcp.opt"; 204f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final int PROPERTY_NFC_DISCOVERY_A = 4; 205f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final String PROPERTY_NFC_DISCOVERY_A_VALUE = "discovery.iso14443A"; 2060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int PROPERTY_NFC_DISCOVERY_B = 5; 207f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final String PROPERTY_NFC_DISCOVERY_B_VALUE = "discovery.iso14443B"; 2080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int PROPERTY_NFC_DISCOVERY_F = 6; 209f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final String PROPERTY_NFC_DISCOVERY_F_VALUE = "discovery.felica"; 2100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int PROPERTY_NFC_DISCOVERY_15693 = 7; 211f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final String PROPERTY_NFC_DISCOVERY_15693_VALUE = "discovery.iso15693"; 2120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int PROPERTY_NFC_DISCOVERY_NFCIP = 8; 213f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final String PROPERTY_NFC_DISCOVERY_NFCIP_VALUE = "discovery.nfcip"; 214f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 215b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau static final int MSG_NDEF_TAG = 0; 216b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau static final int MSG_CARD_EMULATION = 1; 217b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau static final int MSG_LLCP_LINK_ACTIVATION = 2; 218b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau static final int MSG_LLCP_LINK_DEACTIVATED = 3; 219b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau static final int MSG_TARGET_DESELECTED = 4; 22057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton static final int MSG_SHOW_MY_TAG_ICON = 5; 22157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton static final int MSG_HIDE_MY_TAG_ICON = 6; 222b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton static final int MSG_MOCK_NDEF = 7; 223c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas static final int MSG_SE_FIELD_ACTIVATED = 8; 224c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas static final int MSG_SE_FIELD_DEACTIVATED = 9; 225b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 22649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly // Copied from com.android.nfc_extras to avoid library dependency 22749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly // Must keep in sync with com.android.nfc_extras 22849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly static final int ROUTE_OFF = 1; 22949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly static final int ROUTE_ON_WHEN_SCREEN_ON = 2; 23049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public static final String ACTION_RF_FIELD_ON_DETECTED = 23149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly "com.android.nfc_extras.action.RF_FIELD_ON_DETECTED"; 23249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public static final String ACTION_RF_FIELD_OFF_DETECTED = 23349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly "com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED"; 23449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public static final String ACTION_AID_SELECTED = 23549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly "com.android.nfc_extras.action.AID_SELECTED"; 23649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public static final String EXTRA_AID = "com.android.nfc_extras.extra.AID"; 23749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly 23805973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton // Locked on mNfcAdapter 23905973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton PendingIntent mDispatchOverrideIntent; 24024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton IntentFilter[] mDispatchOverrideFilters; 24149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly String[][] mDispatchOverrideTechLists; 24205973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton 24374180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick // TODO: none of these appear to be synchronized but are 24474180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick // read/written from different threads (notably Binder threads)... 245f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private int mGeneratedSocketHandle = 0; 24674180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick private volatile boolean mIsNfcEnabled = false; 24749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private boolean mIsDiscoveryOn = false; 24849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly 24949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly // NFC Execution Environment 25049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly // fields below are protected by this 25149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private static final int SECURE_ELEMENT_ID = 11259375; //TODO: remove hard-coded value 2520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas private NativeNfcSecureElement mSecureElement; 25349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private OpenSecureElement mOpenEe; // null when EE closed 25449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private int mEeRoutingState; // contactless interface routing 2550bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 2562f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly // fields below are used in multiple threads and protected by synchronized(this) 2572f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly private final HashMap<Integer, Object> mObjectMap = new HashMap<Integer, Object>(); 2582f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly private final HashMap<Integer, Object> mSocketMap = new HashMap<Integer, Object>(); 25965945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly private boolean mScreenOn; 2602f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly 2612f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly // fields below are final after onCreate() 26205973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton Context mContext; 2630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private NativeNfcManager mManager; 2640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private SharedPreferences mPrefs; 2650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private SharedPreferences.Editor mPrefsEditor; 266533043d1003de2f6a20a29201100d94c3c7bc9caNick Pelly private PowerManager.WakeLock mWakeLock; 2671a9eca5f84036d7dd3e28000290caa2f641856deNick Pelly private IActivityManager mIActivityManager; 268ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton NdefPushClient mNdefPushClient; 269ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton NdefPushServer mNdefPushServer; 27024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton RegisteredComponentCache mTechListFilters; 271d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton 272d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton private static NfcService sService; 273d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton 274bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks private HashMap<String, ApduList> mTearDownApdus = new HashMap<String, ApduList>(); 275bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 27693d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton public static void enforceAdminPerm(Context context) { 27793d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton int admin = context.checkCallingOrSelfPermission(ADMIN_PERM); 27893d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton int nfcee = context.checkCallingOrSelfPermission(NFCEE_ADMIN_PERM); 27993d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton if (admin != PackageManager.PERMISSION_GRANTED 28093d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton && nfcee != PackageManager.PERMISSION_GRANTED) { 28193d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton throw new SecurityException(ADMIN_PERM_ERROR); 28293d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton } 28393d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton } 28493d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton 28593d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton public static void enforceNfceeAdminPerm(Context context) { 28693d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton context.enforceCallingOrSelfPermission(NFCEE_ADMIN_PERM, NFCEE_ADMIN_PERM_ERROR); 28793d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton } 28893d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton 289d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton public static NfcService getInstance() { 290d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton return sService; 291d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton } 292f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly @Override 2940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public void onCreate() { 2952f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly super.onCreate(); 2962f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly 2972f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly Log.i(TAG, "Starting NFC service"); 2982f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly 299d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton sService = this; 300d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton 3010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mContext = this; 302b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau mManager = new NativeNfcManager(mContext, this); 3030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.initializeNativeStructure(); 30474180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick 305ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton mNdefPushClient = new NdefPushClient(this); 306ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton mNdefPushServer = new NdefPushServer(); 30757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 30824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton mTechListFilters = new RegisteredComponentCache(this, 3098d69f5205e3c4a7c2eb869bbf4983d3d9fe45ab0Nick Pelly NfcAdapter.ACTION_TECH_DISCOVERED, NfcAdapter.ACTION_TECH_DISCOVERED); 31024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 3110bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas mSecureElement = new NativeNfcSecureElement(); 3120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 3130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefs = mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE); 3140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor = mPrefs.edit(); 315f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 316d6fdd3fbb880f1503d56616608e6823b51320dc3Nick Pelly mIsNfcEnabled = false; // real preference read later 317f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 318533043d1003de2f6a20a29201100d94c3c7bc9caNick Pelly PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE); 31952028e699e43e6322021098bbefd761fe6596747Nick Pelly mScreenOn = pm.isScreenOn(); 320533043d1003de2f6a20a29201100d94c3c7bc9caNick Pelly mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "NfcService"); 321533043d1003de2f6a20a29201100d94c3c7bc9caNick Pelly 3221a9eca5f84036d7dd3e28000290caa2f641856deNick Pelly mIActivityManager = ActivityManagerNative.getDefault(); 3231a9eca5f84036d7dd3e28000290caa2f641856deNick Pelly 324bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks readTearDownApdus(); 325bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 326d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton ServiceManager.addService(SERVICE_NAME, mNfcAdapter); 327f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 328eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton IntentFilter filter = new IntentFilter(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION); 32965945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly filter.addAction(Intent.ACTION_SCREEN_OFF); 33065945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly filter.addAction(Intent.ACTION_SCREEN_ON); 331bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks filter.addAction(ACTION_MASTER_CLEAR_NOTIFICATION); 332bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks mContext.registerReceiver(mReceiver, filter); 333bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 334bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks filter = new IntentFilter(); 335bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks filter.addAction(Intent.ACTION_PACKAGE_REMOVED); 336bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks filter.addDataScheme("package"); 337bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 3380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mContext.registerReceiver(mReceiver, filter); 3390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 3400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly Thread t = new Thread() { 3410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly @Override 3420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public void run() { 3430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean nfc_on = mPrefs.getBoolean(PREF_NFC_ON, NFC_ON_DEFAULT); 3440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (nfc_on) { 3450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly _enable(false); 346f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 347f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 3480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly }; 3490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly t.start(); 3500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 3510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 3520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly @Override 3532f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly public void onTerminate() { 3542f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly super.onTerminate(); 3552f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly // NFC application is persistent, it should not be destroyed by framework 3560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly Log.wtf(TAG, "NFC service is under attack!"); 3570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 3580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 3590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private final INfcAdapter.Stub mNfcAdapter = new INfcAdapter.Stub() { 3603ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton /** Protected by "this" */ 3613ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton NdefMessage mLocalMessage = null; 3624acf84356e35861f7df6d07a2b9ff84842a9f221Nick Pelly 363fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 3640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public boolean enable() throws RemoteException { 36593d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton NfcService.enforceAdminPerm(mContext); 3660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 3670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean isSuccess = false; 3680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean previouslyEnabled = isEnabled(); 3690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!previouslyEnabled) { 3700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly reset(); 3710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly isSuccess = _enable(previouslyEnabled); 372f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 3730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return isSuccess; 374f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 375f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 376fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 3770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public boolean disable() throws RemoteException { 3780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean isSuccess = false; 37993d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton NfcService.enforceAdminPerm(mContext); 3800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean previouslyEnabled = isEnabled(); 381ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Disabling NFC. previous=" + previouslyEnabled); 3820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 3830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (previouslyEnabled) { 3846f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton /* tear down the my tag server */ 385ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton mNdefPushServer.stop(); 386e260fc52ed2b4e6e1b7394d6f841d01c98888327Arnaud Ferir 387e260fc52ed2b4e6e1b7394d6f841d01c98888327Arnaud Ferir // Stop watchdog if tag present 388e260fc52ed2b4e6e1b7394d6f841d01c98888327Arnaud Ferir // A convenient way to stop the watchdog properly consists of 389e260fc52ed2b4e6e1b7394d6f841d01c98888327Arnaud Ferir // disconnecting the tag. The polling loop shall be stopped before 390e260fc52ed2b4e6e1b7394d6f841d01c98888327Arnaud Ferir // to avoid the tag being discovered again. 39149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mIsDiscoveryOn = false; 39249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly applyRouting(); 393e260fc52ed2b4e6e1b7394d6f841d01c98888327Arnaud Ferir maybeDisconnectTarget(); 394e260fc52ed2b4e6e1b7394d6f841d01c98888327Arnaud Ferir 3950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly isSuccess = mManager.deinitialize(); 396ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "NFC success of deinitialize = " + isSuccess); 3970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (isSuccess) { 3980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mIsNfcEnabled = false; 399a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // Clear out any old dispatch overrides and NDEF push message 40005973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton synchronized (this) { 40105973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton mDispatchOverrideFilters = null; 40205973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton mDispatchOverrideIntent = null; 40305973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 404a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton mNdefPushClient.setForegroundMessage(null); 4050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 406f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 4070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 4080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly updateNfcOnSetting(previouslyEnabled); 4090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 4100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return isSuccess; 411f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 412f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 413fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 41405973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton public void enableForegroundDispatch(ComponentName activity, PendingIntent intent, 41524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton IntentFilter[] filters, TechListParcel techListsParcel) { 416a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // Permission check 41705973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 418a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton 419a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // Argument validation 420a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (activity == null || intent == null) { 421ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton throw new IllegalArgumentException(); 422ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton } 423a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton 424a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // Validate the IntentFilters 425a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (filters != null) { 426a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (filters.length == 0) { 427a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton filters = null; 428a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } else { 429a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton for (IntentFilter filter : filters) { 430a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (filter == null) { 431a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton throw new IllegalArgumentException("null IntentFilter"); 432a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } 433a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } 434a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } 435a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } 436a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton 43724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // Validate the tech lists 43824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton String[][] techLists = null; 43924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (techListsParcel != null) { 44024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton techLists = techListsParcel.getTechLists(); 44124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 44249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly 44305973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton synchronized (this) { 444a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (mDispatchOverrideIntent != null) { 44505973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton Log.e(TAG, "Replacing active dispatch overrides"); 44605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 44705973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton mDispatchOverrideIntent = intent; 448a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton mDispatchOverrideFilters = filters; 44924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton mDispatchOverrideTechLists = techLists; 45005973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 45105973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 45205973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton 45305973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton @Override 45405973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton public void disableForegroundDispatch(ComponentName activity) { 45505973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 45605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton synchronized (this) { 457a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (mDispatchOverrideIntent == null) { 45805973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton Log.e(TAG, "No active foreground dispatching"); 45905973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 46005973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton mDispatchOverrideIntent = null; 461a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton mDispatchOverrideFilters = null; 46205973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 46305973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 46405973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton 46505973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton @Override 466ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton public void enableForegroundNdefPush(ComponentName activity, NdefMessage msg) { 467ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 468ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton if (activity == null || msg == null) { 469ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton throw new IllegalArgumentException(); 470ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton } 471ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton if (mNdefPushClient.setForegroundMessage(msg)) { 472ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton Log.e(TAG, "Replacing active NDEF push message"); 473ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton } 474ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton } 475ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton 476ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton @Override 4772094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks public void enableForegroundNdefPushWithCallback(ComponentName activity, 4782094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks INdefPushCallback callback) { 4792094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 4802094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks if (activity == null || callback == null) { 4812094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks throw new IllegalArgumentException(); 4822094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks } 4832094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks if (mNdefPushClient.setForegroundCallback(callback)) { 4842094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks Log.e(TAG, "Replacing active NDEF push message"); 4852094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks } 4862094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks } 4872094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks 4882094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks @Override 489ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton public void disableForegroundNdefPush(ComponentName activity) { 490ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 4912094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks boolean hadMsg = mNdefPushClient.setForegroundMessage(null); 4922094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks boolean hadCallback = mNdefPushClient.setForegroundCallback(null); 4932094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks if (!hadMsg || !hadCallback) { 494ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton Log.e(TAG, "No active foreground NDEF push message"); 495ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton } 496ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton } 497ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton 498ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton @Override 4990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int createLlcpConnectionlessSocket(int sap) throws RemoteException { 500d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 501bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 502f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 503f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 504f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 505f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 506f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 5070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Check SAP is not already used */ 5080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 5091878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Store the socket handle */ 5101878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau int sockeHandle = mGeneratedSocketHandle; 5111878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau NativeLlcpConnectionlessSocket socket; 512f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 5131878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau socket = mManager.doCreateLlcpConnectionlessSocket(sap); 5141878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau if (socket != null) { 5151878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau synchronized(NfcService.this) { 5161878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* update socket handle generation */ 5171878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mGeneratedSocketHandle++; 5180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 5191878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Add the socket into the socket map */ 5201878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mSocketMap.put(mGeneratedSocketHandle, socket); 5211878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return mGeneratedSocketHandle; 522f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 523f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 5241878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Get Error Status */ 5251878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau int errorStatus = mManager.doGetLastError(); 5261878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau 5271878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau switch (errorStatus) { 5281878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau case ErrorCodes.ERROR_BUFFER_TO_SMALL: 5291878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_BUFFER_TO_SMALL; 5301878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES: 5311878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; 5321878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau default: 5331878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_SOCKET_CREATION; 5341878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau } 535f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 536f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 537f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 538fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 5390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int createLlcpServiceSocket(int sap, String sn, int miu, int rw, int linearBufferLength) 5400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly throws RemoteException { 541d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 542bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 543f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 544f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 545f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 546f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 547f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 5481878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau NativeLlcpServiceSocket socket; 5490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 5501878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau socket = mManager.doCreateLlcpServiceSocket(sap, sn, miu, rw, linearBufferLength); 5511878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau if (socket != null) { 5521878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau synchronized(NfcService.this) { 5531878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* update socket handle generation */ 5541878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mGeneratedSocketHandle++; 5550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 5561878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Add the socket into the socket map */ 5571878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mSocketMap.put(mGeneratedSocketHandle, socket); 5581878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return mGeneratedSocketHandle; 559f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 560f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 5611878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Get Error Status */ 5621878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau int errorStatus = mManager.doGetLastError(); 5631878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau 5641878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau switch (errorStatus) { 5651878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau case ErrorCodes.ERROR_BUFFER_TO_SMALL: 5661878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_BUFFER_TO_SMALL; 5671878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES: 5681878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; 5691878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau default: 5701878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_SOCKET_CREATION; 5711878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau } 572f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 573f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 574f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 575fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 5760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int createLlcpSocket(int sap, int miu, int rw, int linearBufferLength) 5770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly throws RemoteException { 578d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 579bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 580f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 581f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 582f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 583f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 584f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 5851878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau if (DBG) Log.d(TAG, "creating llcp socket"); 5861878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau NativeLlcpSocket socket; 587bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 5881878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau socket = mManager.doCreateLlcpSocket(sap, miu, rw, linearBufferLength); 589f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 5901878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau if (socket != null) { 5911878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau synchronized(NfcService.this) { 5921878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* update socket handle generation */ 5931878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mGeneratedSocketHandle++; 5940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 5951878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Add the socket into the socket map */ 5961878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mSocketMap.put(mGeneratedSocketHandle, socket); 5971878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return mGeneratedSocketHandle; 5980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 599f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 6001878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Get Error Status */ 6011878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau int errorStatus = mManager.doGetLastError(); 6021878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau 6031878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau Log.d(TAG, "failed to create llcp socket: " + ErrorCodes.asString(errorStatus)); 6041878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau 6051878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau switch (errorStatus) { 6061878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau case ErrorCodes.ERROR_BUFFER_TO_SMALL: 6071878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_BUFFER_TO_SMALL; 6081878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES: 6091878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; 6101878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau default: 6111878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_SOCKET_CREATION; 6121878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau } 613f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 614f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 615f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 616fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public ILlcpConnectionlessSocket getLlcpConnectionlessInterface() throws RemoteException { 618d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 6190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return mLlcpConnectionlessSocketService; 6200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 621bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 622fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public ILlcpSocket getLlcpInterface() throws RemoteException { 624d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 6250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return mLlcpSocket; 6260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 627f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 628fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public ILlcpServiceSocket getLlcpServiceInterface() throws RemoteException { 630d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 6310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return mLlcpServerSocketService; 6320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 633f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 634fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public INfcTag getNfcTagInterface() throws RemoteException { 636d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 6370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return mNfcTagService; 6380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 6390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 640fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public IP2pInitiator getP2pInitiatorInterface() throws RemoteException { 642d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 6430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return mP2pInitiatorService; 6440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 6450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 646fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public IP2pTarget getP2pTargetInterface() throws RemoteException { 648d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 6490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return mP2pTargetService; 6500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 6510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 652bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks @Override 65349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public INfcAdapterExtras getNfcAdapterExtrasInterface() { 65493d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton NfcService.enforceNfceeAdminPerm(mContext); 65549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly return mExtrasService; 6560bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 6570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 658fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public String getProperties(String param) throws RemoteException { 660d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 6610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 6620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (param == null) { 6630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 6640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 6650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 6660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (param.equals(PROPERTY_LLCP_LTO_VALUE)) { 6670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return Integer.toString(mPrefs.getInt(PREF_LLCP_LTO, LLCP_LTO_DEFAULT)); 6680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_LLCP_MIU_VALUE)) { 6690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return Integer.toString(mPrefs.getInt(PREF_LLCP_MIU, LLCP_MIU_DEFAULT)); 6700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_LLCP_WKS_VALUE)) { 6710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return Integer.toString(mPrefs.getInt(PREF_LLCP_WKS, LLCP_WKS_DEFAULT)); 6720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_LLCP_OPT_VALUE)) { 6730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return Integer.toString(mPrefs.getInt(PREF_LLCP_OPT, LLCP_OPT_DEFAULT)); 6740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_NFC_DISCOVERY_A_VALUE)) { 6750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_A, DISCOVERY_A_DEFAULT)); 6760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_NFC_DISCOVERY_B_VALUE)) { 6770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_B, DISCOVERY_B_DEFAULT)); 6780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_NFC_DISCOVERY_F_VALUE)) { 6790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_F, DISCOVERY_F_DEFAULT)); 6800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_NFC_DISCOVERY_NFCIP_VALUE)) { 6810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_NFCIP, DISCOVERY_NFCIP_DEFAULT)); 6820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_NFC_DISCOVERY_15693_VALUE)) { 6830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_15693, DISCOVERY_15693_DEFAULT)); 684f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 6850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return "Unknown property"; 686f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 687f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 688f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 689fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public boolean isEnabled() throws RemoteException { 6910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return mIsNfcEnabled; 6920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 6930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 694fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int setProperties(String param, String value) throws RemoteException { 69693d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton NfcService.enforceAdminPerm(mContext); 6970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 6980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (isEnabled()) { 6990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NFC_ON; 7000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 7010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly int val; 7030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Check params validity */ 7050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (param == null || value == null) { 7060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_INVALID_PARAM; 7070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 7080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (param.equals(PROPERTY_LLCP_LTO_VALUE)) { 7100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly val = Integer.parseInt(value); 7110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Check params */ 7130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (val > LLCP_LTO_MAX) 7140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_INVALID_PARAM; 7150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Store value */ 7170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putInt(PREF_LLCP_LTO, val); 7182f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 7190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Update JNI */ 7210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.doSetProperties(PROPERTY_LLCP_LTO, val); 7220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_LLCP_MIU_VALUE)) { 7240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly val = Integer.parseInt(value); 7250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Check params */ 7270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if ((val < LLCP_MIU_DEFAULT) || (val > LLCP_MIU_MAX)) 7280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_INVALID_PARAM; 7290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Store value */ 7310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putInt(PREF_LLCP_MIU, val); 7322f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 7330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Update JNI */ 7350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.doSetProperties(PROPERTY_LLCP_MIU, val); 7360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_LLCP_WKS_VALUE)) { 7380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly val = Integer.parseInt(value); 7390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Check params */ 7410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (val > LLCP_WKS_MAX) 7420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_INVALID_PARAM; 7430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Store value */ 7450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putInt(PREF_LLCP_WKS, val); 7462f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 7470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Update JNI */ 7490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.doSetProperties(PROPERTY_LLCP_WKS, val); 7500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_LLCP_OPT_VALUE)) { 7520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly val = Integer.parseInt(value); 7530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Check params */ 7550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (val > LLCP_OPT_MAX) 7560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_INVALID_PARAM; 7570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Store value */ 7590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putInt(PREF_LLCP_OPT, val); 7602f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 7610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Update JNI */ 7630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.doSetProperties(PROPERTY_LLCP_OPT, val); 7640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_NFC_DISCOVERY_A_VALUE)) { 7660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean b = Boolean.parseBoolean(value); 7670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Store value */ 7690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putBoolean(PREF_DISCOVERY_A, b); 7702f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 7710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Update JNI */ 7730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_A, b ? 1 : 0); 7740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_NFC_DISCOVERY_B_VALUE)) { 7760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean b = Boolean.parseBoolean(value); 7770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Store value */ 7790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putBoolean(PREF_DISCOVERY_B, b); 7802f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 7810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Update JNI */ 7830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_B, b ? 1 : 0); 7840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_NFC_DISCOVERY_F_VALUE)) { 7860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean b = Boolean.parseBoolean(value); 7870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Store value */ 7890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putBoolean(PREF_DISCOVERY_F, b); 7902f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 7910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Update JNI */ 7930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_F, b ? 1 : 0); 7940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_NFC_DISCOVERY_15693_VALUE)) { 7960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean b = Boolean.parseBoolean(value); 7970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Store value */ 7990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putBoolean(PREF_DISCOVERY_15693, b); 8002f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 8010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Update JNI */ 8030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_15693, b ? 1 : 0); 8040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_NFC_DISCOVERY_NFCIP_VALUE)) { 8060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean b = Boolean.parseBoolean(value); 8070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Store value */ 8090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putBoolean(PREF_DISCOVERY_NFCIP, b); 8102f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 8110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Update JNI */ 8130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_NFCIP, b ? 1 : 0); 8140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 815f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 8160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_INVALID_PARAM; 817f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 8180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.SUCCESS; 820f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 821d65348455ae09a467f288d65dbf924fc60c8d290Jeff Hamilton 822d65348455ae09a467f288d65dbf924fc60c8d290Jeff Hamilton @Override 823d65348455ae09a467f288d65dbf924fc60c8d290Jeff Hamilton public NdefMessage localGet() throws RemoteException { 82457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 82557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 82657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton synchronized (this) { 82757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton return mLocalMessage; 82857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 829d65348455ae09a467f288d65dbf924fc60c8d290Jeff Hamilton } 830d65348455ae09a467f288d65dbf924fc60c8d290Jeff Hamilton 831d65348455ae09a467f288d65dbf924fc60c8d290Jeff Hamilton @Override 832d65348455ae09a467f288d65dbf924fc60c8d290Jeff Hamilton public void localSet(NdefMessage message) throws RemoteException { 83393d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton NfcService.enforceAdminPerm(mContext); 83457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 83557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton synchronized (this) { 83657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton mLocalMessage = message; 83757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Context context = NfcService.this.getApplicationContext(); 83857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 83957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton // Send a message to the UI thread to show or hide the icon so the requests are 84057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton // serialized and the icon can't get out of sync with reality. 84157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton if (message != null) { 84257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton FileOutputStream out = null; 84357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 84457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton try { 84557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton out = context.openFileOutput(MY_TAG_FILE_NAME, Context.MODE_PRIVATE); 84657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton byte[] bytes = message.toByteArray(); 84757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton if (bytes.length == 0) { 84857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Log.w(TAG, "Setting a empty mytag"); 84957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 85057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 85157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton out.write(bytes); 85257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } catch (IOException e) { 85357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Log.e(TAG, "Could not write mytag file", e); 85457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } finally { 85557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton try { 85657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton if (out != null) { 85757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton out.flush(); 85857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton out.close(); 85957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 86057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } catch (IOException e) { 86157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton // Ignore 86257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 86357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 86457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 86557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton // Only show the icon if NFC is enabled. 86657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton if (mIsNfcEnabled) { 86757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton sendMessage(MSG_SHOW_MY_TAG_ICON, null); 86857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 86957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } else { 87057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton context.deleteFile(MY_TAG_FILE_NAME); 87157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton sendMessage(MSG_HIDE_MY_TAG_ICON, null); 87257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 87357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 874d65348455ae09a467f288d65dbf924fc60c8d290Jeff Hamilton } 8750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly }; 8760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private final ILlcpSocket mLlcpSocket = new ILlcpSocket.Stub() { 878f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau 879f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau private NativeLlcpSocket findSocket(int nativeHandle) { 880bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly Object socket = NfcService.this.findSocket(nativeHandle); 881bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly if (!(socket instanceof NativeLlcpSocket)) { 882f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau return null; 883f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau } 884bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly return (NativeLlcpSocket) socket; 885f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau } 886f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau 887fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 8880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int close(int nativeHandle) throws RemoteException { 889d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 890bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 891f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeLlcpSocket socket = null; 892f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 893f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 894f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 895f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 896f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 897f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 898f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 899f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 900f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 9011878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau socket.doClose(); 9021878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Remove the socket closed from the hmap */ 9031878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau RemoveSocket(nativeHandle); 9041878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.SUCCESS; 905f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 9060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_IO; 907f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 908f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 909f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 910fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 9110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int connect(int nativeHandle, int sap) throws RemoteException { 912d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 913bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 914f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeLlcpSocket socket = null; 9150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean isSuccess = false; 916f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 917f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 918f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 919f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 920f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 921f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 922f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 923f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 924f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 92593915e1c6fe6d5d16fcebeda610782bf5812c9b4Nick Pelly isSuccess = socket.doConnect(sap); 9260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (isSuccess) { 9270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.SUCCESS; 928f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 929f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 930f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 931f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 932f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 933f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 9340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 935f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 936f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 937fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 9380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int connectByName(int nativeHandle, String sn) throws RemoteException { 939d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 940bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 941f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeLlcpSocket socket = null; 942f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly boolean isSuccess = false; 943f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 944f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 945f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 946f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 947f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 948f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 949f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 950f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 951f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 95293915e1c6fe6d5d16fcebeda610782bf5812c9b4Nick Pelly isSuccess = socket.doConnectBy(sn); 953f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (isSuccess) { 954f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.SUCCESS; 955f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 956f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 957f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 958f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 959f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 960f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 9610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 962f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 963f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 964fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 9650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int getLocalSap(int nativeHandle) throws RemoteException { 966d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 967bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 9680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket socket = null; 969f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 970f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 971f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 972f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 973f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 974f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 9750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the socket in the hmap */ 976f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 9770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 9780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return socket.getSap(); 979f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 9800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return 0; 981f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 982f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 983f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 984fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 9850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int getLocalSocketMiu(int nativeHandle) throws RemoteException { 986d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 987bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 9880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket socket = null; 989f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 990f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 991f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 9920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 993f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 994f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 995f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 996f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 997f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 9980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return socket.getMiu(); 9990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 10000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return 0; 1001f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1002f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1003f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1004fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 10050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int getLocalSocketRw(int nativeHandle) throws RemoteException { 1006d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1007bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 10080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket socket = null; 1009f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1010f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1011f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1012f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 1013f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1014f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1015f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 1016f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 10170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 10180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return socket.getRw(); 10190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 10200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return 0; 10210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 1024fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 10250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int getRemoteSocketMiu(int nativeHandle) throws RemoteException { 1026d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 10270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 10280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket socket = null; 10290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 10300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 10310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 10320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 10330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 10350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the socket in the hmap */ 1036f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 10370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 10380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket.doGetRemoteSocketMiu() != 0) { 10390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return socket.doGetRemoteSocketMiu(); 10400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 10410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED; 10420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 10440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED; 10450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 1048fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 10490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int getRemoteSocketRw(int nativeHandle) throws RemoteException { 1050d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 10510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 10520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket socket = null; 10530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 10540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 10550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 10560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 10570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 10590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the socket in the hmap */ 1060f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 10610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 10620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket.doGetRemoteSocketRw() != 0) { 10630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return socket.doGetRemoteSocketRw(); 10640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 10650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED; 10660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 10680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED; 10690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 1072fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 10730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int receive(int nativeHandle, byte[] receiveBuffer) throws RemoteException { 1074d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 10750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 10760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket socket = null; 10770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 10780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 10790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 10800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 10810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 10830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the socket in the hmap */ 1084f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 10850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 108628f72bd9880d0b00c486603489d3862733eb638fSylvain Fonteneau return socket.doReceive(receiveBuffer); 10870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 108828f72bd9880d0b00c486603489d3862733eb638fSylvain Fonteneau return 0; 10890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 1092fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 10930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int send(int nativeHandle, byte[] data) throws RemoteException { 1094d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 10950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 10960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket socket = null; 10970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean isSuccess = false; 10980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 10990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 11000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 11010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 11020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the socket in the hmap */ 1105f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 11060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 11070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly isSuccess = socket.doSend(data); 11080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (isSuccess) { 11090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.SUCCESS; 11100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 11110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_IO; 11120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 11140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_IO; 11150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly }; 11180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private final ILlcpServiceSocket mLlcpServerSocketService = new ILlcpServiceSocket.Stub() { 11200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 1121f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau private NativeLlcpServiceSocket findSocket(int nativeHandle) { 1122bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly Object socket = NfcService.this.findSocket(nativeHandle); 1123bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly if (!(socket instanceof NativeLlcpServiceSocket)) { 1124f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau return null; 1125f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau } 1126bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly return (NativeLlcpServiceSocket) socket; 1127f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau } 1128f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau 1129fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 11300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int accept(int nativeHandle) throws RemoteException { 1131d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 11320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpServiceSocket socket = null; 11340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket clientSocket = null; 11350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 11370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 11380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 11390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the socket in the hmap */ 1142f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 11430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 114493915e1c6fe6d5d16fcebeda610782bf5812c9b4Nick Pelly clientSocket = socket.doAccept(socket.getMiu(), 11450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly socket.getRw(), socket.getLinearBufferLength()); 11460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (clientSocket != null) { 11470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Add the socket into the socket map */ 11482f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly synchronized(this) { 11491878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mGeneratedSocketHandle++; 11501878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mSocketMap.put(mGeneratedSocketHandle, clientSocket); 11511878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return mGeneratedSocketHandle; 11522f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly } 11530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 11540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_IO; 11550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 11570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_IO; 11580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 1161fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 11620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public void close(int nativeHandle) throws RemoteException { 1163d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 11640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpServiceSocket socket = null; 11660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 11680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 11690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return; 11700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the socket in the hmap */ 1173f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 11740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 11751878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau socket.doClose(); 1176f63da5f0887eba86d877faaee41dc5dfb8fccd50Jeff Hamilton synchronized (this) { 11770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Remove the socket closed from the hmap */ 11780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly RemoveSocket(nativeHandle); 11790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1182f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly }; 1183f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1184f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private final ILlcpConnectionlessSocket mLlcpConnectionlessSocketService = new ILlcpConnectionlessSocket.Stub() { 1185f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1186f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau private NativeLlcpConnectionlessSocket findSocket(int nativeHandle) { 1187bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly Object socket = NfcService.this.findSocket(nativeHandle); 1188bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly if (!(socket instanceof NativeLlcpConnectionlessSocket)) { 1189f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau return null; 1190f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau } 1191bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly return (NativeLlcpConnectionlessSocket) socket; 1192f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau } 1193f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau 1194fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1195f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public void close(int nativeHandle) throws RemoteException { 1196d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1197bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1198f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeLlcpConnectionlessSocket socket = null; 1199f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1200f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1201f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1202f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return; 1203f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1204f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1205f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 1206f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 1207f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 12081878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau socket.doClose(); 12091878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Remove the socket closed from the hmap */ 12101878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau RemoveSocket(nativeHandle); 1211f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1212f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1213f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1214fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1215f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public int getSap(int nativeHandle) throws RemoteException { 1216d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1217bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1218f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeLlcpConnectionlessSocket socket = null; 1219f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1220f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1221f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1222f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 1223f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1224f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1225f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 1226f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 1227f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 1228f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return socket.getSap(); 1229f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 1230f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return 0; 1231f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1232f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1233f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1234fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1235f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public LlcpPacket receiveFrom(int nativeHandle) throws RemoteException { 1236d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1237bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1238f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeLlcpConnectionlessSocket socket = null; 1239f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly LlcpPacket packet; 1240f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1241f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1242f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1243f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1244f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1245f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1246f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 1247f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 1248f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 1249f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly packet = socket.doReceiveFrom(socket.getLinkMiu()); 1250f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (packet != null) { 1251f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return packet; 1252f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1253f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1254f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 1255f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1256f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1257f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1258f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1259fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1260f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public int sendTo(int nativeHandle, LlcpPacket packet) throws RemoteException { 1261d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1262bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1263f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeLlcpConnectionlessSocket socket = null; 1264f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly boolean isSuccess = false; 1265f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1266f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1267f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1268f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 1269f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1270f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1271f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 1272f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 1273f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 1274f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly isSuccess = socket.doSendTo(packet.getRemoteSap(), packet.getDataBuffer()); 1275f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (isSuccess) { 1276f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.SUCCESS; 1277f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 1278f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 1279f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1280f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 1281f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 1282f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1283f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1284f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly }; 1285f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1286f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private final INfcTag mNfcTagService = new INfcTag.Stub() { 1287f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1288fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1289f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public int close(int nativeHandle) throws RemoteException { 1290d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1291bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1292f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeNfcTag tag = null; 1293f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1294f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1295f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1296f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 1297f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1298f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1299f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1300f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly tag = (NativeNfcTag) findObject(nativeHandle); 1301f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (tag != null) { 1302b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau /* Remove the device from the hmap */ 1303b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau unregisterObject(nativeHandle); 130421545af22f9b913ec9cb124287aab2fcb0cf2b3bNick Pelly tag.disconnect(); 1305b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau return ErrorCodes.SUCCESS; 1306f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1307f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* Restart polling loop for notification */ 130849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly applyRouting(); 1309f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_DISCONNECT; 1310f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1311f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1312fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1313ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen public int connect(int nativeHandle, int technology) throws RemoteException { 1314d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1315bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1316f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeNfcTag tag = null; 1317f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1318f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1319f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1320f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 1321f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1322f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1323f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1324f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly tag = (NativeNfcTag) findObject(nativeHandle); 1325b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau if (tag == null) { 1326b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau return ErrorCodes.ERROR_DISCONNECT; 1327f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1328ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen 1329ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen // Note that on most tags, all technologies are behind a single 1330ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen // handle. This means that the connect at the lower levels 1331ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen // will do nothing, as the tag is already connected to that handle. 1332ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen if (tag.connect(technology)) { 1333ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen return ErrorCodes.SUCCESS; 1334ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen } else { 1335ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen return ErrorCodes.ERROR_DISCONNECT; 1336ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen } 1337f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1338f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1339fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1340aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen public int reconnect(int nativeHandle) throws RemoteException { 1341aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1342aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen 1343aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen NativeNfcTag tag = null; 1344aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen 1345aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen // Check if NFC is enabled 1346aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen if (!mIsNfcEnabled) { 1347aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen return ErrorCodes.ERROR_NOT_INITIALIZED; 1348aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen } 1349aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen 1350aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen /* find the tag in the hmap */ 1351aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen tag = (NativeNfcTag) findObject(nativeHandle); 1352aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen if (tag != null) { 1353aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen if (tag.reconnect()) { 1354aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen return ErrorCodes.SUCCESS; 1355aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen } else { 1356aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen return ErrorCodes.ERROR_DISCONNECT; 1357aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen } 1358aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen } 1359aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen return ErrorCodes.ERROR_DISCONNECT; 1360aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen } 1361aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen 1362aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen @Override 1363b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton public int[] getTechList(int nativeHandle) throws RemoteException { 1364d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1365bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1366f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1367f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1368f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1369f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1370f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1371f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1372b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton NativeNfcTag tag = (NativeNfcTag) findObject(nativeHandle); 1373f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (tag != null) { 1374b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton return tag.getTechList(); 1375f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1376f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1377f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1378f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1379fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1380f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public byte[] getUid(int nativeHandle) throws RemoteException { 1381f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeNfcTag tag = null; 1382f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly byte[] uid; 1383f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1384f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1385f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1386f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1387f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1388f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1389f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1390f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly tag = (NativeNfcTag) findObject(nativeHandle); 1391f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (tag != null) { 1392f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly uid = tag.getUid(); 1393f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return uid; 1394f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1395f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1396f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1397f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1398fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1399b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau public boolean isPresent(int nativeHandle) throws RemoteException { 1400b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau NativeNfcTag tag = null; 1401b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 1402b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau // Check if NFC is enabled 1403b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau if (!mIsNfcEnabled) { 1404b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau return false; 1405b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 1406b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 1407b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau /* find the tag in the hmap */ 1408b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau tag = (NativeNfcTag) findObject(nativeHandle); 1409b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau if (tag == null) { 1410b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau return false; 1411b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 1412b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 1413ab2b44b97936d2c5dbf6eda1245ca793e840713fMartijn Coenen return tag.isPresent(); 1414b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 1415b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 1416fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1417f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public boolean isNdef(int nativeHandle) throws RemoteException { 1418f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeNfcTag tag = null; 1419f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly boolean isSuccess = false; 1420f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1421f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1422f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1423f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return isSuccess; 1424f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1425f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1426f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1427f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly tag = (NativeNfcTag) findObject(nativeHandle); 14283ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen int[] ndefInfo = new int[2]; 1429f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (tag != null) { 14303ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen isSuccess = tag.checkNdef(ndefInfo); 1431f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1432f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return isSuccess; 1433f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1434f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1435fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 14369d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen public TransceiveResult transceive(int nativeHandle, byte[] data, boolean raw) 143797c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen throws RemoteException { 1438d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1439bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1440f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeNfcTag tag = null; 1441f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly byte[] response; 1442f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1443f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1444f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1445f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1446f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1447f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1448f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1449f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly tag = (NativeNfcTag) findObject(nativeHandle); 1450f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (tag != null) { 14519d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen int[] targetLost = new int[1]; 14529d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen response = tag.transceive(data, raw, targetLost); 14539d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen TransceiveResult transResult = new TransceiveResult( 14549d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen (response != null) ? true : false, 14559d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen (targetLost[0] == 1) ? true : false, 14569d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen response); 14579d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen return transResult; 1458f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1459f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1460f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1461f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1462fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 14633fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton public NdefMessage ndefRead(int nativeHandle) throws RemoteException { 1464d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1465bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1466f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeNfcTag tag; 1467f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1468f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1469f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1470f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1471f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1472f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1473f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1474f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly tag = (NativeNfcTag) findObject(nativeHandle); 1475f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (tag != null) { 1476b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau byte[] buf = tag.read(); 1477f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (buf == null) 1478f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1479f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1480f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* Create an NdefMessage */ 1481f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly try { 1482f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return new NdefMessage(buf); 1483f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } catch (FormatException e) { 1484f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1485f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1486f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1487f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1488f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1489f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1490fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 14913fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton public int ndefWrite(int nativeHandle, NdefMessage msg) throws RemoteException { 1492d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1493bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1494f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeNfcTag tag; 1495f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1496f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1497f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1498f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 1499f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1500f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1501f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1502f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly tag = (NativeNfcTag) findObject(nativeHandle); 1503f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (tag == null) { 1504f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 1505f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1506f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1507b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau if (tag.write(msg.toByteArray())) { 1508f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.SUCCESS; 1509f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1510f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly else { 1511f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 1512f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1513f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1514f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1515f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1516fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1517f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public int getLastError(int nativeHandle) throws RemoteException { 1518bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen return(mManager.doGetLastError()); 1519f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1520f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1521fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 15223fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton public boolean ndefIsWritable(int nativeHandle) throws RemoteException { 15233fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton throw new UnsupportedOperationException(); 1524f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1525f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1526fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 15273fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton public int ndefMakeReadOnly(int nativeHandle) throws RemoteException { 152803ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 152903ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen 153003ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen NativeNfcTag tag; 153103ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen 153203ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen // Check if NFC is enabled 153303ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen if (!mIsNfcEnabled) { 153403ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen return ErrorCodes.ERROR_NOT_INITIALIZED; 153503ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen } 153603ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen 153703ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen /* find the tag in the hmap */ 153803ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen tag = (NativeNfcTag) findObject(nativeHandle); 153903ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen if (tag == null) { 154003ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen return ErrorCodes.ERROR_IO; 154103ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen } 154203ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen 154303ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen if (tag.makeReadonly()) { 154403ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen return ErrorCodes.SUCCESS; 154503ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen } 154603ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen else { 154703ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen return ErrorCodes.ERROR_IO; 154803ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen } 1549f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1550f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 15510aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen @Override 15520aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen public int formatNdef(int nativeHandle, byte[] key) throws RemoteException { 15530aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 15540aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen 15550aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen NativeNfcTag tag; 15560aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen 15570aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen // Check if NFC is enabled 15580aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen if (!mIsNfcEnabled) { 15590aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen return ErrorCodes.ERROR_NOT_INITIALIZED; 15600aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen } 15610aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen 15620aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen /* find the tag in the hmap */ 15630aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen tag = (NativeNfcTag) findObject(nativeHandle); 15640aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen if (tag == null) { 15650aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen return ErrorCodes.ERROR_IO; 15660aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen } 15670aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen 15680aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen if (tag.formatNdef(key)) { 15690aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen return ErrorCodes.SUCCESS; 15700aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen } 15710aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen else { 15720aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen return ErrorCodes.ERROR_IO; 15730aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen } 15740aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen } 15750aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen 15761b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen @Override 15771b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen public void setIsoDepTimeout(int timeout) throws RemoteException { 15781b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 15791b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen 15801b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen mManager.setIsoDepTimeout(timeout); 15811b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen } 1582f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 15831b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen @Override 15841b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen public void resetIsoDepTimeout() throws RemoteException { 15851b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 15861b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen 15871b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen mManager.resetIsoDepTimeout(); 15881b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen } 15890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly }; 1590f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 15910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private final IP2pInitiator mP2pInitiatorService = new IP2pInitiator.Stub() { 1592f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1593fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 15940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public byte[] getGeneralBytes(int nativeHandle) throws RemoteException { 1595d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1596f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 15970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeP2pDevice device; 1598f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 15990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 16000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 16010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 16020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1603f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 16050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly device = (NativeP2pDevice) findObject(nativeHandle); 16060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 16070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly byte[] buff = device.getGeneralBytes(); 16080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (buff == null) 16090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 16100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return buff; 16110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 16120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 16130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1614f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1615fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 16160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int getMode(int nativeHandle) throws RemoteException { 1617d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1618f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeP2pDevice device; 1620f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 16220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 16230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 16240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1625f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 16270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly device = (NativeP2pDevice) findObject(nativeHandle); 16280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 16290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return device.getMode(); 16300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1631f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_INVALID_PARAM; 1632f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1633f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1634fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 16350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public byte[] receive(int nativeHandle) throws RemoteException { 1636d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1637f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeP2pDevice device; 1639f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 16410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 16420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 16430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1644f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 16460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly device = (NativeP2pDevice) findObject(nativeHandle); 16470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 16480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly byte[] buff = device.doReceive(); 16490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (buff == null) 16500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 16510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return buff; 16520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 16530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Restart polling loop for notification */ 165449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly applyRouting(); 16550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 16560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1657f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1658fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 16590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public boolean send(int nativeHandle, byte[] data) throws RemoteException { 1660d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1661f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeP2pDevice device; 16630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean isSuccess = false; 1664f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 16660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 16670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return isSuccess; 16680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1669f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 16710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly device = (NativeP2pDevice) findObject(nativeHandle); 16720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 16730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly isSuccess = device.doSend(data); 16740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 16750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return isSuccess; 16760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 16770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly }; 1678f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private final IP2pTarget mP2pTargetService = new IP2pTarget.Stub() { 1680f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1681fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 16820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int connect(int nativeHandle) throws RemoteException { 1683d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1684f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeP2pDevice device; 1686f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 16880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 16890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 16900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1691f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 16930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly device = (NativeP2pDevice) findObject(nativeHandle); 16940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 16950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device.doConnect()) { 16960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.SUCCESS; 16970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 16980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 16990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_CONNECT; 17000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1701f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1702fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 17030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public boolean disconnect(int nativeHandle) throws RemoteException { 1704d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1705f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeP2pDevice device; 17070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean isSuccess = false; 1708f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 17100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 17110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return isSuccess; 17120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1713f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 17150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly device = (NativeP2pDevice) findObject(nativeHandle); 17160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 17170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (isSuccess = device.doDisconnect()) { 17180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* remove the device from the hmap */ 1719b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau unregisterObject(nativeHandle); 17200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Restart polling loop for notification */ 172149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly applyRouting(); 17220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1723f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 17240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return isSuccess; 1725f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1727f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1728fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 17290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public byte[] getGeneralBytes(int nativeHandle) throws RemoteException { 1730d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1731f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeP2pDevice device; 17330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 17340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 17350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 17360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 1737f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1738f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 17400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly device = (NativeP2pDevice) findObject(nativeHandle); 17410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 17420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly byte[] buff = device.getGeneralBytes(); 17430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (buff == null) 17440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 17450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return buff; 17460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 17470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 17480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1749f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1750fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 17510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int getMode(int nativeHandle) throws RemoteException { 1752d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1753f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeP2pDevice device; 1755f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 17570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 17580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 1759f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1760f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 17620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly device = (NativeP2pDevice) findObject(nativeHandle); 17630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 17640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return device.getMode(); 17650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 17660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_INVALID_PARAM; 17670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1768f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1769fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 177097c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen public byte[] transceive(int nativeHandle, byte[] data) 177197c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen throws RemoteException { 1772d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1773f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeP2pDevice device; 1775f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 17770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 17780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 1779f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1780f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 17820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly device = (NativeP2pDevice) findObject(nativeHandle); 17830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 17840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly byte[] buff = device.doTransceive(data); 17850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (buff == null) 17860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 17870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return buff; 17880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 17890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 17900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 17910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly }; 1792f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 179349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private INfcAdapterExtras mExtrasService = new INfcAdapterExtras.Stub() { 179449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private Bundle writeNoException() { 179549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Bundle p = new Bundle(); 179649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly p.putInt("e", 0); 179749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly return p; 179849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 179949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private Bundle writeIoException(IOException e) { 180049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Bundle p = new Bundle(); 180149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly p.putInt("e", -1); 180249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly p.putString("m", e.getMessage()); 180349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly return p; 180449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 18050bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 1806bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks @Override 180749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public Bundle open(IBinder b) throws RemoteException { 180893d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton NfcService.enforceNfceeAdminPerm(mContext); 1809bd555ee64250126b60b24814120a2049943920caNick Pelly 181049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Bundle result; 181149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly try { 181249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly _open(b); 181349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly result = writeNoException(); 181449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } catch (IOException e) { 181549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly result = writeIoException(e); 18160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 181749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly return result; 181849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 18190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 182049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private void _open(IBinder b) throws IOException, RemoteException { 182149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly synchronized(NfcService.this) { 182249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (!mIsNfcEnabled) { 182349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly throw new IOException("NFC adapter is disabled"); 182449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 182549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (mOpenEe != null) { 182649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly throw new IOException("NFC EE already open"); 182749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 18280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 182949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly int handle = mSecureElement.doOpenSecureElementConnection(); 183049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (handle == 0) { 183149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly throw new IOException("NFC EE failed to open"); 183249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 1833ba6401757f8017faeb77423f2d08fd51be1d1051Nick Pelly mManager.doSetIsoDepTimeout(10000); 1834ba6401757f8017faeb77423f2d08fd51be1d1051Nick Pelly 183549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mOpenEe = new OpenSecureElement(getCallingPid(), handle); 183649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly try { 183749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly b.linkToDeath(mOpenEe, 0); 183849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } catch (RemoteException e) { 183949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mOpenEe.binderDied(); 184049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 184149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 18420bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 18430bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 1844bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks @Override 184549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public Bundle close() throws RemoteException { 184693d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton NfcService.enforceNfceeAdminPerm(mContext); 18470bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 184849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Bundle result; 184949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly try { 185049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly _close(); 185149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly result = writeNoException(); 185249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } catch (IOException e) { 185349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly result = writeIoException(e); 18540bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 185549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly return result; 185649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 18570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 185849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly void _close() throws IOException, RemoteException { 185949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly // Blocks until a pending open() or transceive() times out. 186049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly //TODO: This is incorrect behavior - the close should interrupt pending 186149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly // operations. However this is not supported by current hardware. 18620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 186349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly synchronized(NfcService.this) { 186449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (!mIsNfcEnabled) { 186549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly throw new IOException("NFC adapter is disabled"); 1866221b4d6ee301fbfe19402798f7d3c11e6878c888daniel_tomas } 186749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (mOpenEe == null) { 186849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly throw new IOException("NFC EE closed"); 186949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 187049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (mOpenEe.pid != -1 && getCallingPid() != mOpenEe.pid) { 187149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly throw new SecurityException("Wrong PID"); 1872221b4d6ee301fbfe19402798f7d3c11e6878c888daniel_tomas } 1873221b4d6ee301fbfe19402798f7d3c11e6878c888daniel_tomas 1874ba6401757f8017faeb77423f2d08fd51be1d1051Nick Pelly mManager.doResetIsoDepTimeout(); 187549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mSecureElement.doDisconnect(mOpenEe.handle); 187649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mOpenEe = null; 187749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly 187849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly applyRouting(); 18790bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 18800bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 18810bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 1882bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks @Override 188349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public Bundle transceive(byte[] in) throws RemoteException { 188493d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton NfcService.enforceNfceeAdminPerm(mContext); 1885bd555ee64250126b60b24814120a2049943920caNick Pelly 188649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Bundle result; 188749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly byte[] out; 188849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly try { 188949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly out = _transceive(in); 189049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly result = writeNoException(); 189149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly result.putByteArray("out", out); 189249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } catch (IOException e) { 189349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly result = writeIoException(e); 18940bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 189549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly return result; 189649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 18970bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 189849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private byte[] _transceive(byte[] data) throws IOException, RemoteException { 189949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly synchronized(NfcService.this) { 190049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (!mIsNfcEnabled) { 190149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly throw new IOException("NFC is not enabled"); 190249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 190349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (mOpenEe == null){ 190449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly throw new IOException("NFC EE is not open"); 190549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 190649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (getCallingPid() != mOpenEe.pid) { 190749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly throw new SecurityException("Wrong PID"); 190849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 19090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 19100bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 191149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly return mSecureElement.doTransceive(mOpenEe.handle, data); 19120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 19130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 1914bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks @Override 191549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public int getCardEmulationRoute() throws RemoteException { 191693d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton NfcService.enforceNfceeAdminPerm(mContext); 191749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly return mEeRoutingState; 19180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 19190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 1920bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks @Override 192149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public void setCardEmulationRoute(int route) throws RemoteException { 192293d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton NfcService.enforceNfceeAdminPerm(mContext); 192349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mEeRoutingState = route; 192449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly applyRouting(); 19250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 1926bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 1927bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks @Override 1928bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks public void registerTearDownApdus(String packageName, ApduList apdu) throws RemoteException { 1929bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks NfcService.enforceNfceeAdminPerm(mContext); 1930bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks synchronized(NfcService.this) { 1931bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks mTearDownApdus.put(packageName, apdu); 1932bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks writeTearDownApdusLocked(); 1933bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 1934bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 1935bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 1936bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks @Override 1937bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks public void unregisterTearDownApdus(String packageName) throws RemoteException { 1938bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks NfcService.enforceNfceeAdminPerm(mContext); 1939bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks synchronized(NfcService.this) { 1940bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks mTearDownApdus.remove(packageName); 1941bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks writeTearDownApdusLocked(); 1942bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 1943bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 19440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas }; 19450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 194649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly /** resources kept while secure element is open */ 194749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private class OpenSecureElement implements IBinder.DeathRecipient { 194849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public int pid; // pid that opened SE 194949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public int handle; // low-level handle 195049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public OpenSecureElement(int pid, int handle) { 195149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly this.pid = pid; 195249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly this.handle = handle; 195349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 1954bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks @Override 195549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public void binderDied() { 195649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly synchronized (NfcService.this) { 195749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (DBG) Log.d(TAG, "Tracked app " + pid + " died"); 195849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly pid = -1; 19590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas try { 196049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mExtrasService.close(); 196149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } catch (RemoteException e) { /* local call never fails */ } 19620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 19630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 19640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 19650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 19660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private boolean _enable(boolean oldEnabledState) { 19676efda9f3970382554437be037aed863be9889499Sylvain Fonteneau applyProperties(); 19686efda9f3970382554437be037aed863be9889499Sylvain Fonteneau 19690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean isSuccess = mManager.initialize(); 19700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (isSuccess) { 197165945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly mIsNfcEnabled = true; 197249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mIsDiscoveryOn = true; 197365945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly 19740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Start polling loop */ 197549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly applyRouting(); 197657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 197757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton /* bring up the my tag server */ 1978ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton mNdefPushServer.start(); 197957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 1980f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 19810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mIsNfcEnabled = false; 1982f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1983f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 19840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly updateNfcOnSetting(oldEnabledState); 1985f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 19860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return isSuccess; 1987f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1988f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 198949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly /** apply NFC discovery and EE routing */ 199049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private synchronized void applyRouting() { 199149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (mIsNfcEnabled && mOpenEe == null) { 199249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (mScreenOn) { 199349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (mEeRoutingState == ROUTE_ON_WHEN_SCREEN_ON) { 199449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Log.d(TAG, "NFC-EE routing ON"); 199549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mManager.doSelectSecureElement(SECURE_ELEMENT_ID); 199649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } else { 199749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Log.d(TAG, "NFC-EE routing OFF"); 199849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mManager.doDeselectSecureElement(SECURE_ELEMENT_ID); 1999221b4d6ee301fbfe19402798f7d3c11e6878c888daniel_tomas } 200049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (mIsDiscoveryOn) { 200149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Log.d(TAG, "NFC-C discovery ON"); 200249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mManager.enableDiscovery(DISCOVERY_MODE_READER); 200349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } else { 200449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Log.d(TAG, "NFC-C discovery OFF"); 200549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mManager.disableDiscovery(); 2006221b4d6ee301fbfe19402798f7d3c11e6878c888daniel_tomas } 2007221b4d6ee301fbfe19402798f7d3c11e6878c888daniel_tomas } else { 200849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Log.d(TAG, "NFC-EE routing OFF"); 200949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mManager.doDeselectSecureElement(SECURE_ELEMENT_ID); 201049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Log.d(TAG, "NFC-C discovery OFF"); 201149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mManager.disableDiscovery(); 2012221b4d6ee301fbfe19402798f7d3c11e6878c888daniel_tomas } 201365945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly } 201465945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly } 201565945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly 20162436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir /** Disconnect any target if present */ 20172436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir private synchronized void maybeDisconnectTarget() { 20182436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir if (mIsNfcEnabled) { 20192436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir Iterator<?> iterator = mObjectMap.values().iterator(); 20202436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir while(iterator.hasNext()) { 20212436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir Object object = iterator.next(); 2022663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau if(object instanceof NativeNfcTag) { 2023663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau // Disconnect from tags 20242436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir NativeNfcTag tag = (NativeNfcTag) object; 20252436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir tag.disconnect(); 20262436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir } 2027663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau else if(object instanceof NativeP2pDevice) { 2028663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau // Disconnect from P2P devices 2029663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau NativeP2pDevice device = (NativeP2pDevice) object; 2030663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau if (device.getMode() == NativeP2pDevice.MODE_P2P_TARGET) { 2031663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau // Remote peer is target, request disconnection 2032663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau device.doDisconnect(); 2033663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau } 2034663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau else { 2035663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau // Remote peer is initiator, we cannot disconnect 2036663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau // Just wait for field removal 2037663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau } 2038663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau } 2039663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau iterator.remove(); 20402436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir } 20412436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir } 20422436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir } 20432436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir 2044bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks private void readTearDownApdus() { 2045bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks FileInputStream input = null; 2046bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2047bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks try { 2048bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks input = openFileInput(TEAR_DOWN_SCRIPTS_FILE_NAME); 2049bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks DataInputStream stream = new DataInputStream(input); 2050bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2051bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks int packagesSize = stream.readInt(); 2052bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2053bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks for (int i = 0 ; i < packagesSize ; i++) { 2054bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks String packageName = stream.readUTF(); 2055bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks ApduList apdu = new ApduList(); 2056bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2057bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks int commandsSize = stream.readInt(); 2058bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2059bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks for (int j = 0 ; j < commandsSize ; j++) { 2060bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks int length = stream.readInt(); 2061bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2062bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks byte[] cmd = new byte[length]; 2063bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2064bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks stream.read(cmd); 2065bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks apdu.add(cmd); 2066bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2067bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2068bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks mTearDownApdus.put(packageName, apdu); 2069bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2070bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } catch (FileNotFoundException e) { 2071bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks // Ignore. 2072bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } catch (IOException e) { 2073bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks Log.e(TAG, "Could not read tear down scripts file: ", e); 2074bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks deleteFile(TEAR_DOWN_SCRIPTS_FILE_NAME); 2075bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } finally { 2076bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks try { 2077bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks if (input != null) { 2078bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks input.close(); 2079bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2080bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } catch (IOException e) { 2081bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks // Ignore 2082bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2083bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2084bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2085bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2086bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks private void writeTearDownApdusLocked() { 2087bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks FileOutputStream output = null; 2088bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks DataOutputStream stream = null; 2089bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2090bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks try { 2091bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks output = openFileOutput(TEAR_DOWN_SCRIPTS_FILE_NAME, Context.MODE_PRIVATE); 2092bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks stream = new DataOutputStream(output); 2093bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2094bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks stream.writeInt(mTearDownApdus.size()); 2095bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2096bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks for (String packageName : mTearDownApdus.keySet()) { 2097bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks stream.writeUTF(packageName); 2098bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2099bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks List<byte[]> commands = mTearDownApdus.get(packageName).get(); 2100bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks stream.writeInt(commands.size()); 2101bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2102bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks for (byte[] cmd : commands) { 2103bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks stream.writeInt(cmd.length); 2104bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks stream.write(cmd, 0, cmd.length); 2105bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2106bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2107bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2108bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } catch (IOException e) { 2109bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } finally { 2110bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks try { 2111bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks if (output != null) { 2112bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks stream.flush(); 2113bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks stream.close(); 2114bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2115bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } catch (IOException e) { 2116bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks // Ignore 2117bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2118bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2119bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2120bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2121f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly private void applyProperties() { 2122f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mManager.doSetProperties(PROPERTY_LLCP_LTO, mPrefs.getInt(PREF_LLCP_LTO, LLCP_LTO_DEFAULT)); 2123f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mManager.doSetProperties(PROPERTY_LLCP_MIU, mPrefs.getInt(PREF_LLCP_MIU, LLCP_MIU_DEFAULT)); 2124f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mManager.doSetProperties(PROPERTY_LLCP_WKS, mPrefs.getInt(PREF_LLCP_WKS, LLCP_WKS_DEFAULT)); 2125f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mManager.doSetProperties(PROPERTY_LLCP_OPT, mPrefs.getInt(PREF_LLCP_OPT, LLCP_OPT_DEFAULT)); 2126f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_A, 2127f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mPrefs.getBoolean(PREF_DISCOVERY_A, DISCOVERY_A_DEFAULT) ? 1 : 0); 2128f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_B, 2129f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mPrefs.getBoolean(PREF_DISCOVERY_B, DISCOVERY_B_DEFAULT) ? 1 : 0); 2130f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_F, 2131f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mPrefs.getBoolean(PREF_DISCOVERY_F, DISCOVERY_F_DEFAULT) ? 1 : 0); 2132f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_15693, 2133f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mPrefs.getBoolean(PREF_DISCOVERY_15693, DISCOVERY_15693_DEFAULT) ? 1 : 0); 2134f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_NFCIP, 2135f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mPrefs.getBoolean(PREF_DISCOVERY_NFCIP, DISCOVERY_NFCIP_DEFAULT) ? 1 : 0); 2136f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly } 2137f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly 21380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private void updateNfcOnSetting(boolean oldEnabledState) { 21390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putBoolean(PREF_NFC_ON, mIsNfcEnabled); 21402f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 21410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 21422f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly synchronized(this) { 21434acf84356e35861f7df6d07a2b9ff84842a9f221Nick Pelly if (oldEnabledState != mIsNfcEnabled) { 21442f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly Intent intent = new Intent(NfcAdapter.ACTION_ADAPTER_STATE_CHANGE); 21454acf84356e35861f7df6d07a2b9ff84842a9f221Nick Pelly intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 21462f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly intent.putExtra(NfcAdapter.EXTRA_NEW_BOOLEAN_STATE, mIsNfcEnabled); 21472f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly mContext.sendBroadcast(intent); 21482f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly } 214957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 215057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton if (mIsNfcEnabled) { 215157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 215257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Context context = getApplicationContext(); 215357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 215457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton // Set this to null by default. If there isn't a tag on disk 215557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton // or if there was an error reading the tag then this will cause 215657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton // the status bar icon to be removed. 215757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton NdefMessage myTag = null; 215857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 215957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton FileInputStream input = null; 216057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 216157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton try { 216257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton input = context.openFileInput(MY_TAG_FILE_NAME); 216357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton ByteArrayOutputStream bytes = new ByteArrayOutputStream(); 216457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 216557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton byte[] buffer = new byte[4096]; 216657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton int read = 0; 216757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton while ((read = input.read(buffer)) > 0) { 216857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton bytes.write(buffer, 0, read); 216957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 217057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 217157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton myTag = new NdefMessage(bytes.toByteArray()); 217257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } catch (FileNotFoundException e) { 217357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton // Ignore. 217457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } catch (IOException e) { 217557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Log.e(TAG, "Could not read mytag file: ", e); 217657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton context.deleteFile(MY_TAG_FILE_NAME); 217757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } catch (FormatException e) { 217857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Log.e(TAG, "Invalid NdefMessage for mytag", e); 217957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton context.deleteFile(MY_TAG_FILE_NAME); 218057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } finally { 218157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton try { 218257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton if (input != null) { 218357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton input.close(); 218457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 218557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } catch (IOException e) { 218657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton // Ignore 218757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 218857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 218957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 219057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton try { 219157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton mNfcAdapter.localSet(myTag); 219257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } catch (RemoteException e) { 219357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton // Ignore 219457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 219557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } else { 219657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton sendMessage(MSG_HIDE_MY_TAG_ICON, null); 219757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 21980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 2199f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2200f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2201f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Reset all internals 22022f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly private synchronized void reset() { 220374180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick // TODO: none of these appear to be synchronized but are 220474180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick // read/written from different threads (notably Binder threads)... 2205f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2206f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Clear tables 2207f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly mObjectMap.clear(); 2208f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly mSocketMap.clear(); 2209f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2210f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Reset variables 2211f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly mIsNfcEnabled = false; 2212f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2213f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 22142f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly private synchronized Object findObject(int key) { 2215f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly Object device = null; 2216f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2217f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly device = mObjectMap.get(key); 2218f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (device == null) { 2219f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly Log.w(TAG, "Handle not found !"); 2220f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2221f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2222f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return device; 2223f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2224f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 22252f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly synchronized void registerTagObject(NativeNfcTag nativeTag) { 2226b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau mObjectMap.put(nativeTag.getHandle(), nativeTag); 2227b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 2228b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 22292f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly synchronized void unregisterObject(int handle) { 2230b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau mObjectMap.remove(handle); 2231f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2232f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 22332f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly private synchronized Object findSocket(int key) { 2234bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly if (mSocketMap == null) { 2235bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly return null; 2236bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly } 2237bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly return mSocketMap.get(key); 2238f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2239f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2240f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private void RemoveSocket(int key) { 2241f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly mSocketMap.remove(key); 2242f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2243f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2244d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton /** For use by code in this process */ 2245d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton public LlcpSocket createLlcpSocket(int sap, int miu, int rw, int linearBufferLength) { 2246d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton try { 2247d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton int handle = mNfcAdapter.createLlcpSocket(sap, miu, rw, linearBufferLength); 22481be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton if (ErrorCodes.isError(handle)) { 22491be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton Log.e(TAG, "unable to create socket: " + ErrorCodes.asString(handle)); 22501be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton return null; 22511be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton } 2252d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton return new LlcpSocket(mLlcpSocket, handle); 2253d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton } catch (RemoteException e) { 2254d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton // This will never happen since the code is calling into it's own process 2255d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton throw new IllegalStateException("unable to talk to myself", e); 2256d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton } 2257d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton } 2258d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton 2259d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton /** For use by code in this process */ 2260d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton public LlcpServiceSocket createLlcpServiceSocket(int sap, String sn, int miu, int rw, 2261d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton int linearBufferLength) { 2262d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton try { 2263d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton int handle = mNfcAdapter.createLlcpServiceSocket(sap, sn, miu, rw, linearBufferLength); 22641be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton if (ErrorCodes.isError(handle)) { 22651be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton Log.e(TAG, "unable to create socket: " + ErrorCodes.asString(handle)); 22661be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton return null; 22671be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton } 2268d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton return new LlcpServiceSocket(mLlcpServerSocketService, mLlcpSocket, handle); 2269d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton } catch (RemoteException e) { 2270d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton // This will never happen since the code is calling into it's own process 2271d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton throw new IllegalStateException("unable to talk to myself", e); 2272d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton } 2273d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton } 2274d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton 22750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private void activateLlcpLink() { 22760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Broadcast Intent Link LLCP activated */ 22770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly Intent LlcpLinkIntent = new Intent(); 22780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly LlcpLinkIntent.setAction(NfcAdapter.ACTION_LLCP_LINK_STATE_CHANGED); 2279f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 22800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly LlcpLinkIntent.putExtra(NfcAdapter.EXTRA_LLCP_LINK_STATE_CHANGED, 22810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NfcAdapter.LLCP_LINK_STATE_ACTIVATED); 2282f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2283ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Broadcasting LLCP activation"); 22840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mContext.sendOrderedBroadcast(LlcpLinkIntent, NFC_PERM); 22850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 2286f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 228757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton public void sendMockNdefTag(NdefMessage msg) { 2288b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton sendMessage(MSG_MOCK_NDEF, msg); 228957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 229057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 2291b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau void sendMessage(int what, Object obj) { 2292b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau Message msg = mHandler.obtainMessage(); 2293b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau msg.what = what; 2294b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau msg.obj = obj; 2295b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau mHandler.sendMessage(msg); 2296b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 2297b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 2298b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton final class NfcServiceHandler extends Handler { 2299232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen 2300232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen public NdefMessage[] findAndReadNdef(NativeNfcTag nativeTag) { 2301232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen // Try to find NDEF on any of the technologies. 2302232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen int[] technologies = nativeTag.getTechList(); 2303232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen int[] handles = nativeTag.getHandleList(); 2304232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen int techIndex = 0; 2305232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen int lastHandleScanned = 0; 2306232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen boolean ndefFoundAndConnected = false; 2307232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen NdefMessage[] ndefMsgs = null; 2308eb488e0b323ec2d4fe03528e2b9f3a73e66ae17dMartijn Coenen boolean foundFormattable = false; 2309e08c8939be916c393a62b995b2dee438cb8cec2fMartijn Coenen int formattableHandle = 0; 2310e08c8939be916c393a62b995b2dee438cb8cec2fMartijn Coenen int formattableTechnology = 0; 2311232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen 2312232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen while ((!ndefFoundAndConnected) && (techIndex < technologies.length)) { 2313232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen if (handles[techIndex] != lastHandleScanned) { 2314232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen // We haven't seen this handle yet, connect and checkndef 2315232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen if (nativeTag.connect(technologies[techIndex])) { 2316eb488e0b323ec2d4fe03528e2b9f3a73e66ae17dMartijn Coenen // Check if this type is NDEF formatable 2317434bb34457422a9cad664b73ed0d425db4a3093dMartijn Coenen if (!foundFormattable) { 2318434bb34457422a9cad664b73ed0d425db4a3093dMartijn Coenen if (nativeTag.isNdefFormatable()) { 2319434bb34457422a9cad664b73ed0d425db4a3093dMartijn Coenen foundFormattable = true; 2320434bb34457422a9cad664b73ed0d425db4a3093dMartijn Coenen formattableHandle = nativeTag.getConnectedHandle(); 2321434bb34457422a9cad664b73ed0d425db4a3093dMartijn Coenen formattableTechnology = nativeTag.getConnectedTechnology(); 2322434bb34457422a9cad664b73ed0d425db4a3093dMartijn Coenen // We'll only add formattable tech if no ndef is 2323434bb34457422a9cad664b73ed0d425db4a3093dMartijn Coenen // found - this is because libNFC refuses to format 2324434bb34457422a9cad664b73ed0d425db4a3093dMartijn Coenen // an already NDEF formatted tag. 2325434bb34457422a9cad664b73ed0d425db4a3093dMartijn Coenen } 2326434bb34457422a9cad664b73ed0d425db4a3093dMartijn Coenen nativeTag.reconnect(); 2327434bb34457422a9cad664b73ed0d425db4a3093dMartijn Coenen } // else, already found formattable technology 2328434bb34457422a9cad664b73ed0d425db4a3093dMartijn Coenen 2329232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen int[] ndefinfo = new int[2]; 2330232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen if (nativeTag.checkNdef(ndefinfo)) { 2331232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen ndefFoundAndConnected = true; 2332232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen boolean generateEmptyNdef = false; 2333232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen 2334232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen int supportedNdefLength = ndefinfo[0]; 2335232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen int cardState = ndefinfo[1]; 2336232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen byte[] buff = nativeTag.read(); 2337232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen if (buff != null) { 2338232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen ndefMsgs = new NdefMessage[1]; 2339232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen try { 2340232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen ndefMsgs[0] = new NdefMessage(buff); 2341232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen nativeTag.addNdefTechnology(ndefMsgs[0], 2342ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen nativeTag.getConnectedHandle(), 23430a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen nativeTag.getConnectedLibNfcType(), 2344f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen nativeTag.getConnectedTechnology(), 2345232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen supportedNdefLength, cardState); 2346232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen nativeTag.reconnect(); 2347232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } catch (FormatException e) { 2348232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen // Create an intent anyway, without NDEF messages 2349232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen generateEmptyNdef = true; 2350232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } 2351232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } else { 2352232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen generateEmptyNdef = true; 2353232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } 2354232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen 2355232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen if (generateEmptyNdef) { 2356232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen ndefMsgs = new NdefMessage[] { }; 2357ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen nativeTag.addNdefTechnology(null, 2358ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen nativeTag.getConnectedHandle(), 23590a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen nativeTag.getConnectedLibNfcType(), 2360f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen nativeTag.getConnectedTechnology(), 2361ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen supportedNdefLength, cardState); 2362232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen nativeTag.reconnect(); 2363232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } 2364232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } // else, no NDEF on this tech, continue loop 2365232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } else { 2366232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen // Connect failed, tag maybe lost. Try next handle 2367232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen // anyway. 2368232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } 2369232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } 2370232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen lastHandleScanned = handles[techIndex]; 2371232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen techIndex++; 2372232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } 2373e08c8939be916c393a62b995b2dee438cb8cec2fMartijn Coenen if (ndefMsgs == null && foundFormattable) { 2374e08c8939be916c393a62b995b2dee438cb8cec2fMartijn Coenen // Tag is not NDEF yet, and found a formattable target, 2375e08c8939be916c393a62b995b2dee438cb8cec2fMartijn Coenen // so add formattable tech to tech list. 2376e08c8939be916c393a62b995b2dee438cb8cec2fMartijn Coenen nativeTag.addNdefFormatableTechnology( 2377e08c8939be916c393a62b995b2dee438cb8cec2fMartijn Coenen formattableHandle, 2378e08c8939be916c393a62b995b2dee438cb8cec2fMartijn Coenen formattableTechnology); 2379e08c8939be916c393a62b995b2dee438cb8cec2fMartijn Coenen } 2380232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen 2381232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen return ndefMsgs; 2382232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } 2383232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen 2384b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau @Override 2385b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau public void handleMessage(Message msg) { 2386f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly switch (msg.what) { 2387b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton case MSG_MOCK_NDEF: { 2388b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton NdefMessage ndefMsg = (NdefMessage) msg.obj; 2389b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton Tag tag = Tag.createMockTag(new byte[] { 0x00 }, 2390b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton new int[] { }, 2391b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton new Bundle[] { }); 239257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Log.d(TAG, "mock NDEF tag, starting corresponding activity"); 239357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Log.d(TAG, tag.toString()); 23943fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton dispatchTag(tag, new NdefMessage[] { ndefMsg }); 239557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton break; 239657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 239757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 2398f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly case MSG_NDEF_TAG: 2399ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Tag detected, notifying applications"); 2400f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly NativeNfcTag nativeTag = (NativeNfcTag) msg.obj; 2401232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen NdefMessage[] ndefMsgs = findAndReadNdef(nativeTag); 2402232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen 2403232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen if (ndefMsgs != null) { 240498eb4249dcec63009b1839c005f0cf9048e1f7beMartijn Coenen nativeTag.startPresenceChecking(); 2405232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen dispatchNativeTag(nativeTag, ndefMsgs); 2406232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } else { 2407232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen // No ndef found or connect failed, just try to reconnect and dispatch 2408232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen if (nativeTag.reconnect()) { 240998eb4249dcec63009b1839c005f0cf9048e1f7beMartijn Coenen nativeTag.startPresenceChecking(); 24103fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton dispatchNativeTag(nativeTag, null); 2411232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } else { 2412232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen Log.w(TAG, "Failed to connect to tag"); 2413232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen nativeTag.disconnect(); 2414f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly } 2415f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly } 2416f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly break; 24173fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 2418f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly case MSG_CARD_EMULATION: 2419ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Card Emulation message"); 2420f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly byte[] aid = (byte[]) msg.obj; 242149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly /* Send broadcast */ 242249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Intent aidIntent = new Intent(); 242349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly aidIntent.setAction(ACTION_AID_SELECTED); 242449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly aidIntent.putExtra(EXTRA_AID, aid); 242549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (DBG) Log.d(TAG, "Broadcasting ACTION_AID_SELECTED"); 242693d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton mContext.sendBroadcast(aidIntent, NFCEE_ADMIN_PERM); 2427f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly break; 2428f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly 2429f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly case MSG_LLCP_LINK_ACTIVATION: 2430f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly NativeP2pDevice device = (NativeP2pDevice) msg.obj; 2431f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly 2432f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly Log.d(TAG, "LLCP Activation message"); 2433f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly 2434f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly if (device.getMode() == NativeP2pDevice.MODE_P2P_TARGET) { 2435ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "NativeP2pDevice.MODE_P2P_TARGET"); 2436f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly if (device.doConnect()) { 2437f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly /* Check Llcp compliancy */ 2438f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly if (mManager.doCheckLlcp()) { 2439f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly /* Activate Llcp Link */ 2440f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly if (mManager.doActivateLlcp()) { 2441ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Initiator Activate LLCP OK"); 2442663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau // Register P2P device 2443663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau mObjectMap.put(device.getHandle(), device); 2444eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton activateLlcpLink(); 2445eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton } else { 2446eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton /* should not happen */ 2447eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton Log.w(TAG, "Initiator Activate LLCP NOK. Disconnect."); 2448eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton device.doDisconnect(); 2449b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 2450b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 2451f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly } else { 2452ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Remote Target does not support LLCP. Disconnect."); 2453f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly device.doDisconnect(); 2454b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 2455eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton } else { 24567f5487be0414b1f92b41cc5f7b0b7db846d9b1c9Arnaud Ferir if (DBG) Log.d(TAG, "Cannot connect remote Target. Polling loop restarted..."); 24577f5487be0414b1f92b41cc5f7b0b7db846d9b1c9Arnaud Ferir /* The polling loop should have been restarted in failing doConnect */ 2458f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly } 2459f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly 2460f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly } else if (device.getMode() == NativeP2pDevice.MODE_P2P_INITIATOR) { 2461ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "NativeP2pDevice.MODE_P2P_INITIATOR"); 2462f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly /* Check Llcp compliancy */ 2463f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly if (mManager.doCheckLlcp()) { 2464f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly /* Activate Llcp Link */ 2465f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly if (mManager.doActivateLlcp()) { 2466ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Target Activate LLCP OK"); 2467663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau // Register P2P device 2468663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau mObjectMap.put(device.getHandle(), device); 2469eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton activateLlcpLink(); 2470eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton } 24716f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton } else { 2472ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton Log.w(TAG, "checkLlcp failed"); 2473f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly } 2474b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 2475f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly break; 2476f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly 2477f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly case MSG_LLCP_LINK_DEACTIVATED: 2478eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton device = (NativeP2pDevice) msg.obj; 2479eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton 2480eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton Log.d(TAG, "LLCP Link Deactivated message. Restart polling loop."); 2481663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau synchronized (NfcService.this) { 2482663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau /* Check if the device has been already unregistered */ 2483663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau if (mObjectMap.remove(device.getHandle()) != null) { 2484663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau /* Disconnect if we are initiator */ 2485663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau if (device.getMode() == NativeP2pDevice.MODE_P2P_TARGET) { 2486663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau if (DBG) Log.d(TAG, "disconnecting from target"); 2487663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau /* Restart polling loop */ 2488663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau device.doDisconnect(); 2489663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau } else { 2490663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau if (DBG) Log.d(TAG, "not disconnecting from initiator"); 2491663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau } 2492663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau } 2493cdab1112486288ee6ccc9eb5c55456f9618f6b9cJeff Hamilton } 2494eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton 2495f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly /* Broadcast Intent Link LLCP activated */ 2496f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly Intent LlcpLinkIntent = new Intent(); 2497f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly LlcpLinkIntent.setAction(NfcAdapter.ACTION_LLCP_LINK_STATE_CHANGED); 2498f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly LlcpLinkIntent.putExtra(NfcAdapter.EXTRA_LLCP_LINK_STATE_CHANGED, 2499f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly NfcAdapter.LLCP_LINK_STATE_DEACTIVATED); 2500ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Broadcasting LLCP deactivation"); 2501f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly mContext.sendOrderedBroadcast(LlcpLinkIntent, NFC_PERM); 2502f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly break; 2503f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly 2504f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly case MSG_TARGET_DESELECTED: 2505f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly /* Broadcast Intent Target Deselected */ 2506ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Target Deselected"); 2507f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly Intent TargetDeselectedIntent = new Intent(); 2508f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly TargetDeselectedIntent.setAction(mManager.INTERNAL_TARGET_DESELECTED_ACTION); 2509ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Broadcasting Intent"); 2510f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly mContext.sendOrderedBroadcast(TargetDeselectedIntent, NFC_PERM); 2511f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly break; 2512f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly 251357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton case MSG_SHOW_MY_TAG_ICON: { 251457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton StatusBarManager sb = (StatusBarManager) getSystemService( 251557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Context.STATUS_BAR_SERVICE); 251657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton sb.setIcon("nfc", R.drawable.stat_sys_nfc, 0); 251757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton break; 251857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 251957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 252057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton case MSG_HIDE_MY_TAG_ICON: { 252157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton StatusBarManager sb = (StatusBarManager) getSystemService( 252257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Context.STATUS_BAR_SERVICE); 252357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton sb.removeIcon("nfc"); 252457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton break; 252557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 252657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 2527c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas case MSG_SE_FIELD_ACTIVATED:{ 2528c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas if (DBG) Log.d(TAG, "SE FIELD ACTIVATED"); 2529c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas Intent eventFieldOnIntent = new Intent(); 253049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly eventFieldOnIntent.setAction(ACTION_RF_FIELD_ON_DETECTED); 2531c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas if (DBG) Log.d(TAG, "Broadcasting Intent"); 253293d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton mContext.sendBroadcast(eventFieldOnIntent, NFCEE_ADMIN_PERM); 2533c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas break; 2534c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas } 2535c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas 2536c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas case MSG_SE_FIELD_DEACTIVATED:{ 2537c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas if (DBG) Log.d(TAG, "SE FIELD DEACTIVATED"); 2538c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas Intent eventFieldOffIntent = new Intent(); 253949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly eventFieldOffIntent.setAction(ACTION_RF_FIELD_OFF_DETECTED); 2540c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas if (DBG) Log.d(TAG, "Broadcasting Intent"); 254193d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton mContext.sendBroadcast(eventFieldOffIntent, NFCEE_ADMIN_PERM); 2542c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas break; 2543c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas } 2544c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas 2545f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly default: 2546f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly Log.e(TAG, "Unknown message received"); 2547f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly break; 2548f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly } 2549b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 2550d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton 25513fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton private Intent buildTagIntent(Tag tag, NdefMessage[] msgs, String action) { 25523fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton Intent intent = new Intent(action); 2553b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton intent.putExtra(NfcAdapter.EXTRA_TAG, tag); 2554b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton intent.putExtra(NfcAdapter.EXTRA_ID, tag.getId()); 2555b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton intent.putExtra(NfcAdapter.EXTRA_NDEF_MESSAGES, msgs); 2556b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2557d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton return intent; 2558d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton } 25593fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 25603fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton private void dispatchNativeTag(NativeNfcTag nativeTag, NdefMessage[] msgs) { 25613fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton Tag tag = new Tag(nativeTag.getUid(), nativeTag.getTechList(), 25620c322dc2d942285bfcd9fe5c0bba1a5f36a967f5Jeff Hamilton nativeTag.getTechExtras(), nativeTag.getHandle(), mNfcTagService); 256310389c11abdae4c794082f6c51f11b28b422eddbMartijn Coenen registerTagObject(nativeTag); 256410389c11abdae4c794082f6c51f11b28b422eddbMartijn Coenen if (!dispatchTag(tag, msgs)) { 256510389c11abdae4c794082f6c51f11b28b422eddbMartijn Coenen unregisterObject(nativeTag.getHandle()); 25663fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton nativeTag.disconnect(); 25673fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 25683fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 25693fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 25703fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton public byte[] concat(byte[]... arrays) { 25713fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton int length = 0; 25723fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton for (byte[] array : arrays) { 25733fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton length += array.length; 25743fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 25753fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton byte[] result = new byte[length]; 25763fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton int pos = 0; 25773fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton for (byte[] array : arrays) { 25783fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton System.arraycopy(array, 0, result, pos, array.length); 25793fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton pos += array.length; 25803fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 25813fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton return result; 25823fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 25833fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 25843fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton private Uri parseWellKnownUriRecord(NdefRecord record) { 25853fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton byte[] payload = record.getPayload(); 25863fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 25873fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton /* 25883fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton * payload[0] contains the URI Identifier Code, per the 25893fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton * NFC Forum "URI Record Type Definition" section 3.2.2. 25903fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton * 25913fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton * payload[1]...payload[payload.length - 1] contains the rest of 25923fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton * the URI. 25933fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton */ 25943fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton String prefix = URI_PREFIX_MAP[(payload[0] & 0xff)]; 25953fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton byte[] fullUri = concat(prefix.getBytes(Charsets.UTF_8), 25963fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton Arrays.copyOfRange(payload, 1, payload.length)); 25973fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton return Uri.parse(new String(fullUri, Charsets.UTF_8)); 25983fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 25993fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 26003fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton private boolean setTypeOrDataFromNdef(Intent intent, NdefRecord record) { 26013fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton short tnf = record.getTnf(); 26023fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton byte[] type = record.getType(); 2603adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton try { 2604adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton switch (tnf) { 2605adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton case NdefRecord.TNF_MIME_MEDIA: { 2606adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton intent.setType(new String(type, Charsets.US_ASCII)); 26073fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton return true; 2608adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton } 2609adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton case NdefRecord.TNF_ABSOLUTE_URI: { 2610adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton intent.setData(Uri.parse(new String(record.getPayload(), Charsets.UTF_8))); 2611adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton return true; 2612adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton } 2613adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton case NdefRecord.TNF_WELL_KNOWN: { 2614adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton byte[] payload = record.getPayload(); 2615adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton if (payload == null || payload.length == 0) return false; 2616adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton if (Arrays.equals(type, NdefRecord.RTD_TEXT)) { 2617adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton intent.setType("text/plain"); 2618adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton return true; 2619adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton } else if (Arrays.equals(type, NdefRecord.RTD_SMART_POSTER)) { 2620adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton // Parse the smart poster looking for the URI 2621adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton try { 2622adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton NdefMessage msg = new NdefMessage(record.getPayload()); 2623adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton for (NdefRecord subRecord : msg.getRecords()) { 2624adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton short subTnf = subRecord.getTnf(); 2625adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton if (subTnf == NdefRecord.TNF_WELL_KNOWN 2626adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton && Arrays.equals(subRecord.getType(), 2627adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton NdefRecord.RTD_URI)) { 2628adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton intent.setData(parseWellKnownUriRecord(subRecord)); 2629adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton return true; 2630adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton } else if (subTnf == NdefRecord.TNF_ABSOLUTE_URI) { 2631adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton intent.setData(Uri.parse(new String(subRecord.getPayload(), 2632adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton Charsets.UTF_8))); 2633adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton return true; 2634adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton } 26353fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 2636adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton } catch (FormatException e) { 2637adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton return false; 26383fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 2639adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton } else if (Arrays.equals(type, NdefRecord.RTD_URI)) { 2640adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton intent.setData(parseWellKnownUriRecord(record)); 2641adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton return true; 26423fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 2643adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton return false; 26443fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 26453fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 2646adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton return false; 2647adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton } catch (Exception e) { 2648adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton Log.e(TAG, "failed to parse record", e); 2649adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton return false; 26503fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 26513fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 26523fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 26533fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton /** Returns false if no activities were found to dispatch to */ 26543fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton private boolean dispatchTag(Tag tag, NdefMessage[] msgs) { 26553fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton if (DBG) { 26563fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton Log.d(TAG, "Dispatching tag"); 26573fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton Log.d(TAG, tag.toString()); 26583fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 26593fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 266005973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton IntentFilter[] overrideFilters; 266105973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton PendingIntent overrideIntent; 266224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton String[][] overrideTechLists; 2663a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton boolean foregroundNdefPush = mNdefPushClient.getForegroundMessage() != null; 266405973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton synchronized (mNfcAdapter) { 266505973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton overrideFilters = mDispatchOverrideFilters; 266605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton overrideIntent = mDispatchOverrideIntent; 266724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton overrideTechLists = mDispatchOverrideTechLists; 266805973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 266905973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton 267005973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton // First look for dispatch overrides 2671a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (overrideIntent != null) { 267205973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton if (DBG) Log.d(TAG, "Attempting to dispatch tag with override"); 267349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly try { 267424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (dispatchTagInternal(tag, msgs, overrideIntent, overrideFilters, 267524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton overrideTechLists)) { 267605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton if (DBG) Log.d(TAG, "Dispatched to override"); 267705973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton return true; 267805973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 267905973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton Log.w(TAG, "Dispatch override registered, but no filters matched"); 268005973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } catch (CanceledException e) { 268105973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton Log.w(TAG, "Dispatch overrides pending intent was canceled"); 268205973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton synchronized (mNfcAdapter) { 268305973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton mDispatchOverrideFilters = null; 268405973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton mDispatchOverrideIntent = null; 268524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton mDispatchOverrideTechLists = null; 268605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 268705973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 268805973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 268905973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton 2690a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // If there is not foreground NDEF push setup try a normal dispatch. 2691a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // 2692a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // This is avoided when disabled in the NDEF push case to avoid the situation where each 2693a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // user has a different app in the foreground, causing each to launch itself on the 2694a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // remote device and the apps swapping which is in the foreground on each phone. 2695a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (!foregroundNdefPush) { 2696a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton try { 269724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton return dispatchTagInternal(tag, msgs, null, null, null); 2698a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } catch (CanceledException e) { 2699a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton Log.e(TAG, "CanceledException unexpected here", e); 2700a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton return false; 2701a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } 270205973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 2703a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton 2704a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton return false; 270505973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 270605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton 270724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton /** Returns true if the tech list filter matches the techs on the tag */ 270824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton private boolean filterMatch(String[] tagTechs, String[] filterTechs) { 270924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (filterTechs == null || filterTechs.length == 0) return false; 271024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 271124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton for (String tech : filterTechs) { 271224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (Arrays.binarySearch(tagTechs, tech) < 0) { 271324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton return false; 271424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 271524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 271624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton return true; 271724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 271824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 271905973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton // Dispatch to either an override pending intent or a standard startActivity() 272005973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton private boolean dispatchTagInternal(Tag tag, NdefMessage[] msgs, 272124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton PendingIntent overrideIntent, IntentFilter[] overrideFilters, 272224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton String[][] overrideTechLists) 272305973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton throws CanceledException{ 27243fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton Intent intent; 272524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 272624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // 272724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // Try the NDEF content specific dispatch 272824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // 27293fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton if (msgs != null && msgs.length > 0) { 27303fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton NdefMessage msg = msgs[0]; 27313fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton NdefRecord[] records = msg.getRecords(); 27323fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton if (records.length > 0) { 27333fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton // Found valid NDEF data, try to dispatch that first 27343fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton NdefRecord record = records[0]; 27353fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 27363fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton intent = buildTagIntent(tag, msgs, NfcAdapter.ACTION_NDEF_DISCOVERED); 2737adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton if (setTypeOrDataFromNdef(intent, record)) { 2738adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton // The record contains filterable data, try to start a matching activity 273924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (startDispatchActivity(intent, overrideIntent, overrideFilters, 274024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton overrideTechLists)) { 2741adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton // If an activity is found then skip further dispatching 2742adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton return true; 2743adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton } else { 2744adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton if (DBG) Log.d(TAG, "No activities for NDEF handling of " + intent); 2745adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton } 27463fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 27473fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 27483fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 27493fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 275024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // 27513fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton // Try the technology specific dispatch 275224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // 275324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton String[] tagTechs = tag.getTechList(); 275424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton Arrays.sort(tagTechs); 275524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 275624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (overrideIntent != null) { 275724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // There are dispatch overrides in place 275824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (overrideTechLists != null) { 275924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton for (String[] filterTechs : overrideTechLists) { 276024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (filterMatch(tagTechs, filterTechs)) { 276124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // An override matched, send it to the foreground activity. 276224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton intent = buildTagIntent(tag, msgs, 27638d69f5205e3c4a7c2eb869bbf4983d3d9fe45ab0Nick Pelly NfcAdapter.ACTION_TECH_DISCOVERED); 276424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton overrideIntent.send(mContext, Activity.RESULT_OK, intent); 276524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton return true; 276624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 276724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 276824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 276905973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } else { 277024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // Standard tech dispatch path 277124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton ArrayList<ResolveInfo> matches = new ArrayList<ResolveInfo>(); 277224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton ArrayList<ComponentInfo> registered = mTechListFilters.getComponents(); 277349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly 277424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // Check each registered activity to see if it matches 277524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton for (ComponentInfo info : registered) { 277624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // Don't allow wild card matching 277724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (filterMatch(tagTechs, info.techs)) { 27783ca2b3f925d434559300ee2fb10bfcdd365a0fb6Jeff Hamilton // Add the activity as a match if it's not already in the list 27793ca2b3f925d434559300ee2fb10bfcdd365a0fb6Jeff Hamilton if (!matches.contains(info.resolveInfo)) { 27803ca2b3f925d434559300ee2fb10bfcdd365a0fb6Jeff Hamilton matches.add(info.resolveInfo); 27813ca2b3f925d434559300ee2fb10bfcdd365a0fb6Jeff Hamilton } 278224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 278324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 278449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly 278524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (matches.size() == 1) { 278624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // Single match, launch directly 27878d69f5205e3c4a7c2eb869bbf4983d3d9fe45ab0Nick Pelly intent = buildTagIntent(tag, msgs, NfcAdapter.ACTION_TECH_DISCOVERED); 278824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton ResolveInfo info = matches.get(0); 278924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton intent.setClassName(info.activityInfo.packageName, info.activityInfo.name); 279024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton try { 279124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton mContext.startActivity(intent); 279224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton return true; 279324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } catch (ActivityNotFoundException e) { 279424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (DBG) Log.w(TAG, "No activities for technology handling of " + intent); 279524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 279624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } else if (matches.size() > 1) { 279724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // Multiple matches, show a custom activity chooser dialog 279824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton intent = new Intent(mContext, TechListChooserActivity.class); 279924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 280024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton intent.putExtra(Intent.EXTRA_INTENT, 28018d69f5205e3c4a7c2eb869bbf4983d3d9fe45ab0Nick Pelly buildTagIntent(tag, msgs, NfcAdapter.ACTION_TECH_DISCOVERED)); 280224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton intent.putParcelableArrayListExtra(TechListChooserActivity.EXTRA_RESOLVE_INFOS, 280324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton matches); 280424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton try { 280524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton mContext.startActivity(intent); 280624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton return true; 280724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } catch (ActivityNotFoundException e) { 280824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (DBG) Log.w(TAG, "No activities for technology handling of " + intent); 280924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 281024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } else { 281124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // No matches, move on 281249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (DBG) Log.w(TAG, "No activities for technology handling"); 281324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 28143fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 28153fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 281624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // 28173fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton // Try the generic intent 281824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // 28193fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton intent = buildTagIntent(tag, msgs, NfcAdapter.ACTION_TAG_DISCOVERED); 282024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (startDispatchActivity(intent, overrideIntent, overrideFilters, overrideTechLists)) { 28213fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton return true; 282205973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } else { 28233fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton Log.e(TAG, "No tag fallback activity found for " + intent); 28243fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton return false; 28253fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 28263fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 282705973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton 282805973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton private boolean startDispatchActivity(Intent intent, PendingIntent overrideIntent, 282924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton IntentFilter[] overrideFilters, String[][] overrideTechLists) 283024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton throws CanceledException { 283105973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton if (overrideIntent != null) { 2832a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton boolean found = false; 283324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (overrideFilters == null && overrideTechLists == null) { 2834a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // No filters means to always dispatch regardless of match 2835a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton found = true; 283624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } else if (overrideFilters != null) { 2837a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton for (IntentFilter filter : overrideFilters) { 2838a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (filter.match(mContext.getContentResolver(), intent, false, TAG) >= 0) { 2839a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton found = true; 2840a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton break; 2841a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } 284205973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 284305973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 2844a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton 2845a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (found) { 2846a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton Log.i(TAG, "Dispatching to override intent " + overrideIntent); 2847a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton overrideIntent.send(mContext, Activity.RESULT_OK, intent); 2848a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton return true; 2849a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } else { 2850a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton return false; 2851a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } 285205973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } else { 285305973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton try { 28541a9eca5f84036d7dd3e28000290caa2f641856deNick Pelly // If the current app called stopAppSwitches() then our startActivity() 28551a9eca5f84036d7dd3e28000290caa2f641856deNick Pelly // can be delayed for several seconds. This happens with the default home 28561a9eca5f84036d7dd3e28000290caa2f641856deNick Pelly // screen. As a system service we can override this behavior with 28571a9eca5f84036d7dd3e28000290caa2f641856deNick Pelly // resumeAppSwitches() 28581a9eca5f84036d7dd3e28000290caa2f641856deNick Pelly mIActivityManager.resumeAppSwitches(); 28591a9eca5f84036d7dd3e28000290caa2f641856deNick Pelly } catch (RemoteException e) { } 28601a9eca5f84036d7dd3e28000290caa2f641856deNick Pelly try { 286105973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton mContext.startActivity(intent); 286205973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton return true; 286305973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } catch (ActivityNotFoundException e) { 286405973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton return false; 286505973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 286605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 286705973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 2868b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton } 2869b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 2870b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton private NfcServiceHandler mHandler = new NfcServiceHandler(); 287149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly 28727c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly private class EnableDisableDiscoveryTask extends AsyncTask<Boolean, Void, Void> { 2873fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 28747c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly protected Void doInBackground(Boolean... enable) { 2875df4e65b5dacb313e7d68bad797a843a175febbedNick Pelly if (enable != null && enable.length > 0 && enable[0]) { 2876161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly synchronized (NfcService.this) { 2877161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly mScreenOn = true; 287849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly applyRouting(); 2879161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly } 28807c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly } else { 2881533043d1003de2f6a20a29201100d94c3c7bc9caNick Pelly mWakeLock.acquire(); 2882161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly synchronized (NfcService.this) { 2883161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly mScreenOn = false; 288449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly applyRouting(); 28852436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir maybeDisconnectTarget(); 2886161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly } 2887533043d1003de2f6a20a29201100d94c3c7bc9caNick Pelly mWakeLock.release(); 28887c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly } 28897c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly return null; 28907c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly } 28917c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly } 28927c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly 28930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 28940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly @Override 28950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public void onReceive(Context context, Intent intent) { 2896eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton if (intent.getAction().equals( 2897f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION)) { 2898ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "INERNAL_TARGET_DESELECTED_ACTION"); 28990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 2900f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* Restart polling loop for notification */ 290149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly applyRouting(); 2902f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 290365945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) { 29047c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly // Perform discovery enable in thread to protect against ANR when the 29057c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly // NFC stack wedges. This is *not* the correct way to fix this issue - 29067c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly // configuration of the local NFC adapter should be very quick and should 29077c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly // be safe on the main thread, and the NFC stack should not wedge. 290809f28764768ce0236cc3faf3dba17b1bbd6c8fdfKenny Root new EnableDisableDiscoveryTask().execute(Boolean.TRUE); 290965945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly } else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { 29107c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly // Perform discovery disable in thread to protect against ANR when the 29117c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly // NFC stack wedges. This is *not* the correct way to fix this issue - 29127c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly // configuration of the local NFC adapter should be very quick and should 29137c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly // be safe on the main thread, and the NFC stack should not wedge. 2914df4e65b5dacb313e7d68bad797a843a175febbedNick Pelly new EnableDisableDiscoveryTask().execute(new Boolean(false)); 2915bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } else if (intent.getAction().equals(ACTION_MASTER_CLEAR_NOTIFICATION)) { 2916bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks int handle = mSecureElement.doOpenSecureElementConnection(); 2917bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks if (handle == 0) { 2918bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks Log.e(TAG, "Could not open the secure element!"); 2919bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks return; 2920bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2921bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2922bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks synchronized (NfcService.this) { 2923bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks for (String packageName : mTearDownApdus.keySet()) { 2924bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks for (byte[] cmd : mTearDownApdus.get(packageName).get()) { 2925bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks mSecureElement.doTransceive(handle, cmd); 2926bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2927bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2928bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2929bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2930bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks mSecureElement.doDisconnect(handle); 2931bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } else if (intent.getAction().equals(Intent.ACTION_PACKAGE_REMOVED)) { 29327a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton boolean dataRemoved = intent.getBooleanExtra(Intent.EXTRA_DATA_REMOVED, false); 29337a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton if (dataRemoved) { 29347a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton Uri data = intent.getData(); 29357a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton if (data == null) return; 29367a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton String packageName = data.getSchemeSpecificPart(); 29377a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton ApduList apdus = null; 29387a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton 29397a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton synchronized (NfcService.this) { 29407a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton apdus = mTearDownApdus.remove(packageName); 29417a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton if (apdus == null) { 29427a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton return; 29437a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton } 29445e7b58d9c95a9074a42c3e4820e2467dfa85af10Jeff Hamilton 29455e7b58d9c95a9074a42c3e4820e2467dfa85af10Jeff Hamilton 29467a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton writeTearDownApdusLocked(); 29477a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton } 2948bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 29497a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton int handle = mSecureElement.doOpenSecureElementConnection(); 29507a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton if (handle == 0) { 29517a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton Log.e(TAG, "Could not open the secure element!"); 29527a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton return; 29537a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton } 2954bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 29557a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton try { 29567a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton for (byte[] cmd : apdus.get()) { 29577a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton mSecureElement.doTransceive(handle, cmd); 29587a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton } 29597a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton } finally { 29607a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton mSecureElement.doDisconnect(handle); 2961bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2962bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2963f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2964f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2965f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly }; 296674180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick} 2967