├── core └── java │ └── android │ ├── nfc │ ├── ITagRemovedCallback.aidl │ ├── INfcUnlockHandler.aidl │ ├── tech │ │ ├── package.html │ │ ├── NfcV.java │ │ ├── NfcB.java │ │ ├── NfcBarcode.java │ │ ├── BasicTagTechnology.java │ │ ├── NfcF.java │ │ ├── NfcA.java │ │ ├── NdefFormatable.java │ │ ├── IsoDep.java │ │ ├── TagTechnology.java │ │ └── MifareUltralight.java │ ├── Tag.aidl │ ├── ApduList.aidl │ ├── NdefRecord.aidl │ ├── NdefMessage.aidl │ ├── TechListParcel.aidl │ ├── BeamShareData.aidl │ ├── TransceiveResult.aidl │ ├── cardemulation │ │ ├── AidGroup.aidl │ │ ├── ApduServiceInfo.aidl │ │ ├── NfcFServiceInfo.aidl │ │ ├── AidGroup.java │ │ ├── OffHostApduService.java │ │ ├── HostNfcFService.java │ │ └── NfcFServiceInfo.java │ ├── TagLostException.java │ ├── IAppCallback.aidl │ ├── FormatException.java │ ├── INfcAdapterExtras.aidl │ ├── INfcDta.aidl │ ├── INfcFCardEmulation.aidl │ ├── ApduList.java │ ├── package.html │ ├── INfcTag.aidl │ ├── INfcCardEmulation.aidl │ ├── NfcEvent.java │ ├── TechListParcel.java │ ├── BeamShareData.java │ ├── NfcManager.java │ ├── TransceiveResult.java │ ├── INfcAdapter.aidl │ ├── ErrorCodes.java │ ├── dta │ │ └── NfcDta.java │ └── NdefMessage.java │ └── se │ └── omapi │ ├── ISecureElementListener.aidl │ ├── ISecureElementService.aidl │ ├── ISecureElementReader.aidl │ ├── ISecureElementSession.aidl │ ├── ISecureElementChannel.aidl │ ├── Reader.java │ ├── SEService.java │ └── Channel.java └── README.md /core/java/android/nfc/ITagRemovedCallback.aidl: -------------------------------------------------------------------------------- 1 | package android.nfc; 2 | 3 | /** 4 | * @hide 5 | */ 6 | oneway interface ITagRemovedCallback { 7 | void onTagRemoved(); 8 | } 9 | -------------------------------------------------------------------------------- /core/java/android/nfc/INfcUnlockHandler.aidl: -------------------------------------------------------------------------------- 1 | package android.nfc; 2 | 3 | import android.nfc.Tag; 4 | 5 | /** 6 | * @hide 7 | */ 8 | interface INfcUnlockHandler { 9 | 10 | boolean onUnlockAttempted(in Tag tag); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /core/java/android/nfc/tech/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

4 | These classes provide access to a tag technology's features, which vary by the type 5 | of tag that is scanned. A scanned tag can support multiple technologies, and you can find 6 | out what they are by calling {@link android.nfc.Tag#getTechList getTechList()}.

7 | 8 |

For more information on dealing with tag technologies and handling the ones that you care about, see 9 | The Tag Dispatch System. 10 | The {@link android.nfc.tech.TagTechnology} interface provides an overview of the 11 | supported technologies.

12 | 13 | 14 | -------------------------------------------------------------------------------- /core/java/android/nfc/Tag.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc; 18 | 19 | parcelable Tag; -------------------------------------------------------------------------------- /core/java/android/nfc/ApduList.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc; 18 | 19 | parcelable ApduList; -------------------------------------------------------------------------------- /core/java/android/nfc/NdefRecord.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc; 18 | 19 | parcelable NdefRecord; -------------------------------------------------------------------------------- /core/java/android/nfc/NdefMessage.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc; 18 | 19 | parcelable NdefMessage; 20 | -------------------------------------------------------------------------------- /core/java/android/nfc/TechListParcel.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc; 18 | 19 | parcelable TechListParcel; -------------------------------------------------------------------------------- /core/java/android/nfc/BeamShareData.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc; 18 | 19 | parcelable BeamShareData; 20 | -------------------------------------------------------------------------------- /core/java/android/nfc/TransceiveResult.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc; 18 | 19 | parcelable TransceiveResult; 20 | -------------------------------------------------------------------------------- /core/java/android/nfc/cardemulation/AidGroup.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc.cardemulation; 18 | 19 | parcelable AidGroup; 20 | -------------------------------------------------------------------------------- /core/java/android/nfc/cardemulation/ApduServiceInfo.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc.cardemulation; 18 | 19 | parcelable ApduServiceInfo; 20 | -------------------------------------------------------------------------------- /core/java/android/nfc/cardemulation/NfcFServiceInfo.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc.cardemulation; 18 | 19 | parcelable NfcFServiceInfo; 20 | -------------------------------------------------------------------------------- /core/java/android/se/omapi/ISecureElementListener.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017, The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | /* 17 | * Contributed by: Giesecke & Devrient GmbH. 18 | */ 19 | 20 | package android.se.omapi; 21 | 22 | /** 23 | * Interface to receive call-backs when the service is connected. 24 | * @hide 25 | */ 26 | interface ISecureElementListener { 27 | } 28 | -------------------------------------------------------------------------------- /core/java/android/nfc/TagLostException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011, The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc; 18 | 19 | import java.io.IOException; 20 | 21 | public class TagLostException extends IOException { 22 | public TagLostException() { 23 | super(); 24 | } 25 | 26 | public TagLostException(String message) { 27 | super(message); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /core/java/android/nfc/IAppCallback.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc; 18 | 19 | import android.nfc.BeamShareData; 20 | import android.nfc.Tag; 21 | 22 | /** 23 | * @hide 24 | */ 25 | interface IAppCallback 26 | { 27 | BeamShareData createBeamShareData(byte peerLlcpVersion); 28 | oneway void onNdefPushComplete(byte peerLlcpVersion); 29 | oneway void onTagDiscovered(in Tag tag); 30 | } 31 | -------------------------------------------------------------------------------- /core/java/android/nfc/FormatException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010, The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc; 18 | 19 | public class FormatException extends Exception { 20 | public FormatException() { 21 | super(); 22 | } 23 | 24 | public FormatException(String message) { 25 | super(message); 26 | } 27 | 28 | public FormatException(String message, Throwable e) { 29 | super(message, e); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /core/java/android/nfc/INfcAdapterExtras.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc; 18 | 19 | import android.os.Bundle; 20 | 21 | 22 | /** 23 | * {@hide} 24 | */ 25 | interface INfcAdapterExtras { 26 | Bundle open(in String pkg, IBinder b); 27 | Bundle close(in String pkg, IBinder b); 28 | Bundle transceive(in String pkg, in byte[] data_in); 29 | int getCardEmulationRoute(in String pkg); 30 | void setCardEmulationRoute(in String pkg, int route); 31 | void authenticate(in String pkg, in byte[] token); 32 | String getDriverName(in String pkg); 33 | } 34 | -------------------------------------------------------------------------------- /core/java/android/nfc/INfcDta.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2018 NXP Semiconductors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package android.nfc; 17 | 18 | import android.os.Bundle; 19 | 20 | /** 21 | * {@hide} 22 | */ 23 | interface INfcDta { 24 | 25 | void enableDta(); 26 | void disableDta(); 27 | boolean enableServer(String serviceName, int serviceSap, int miu, 28 | int rwSize,int testCaseId); 29 | void disableServer(); 30 | boolean enableClient(String serviceName, int miu, int rwSize, 31 | int testCaseId); 32 | void disableClient(); 33 | boolean registerMessageService(String msgServiceName); 34 | } 35 | -------------------------------------------------------------------------------- /core/java/android/nfc/INfcFCardEmulation.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc; 18 | 19 | import android.content.ComponentName; 20 | import android.nfc.cardemulation.NfcFServiceInfo; 21 | 22 | /** 23 | * @hide 24 | */ 25 | interface INfcFCardEmulation 26 | { 27 | String getSystemCodeForService(int userHandle, in ComponentName service); 28 | boolean registerSystemCodeForService(int userHandle, in ComponentName service, String systemCode); 29 | boolean removeSystemCodeForService(int userHandle, in ComponentName service); 30 | String getNfcid2ForService(int userHandle, in ComponentName service); 31 | boolean setNfcid2ForService(int userHandle, in ComponentName service, String nfcid2); 32 | boolean enableNfcFForegroundService(in ComponentName service); 33 | boolean disableNfcFForegroundService(); 34 | List getNfcFServices(int userHandle); 35 | int getMaxNumOfRegisterableSystemCodes(); 36 | } 37 | -------------------------------------------------------------------------------- /core/java/android/se/omapi/ISecureElementService.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017, The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | /* 17 | * Copyright (c) 2015-2017, The Linux Foundation. 18 | */ 19 | /* 20 | * Contributed by: Giesecke & Devrient GmbH. 21 | */ 22 | 23 | package android.se.omapi; 24 | 25 | import android.se.omapi.ISecureElementReader; 26 | 27 | /** 28 | * SecureElement service interface. 29 | * @hide 30 | */ 31 | interface ISecureElementService { 32 | 33 | /** 34 | * Returns the friendly names of available Secure Element readers. 35 | */ 36 | String[] getReaders(); 37 | 38 | /** 39 | * Returns SecureElement Service reader object to the given name. 40 | */ 41 | ISecureElementReader getReader(String reader); 42 | 43 | /** 44 | * Checks if the application defined by the package name is allowed to 45 | * receive NFC transaction events for the defined AID. 46 | */ 47 | boolean[] isNFCEventAllowed(String reader, in byte[] aid, 48 | in String[] packageNames); 49 | 50 | } 51 | -------------------------------------------------------------------------------- /core/java/android/nfc/ApduList.java: -------------------------------------------------------------------------------- 1 | package android.nfc; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * @hide 11 | */ 12 | public class ApduList implements Parcelable { 13 | 14 | private ArrayList commands = new ArrayList(); 15 | 16 | public ApduList() { 17 | } 18 | 19 | public void add(byte[] command) { 20 | commands.add(command); 21 | } 22 | 23 | public List get() { 24 | return commands; 25 | } 26 | 27 | public static final Parcelable.Creator CREATOR = 28 | new Parcelable.Creator() { 29 | @Override 30 | public ApduList createFromParcel(Parcel in) { 31 | return new ApduList(in); 32 | } 33 | 34 | @Override 35 | public ApduList[] newArray(int size) { 36 | return new ApduList[size]; 37 | } 38 | }; 39 | 40 | private ApduList(Parcel in) { 41 | int count = in.readInt(); 42 | 43 | for (int i = 0 ; i < count ; i++) { 44 | 45 | int length = in.readInt(); 46 | byte[] cmd = new byte[length]; 47 | in.readByteArray(cmd); 48 | commands.add(cmd); 49 | } 50 | } 51 | 52 | @Override 53 | public int describeContents() { 54 | return 0; 55 | } 56 | 57 | @Override 58 | public void writeToParcel(Parcel dest, int flags) { 59 | dest.writeInt(commands.size()); 60 | 61 | for (byte[] cmd : commands) { 62 | dest.writeInt(cmd.length); 63 | dest.writeByteArray(cmd); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /core/java/android/nfc/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Provides access to Near Field Communication (NFC) functionality, allowing applications to read 4 | NDEF message in NFC tags. A "tag" may actually be another device that appears as a tag.

5 | 6 |

For more information, see the 7 | Near Field Communication guide.

8 | {@more} 9 | 10 |

Here's a summary of the classes:

11 | 12 |
13 |
{@link android.nfc.NfcManager}
14 |
This is the high level manager, used to obtain this device's {@link android.nfc.NfcAdapter}. You can 15 | acquire an instance using {@link android.content.Context#getSystemService}.
16 |
{@link android.nfc.NfcAdapter}
17 |
This represents the device's NFC adapter, which is your entry-point to performing NFC 18 | operations. You can acquire an instance with {@link android.nfc.NfcManager#getDefaultAdapter}, or 19 | {@link android.nfc.NfcAdapter#getDefaultAdapter(android.content.Context)}.
20 |
{@link android.nfc.NdefMessage}
21 |
Represents an NDEF data message, which is the standard format in which "records" 22 | carrying data are transmitted between devices and tags. Your application can receive these 23 | messages from an {@link android.nfc.NfcAdapter#ACTION_TAG_DISCOVERED} intent.
24 |
{@link android.nfc.NdefRecord}
25 |
Represents a record, which is delivered in a {@link android.nfc.NdefMessage} and describes the 26 | type of data being shared and carries the data itself.
27 |
28 | 29 |

Note: 30 | Not all Android-powered devices provide NFC functionality.

31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /core/java/android/nfc/INfcTag.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc; 18 | 19 | import android.nfc.NdefMessage; 20 | import android.nfc.Tag; 21 | import android.nfc.TransceiveResult; 22 | 23 | /** 24 | * @hide 25 | */ 26 | interface INfcTag 27 | { 28 | int connect(int nativeHandle, int technology); 29 | int reconnect(int nativeHandle); 30 | int[] getTechList(int nativeHandle); 31 | boolean isNdef(int nativeHandle); 32 | boolean isPresent(int nativeHandle); 33 | TransceiveResult transceive(int nativeHandle, in byte[] data, boolean raw); 34 | 35 | NdefMessage ndefRead(int nativeHandle); 36 | int ndefWrite(int nativeHandle, in NdefMessage msg); 37 | int ndefMakeReadOnly(int nativeHandle); 38 | boolean ndefIsWritable(int nativeHandle); 39 | int formatNdef(int nativeHandle, in byte[] key); 40 | Tag rediscover(int nativehandle); 41 | 42 | int setTimeout(int technology, int timeout); 43 | int getTimeout(int technology); 44 | void resetTimeouts(); 45 | boolean canMakeReadOnly(int ndefType); 46 | int getMaxTransceiveLength(int technology); 47 | boolean getExtendedLengthApdusSupported(); 48 | } 49 | -------------------------------------------------------------------------------- /core/java/android/nfc/INfcCardEmulation.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc; 18 | 19 | import android.content.ComponentName; 20 | import android.nfc.cardemulation.AidGroup; 21 | import android.nfc.cardemulation.ApduServiceInfo; 22 | import android.os.RemoteCallback; 23 | 24 | /** 25 | * @hide 26 | */ 27 | interface INfcCardEmulation 28 | { 29 | boolean isDefaultServiceForCategory(int userHandle, in ComponentName service, String category); 30 | boolean isDefaultServiceForAid(int userHandle, in ComponentName service, String aid); 31 | boolean setDefaultServiceForCategory(int userHandle, in ComponentName service, String category); 32 | boolean setDefaultForNextTap(int userHandle, in ComponentName service); 33 | boolean registerAidGroupForService(int userHandle, in ComponentName service, in AidGroup aidGroup); 34 | AidGroup getAidGroupForService(int userHandle, in ComponentName service, String category); 35 | boolean removeAidGroupForService(int userHandle, in ComponentName service, String category); 36 | List getServices(int userHandle, in String category); 37 | boolean setPreferredService(in ComponentName service); 38 | boolean unsetPreferredService(); 39 | boolean supportsAidPrefixRegistration(); 40 | } 41 | -------------------------------------------------------------------------------- /core/java/android/se/omapi/ISecureElementReader.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017, The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | /* 17 | * Contributed by: Giesecke & Devrient GmbH. 18 | */ 19 | 20 | package android.se.omapi; 21 | 22 | import android.se.omapi.ISecureElementSession; 23 | 24 | /** @hide */ 25 | interface ISecureElementReader { 26 | 27 | /** 28 | * Returns true if a card is present in the specified reader. 29 | * Returns false if a card is not present in the specified reader. 30 | */ 31 | boolean isSecureElementPresent(); 32 | 33 | /** 34 | * Connects to a secure element in this reader.
35 | * This method prepares (initialises) the Secure Element for communication 36 | * before the Session object is returned (e.g. powers the Secure Element by 37 | * ICC ON if its not already on). There might be multiple sessions opened at 38 | * the same time on the same reader. The system ensures the interleaving of 39 | * APDUs between the respective sessions. 40 | * 41 | * @return a Session object to be used to create Channels. 42 | */ 43 | ISecureElementSession openSession(); 44 | 45 | /** 46 | * Close all the sessions opened on this reader. All the channels opened by 47 | * all these sessions will be closed. 48 | */ 49 | void closeSessions(); 50 | 51 | } 52 | -------------------------------------------------------------------------------- /core/java/android/nfc/NfcEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc; 18 | 19 | /** 20 | * Wraps information associated with any NFC event. 21 | * 22 | *

Immutable object, with direct access to the (final) fields. 23 | * 24 | *

An {@link NfcEvent} object is usually included in callbacks from 25 | * {@link NfcAdapter}. Check the documentation of the callback to see 26 | * which fields may be set. 27 | * 28 | *

This wrapper object is used (instead of parameters 29 | * in the callback) because it allows new fields to be added without breaking 30 | * API compatibility. 31 | * 32 | * @see NfcAdapter.OnNdefPushCompleteCallback#onNdefPushComplete 33 | * @see NfcAdapter.CreateNdefMessageCallback#createNdefMessage 34 | */ 35 | public final class NfcEvent { 36 | /** 37 | * The {@link NfcAdapter} associated with the NFC event. 38 | */ 39 | public final NfcAdapter nfcAdapter; 40 | 41 | /** 42 | * The major LLCP version number of the peer associated with the NFC event. 43 | */ 44 | public final int peerLlcpMajorVersion; 45 | 46 | /** 47 | * The minor LLCP version number of the peer associated with the NFC event. 48 | */ 49 | public final int peerLlcpMinorVersion; 50 | 51 | NfcEvent(NfcAdapter nfcAdapter, byte peerLlcpVersion) { 52 | this.nfcAdapter = nfcAdapter; 53 | this.peerLlcpMajorVersion = (peerLlcpVersion & 0xF0) >> 4; 54 | this.peerLlcpMinorVersion = peerLlcpVersion & 0x0F; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /core/java/android/nfc/TechListParcel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License 15 | */ 16 | 17 | package android.nfc; 18 | 19 | import android.os.Parcel; 20 | import android.os.Parcelable; 21 | 22 | /** @hide */ 23 | public class TechListParcel implements Parcelable { 24 | 25 | private String[][] mTechLists; 26 | 27 | public TechListParcel(String[]... strings) { 28 | mTechLists = strings; 29 | } 30 | 31 | public String[][] getTechLists() { 32 | return mTechLists; 33 | } 34 | 35 | @Override 36 | public int describeContents() { 37 | return 0; 38 | } 39 | 40 | @Override 41 | public void writeToParcel(Parcel dest, int flags) { 42 | int count = mTechLists.length; 43 | dest.writeInt(count); 44 | for (int i = 0; i < count; i++) { 45 | String[] techList = mTechLists[i]; 46 | dest.writeStringArray(techList); 47 | } 48 | } 49 | 50 | public static final Creator CREATOR = new Creator() { 51 | @Override 52 | public TechListParcel createFromParcel(Parcel source) { 53 | int count = source.readInt(); 54 | String[][] techLists = new String[count][]; 55 | for (int i = 0; i < count; i++) { 56 | techLists[i] = source.readStringArray(); 57 | } 58 | return new TechListParcel(techLists); 59 | } 60 | 61 | @Override 62 | public TechListParcel[] newArray(int size) { 63 | return new TechListParcel[size]; 64 | } 65 | }; 66 | } 67 | -------------------------------------------------------------------------------- /core/java/android/nfc/BeamShareData.java: -------------------------------------------------------------------------------- 1 | package android.nfc; 2 | 3 | import android.net.Uri; 4 | import android.os.Parcel; 5 | import android.os.Parcelable; 6 | import android.os.UserHandle; 7 | 8 | /** 9 | * Class to IPC data to be shared over Android Beam. 10 | * Allows bundling NdefMessage, Uris and flags in a single 11 | * IPC call. This is important as we want to reduce the 12 | * amount of IPC calls at "touch time". 13 | * @hide 14 | */ 15 | public final class BeamShareData implements Parcelable { 16 | public final NdefMessage ndefMessage; 17 | public final Uri[] uris; 18 | public final UserHandle userHandle; 19 | public final int flags; 20 | 21 | public BeamShareData(NdefMessage msg, Uri[] uris, UserHandle userHandle, int flags) { 22 | this.ndefMessage = msg; 23 | this.uris = uris; 24 | this.userHandle = userHandle; 25 | this.flags = flags; 26 | } 27 | 28 | @Override 29 | public int describeContents() { 30 | return 0; 31 | } 32 | 33 | @Override 34 | public void writeToParcel(Parcel dest, int flags) { 35 | int urisLength = (uris != null) ? uris.length : 0; 36 | dest.writeParcelable(ndefMessage, 0); 37 | dest.writeInt(urisLength); 38 | if (urisLength > 0) { 39 | dest.writeTypedArray(uris, 0); 40 | } 41 | dest.writeParcelable(userHandle, 0); 42 | dest.writeInt(this.flags); 43 | } 44 | 45 | public static final Parcelable.Creator CREATOR = 46 | new Parcelable.Creator() { 47 | @Override 48 | public BeamShareData createFromParcel(Parcel source) { 49 | Uri[] uris = null; 50 | NdefMessage msg = source.readParcelable(NdefMessage.class.getClassLoader()); 51 | int numUris = source.readInt(); 52 | if (numUris > 0) { 53 | uris = new Uri[numUris]; 54 | source.readTypedArray(uris, Uri.CREATOR); 55 | } 56 | UserHandle userHandle = source.readParcelable(UserHandle.class.getClassLoader()); 57 | int flags = source.readInt(); 58 | 59 | return new BeamShareData(msg, uris, userHandle, flags); 60 | } 61 | 62 | @Override 63 | public BeamShareData[] newArray(int size) { 64 | return new BeamShareData[size]; 65 | } 66 | }; 67 | } 68 | -------------------------------------------------------------------------------- /core/java/android/nfc/NfcManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc; 18 | 19 | import android.annotation.SystemService; 20 | import android.content.Context; 21 | 22 | /** 23 | * High level manager used to obtain an instance of an {@link NfcAdapter}. 24 | *

25 | * Use {@link android.content.Context#getSystemService(java.lang.String)} 26 | * with {@link Context#NFC_SERVICE} to create an {@link NfcManager}, 27 | * then call {@link #getDefaultAdapter} to obtain the {@link NfcAdapter}. 28 | *

29 | * Alternately, you can just call the static helper 30 | * {@link NfcAdapter#getDefaultAdapter(android.content.Context)}. 31 | * 32 | *

33 | *

Developer Guides

34 | *

For more information about using NFC, read the 35 | * Near Field Communication developer guide.

36 | *
37 | * 38 | * @see NfcAdapter#getDefaultAdapter(android.content.Context) 39 | */ 40 | @SystemService(Context.NFC_SERVICE) 41 | public final class NfcManager { 42 | private final NfcAdapter mAdapter; 43 | 44 | /** 45 | * @hide 46 | */ 47 | public NfcManager(Context context) { 48 | NfcAdapter adapter; 49 | context = context.getApplicationContext(); 50 | if (context == null) { 51 | throw new IllegalArgumentException( 52 | "context not associated with any application (using a mock context?)"); 53 | } 54 | try { 55 | adapter = NfcAdapter.getNfcAdapter(context); 56 | } catch (UnsupportedOperationException e) { 57 | adapter = null; 58 | } 59 | mAdapter = adapter; 60 | } 61 | 62 | /** 63 | * Get the default NFC Adapter for this device. 64 | * 65 | * @return the default NFC Adapter 66 | */ 67 | public NfcAdapter getDefaultAdapter() { 68 | return mAdapter; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /core/java/android/se/omapi/ISecureElementSession.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017, The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | /* 17 | * Copyright (c) 2015-2017, The Linux Foundation. 18 | */ 19 | /* 20 | * Contributed by: Giesecke & Devrient GmbH. 21 | */ 22 | 23 | package android.se.omapi; 24 | 25 | import android.se.omapi.ISecureElementChannel; 26 | import android.se.omapi.ISecureElementReader; 27 | import android.se.omapi.ISecureElementListener; 28 | 29 | /** @hide */ 30 | interface ISecureElementSession { 31 | 32 | /** 33 | * Returns the ATR of the connected card or null if the ATR is not available 34 | */ 35 | byte[] getAtr(); 36 | 37 | /** 38 | * Close the connection with the Secure Element. This will close any 39 | * channels opened by this application with this Secure Element. 40 | */ 41 | void close(); 42 | 43 | /** 44 | * Close any channel opened on this session. 45 | */ 46 | void closeChannels(); 47 | 48 | 49 | /** 50 | * Tells if this session is closed. 51 | * 52 | * @return true if the session is closed, false otherwise. 53 | */ 54 | boolean isClosed(); 55 | 56 | /** 57 | * Opens a connection using the basic channel of the card in the 58 | * specified reader and returns a channel handle. Selects the specified 59 | * applet if aid != null. 60 | * Logical channels cannot be opened with this connection. 61 | * Use interface method openLogicalChannel() to open a logical channel. 62 | */ 63 | ISecureElementChannel openBasicChannel(in byte[] aid, in byte p2, 64 | ISecureElementListener listener); 65 | 66 | /** 67 | * Opens a connection using the next free logical channel of the card in the 68 | * specified reader. Selects the specified applet. 69 | * Selection of other applets with this connection is not supported. 70 | */ 71 | ISecureElementChannel openLogicalChannel(in byte[] aid, in byte p2, 72 | ISecureElementListener listener); 73 | } 74 | -------------------------------------------------------------------------------- /core/java/android/se/omapi/ISecureElementChannel.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017, The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | /* 17 | * Contributed by: Giesecke & Devrient GmbH. 18 | */ 19 | 20 | package android.se.omapi; 21 | 22 | import android.se.omapi.ISecureElementSession; 23 | 24 | /** @hide */ 25 | interface ISecureElementChannel { 26 | 27 | /** 28 | * Closes the specified connection and frees internal resources. 29 | * A logical channel will be closed. 30 | */ 31 | void close(); 32 | 33 | /** 34 | * Tells if this channel is closed. 35 | * 36 | * @return true if the channel is closed, 37 | * false otherwise. 38 | */ 39 | boolean isClosed(); 40 | 41 | /** 42 | * Returns a boolean telling if this channel is the basic channel. 43 | * 44 | * @return true if this channel is a basic channel. 45 | * false if this channel is a logical channel. 46 | */ 47 | boolean isBasicChannel(); 48 | 49 | /** 50 | * Returns the data as received from the application select command 51 | * inclusively the status word. The returned byte array contains the data 52 | * bytes in the following order: 53 | * [, ..., , , ] 54 | */ 55 | byte[] getSelectResponse(); 56 | 57 | /** 58 | * Transmits the specified command APDU and returns the response APDU. 59 | * MANAGE channel commands are not supported. 60 | * Selection of applets is not supported in logical channels. 61 | */ 62 | byte[] transmit(in byte[] command); 63 | 64 | /** 65 | * Performs a selection of the next Applet on this channel that matches to 66 | * the partial AID specified in the openBasicChannel(byte[] aid) or 67 | * openLogicalChannel(byte[] aid) method. This mechanism can be used by a 68 | * device application to iterate through all Applets matching to the same 69 | * partial AID. 70 | * If selectNext() returns true a new Applet was successfully selected on 71 | * this channel. 72 | * If no further Applet exists with matches to the partial AID this method 73 | * returns false and the already selected Applet stays selected. 74 | * 75 | * @return true if new Applet was successfully selected. 76 | * false if no further Applet exists which matches the 77 | * partial AID. 78 | */ 79 | boolean selectNext(); 80 | } 81 | -------------------------------------------------------------------------------- /core/java/android/nfc/TransceiveResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011, The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc; 18 | 19 | import android.os.Parcel; 20 | import android.os.Parcelable; 21 | 22 | import java.io.IOException; 23 | 24 | /** 25 | * Class used to pipe transceive result from the NFC service. 26 | * 27 | * @hide 28 | */ 29 | public final class TransceiveResult implements Parcelable { 30 | public static final int RESULT_SUCCESS = 0; 31 | public static final int RESULT_FAILURE = 1; 32 | public static final int RESULT_TAGLOST = 2; 33 | public static final int RESULT_EXCEEDED_LENGTH = 3; 34 | 35 | final int mResult; 36 | final byte[] mResponseData; 37 | 38 | public TransceiveResult(final int result, final byte[] data) { 39 | mResult = result; 40 | mResponseData = data; 41 | } 42 | 43 | public byte[] getResponseOrThrow() throws IOException { 44 | switch (mResult) { 45 | case RESULT_SUCCESS: 46 | return mResponseData; 47 | case RESULT_TAGLOST: 48 | throw new TagLostException("Tag was lost."); 49 | case RESULT_EXCEEDED_LENGTH: 50 | throw new IOException("Transceive length exceeds supported maximum"); 51 | default: 52 | throw new IOException("Transceive failed"); 53 | } 54 | } 55 | 56 | @Override 57 | public int describeContents() { 58 | return 0; 59 | } 60 | 61 | @Override 62 | public void writeToParcel(Parcel dest, int flags) { 63 | dest.writeInt(mResult); 64 | if (mResult == RESULT_SUCCESS) { 65 | dest.writeInt(mResponseData.length); 66 | dest.writeByteArray(mResponseData); 67 | } 68 | } 69 | 70 | public static final Parcelable.Creator CREATOR = 71 | new Parcelable.Creator() { 72 | @Override 73 | public TransceiveResult createFromParcel(Parcel in) { 74 | int result = in.readInt(); 75 | byte[] responseData; 76 | 77 | if (result == RESULT_SUCCESS) { 78 | int responseLength = in.readInt(); 79 | responseData = new byte[responseLength]; 80 | in.readByteArray(responseData); 81 | } else { 82 | responseData = null; 83 | } 84 | return new TransceiveResult(result, responseData); 85 | } 86 | 87 | @Override 88 | public TransceiveResult[] newArray(int size) { 89 | return new TransceiveResult[size]; 90 | } 91 | }; 92 | 93 | } 94 | -------------------------------------------------------------------------------- /core/java/android/nfc/INfcAdapter.aidl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | /****************************************************************************** 17 | * 18 | * The original Work has been changed by NXP Semiconductors. 19 | * 20 | * Copyright (C) 2015-2018 NXP Semiconductors 21 | * 22 | * Licensed under the Apache License, Version 2.0 (the "License"); 23 | * you may not use this file except in compliance with the License. 24 | * You may obtain a copy of the License at 25 | * 26 | * http://www.apache.org/licenses/LICENSE-2.0 27 | * 28 | * Unless required by applicable law or agreed to in writing, software 29 | * distributed under the License is distributed on an "AS IS" BASIS, 30 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 31 | * See the License for the specific language governing permissions and 32 | * limitations under the License. 33 | * 34 | ******************************************************************************/ 35 | 36 | 37 | package android.nfc; 38 | 39 | import android.app.PendingIntent; 40 | import android.content.IntentFilter; 41 | import android.nfc.BeamShareData; 42 | import android.nfc.NdefMessage; 43 | import android.nfc.Tag; 44 | import android.nfc.TechListParcel; 45 | import android.nfc.IAppCallback; 46 | import android.nfc.INfcAdapterExtras; 47 | import android.nfc.INfcTag; 48 | import android.nfc.INfcCardEmulation; 49 | import android.nfc.INfcFCardEmulation; 50 | import android.nfc.INfcUnlockHandler; 51 | import android.nfc.ITagRemovedCallback; 52 | import android.nfc.INfcDta; 53 | import android.os.Bundle; 54 | import android.os.IBinder; 55 | 56 | /** 57 | * @hide 58 | */ 59 | interface INfcAdapter 60 | { 61 | INfcTag getNfcTagInterface(); 62 | INfcCardEmulation getNfcCardEmulationInterface(); 63 | INfcFCardEmulation getNfcFCardEmulationInterface(); 64 | INfcAdapterExtras getNfcAdapterExtrasInterface(in String pkg); 65 | INfcDta getNfcDtaInterface(in String pkg); 66 | IBinder getNfcAdapterVendorInterface(in String vendor); 67 | 68 | int getState(); 69 | boolean disable(boolean saveState); 70 | boolean enable(); 71 | boolean enableNdefPush(); 72 | boolean disableNdefPush(); 73 | boolean isNdefPushEnabled(); 74 | void pausePolling(int timeoutInMs); 75 | void resumePolling(); 76 | void verifyNfcPermission(); 77 | 78 | void setForegroundDispatch(in PendingIntent intent, 79 | in IntentFilter[] filters, in TechListParcel techLists); 80 | void setAppCallback(in IAppCallback callback); 81 | oneway void invokeBeam(); 82 | oneway void invokeBeamInternal(in BeamShareData shareData); 83 | 84 | boolean ignore(int nativeHandle, int debounceMs, ITagRemovedCallback callback); 85 | 86 | void dispatch(in Tag tag); 87 | 88 | void setReaderMode (IBinder b, IAppCallback callback, int flags, in Bundle extras); 89 | void setP2pModes(int initatorModes, int targetModes); 90 | void addNfcUnlockHandler(INfcUnlockHandler unlockHandler, in int[] techList); 91 | void removeNfcUnlockHandler(INfcUnlockHandler unlockHandler); 92 | } 93 | -------------------------------------------------------------------------------- /core/java/android/nfc/ErrorCodes.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010, The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc; 18 | 19 | /** 20 | * This class defines all the error codes that can be returned by the service 21 | * and producing an exception on the application level. These are needed since 22 | * binders does not support exceptions. 23 | * 24 | * @hide 25 | */ 26 | public class ErrorCodes { 27 | 28 | public static boolean isError(int code) { 29 | if (code < 0) { 30 | return true; 31 | } else { 32 | return false; 33 | } 34 | } 35 | 36 | public static String asString(int code) { 37 | switch (code) { 38 | case SUCCESS: return "SUCCESS"; 39 | case ERROR_IO: return "IO"; 40 | case ERROR_CANCELLED: return "CANCELLED"; 41 | case ERROR_TIMEOUT: return "TIMEOUT"; 42 | case ERROR_BUSY: return "BUSY"; 43 | case ERROR_CONNECT: return "CONNECT/DISCONNECT"; 44 | // case ERROR_DISCONNECT: return "DISCONNECT"; 45 | case ERROR_READ: return "READ"; 46 | case ERROR_WRITE: return "WRITE"; 47 | case ERROR_INVALID_PARAM: return "INVALID_PARAM"; 48 | case ERROR_INSUFFICIENT_RESOURCES: return "INSUFFICIENT_RESOURCES"; 49 | case ERROR_SOCKET_CREATION: return "SOCKET_CREATION"; 50 | case ERROR_SOCKET_NOT_CONNECTED: return "SOCKET_NOT_CONNECTED"; 51 | case ERROR_BUFFER_TO_SMALL: return "BUFFER_TO_SMALL"; 52 | case ERROR_SAP_USED: return "SAP_USED"; 53 | case ERROR_SERVICE_NAME_USED: return "SERVICE_NAME_USED"; 54 | case ERROR_SOCKET_OPTIONS: return "SOCKET_OPTIONS"; 55 | case ERROR_NFC_ON: return "NFC_ON"; 56 | case ERROR_NOT_INITIALIZED: return "NOT_INITIALIZED"; 57 | case ERROR_SE_ALREADY_SELECTED: return "SE_ALREADY_SELECTED"; 58 | case ERROR_SE_CONNECTED: return "SE_CONNECTED"; 59 | case ERROR_NO_SE_CONNECTED: return "NO_SE_CONNECTED"; 60 | case ERROR_NOT_SUPPORTED: return "NOT_SUPPORTED"; 61 | default: return "UNKNOWN ERROR"; 62 | } 63 | } 64 | 65 | public static final int SUCCESS = 0; 66 | 67 | public static final int ERROR_IO = -1; 68 | 69 | public static final int ERROR_CANCELLED = -2; 70 | 71 | public static final int ERROR_TIMEOUT = -3; 72 | 73 | public static final int ERROR_BUSY = -4; 74 | 75 | public static final int ERROR_CONNECT = -5; 76 | 77 | public static final int ERROR_DISCONNECT = -5; 78 | 79 | public static final int ERROR_READ = -6; 80 | 81 | public static final int ERROR_WRITE = -7; 82 | 83 | public static final int ERROR_INVALID_PARAM = -8; 84 | 85 | public static final int ERROR_INSUFFICIENT_RESOURCES = -9; 86 | 87 | public static final int ERROR_SOCKET_CREATION = -10; 88 | 89 | public static final int ERROR_SOCKET_NOT_CONNECTED = -11; 90 | 91 | public static final int ERROR_BUFFER_TO_SMALL = -12; 92 | 93 | public static final int ERROR_SAP_USED = -13; 94 | 95 | public static final int ERROR_SERVICE_NAME_USED = -14; 96 | 97 | public static final int ERROR_SOCKET_OPTIONS = -15; 98 | 99 | public static final int ERROR_NFC_ON = -16; 100 | 101 | public static final int ERROR_NOT_INITIALIZED = -17; 102 | 103 | public static final int ERROR_SE_ALREADY_SELECTED = -18; 104 | 105 | public static final int ERROR_SE_CONNECTED = -19; 106 | 107 | public static final int ERROR_NO_SE_CONNECTED = -20; 108 | 109 | public static final int ERROR_NOT_SUPPORTED = -21; 110 | 111 | } 112 | -------------------------------------------------------------------------------- /core/java/android/nfc/tech/NfcV.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc.tech; 18 | 19 | import android.nfc.Tag; 20 | import android.os.Bundle; 21 | import android.os.RemoteException; 22 | 23 | import java.io.IOException; 24 | 25 | /** 26 | * Provides access to NFC-V (ISO 15693) properties and I/O operations on a {@link Tag}. 27 | * 28 | *

Acquire a {@link NfcV} object using {@link #get}. 29 | *

The primary NFC-V I/O operation is {@link #transceive}. Applications must 30 | * implement their own protocol stack on top of {@link #transceive}. 31 | * 32 | *

Note: Methods that perform I/O operations 33 | * require the {@link android.Manifest.permission#NFC} permission. 34 | */ 35 | public final class NfcV extends BasicTagTechnology { 36 | /** @hide */ 37 | public static final String EXTRA_RESP_FLAGS = "respflags"; 38 | 39 | /** @hide */ 40 | public static final String EXTRA_DSFID = "dsfid"; 41 | 42 | private byte mRespFlags; 43 | private byte mDsfId; 44 | 45 | /** 46 | * Get an instance of {@link NfcV} for the given tag. 47 | *

Returns null if {@link NfcV} was not enumerated in {@link Tag#getTechList}. 48 | * This indicates the tag does not support NFC-V. 49 | *

Does not cause any RF activity and does not block. 50 | * 51 | * @param tag an NFC-V compatible tag 52 | * @return NFC-V object 53 | */ 54 | public static NfcV get(Tag tag) { 55 | if (!tag.hasTech(TagTechnology.NFC_V)) return null; 56 | try { 57 | return new NfcV(tag); 58 | } catch (RemoteException e) { 59 | return null; 60 | } 61 | } 62 | 63 | /** @hide */ 64 | public NfcV(Tag tag) throws RemoteException { 65 | super(tag, TagTechnology.NFC_V); 66 | Bundle extras = tag.getTechExtras(TagTechnology.NFC_V); 67 | mRespFlags = extras.getByte(EXTRA_RESP_FLAGS); 68 | mDsfId = extras.getByte(EXTRA_DSFID); 69 | } 70 | 71 | /** 72 | * Return the Response Flag bytes from tag discovery. 73 | * 74 | *

Does not cause any RF activity and does not block. 75 | * 76 | * @return Response Flag bytes 77 | */ 78 | public byte getResponseFlags() { 79 | return mRespFlags; 80 | } 81 | 82 | /** 83 | * Return the DSF ID bytes from tag discovery. 84 | * 85 | *

Does not cause any RF activity and does not block. 86 | * 87 | * @return DSF ID bytes 88 | */ 89 | public byte getDsfId() { 90 | return mDsfId; 91 | } 92 | 93 | /** 94 | * Send raw NFC-V commands to the tag and receive the response. 95 | * 96 | *

Applications must not append the CRC to the payload, 97 | * it will be automatically calculated. The application does 98 | * provide FLAGS, CMD and PARAMETER bytes. 99 | * 100 | *

Use {@link #getMaxTransceiveLength} to retrieve the maximum amount of bytes 101 | * that can be sent with {@link #transceive}. 102 | * 103 | *

This is an I/O operation and will block until complete. It must 104 | * not be called from the main application thread. A blocked call will be canceled with 105 | * {@link IOException} if {@link #close} is called from another thread. 106 | * 107 | *

Requires the {@link android.Manifest.permission#NFC} permission. 108 | * 109 | * @param data bytes to send 110 | * @return bytes received in response 111 | * @throws TagLostException if the tag leaves the field 112 | * @throws IOException if there is an I/O failure, or this operation is canceled 113 | */ 114 | public byte[] transceive(byte[] data) throws IOException { 115 | return transceive(data, true); 116 | } 117 | 118 | 119 | /** 120 | * Return the maximum number of bytes that can be sent with {@link #transceive}. 121 | * @return the maximum number of bytes that can be sent with {@link #transceive}. 122 | */ 123 | public int getMaxTransceiveLength() { 124 | return getMaxTransceiveLengthInternal(); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /core/java/android/nfc/tech/NfcB.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc.tech; 18 | 19 | import android.nfc.Tag; 20 | import android.os.Bundle; 21 | import android.os.RemoteException; 22 | 23 | import java.io.IOException; 24 | 25 | /** 26 | * Provides access to NFC-B (ISO 14443-3B) properties and I/O operations on a {@link Tag}. 27 | * 28 | *

Acquire a {@link NfcB} object using {@link #get}. 29 | *

The primary NFC-B I/O operation is {@link #transceive}. Applications must 30 | * implement their own protocol stack on top of {@link #transceive}. 31 | * 32 | *

Note: Methods that perform I/O operations 33 | * require the {@link android.Manifest.permission#NFC} permission. 34 | */ 35 | public final class NfcB extends BasicTagTechnology { 36 | /** @hide */ 37 | public static final String EXTRA_APPDATA = "appdata"; 38 | /** @hide */ 39 | public static final String EXTRA_PROTINFO = "protinfo"; 40 | 41 | private byte[] mAppData; 42 | private byte[] mProtInfo; 43 | 44 | /** 45 | * Get an instance of {@link NfcB} for the given tag. 46 | *

Returns null if {@link NfcB} was not enumerated in {@link Tag#getTechList}. 47 | * This indicates the tag does not support NFC-B. 48 | *

Does not cause any RF activity and does not block. 49 | * 50 | * @param tag an NFC-B compatible tag 51 | * @return NFC-B object 52 | */ 53 | public static NfcB get(Tag tag) { 54 | if (!tag.hasTech(TagTechnology.NFC_B)) return null; 55 | try { 56 | return new NfcB(tag); 57 | } catch (RemoteException e) { 58 | return null; 59 | } 60 | } 61 | 62 | /** @hide */ 63 | public NfcB(Tag tag) throws RemoteException { 64 | super(tag, TagTechnology.NFC_B); 65 | Bundle extras = tag.getTechExtras(TagTechnology.NFC_B); 66 | mAppData = extras.getByteArray(EXTRA_APPDATA); 67 | mProtInfo = extras.getByteArray(EXTRA_PROTINFO); 68 | } 69 | 70 | /** 71 | * Return the Application Data bytes from ATQB/SENSB_RES at tag discovery. 72 | * 73 | *

Does not cause any RF activity and does not block. 74 | * 75 | * @return Application Data bytes from ATQB/SENSB_RES bytes 76 | */ 77 | public byte[] getApplicationData() { 78 | return mAppData; 79 | } 80 | 81 | /** 82 | * Return the Protocol Info bytes from ATQB/SENSB_RES at tag discovery. 83 | * 84 | *

Does not cause any RF activity and does not block. 85 | * 86 | * @return Protocol Info bytes from ATQB/SENSB_RES bytes 87 | */ 88 | public byte[] getProtocolInfo() { 89 | return mProtInfo; 90 | } 91 | 92 | /** 93 | * Send raw NFC-B commands to the tag and receive the response. 94 | * 95 | *

Applications must not append the EoD (CRC) to the payload, 96 | * it will be automatically calculated. 97 | *

Applications must not send commands that manage the polling 98 | * loop and initialization (SENSB_REQ, SLOT_MARKER etc). 99 | * 100 | *

Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes 101 | * that can be sent with {@link #transceive}. 102 | * 103 | *

This is an I/O operation and will block until complete. It must 104 | * not be called from the main application thread. A blocked call will be canceled with 105 | * {@link IOException} if {@link #close} is called from another thread. 106 | * 107 | *

Requires the {@link android.Manifest.permission#NFC} permission. 108 | * 109 | * @param data bytes to send 110 | * @return bytes received in response 111 | * @throws TagLostException if the tag leaves the field 112 | * @throws IOException if there is an I/O failure, or this operation is canceled 113 | */ 114 | public byte[] transceive(byte[] data) throws IOException { 115 | return transceive(data, true); 116 | } 117 | 118 | /** 119 | * Return the maximum number of bytes that can be sent with {@link #transceive}. 120 | * @return the maximum number of bytes that can be sent with {@link #transceive}. 121 | */ 122 | public int getMaxTransceiveLength() { 123 | return getMaxTransceiveLengthInternal(); 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /core/java/android/nfc/tech/NfcBarcode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc.tech; 18 | 19 | import android.nfc.Tag; 20 | import android.os.Bundle; 21 | import android.os.RemoteException; 22 | 23 | /** 24 | * Provides access to tags containing just a barcode. 25 | * 26 | *

Acquire an {@link NfcBarcode} object using {@link #get}. 27 | * 28 | */ 29 | public final class NfcBarcode extends BasicTagTechnology { 30 | 31 | /** Kovio Tags */ 32 | public static final int TYPE_KOVIO = 1; 33 | public static final int TYPE_UNKNOWN = -1; 34 | 35 | /** @hide */ 36 | public static final String EXTRA_BARCODE_TYPE = "barcodetype"; 37 | 38 | private int mType; 39 | 40 | /** 41 | * Get an instance of {@link NfcBarcode} for the given tag. 42 | * 43 | *

Returns null if {@link NfcBarcode} was not enumerated in {@link Tag#getTechList}. 44 | * 45 | *

Does not cause any RF activity and does not block. 46 | * 47 | * @param tag an NfcBarcode compatible tag 48 | * @return NfcBarcode object 49 | */ 50 | public static NfcBarcode get(Tag tag) { 51 | if (!tag.hasTech(TagTechnology.NFC_BARCODE)) return null; 52 | try { 53 | return new NfcBarcode(tag); 54 | } catch (RemoteException e) { 55 | return null; 56 | } 57 | } 58 | 59 | /** 60 | * Internal constructor, to be used by NfcAdapter 61 | * @hide 62 | */ 63 | public NfcBarcode(Tag tag) throws RemoteException { 64 | super(tag, TagTechnology.NFC_BARCODE); 65 | Bundle extras = tag.getTechExtras(TagTechnology.NFC_BARCODE); 66 | if (extras != null) { 67 | mType = extras.getInt(EXTRA_BARCODE_TYPE); 68 | } else { 69 | throw new NullPointerException("NfcBarcode tech extras are null."); 70 | } 71 | } 72 | 73 | /** 74 | * Returns the NFC Barcode tag type. 75 | * 76 | *

Currently only one of {@link #TYPE_KOVIO} or {@link #TYPE_UNKNOWN}. 77 | * 78 | *

Does not cause any RF activity and does not block. 79 | * 80 | * @return the NFC Barcode tag type 81 | */ 82 | public int getType() { 83 | return mType; 84 | } 85 | 86 | /** 87 | * Returns the barcode of an NfcBarcode tag. 88 | * 89 | *

Tags of {@link #TYPE_KOVIO} return 16 bytes: 90 | *

    91 | *

    The first byte is 0x80 ORd with a manufacturer ID, corresponding 92 | * to ISO/IEC 7816-6. 93 | *

    The second byte describes the payload data format. Defined data 94 | * format types include the following:

      95 | *
    • 0x00: Reserved for manufacturer assignment
    • 96 | *
    • 0x01: 96-bit URL with "http://www." prefix
    • 97 | *
    • 0x02: 96-bit URL with "https://www." prefix
    • 98 | *
    • 0x03: 96-bit URL with "http://" prefix
    • 99 | *
    • 0x04: 96-bit URL with "https://" prefix
    • 100 | *
    • 0x05: 96-bit GS1 EPC
    • 101 | *
    • 0x06-0xFF: reserved
    • 102 | *
    103 | *

    The following 12 bytes are payload:

    111 | *

    The last 2 bytes comprise the CRC. 112 | *

113 | *

Does not cause any RF activity and does not block. 114 | * 115 | * @return a byte array containing the barcode 116 | * @see 117 | * Thinfilm NFC Barcode tag specification (previously Kovio NFC Barcode) 118 | * @see 119 | * Thinfilm NFC Barcode data format (previously Kovio NFC Barcode) 120 | */ 121 | public byte[] getBarcode() { 122 | switch (mType) { 123 | case TYPE_KOVIO: 124 | // For Kovio tags the barcode matches the ID 125 | return mTag.getId(); 126 | default: 127 | return null; 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /core/java/android/nfc/dta/NfcDta.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc.dta; 18 | 19 | import android.content.Context; 20 | import android.nfc.INfcDta; 21 | import android.nfc.NfcAdapter; 22 | import android.os.RemoteException; 23 | import android.util.Log; 24 | 25 | import java.util.HashMap; 26 | 27 | /** 28 | * This class provides the primary API for DTA operations. 29 | * @hide 30 | */ 31 | public final class NfcDta { 32 | private static final String TAG = "NfcDta"; 33 | 34 | private static INfcDta sService; 35 | private static HashMap sNfcDtas = new HashMap(); 36 | 37 | private final Context mContext; 38 | 39 | private NfcDta(Context context, INfcDta service) { 40 | mContext = context.getApplicationContext(); 41 | sService = service; 42 | } 43 | 44 | /** 45 | * Helper to get an instance of this class. 46 | * 47 | * @param adapter A reference to an NfcAdapter object. 48 | * @return 49 | */ 50 | public static synchronized NfcDta getInstance(NfcAdapter adapter) { 51 | if (adapter == null) throw new NullPointerException("NfcAdapter is null"); 52 | Context context = adapter.getContext(); 53 | if (context == null) { 54 | Log.e(TAG, "NfcAdapter context is null."); 55 | throw new UnsupportedOperationException(); 56 | } 57 | 58 | NfcDta manager = sNfcDtas.get(context); 59 | if (manager == null) { 60 | INfcDta service = adapter.getNfcDtaInterface(); 61 | if (service == null) { 62 | Log.e(TAG, "This device does not implement the INfcDta interface."); 63 | throw new UnsupportedOperationException(); 64 | } 65 | manager = new NfcDta(context, service); 66 | sNfcDtas.put(context, manager); 67 | } 68 | return manager; 69 | } 70 | 71 | /** 72 | * Enables DTA mode 73 | * 74 | * @return true/false if enabling was successful 75 | */ 76 | public boolean enableDta() { 77 | try { 78 | sService.enableDta(); 79 | } catch (RemoteException e) { 80 | return false; 81 | } 82 | return true; 83 | } 84 | 85 | /** 86 | * Disables DTA mode 87 | * 88 | * @return true/false if disabling was successful 89 | */ 90 | public boolean disableDta() { 91 | try { 92 | sService.disableDta(); 93 | } catch (RemoteException e) { 94 | return false; 95 | } 96 | return true; 97 | } 98 | 99 | /** 100 | * Enables Server 101 | * 102 | * @return true/false if enabling was successful 103 | */ 104 | public boolean enableServer(String serviceName, int serviceSap, int miu, 105 | int rwSize, int testCaseId) { 106 | try { 107 | return sService.enableServer(serviceName, serviceSap, miu, rwSize, testCaseId); 108 | } catch (RemoteException e) { 109 | return false; 110 | } 111 | } 112 | 113 | /** 114 | * Disables Server 115 | * 116 | * @return true/false if disabling was successful 117 | */ 118 | public boolean disableServer() { 119 | try { 120 | sService.disableServer(); 121 | } catch (RemoteException e) { 122 | return false; 123 | } 124 | return true; 125 | } 126 | 127 | /** 128 | * Enables Client 129 | * 130 | * @return true/false if enabling was successful 131 | */ 132 | public boolean enableClient(String serviceName, int miu, int rwSize, 133 | int testCaseId) { 134 | try { 135 | return sService.enableClient(serviceName, miu, rwSize, testCaseId); 136 | } catch (RemoteException e) { 137 | return false; 138 | } 139 | } 140 | 141 | /** 142 | * Disables client 143 | * 144 | * @return true/false if disabling was successful 145 | */ 146 | public boolean disableClient() { 147 | try { 148 | sService.disableClient(); 149 | } catch (RemoteException e) { 150 | return false; 151 | } 152 | return true; 153 | } 154 | 155 | /** 156 | * Registers Message Service 157 | * 158 | * @return true/false if registration was successful 159 | */ 160 | public boolean registerMessageService(String msgServiceName) { 161 | try { 162 | return sService.registerMessageService(msgServiceName); 163 | } catch (RemoteException e) { 164 | return false; 165 | } 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /core/java/android/nfc/tech/BasicTagTechnology.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc.tech; 18 | 19 | import android.nfc.ErrorCodes; 20 | import android.nfc.Tag; 21 | import android.nfc.TransceiveResult; 22 | import android.os.RemoteException; 23 | import android.util.Log; 24 | 25 | import java.io.IOException; 26 | 27 | /** 28 | * A base class for tag technologies that are built on top of transceive(). 29 | */ 30 | abstract class BasicTagTechnology implements TagTechnology { 31 | private static final String TAG = "NFC"; 32 | 33 | final Tag mTag; 34 | 35 | boolean mIsConnected; 36 | int mSelectedTechnology; 37 | 38 | BasicTagTechnology(Tag tag, int tech) throws RemoteException { 39 | mTag = tag; 40 | mSelectedTechnology = tech; 41 | } 42 | 43 | @Override 44 | public Tag getTag() { 45 | return mTag; 46 | } 47 | 48 | /** Internal helper to throw IllegalStateException if the technology isn't connected */ 49 | void checkConnected() { 50 | if ((mTag.getConnectedTechnology() != mSelectedTechnology) || 51 | (mTag.getConnectedTechnology() == -1)) { 52 | throw new IllegalStateException("Call connect() first!"); 53 | } 54 | } 55 | 56 | @Override 57 | public boolean isConnected() { 58 | if (!mIsConnected) { 59 | return false; 60 | } 61 | 62 | try { 63 | return mTag.getTagService().isPresent(mTag.getServiceHandle()); 64 | } catch (RemoteException e) { 65 | Log.e(TAG, "NFC service dead", e); 66 | return false; 67 | } 68 | } 69 | 70 | @Override 71 | public void connect() throws IOException { 72 | try { 73 | int errorCode = mTag.getTagService().connect(mTag.getServiceHandle(), 74 | mSelectedTechnology); 75 | 76 | if (errorCode == ErrorCodes.SUCCESS) { 77 | // Store this in the tag object 78 | mTag.setConnectedTechnology(mSelectedTechnology); 79 | mIsConnected = true; 80 | } else if (errorCode == ErrorCodes.ERROR_NOT_SUPPORTED) { 81 | throw new UnsupportedOperationException("Connecting to " + 82 | "this technology is not supported by the NFC " + 83 | "adapter."); 84 | } else { 85 | throw new IOException(); 86 | } 87 | } catch (RemoteException e) { 88 | Log.e(TAG, "NFC service dead", e); 89 | throw new IOException("NFC service died"); 90 | } 91 | } 92 | 93 | /** @hide */ 94 | @Override 95 | public void reconnect() throws IOException { 96 | if (!mIsConnected) { 97 | throw new IllegalStateException("Technology not connected yet"); 98 | } 99 | 100 | try { 101 | int errorCode = mTag.getTagService().reconnect(mTag.getServiceHandle()); 102 | 103 | if (errorCode != ErrorCodes.SUCCESS) { 104 | mIsConnected = false; 105 | mTag.setTechnologyDisconnected(); 106 | throw new IOException(); 107 | } 108 | } catch (RemoteException e) { 109 | mIsConnected = false; 110 | mTag.setTechnologyDisconnected(); 111 | Log.e(TAG, "NFC service dead", e); 112 | throw new IOException("NFC service died"); 113 | } 114 | } 115 | 116 | @Override 117 | public void close() throws IOException { 118 | try { 119 | /* Note that we don't want to physically disconnect the tag, 120 | * but just reconnect to it to reset its state 121 | */ 122 | mTag.getTagService().resetTimeouts(); 123 | mTag.getTagService().reconnect(mTag.getServiceHandle()); 124 | } catch (RemoteException e) { 125 | Log.e(TAG, "NFC service dead", e); 126 | } finally { 127 | mIsConnected = false; 128 | mTag.setTechnologyDisconnected(); 129 | } 130 | } 131 | 132 | /** Internal getMaxTransceiveLength() */ 133 | int getMaxTransceiveLengthInternal() { 134 | try { 135 | return mTag.getTagService().getMaxTransceiveLength(mSelectedTechnology); 136 | } catch (RemoteException e) { 137 | Log.e(TAG, "NFC service dead", e); 138 | return 0; 139 | } 140 | } 141 | /** Internal transceive */ 142 | byte[] transceive(byte[] data, boolean raw) throws IOException { 143 | checkConnected(); 144 | 145 | try { 146 | TransceiveResult result = mTag.getTagService().transceive(mTag.getServiceHandle(), 147 | data, raw); 148 | if (result == null) { 149 | throw new IOException("transceive failed"); 150 | } else { 151 | return result.getResponseOrThrow(); 152 | } 153 | } catch (RemoteException e) { 154 | Log.e(TAG, "NFC service dead", e); 155 | throw new IOException("NFC service died"); 156 | } 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /core/java/android/se/omapi/Reader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | /* 17 | * Copyright (c) 2015-2017, The Linux Foundation. 18 | */ 19 | /* 20 | * Contributed by: Giesecke & Devrient GmbH. 21 | */ 22 | 23 | package android.se.omapi; 24 | 25 | import android.annotation.NonNull; 26 | import android.os.RemoteException; 27 | import android.os.ServiceSpecificException; 28 | import android.util.Log; 29 | 30 | import java.io.IOException; 31 | 32 | /** 33 | * Instances of this class represent Secure Element Readers supported to this 34 | * device. These Readers can be physical devices or virtual devices. They can be 35 | * removable or not. They can contain Secure Element that can or cannot be 36 | * removed. 37 | * 38 | * @see GlobalPlatform Open Mobile API 39 | */ 40 | public final class Reader { 41 | 42 | private static final String TAG = "OMAPI.Reader"; 43 | private final String mName; 44 | private final SEService mService; 45 | private ISecureElementReader mReader; 46 | private final Object mLock = new Object(); 47 | 48 | 49 | Reader(@NonNull SEService service, @NonNull String name, @NonNull ISecureElementReader reader) { 50 | if (reader == null || service == null || name == null) { 51 | throw new IllegalArgumentException("Parameters cannot be null"); 52 | } 53 | mName = name; 54 | mService = service; 55 | mReader = reader; 56 | } 57 | 58 | /** 59 | * Return the name of this reader. 60 | *

    61 | *
  • If this reader is a SIM reader, then its name must be "SIM[Slot]".
  • 62 | *
  • If the reader is a SD or micro SD reader, then its name must be "SD[Slot]"
  • 63 | *
  • If the reader is a embedded SE reader, then its name must be "eSE[Slot]"
  • 64 | *
65 | * Slot is a decimal number without leading zeros. The Numbering must start with 1 66 | * (e.g. SIM1, SIM2, ... or SD1, SD2, ... or eSE1, eSE2, ...). 67 | * The slot number “1” for a reader is optional 68 | * (SIM and SIM1 are both valid for the first SIM-reader, 69 | * but if there are two readers then the second reader must be named SIM2). 70 | * This applies also for other SD or SE readers. 71 | * 72 | * @return the reader name, as a String. 73 | */ 74 | public @NonNull String getName() { 75 | return mName; 76 | } 77 | 78 | /** 79 | * Connects to a Secure Element in this reader.
80 | * This method prepares (initialises) the Secure Element for communication 81 | * before the Session object is returned (e.g. powers the Secure Element by 82 | * ICC ON if its not already on). There might be multiple sessions opened at 83 | * the same time on the same reader. The system ensures the interleaving of 84 | * APDUs between the respective sessions. 85 | * 86 | * @throws IOException if something went wrong with the communicating to the 87 | * Secure Element or the reader. 88 | * @return a Session object to be used to create Channels. 89 | */ 90 | public @NonNull Session openSession() throws IOException { 91 | if (!mService.isConnected()) { 92 | throw new IllegalStateException("service is not connected"); 93 | } 94 | 95 | synchronized (mLock) { 96 | ISecureElementSession session; 97 | try { 98 | session = mReader.openSession(); 99 | } catch (ServiceSpecificException e) { 100 | throw new IOException(e.getMessage()); 101 | } catch (RemoteException e) { 102 | throw new IllegalStateException(e.getMessage()); 103 | } 104 | if (session == null) { 105 | throw new IOException("service session is null."); 106 | } 107 | return new Session(mService, session, this); 108 | } 109 | } 110 | 111 | /** 112 | * Check if a Secure Element is present in this reader. 113 | * 114 | * @throws IllegalStateException if the service is not connected 115 | * @return true if the SE is present, false otherwise. 116 | */ 117 | public boolean isSecureElementPresent() { 118 | if (!mService.isConnected()) { 119 | throw new IllegalStateException("service is not connected"); 120 | } 121 | 122 | try { 123 | return mReader.isSecureElementPresent(); 124 | } catch (RemoteException e) { 125 | throw new IllegalStateException("Error in isSecureElementPresent()"); 126 | } 127 | } 128 | 129 | /** 130 | * Return the Secure Element service this reader is bound to. 131 | * 132 | * @return the SEService object. 133 | */ 134 | public @NonNull SEService getSEService() { 135 | return mService; 136 | } 137 | 138 | /** 139 | * Close all the sessions opened on this reader. 140 | * All the channels opened by all these sessions will be closed. 141 | */ 142 | public void closeSessions() { 143 | if (!mService.isConnected()) { 144 | Log.e(TAG, "service is not connected"); 145 | return; 146 | } 147 | synchronized (mLock) { 148 | try { 149 | mReader.closeSessions(); 150 | } catch (RemoteException ignore) { } 151 | } 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /core/java/android/nfc/tech/NfcF.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc.tech; 18 | 19 | import android.nfc.ErrorCodes; 20 | import android.nfc.Tag; 21 | import android.os.Bundle; 22 | import android.os.RemoteException; 23 | import android.util.Log; 24 | 25 | import java.io.IOException; 26 | 27 | /** 28 | * Provides access to NFC-F (JIS 6319-4) properties and I/O operations on a {@link Tag}. 29 | * 30 | *

Acquire a {@link NfcF} object using {@link #get}. 31 | *

The primary NFC-F I/O operation is {@link #transceive}. Applications must 32 | * implement their own protocol stack on top of {@link #transceive}. 33 | * 34 | *

Note: Methods that perform I/O operations 35 | * require the {@link android.Manifest.permission#NFC} permission. 36 | */ 37 | public final class NfcF extends BasicTagTechnology { 38 | private static final String TAG = "NFC"; 39 | 40 | /** @hide */ 41 | public static final String EXTRA_SC = "systemcode"; 42 | /** @hide */ 43 | public static final String EXTRA_PMM = "pmm"; 44 | 45 | private byte[] mSystemCode = null; 46 | private byte[] mManufacturer = null; 47 | 48 | /** 49 | * Get an instance of {@link NfcF} for the given tag. 50 | *

Returns null if {@link NfcF} was not enumerated in {@link Tag#getTechList}. 51 | * This indicates the tag does not support NFC-F. 52 | *

Does not cause any RF activity and does not block. 53 | * 54 | * @param tag an NFC-F compatible tag 55 | * @return NFC-F object 56 | */ 57 | public static NfcF get(Tag tag) { 58 | if (!tag.hasTech(TagTechnology.NFC_F)) return null; 59 | try { 60 | return new NfcF(tag); 61 | } catch (RemoteException e) { 62 | return null; 63 | } 64 | } 65 | 66 | /** @hide */ 67 | public NfcF(Tag tag) throws RemoteException { 68 | super(tag, TagTechnology.NFC_F); 69 | Bundle extras = tag.getTechExtras(TagTechnology.NFC_F); 70 | if (extras != null) { 71 | mSystemCode = extras.getByteArray(EXTRA_SC); 72 | mManufacturer = extras.getByteArray(EXTRA_PMM); 73 | } 74 | } 75 | 76 | /** 77 | * Return the System Code bytes from tag discovery. 78 | * 79 | *

Does not cause any RF activity and does not block. 80 | * 81 | * @return System Code bytes 82 | */ 83 | public byte[] getSystemCode() { 84 | return mSystemCode; 85 | } 86 | 87 | /** 88 | * Return the Manufacturer bytes from tag discovery. 89 | * 90 | *

Does not cause any RF activity and does not block. 91 | * 92 | * @return Manufacturer bytes 93 | */ 94 | public byte[] getManufacturer() { 95 | return mManufacturer; 96 | } 97 | 98 | /** 99 | * Send raw NFC-F commands to the tag and receive the response. 100 | * 101 | *

Applications must not prefix the SoD (preamble and sync code) 102 | * and/or append the EoD (CRC) to the payload, it will be automatically calculated. 103 | * 104 | *

A typical NFC-F frame for this method looks like: 105 | *

106 |      * LENGTH (1 byte) --- CMD (1 byte) -- IDm (8 bytes) -- PARAMS (LENGTH - 10 bytes)
107 |      * 
108 | * 109 | *

Use {@link #getMaxTransceiveLength} to retrieve the maximum amount of bytes 110 | * that can be sent with {@link #transceive}. 111 | * 112 | *

This is an I/O operation and will block until complete. It must 113 | * not be called from the main application thread. A blocked call will be canceled with 114 | * {@link IOException} if {@link #close} is called from another thread. 115 | * 116 | *

Requires the {@link android.Manifest.permission#NFC} permission. 117 | * 118 | * @param data bytes to send 119 | * @return bytes received in response 120 | * @throws TagLostException if the tag leaves the field 121 | * @throws IOException if there is an I/O failure, or this operation is canceled 122 | */ 123 | public byte[] transceive(byte[] data) throws IOException { 124 | return transceive(data, true); 125 | } 126 | 127 | /** 128 | * Return the maximum number of bytes that can be sent with {@link #transceive}. 129 | * @return the maximum number of bytes that can be sent with {@link #transceive}. 130 | */ 131 | public int getMaxTransceiveLength() { 132 | return getMaxTransceiveLengthInternal(); 133 | } 134 | 135 | /** 136 | * Set the {@link #transceive} timeout in milliseconds. 137 | * 138 | *

The timeout only applies to {@link #transceive} on this object, 139 | * and is reset to a default value when {@link #close} is called. 140 | * 141 | *

Setting a longer timeout may be useful when performing 142 | * transactions that require a long processing time on the tag 143 | * such as key generation. 144 | * 145 | *

Requires the {@link android.Manifest.permission#NFC} permission. 146 | * 147 | * @param timeout timeout value in milliseconds 148 | */ 149 | public void setTimeout(int timeout) { 150 | try { 151 | int err = mTag.getTagService().setTimeout(TagTechnology.NFC_F, timeout); 152 | if (err != ErrorCodes.SUCCESS) { 153 | throw new IllegalArgumentException("The supplied timeout is not valid"); 154 | } 155 | } catch (RemoteException e) { 156 | Log.e(TAG, "NFC service dead", e); 157 | } 158 | } 159 | 160 | /** 161 | * Get the current {@link #transceive} timeout in milliseconds. 162 | * 163 | *

Requires the {@link android.Manifest.permission#NFC} permission. 164 | * 165 | * @return timeout value in milliseconds 166 | */ 167 | public int getTimeout() { 168 | try { 169 | return mTag.getTagService().getTimeout(TagTechnology.NFC_F); 170 | } catch (RemoteException e) { 171 | Log.e(TAG, "NFC service dead", e); 172 | return 0; 173 | } 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /core/java/android/nfc/tech/NfcA.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | /****************************************************************************** 17 | * 18 | * The original Work has been changed by NXP Semiconductors. 19 | * 20 | * Copyright (C) 2015 NXP Semiconductors 21 | * 22 | * Licensed under the Apache License, Version 2.0 (the "License"); 23 | * you may not use this file except in compliance with the License. 24 | * You may obtain a copy of the License at 25 | * 26 | * http://www.apache.org/licenses/LICENSE-2.0 27 | * 28 | * Unless required by applicable law or agreed to in writing, software 29 | * distributed under the License is distributed on an "AS IS" BASIS, 30 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 31 | * See the License for the specific language governing permissions and 32 | * limitations under the License. 33 | * 34 | ******************************************************************************/ 35 | package android.nfc.tech; 36 | 37 | import android.nfc.ErrorCodes; 38 | import android.nfc.Tag; 39 | import android.os.Bundle; 40 | import android.os.RemoteException; 41 | import android.util.Log; 42 | 43 | import java.io.IOException; 44 | 45 | /** 46 | * Provides access to NFC-A (ISO 14443-3A) properties and I/O operations on a {@link Tag}. 47 | * 48 | *

Acquire a {@link NfcA} object using {@link #get}. 49 | *

The primary NFC-A I/O operation is {@link #transceive}. Applications must 50 | * implement their own protocol stack on top of {@link #transceive}. 51 | * 52 | *

Note: Methods that perform I/O operations 53 | * require the {@link android.Manifest.permission#NFC} permission. 54 | */ 55 | public final class NfcA extends BasicTagTechnology { 56 | private static final String TAG = "NFC"; 57 | 58 | /** @hide */ 59 | public static final String EXTRA_SAK = "sak"; 60 | /** @hide */ 61 | public static final String EXTRA_ATQA = "atqa"; 62 | 63 | private short mSak; 64 | private byte[] mAtqa; 65 | 66 | /** 67 | * Get an instance of {@link NfcA} for the given tag. 68 | *

Returns null if {@link NfcA} was not enumerated in {@link Tag#getTechList}. 69 | * This indicates the tag does not support NFC-A. 70 | *

Does not cause any RF activity and does not block. 71 | * 72 | * @param tag an NFC-A compatible tag 73 | * @return NFC-A object 74 | */ 75 | public static NfcA get(Tag tag) { 76 | if (!tag.hasTech(TagTechnology.NFC_A)) return null; 77 | try { 78 | return new NfcA(tag); 79 | } catch (RemoteException e) { 80 | return null; 81 | } 82 | } 83 | 84 | /** @hide */ 85 | public NfcA(Tag tag) throws RemoteException { 86 | super(tag, TagTechnology.NFC_A); 87 | Bundle extras; 88 | mSak = 0; 89 | if(tag.hasTech(TagTechnology.MIFARE_CLASSIC)) 90 | { 91 | extras = tag.getTechExtras(TagTechnology.MIFARE_CLASSIC); 92 | mSak = extras.getShort(EXTRA_SAK); 93 | } 94 | extras = tag.getTechExtras(TagTechnology.NFC_A); 95 | mSak |= extras.getShort(EXTRA_SAK); 96 | mAtqa = extras.getByteArray(EXTRA_ATQA); 97 | } 98 | 99 | /** 100 | * Return the ATQA/SENS_RES bytes from tag discovery. 101 | * 102 | *

Does not cause any RF activity and does not block. 103 | * 104 | * @return ATQA/SENS_RES bytes 105 | */ 106 | public byte[] getAtqa() { 107 | return mAtqa; 108 | } 109 | 110 | /** 111 | * Return the SAK/SEL_RES bytes from tag discovery. 112 | * 113 | *

Does not cause any RF activity and does not block. 114 | * 115 | * @return SAK bytes 116 | */ 117 | public short getSak() { 118 | return mSak; 119 | } 120 | 121 | /** 122 | * Send raw NFC-A commands to the tag and receive the response. 123 | * 124 | *

Applications must not append the EoD (CRC) to the payload, 125 | * it will be automatically calculated. 126 | *

Applications must only send commands that are complete bytes, 127 | * for example a SENS_REQ is not possible (these are used to 128 | * manage tag polling and initialization). 129 | * 130 | *

Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes 131 | * that can be sent with {@link #transceive}. 132 | * 133 | *

This is an I/O operation and will block until complete. It must 134 | * not be called from the main application thread. A blocked call will be canceled with 135 | * {@link IOException} if {@link #close} is called from another thread. 136 | * 137 | *

Requires the {@link android.Manifest.permission#NFC} permission. 138 | * 139 | * @param data bytes to send 140 | * @return bytes received in response 141 | * @throws TagLostException if the tag leaves the field 142 | * @throws IOException if there is an I/O failure, or this operation is canceled 143 | */ 144 | public byte[] transceive(byte[] data) throws IOException { 145 | return transceive(data, true); 146 | } 147 | 148 | /** 149 | * Return the maximum number of bytes that can be sent with {@link #transceive}. 150 | * @return the maximum number of bytes that can be sent with {@link #transceive}. 151 | */ 152 | public int getMaxTransceiveLength() { 153 | return getMaxTransceiveLengthInternal(); 154 | } 155 | 156 | /** 157 | * Set the {@link #transceive} timeout in milliseconds. 158 | * 159 | *

The timeout only applies to {@link #transceive} on this object, 160 | * and is reset to a default value when {@link #close} is called. 161 | * 162 | *

Setting a longer timeout may be useful when performing 163 | * transactions that require a long processing time on the tag 164 | * such as key generation. 165 | * 166 | *

Requires the {@link android.Manifest.permission#NFC} permission. 167 | * 168 | * @param timeout timeout value in milliseconds 169 | */ 170 | public void setTimeout(int timeout) { 171 | try { 172 | int err = mTag.getTagService().setTimeout(TagTechnology.NFC_A, timeout); 173 | if (err != ErrorCodes.SUCCESS) { 174 | throw new IllegalArgumentException("The supplied timeout is not valid"); 175 | } 176 | } catch (RemoteException e) { 177 | Log.e(TAG, "NFC service dead", e); 178 | } 179 | } 180 | 181 | /** 182 | * Get the current {@link #transceive} timeout in milliseconds. 183 | * 184 | *

Requires the {@link android.Manifest.permission#NFC} permission. 185 | * 186 | * @return timeout value in milliseconds 187 | */ 188 | public int getTimeout() { 189 | try { 190 | return mTag.getTagService().getTimeout(TagTechnology.NFC_A); 191 | } catch (RemoteException e) { 192 | Log.e(TAG, "NFC service dead", e); 193 | return 0; 194 | } 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /core/java/android/nfc/tech/NdefFormatable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc.tech; 18 | 19 | import android.nfc.ErrorCodes; 20 | import android.nfc.FormatException; 21 | import android.nfc.INfcTag; 22 | import android.nfc.NdefMessage; 23 | import android.nfc.Tag; 24 | import android.nfc.TagLostException; 25 | import android.os.RemoteException; 26 | import android.util.Log; 27 | 28 | import java.io.IOException; 29 | 30 | /** 31 | * Provide access to NDEF format operations on a {@link Tag}. 32 | * 33 | *

Acquire a {@link NdefFormatable} object using {@link #get}. 34 | * 35 | *

Android devices with NFC must only enumerate and implement this 36 | * class for tags for which it can format to NDEF. 37 | * 38 | *

Unfortunately the procedures to convert unformated tags to NDEF formatted 39 | * tags are not specified by NFC Forum, and are not generally well-known. So 40 | * there is no mandatory set of tags for which all Android devices with NFC 41 | * must support {@link NdefFormatable}. 42 | * 43 | *

Note: Methods that perform I/O operations 44 | * require the {@link android.Manifest.permission#NFC} permission. 45 | */ 46 | public final class NdefFormatable extends BasicTagTechnology { 47 | private static final String TAG = "NFC"; 48 | 49 | /** 50 | * Get an instance of {@link NdefFormatable} for the given tag. 51 | *

Does not cause any RF activity and does not block. 52 | *

Returns null if {@link NdefFormatable} was not enumerated in {@link Tag#getTechList}. 53 | * This indicates the tag is not NDEF formatable by this Android device. 54 | * 55 | * @param tag an NDEF formatable tag 56 | * @return NDEF formatable object 57 | */ 58 | public static NdefFormatable get(Tag tag) { 59 | if (!tag.hasTech(TagTechnology.NDEF_FORMATABLE)) return null; 60 | try { 61 | return new NdefFormatable(tag); 62 | } catch (RemoteException e) { 63 | return null; 64 | } 65 | } 66 | 67 | /** 68 | * Internal constructor, to be used by NfcAdapter 69 | * @hide 70 | */ 71 | public NdefFormatable(Tag tag) throws RemoteException { 72 | super(tag, TagTechnology.NDEF_FORMATABLE); 73 | } 74 | 75 | /** 76 | * Format a tag as NDEF, and write a {@link NdefMessage}. 77 | * 78 | *

This is a multi-step process, an IOException is thrown 79 | * if any one step fails. 80 | *

The card is left in a read-write state after this operation. 81 | * 82 | *

This is an I/O operation and will block until complete. It must 83 | * not be called from the main application thread. A blocked call will be canceled with 84 | * {@link IOException} if {@link #close} is called from another thread. 85 | * 86 | *

Requires the {@link android.Manifest.permission#NFC} permission. 87 | * 88 | * @param firstMessage the NDEF message to write after formatting, can be null 89 | * @throws TagLostException if the tag leaves the field 90 | * @throws IOException if there is an I/O failure, or the operation is canceled 91 | * @throws FormatException if the NDEF Message to write is malformed 92 | */ 93 | public void format(NdefMessage firstMessage) throws IOException, FormatException { 94 | format(firstMessage, false); 95 | } 96 | 97 | /** 98 | * Formats a tag as NDEF, write a {@link NdefMessage}, and make read-only. 99 | * 100 | *

This is a multi-step process, an IOException is thrown 101 | * if any one step fails. 102 | *

The card is left in a read-only state if this method returns successfully. 103 | * 104 | *

This is an I/O operation and will block until complete. It must 105 | * not be called from the main application thread. A blocked call will be canceled with 106 | * {@link IOException} if {@link #close} is called from another thread. 107 | * 108 | *

Requires the {@link android.Manifest.permission#NFC} permission. 109 | * 110 | * @param firstMessage the NDEF message to write after formatting 111 | * @throws TagLostException if the tag leaves the field 112 | * @throws IOException if there is an I/O failure, or the operation is canceled 113 | * @throws FormatException if the NDEF Message to write is malformed 114 | */ 115 | public void formatReadOnly(NdefMessage firstMessage) throws IOException, FormatException { 116 | format(firstMessage, true); 117 | } 118 | 119 | /*package*/ void format(NdefMessage firstMessage, boolean makeReadOnly) throws IOException, 120 | FormatException { 121 | checkConnected(); 122 | 123 | try { 124 | int serviceHandle = mTag.getServiceHandle(); 125 | INfcTag tagService = mTag.getTagService(); 126 | int errorCode = tagService.formatNdef(serviceHandle, MifareClassic.KEY_DEFAULT); 127 | switch (errorCode) { 128 | case ErrorCodes.SUCCESS: 129 | break; 130 | case ErrorCodes.ERROR_IO: 131 | throw new IOException(); 132 | case ErrorCodes.ERROR_INVALID_PARAM: 133 | throw new FormatException(); 134 | default: 135 | // Should not happen 136 | throw new IOException(); 137 | } 138 | // Now check and see if the format worked 139 | if (!tagService.isNdef(serviceHandle)) { 140 | throw new IOException(); 141 | } 142 | 143 | // Write a message, if one was provided 144 | if (firstMessage != null) { 145 | errorCode = tagService.ndefWrite(serviceHandle, firstMessage); 146 | switch (errorCode) { 147 | case ErrorCodes.SUCCESS: 148 | break; 149 | case ErrorCodes.ERROR_IO: 150 | throw new IOException(); 151 | case ErrorCodes.ERROR_INVALID_PARAM: 152 | throw new FormatException(); 153 | default: 154 | // Should not happen 155 | throw new IOException(); 156 | } 157 | } 158 | 159 | // optionally make read-only 160 | if (makeReadOnly) { 161 | errorCode = tagService.ndefMakeReadOnly(serviceHandle); 162 | switch (errorCode) { 163 | case ErrorCodes.SUCCESS: 164 | break; 165 | case ErrorCodes.ERROR_IO: 166 | throw new IOException(); 167 | case ErrorCodes.ERROR_INVALID_PARAM: 168 | throw new IOException(); 169 | default: 170 | // Should not happen 171 | throw new IOException(); 172 | } 173 | } 174 | } catch (RemoteException e) { 175 | Log.e(TAG, "NFC service dead", e); 176 | } 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /core/java/android/nfc/cardemulation/AidGroup.java: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * 3 | * The original Work has been changed by NXP Semiconductors. 4 | * 5 | * Copyright (C) 2015 NXP Semiconductors 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * 19 | ******************************************************************************/ 20 | 21 | package android.nfc.cardemulation; 22 | 23 | import java.io.IOException; 24 | import java.util.ArrayList; 25 | import java.util.List; 26 | 27 | import org.xmlpull.v1.XmlPullParser; 28 | import org.xmlpull.v1.XmlPullParserException; 29 | import org.xmlpull.v1.XmlSerializer; 30 | 31 | import android.os.Parcel; 32 | import android.os.Parcelable; 33 | import android.util.Log; 34 | 35 | /** 36 | * The AidGroup class represents a group of Application Identifiers (AIDs). 37 | * 38 | *

The format of AIDs is defined in the ISO/IEC 7816-4 specification. This class 39 | * requires the AIDs to be input as a hexadecimal string, with an even amount of 40 | * hexadecimal characters, e.g. "F014811481". 41 | * 42 | * @hide 43 | */ 44 | public class AidGroup implements Parcelable { 45 | /** 46 | * The maximum number of AIDs that can be present in any one group. 47 | */ 48 | public static final int MAX_NUM_AIDS = 256; 49 | 50 | static final String TAG = "AidGroup"; 51 | 52 | protected List aids; 53 | protected String category; 54 | protected String description; 55 | 56 | /** 57 | * Creates a new AidGroup object. 58 | * 59 | * @param aids The list of AIDs present in the group 60 | * @param category The category of this group, e.g. {@link CardEmulation#CATEGORY_PAYMENT} 61 | */ 62 | public AidGroup(List aids, String category) { 63 | if (aids == null || aids.size() == 0) { 64 | throw new IllegalArgumentException("No AIDS in AID group."); 65 | } 66 | if (aids.size() > MAX_NUM_AIDS) { 67 | throw new IllegalArgumentException("Too many AIDs in AID group."); 68 | } 69 | for (String aid : aids) { 70 | if (!CardEmulation.isValidAid(aid)) { 71 | throw new IllegalArgumentException("AID " + aid + " is not a valid AID."); 72 | } 73 | } 74 | if (isValidCategory(category)) { 75 | this.category = category; 76 | } else { 77 | this.category = CardEmulation.CATEGORY_OTHER; 78 | } 79 | this.aids = new ArrayList(aids.size()); 80 | for (String aid : aids) { 81 | this.aids.add(aid.toUpperCase()); 82 | } 83 | this.description = null; 84 | } 85 | 86 | AidGroup(String category, String description) { 87 | this.aids = new ArrayList(); 88 | this.category = category; 89 | this.description = description; 90 | } 91 | 92 | /** 93 | * @return the category of this AID group 94 | */ 95 | public String getCategory() { 96 | return category; 97 | } 98 | 99 | /** 100 | * @return the list of AIDs in this group 101 | */ 102 | public List getAids() { 103 | return aids; 104 | } 105 | 106 | @Override 107 | public String toString() { 108 | StringBuilder out = new StringBuilder("Category: " + category + 109 | ", AIDs:"); 110 | for (String aid : aids) { 111 | out.append(aid); 112 | out.append(", "); 113 | } 114 | return out.toString(); 115 | } 116 | 117 | @Override 118 | public int describeContents() { 119 | return 0; 120 | } 121 | 122 | @Override 123 | public void writeToParcel(Parcel dest, int flags) { 124 | dest.writeString(category); 125 | dest.writeInt(aids.size()); 126 | if (aids.size() > 0) { 127 | dest.writeStringList(aids); 128 | } 129 | } 130 | 131 | public static final Parcelable.Creator CREATOR = 132 | new Parcelable.Creator() { 133 | 134 | @Override 135 | public AidGroup createFromParcel(Parcel source) { 136 | String category = source.readString(); 137 | int listSize = source.readInt(); 138 | ArrayList aidList = new ArrayList(); 139 | if (listSize > 0) { 140 | source.readStringList(aidList); 141 | } 142 | return new AidGroup(aidList, category); 143 | } 144 | 145 | @Override 146 | public AidGroup[] newArray(int size) { 147 | return new AidGroup[size]; 148 | } 149 | }; 150 | 151 | static public AidGroup createFromXml(XmlPullParser parser) throws XmlPullParserException, IOException { 152 | String category = null; 153 | ArrayList aids = new ArrayList(); 154 | AidGroup group = null; 155 | boolean inGroup = false; 156 | 157 | int eventType = parser.getEventType(); 158 | int minDepth = parser.getDepth(); 159 | while (eventType != XmlPullParser.END_DOCUMENT && parser.getDepth() >= minDepth) { 160 | String tagName = parser.getName(); 161 | if (eventType == XmlPullParser.START_TAG) { 162 | if (tagName.equals("aid")) { 163 | if (inGroup) { 164 | String aid = parser.getAttributeValue(null, "value"); 165 | if (aid != null) { 166 | aids.add(aid.toUpperCase()); 167 | } 168 | } else { 169 | Log.d(TAG, "Ignoring tag while not in group"); 170 | } 171 | } else if (tagName.equals("aid-group")) { 172 | category = parser.getAttributeValue(null, "category"); 173 | if (category == null) { 174 | Log.e(TAG, " tag without valid category"); 175 | return null; 176 | } 177 | inGroup = true; 178 | } else { 179 | Log.d(TAG, "Ignoring unexpected tag: " + tagName); 180 | } 181 | } else if (eventType == XmlPullParser.END_TAG) { 182 | if (tagName.equals("aid-group") && inGroup && aids.size() > 0) { 183 | group = new AidGroup(aids, category); 184 | break; 185 | } 186 | } 187 | eventType = parser.next(); 188 | } 189 | return group; 190 | } 191 | 192 | public void writeAsXml(XmlSerializer out) throws IOException { 193 | out.startTag(null, "aid-group"); 194 | out.attribute(null, "category", category); 195 | for (String aid : aids) { 196 | out.startTag(null, "aid"); 197 | out.attribute(null, "value", aid); 198 | out.endTag(null, "aid"); 199 | } 200 | out.endTag(null, "aid-group"); 201 | } 202 | 203 | static boolean isValidCategory(String category) { 204 | return CardEmulation.CATEGORY_PAYMENT.equals(category) || 205 | CardEmulation.CATEGORY_OTHER.equals(category); 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /core/java/android/nfc/tech/IsoDep.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc.tech; 18 | 19 | import android.nfc.ErrorCodes; 20 | import android.nfc.Tag; 21 | import android.os.Bundle; 22 | import android.os.RemoteException; 23 | import android.util.Log; 24 | 25 | import java.io.IOException; 26 | 27 | /** 28 | * Provides access to ISO-DEP (ISO 14443-4) properties and I/O operations on a {@link Tag}. 29 | * 30 | *

Acquire an {@link IsoDep} object using {@link #get}. 31 | *

The primary ISO-DEP I/O operation is {@link #transceive}. Applications must 32 | * implement their own protocol stack on top of {@link #transceive}. 33 | *

Tags that enumerate the {@link IsoDep} technology in {@link Tag#getTechList} 34 | * will also enumerate 35 | * {@link NfcA} or {@link NfcB} (since IsoDep builds on top of either of these). 36 | * 37 | *

Note: Methods that perform I/O operations 38 | * require the {@link android.Manifest.permission#NFC} permission. 39 | */ 40 | public final class IsoDep extends BasicTagTechnology { 41 | private static final String TAG = "NFC"; 42 | 43 | /** @hide */ 44 | public static final String EXTRA_HI_LAYER_RESP = "hiresp"; 45 | /** @hide */ 46 | public static final String EXTRA_HIST_BYTES = "histbytes"; 47 | 48 | private byte[] mHiLayerResponse = null; 49 | private byte[] mHistBytes = null; 50 | 51 | /** 52 | * Get an instance of {@link IsoDep} for the given tag. 53 | *

Does not cause any RF activity and does not block. 54 | *

Returns null if {@link IsoDep} was not enumerated in {@link Tag#getTechList}. 55 | * This indicates the tag does not support ISO-DEP. 56 | * 57 | * @param tag an ISO-DEP compatible tag 58 | * @return ISO-DEP object 59 | */ 60 | public static IsoDep get(Tag tag) { 61 | if (!tag.hasTech(TagTechnology.ISO_DEP)) return null; 62 | try { 63 | return new IsoDep(tag); 64 | } catch (RemoteException e) { 65 | return null; 66 | } 67 | } 68 | 69 | /** @hide */ 70 | public IsoDep(Tag tag) 71 | throws RemoteException { 72 | super(tag, TagTechnology.ISO_DEP); 73 | Bundle extras = tag.getTechExtras(TagTechnology.ISO_DEP); 74 | if (extras != null) { 75 | mHiLayerResponse = extras.getByteArray(EXTRA_HI_LAYER_RESP); 76 | mHistBytes = extras.getByteArray(EXTRA_HIST_BYTES); 77 | } 78 | } 79 | 80 | /** 81 | * Set the timeout of {@link #transceive} in milliseconds. 82 | *

The timeout only applies to ISO-DEP {@link #transceive}, and is 83 | * reset to a default value when {@link #close} is called. 84 | *

Setting a longer timeout may be useful when performing 85 | * transactions that require a long processing time on the tag 86 | * such as key generation. 87 | * 88 | *

Requires the {@link android.Manifest.permission#NFC} permission. 89 | * 90 | * @param timeout timeout value in milliseconds 91 | */ 92 | public void setTimeout(int timeout) { 93 | try { 94 | int err = mTag.getTagService().setTimeout(TagTechnology.ISO_DEP, timeout); 95 | if (err != ErrorCodes.SUCCESS) { 96 | throw new IllegalArgumentException("The supplied timeout is not valid"); 97 | } 98 | } catch (RemoteException e) { 99 | Log.e(TAG, "NFC service dead", e); 100 | } 101 | } 102 | 103 | /** 104 | * Get the current timeout for {@link #transceive} in milliseconds. 105 | * 106 | *

Requires the {@link android.Manifest.permission#NFC} permission. 107 | * 108 | * @return timeout value in milliseconds 109 | */ 110 | public int getTimeout() { 111 | try { 112 | return mTag.getTagService().getTimeout(TagTechnology.ISO_DEP); 113 | } catch (RemoteException e) { 114 | Log.e(TAG, "NFC service dead", e); 115 | return 0; 116 | } 117 | } 118 | 119 | /** 120 | * Return the ISO-DEP historical bytes for {@link NfcA} tags. 121 | *

Does not cause any RF activity and does not block. 122 | *

The historical bytes can be used to help identify a tag. They are present 123 | * only on {@link IsoDep} tags that are based on {@link NfcA} RF technology. 124 | * If this tag is not {@link NfcA} then null is returned. 125 | *

In ISO 14443-4 terminology, the historical bytes are a subset of the RATS 126 | * response. 127 | * 128 | * @return ISO-DEP historical bytes, or null if this is not a {@link NfcA} tag 129 | */ 130 | public byte[] getHistoricalBytes() { 131 | return mHistBytes; 132 | } 133 | 134 | /** 135 | * Return the higher layer response bytes for {@link NfcB} tags. 136 | *

Does not cause any RF activity and does not block. 137 | *

The higher layer response bytes can be used to help identify a tag. 138 | * They are present only on {@link IsoDep} tags that are based on {@link NfcB} 139 | * RF technology. If this tag is not {@link NfcB} then null is returned. 140 | *

In ISO 14443-4 terminology, the higher layer bytes are a subset of the 141 | * ATTRIB response. 142 | * 143 | * @return ISO-DEP historical bytes, or null if this is not a {@link NfcB} tag 144 | */ 145 | public byte[] getHiLayerResponse() { 146 | return mHiLayerResponse; 147 | } 148 | 149 | /** 150 | * Send raw ISO-DEP data to the tag and receive the response. 151 | * 152 | *

Applications must only send the INF payload, and not the start of frame and 153 | * end of frame indicators. Applications do not need to fragment the payload, it 154 | * will be automatically fragmented and defragmented by {@link #transceive} if 155 | * it exceeds FSD/FSC limits. 156 | * 157 | *

Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes 158 | * that can be sent with {@link #transceive}. 159 | * 160 | *

This is an I/O operation and will block until complete. It must 161 | * not be called from the main application thread. A blocked call will be canceled with 162 | * {@link IOException} if {@link #close} is called from another thread. 163 | * 164 | *

Requires the {@link android.Manifest.permission#NFC} permission. 165 | * 166 | * @param data command bytes to send, must not be null 167 | * @return response bytes received, will not be null 168 | * @throws TagLostException if the tag leaves the field 169 | * @throws IOException if there is an I/O failure, or this operation is canceled 170 | */ 171 | public byte[] transceive(byte[] data) throws IOException { 172 | return transceive(data, true); 173 | } 174 | 175 | /** 176 | * Return the maximum number of bytes that can be sent with {@link #transceive}. 177 | * @return the maximum number of bytes that can be sent with {@link #transceive}. 178 | */ 179 | public int getMaxTransceiveLength() { 180 | return getMaxTransceiveLengthInternal(); 181 | } 182 | 183 | /** 184 | *

Standard APDUs have a 1-byte length field, allowing a maximum of 185 | * 255 payload bytes, which results in a maximum APDU length of 261 bytes. 186 | * 187 | *

Extended length APDUs have a 3-byte length field, allowing 65535 188 | * payload bytes. 189 | * 190 | *

Some NFC adapters, like the one used in the Nexus S and the Galaxy Nexus 191 | * do not support extended length APDUs. They are expected to be well-supported 192 | * in the future though. Use this method to check for extended length APDU 193 | * support. 194 | * 195 | * @return whether the NFC adapter on this device supports extended length APDUs. 196 | */ 197 | public boolean isExtendedLengthApduSupported() { 198 | try { 199 | return mTag.getTagService().getExtendedLengthApdusSupported(); 200 | } catch (RemoteException e) { 201 | Log.e(TAG, "NFC service dead", e); 202 | return false; 203 | } 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /core/java/android/nfc/cardemulation/OffHostApduService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package android.nfc.cardemulation; 17 | 18 | import android.annotation.SdkConstant; 19 | import android.annotation.SdkConstant.SdkConstantType; 20 | import android.app.Service; 21 | import android.content.Intent; 22 | import android.content.pm.PackageManager; 23 | import android.os.IBinder; 24 | 25 | /** 26 | *

OffHostApduService is a convenience {@link Service} class that can be 27 | * extended to describe one or more NFC applications that are residing 28 | * off-host, for example on an embedded secure element or a UICC. 29 | * 30 | *

31 | *

Developer Guide

32 | * For a general introduction into the topic of card emulation, 33 | * please read the 34 | * NFC card emulation developer guide.

35 | *
36 | * 37 | *

NFC Protocols

38 | *

Off-host applications represented by this class are based on the NFC-Forum ISO-DEP 39 | * protocol (based on ISO/IEC 14443-4) and support processing 40 | * command Application Protocol Data Units (APDUs) as 41 | * defined in the ISO/IEC 7816-4 specification. 42 | * 43 | *

Service selection

44 | *

When a remote NFC device wants to talk to your 45 | * off-host NFC application, it sends a so-called 46 | * "SELECT AID" APDU as defined in the ISO/IEC 7816-4 specification. 47 | * The AID is an application identifier defined in ISO/IEC 7816-4. 48 | * 49 | *

The registration procedure for AIDs is defined in the 50 | * ISO/IEC 7816-5 specification. If you don't want to register an 51 | * AID, you are free to use AIDs in the proprietary range: 52 | * bits 8-5 of the first byte must each be set to '1'. For example, 53 | * "0xF00102030405" is a proprietary AID. If you do use proprietary 54 | * AIDs, it is recommended to choose an AID of at least 6 bytes, 55 | * to reduce the risk of collisions with other applications that 56 | * might be using proprietary AIDs as well. 57 | * 58 | *

AID groups

59 | *

In some cases, an off-host environment may need to register multiple AIDs 60 | * to implement a certain application, and it needs to be sure 61 | * that it is the default handler for all of these AIDs (as opposed 62 | * to some AIDs in the group going to another service). 63 | * 64 | *

An AID group is a list of AIDs that should be considered as 65 | * belonging together by the OS. For all AIDs in an AID group, the 66 | * OS will guarantee one of the following: 67 | *

    68 | *
  • All AIDs in the group are routed to the off-host execution environment 69 | *
  • No AIDs in the group are routed to the off-host execution environment 70 | *
71 | * In other words, there is no in-between state, where some AIDs 72 | * in the group can be routed to this off-host execution environment, 73 | * and some to another or a host-based {@link HostApduService}. 74 | *

AID groups and categories

75 | *

Each AID group can be associated with a category. This allows 76 | * the Android OS to classify services, and it allows the user to 77 | * set defaults at the category level instead of the AID level. 78 | * 79 | *

You can use 80 | * {@link CardEmulation#isDefaultServiceForCategory(android.content.ComponentName, String)} 81 | * to determine if your off-host service is the default handler for a category. 82 | * 83 | *

In this version of the platform, the only known categories 84 | * are {@link CardEmulation#CATEGORY_PAYMENT} and {@link CardEmulation#CATEGORY_OTHER}. 85 | * AID groups without a category, or with a category that is not recognized 86 | * by the current platform version, will automatically be 87 | * grouped into the {@link CardEmulation#CATEGORY_OTHER} category. 88 | * 89 | *

Service AID registration

90 | *

To tell the platform which AIDs 91 | * reside off-host and are managed by this service, a {@link #SERVICE_META_DATA} 92 | * entry must be included in the declaration of the service. An 93 | * example of a OffHostApduService manifest declaration is shown below: 94 | *

 <service android:name=".MyOffHostApduService" android:exported="true" android:permission="android.permission.BIND_NFC_SERVICE">
 95 |  *     <intent-filter>
 96 |  *         <action android:name="android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE"/>
 97 |  *     </intent-filter>
 98 |  *     <meta-data android:name="android.nfc.cardemulation.off_host_apdu_ervice" android:resource="@xml/apduservice"/>
 99 |  * </service>
100 | * 101 | * This meta-data tag points to an apduservice.xml file. 102 | * An example of this file with a single AID group declaration is shown below: 103 | *
104 |  * <offhost-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
105 |  *           android:description="@string/servicedesc">
106 |  *       <aid-group android:description="@string/subscription" android:category="other">
107 |  *           <aid-filter android:name="F0010203040506"/>
108 |  *           <aid-filter android:name="F0394148148100"/>
109 |  *       </aid-group>
110 |  * </offhost-apdu-service>
111 |  * 
112 | * 113 | *

The {@link android.R.styleable#OffHostApduService <offhost-apdu-service>} is required 114 | * to contain a 115 | * {@link android.R.styleable#OffHostApduService_description <android:description>} 116 | * attribute that contains a user-friendly description of the service that may be shown in UI. 117 | * 118 | *

The {@link android.R.styleable#OffHostApduService <offhost-apdu-service>} must 119 | * contain one or more {@link android.R.styleable#AidGroup <aid-group>} tags. 120 | * Each {@link android.R.styleable#AidGroup <aid-group>} must contain one or 121 | * more {@link android.R.styleable#AidFilter <aid-filter>} tags, each of which 122 | * contains a single AID. The AID must be specified in hexadecimal format, and contain 123 | * an even number of characters. 124 | * 125 | *

This registration will allow the service to be included 126 | * as an option for being the default handler for categories. 127 | * The Android OS will take care of correctly 128 | * routing the AIDs to the off-host execution environment, 129 | * based on which service the user has selected to be the handler for a certain category. 130 | * 131 | *

The service may define additional actions outside of the 132 | * Android namespace that provide further interaction with 133 | * the off-host execution environment. 134 | * 135 | *

Use of this class requires the 136 | * {@link PackageManager#FEATURE_NFC_HOST_CARD_EMULATION} to be present 137 | * on the device. 138 | */ 139 | public abstract class OffHostApduService extends Service { 140 | /** 141 | * The {@link Intent} action that must be declared as handled by the service. 142 | */ 143 | @SdkConstant(SdkConstantType.SERVICE_ACTION) 144 | public static final String SERVICE_INTERFACE = 145 | "android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE"; 146 | 147 | /** 148 | * The name of the meta-data element that contains 149 | * more information about this service. 150 | */ 151 | public static final String SERVICE_META_DATA = 152 | "android.nfc.cardemulation.off_host_apdu_service"; 153 | 154 | /** 155 | * The Android platform itself will not bind to this service, 156 | * but merely uses its declaration to keep track of what AIDs 157 | * the service is interested in. This information is then used 158 | * to present the user with a list of applications that can handle 159 | * an AID, as well as correctly route those AIDs either to the host (in case 160 | * the user preferred a {@link HostApduService}), or to an off-host 161 | * execution environment (in case the user preferred a {@link OffHostApduService}. 162 | * 163 | * Implementers may define additional actions outside of the 164 | * Android namespace that allow further interactions with 165 | * the off-host execution environment. Such implementations 166 | * would need to override this method. 167 | */ 168 | public abstract IBinder onBind(Intent intent); 169 | } 170 | -------------------------------------------------------------------------------- /core/java/android/nfc/tech/TagTechnology.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc.tech; 18 | 19 | import android.nfc.Tag; 20 | 21 | import java.io.Closeable; 22 | import java.io.IOException; 23 | 24 | /** 25 | * {@link TagTechnology} is an interface to a technology in a {@link Tag}. 26 | *

27 | * Obtain a {@link TagTechnology} implementation by calling the static method get() 28 | * on the implementation class. 29 | *

30 | * NFC tags are based on a number of independently developed technologies and offer a 31 | * wide range of capabilities. The 32 | * {@link TagTechnology} implementations provide access to these different 33 | * technologies and capabilities. Some sub-classes map to technology 34 | * specification (for example {@link NfcA}, {@link IsoDep}, others map to 35 | * pseudo-technologies or capabilities (for example {@link Ndef}, {@link NdefFormatable}). 36 | *

37 | * It is mandatory for all Android NFC devices to provide the following 38 | * {@link TagTechnology} implementations. 39 | *

    40 | *
  • {@link NfcA} (also known as ISO 14443-3A) 41 | *
  • {@link NfcB} (also known as ISO 14443-3B) 42 | *
  • {@link NfcF} (also known as JIS 6319-4) 43 | *
  • {@link NfcV} (also known as ISO 15693) 44 | *
  • {@link IsoDep} 45 | *
  • {@link Ndef} on NFC Forum Type 1, Type 2, Type 3 or Type 4 compliant tags 46 | *
47 | * It is optional for Android NFC devices to provide the following 48 | * {@link TagTechnology} implementations. If it is not provided, the 49 | * Android device will never enumerate that class via {@link Tag#getTechList}. 50 | *
    51 | *
  • {@link MifareClassic} 52 | *
  • {@link MifareUltralight} 53 | *
  • {@link NfcBarcode} 54 | *
  • {@link NdefFormatable} must only be enumerated on tags for which this Android device 55 | * is capable of formatting. Proprietary knowledge is often required to format a tag 56 | * to make it NDEF compatible. 57 | *
58 | *

59 | * {@link TagTechnology} implementations provide methods that fall into two classes: 60 | * cached getters and I/O operations. 61 | *

Cached getters

62 | * These methods (usually prefixed by get or is) return 63 | * properties of the tag, as determined at discovery time. These methods will never 64 | * block or cause RF activity, and do not require {@link #connect} to have been called. 65 | * They also never update, for example if a property is changed by an I/O operation with a tag 66 | * then the cached getter will still return the result from tag discovery time. 67 | *

I/O operations

68 | * I/O operations may require RF activity, and may block. They have the following semantics. 69 | *
    70 | *
  • {@link #connect} must be called before using any other I/O operation. 71 | *
  • {@link #close} must be called after completing I/O operations with a 72 | * {@link TagTechnology}, and it will cancel all other blocked I/O operations on other threads 73 | * (including {@link #connect} with {@link IOException}. 74 | *
  • Only one {@link TagTechnology} can be connected at a time. Other calls to 75 | * {@link #connect} will return {@link IOException}. 76 | *
  • I/O operations may block, and should never be called on the main application 77 | * thread. 78 | *
79 | * 80 | *

Note: Methods that perform I/O operations 81 | * require the {@link android.Manifest.permission#NFC} permission. 82 | */ 83 | public interface TagTechnology extends Closeable { 84 | /** 85 | * This technology is an instance of {@link NfcA}. 86 | *

Support for this technology type is mandatory. 87 | * @hide 88 | */ 89 | public static final int NFC_A = 1; 90 | 91 | /** 92 | * This technology is an instance of {@link NfcB}. 93 | *

Support for this technology type is mandatory. 94 | * @hide 95 | */ 96 | public static final int NFC_B = 2; 97 | 98 | /** 99 | * This technology is an instance of {@link IsoDep}. 100 | *

Support for this technology type is mandatory. 101 | * @hide 102 | */ 103 | public static final int ISO_DEP = 3; 104 | 105 | /** 106 | * This technology is an instance of {@link NfcF}. 107 | *

Support for this technology type is mandatory. 108 | * @hide 109 | */ 110 | public static final int NFC_F = 4; 111 | 112 | /** 113 | * This technology is an instance of {@link NfcV}. 114 | *

Support for this technology type is mandatory. 115 | * @hide 116 | */ 117 | public static final int NFC_V = 5; 118 | 119 | /** 120 | * This technology is an instance of {@link Ndef}. 121 | *

Support for this technology type is mandatory. 122 | * @hide 123 | */ 124 | public static final int NDEF = 6; 125 | 126 | /** 127 | * This technology is an instance of {@link NdefFormatable}. 128 | *

Support for this technology type is mandatory. 129 | * @hide 130 | */ 131 | public static final int NDEF_FORMATABLE = 7; 132 | 133 | /** 134 | * This technology is an instance of {@link MifareClassic}. 135 | *

Support for this technology type is optional. If a stack doesn't support this technology 136 | * type tags using it must still be discovered and present the lower level radio interface 137 | * technologies in use. 138 | * @hide 139 | */ 140 | public static final int MIFARE_CLASSIC = 8; 141 | 142 | /** 143 | * This technology is an instance of {@link MifareUltralight}. 144 | *

Support for this technology type is optional. If a stack doesn't support this technology 145 | * type tags using it must still be discovered and present the lower level radio interface 146 | * technologies in use. 147 | * @hide 148 | */ 149 | public static final int MIFARE_ULTRALIGHT = 9; 150 | 151 | /** 152 | * This technology is an instance of {@link NfcBarcode}. 153 | *

Support for this technology type is optional. If a stack doesn't support this technology 154 | * type tags using it must still be discovered and present the lower level radio interface 155 | * technologies in use. 156 | * @hide 157 | */ 158 | public static final int NFC_BARCODE = 10; 159 | 160 | /** 161 | * Get the {@link Tag} object backing this {@link TagTechnology} object. 162 | * @return the {@link Tag} backing this {@link TagTechnology} object. 163 | */ 164 | public Tag getTag(); 165 | 166 | /** 167 | * Enable I/O operations to the tag from this {@link TagTechnology} object. 168 | *

May cause RF activity and may block. Must not be called 169 | * from the main application thread. A blocked call will be canceled with 170 | * {@link IOException} by calling {@link #close} from another thread. 171 | *

Only one {@link TagTechnology} object can be connected to a {@link Tag} at a time. 172 | *

Applications must call {@link #close} when I/O operations are complete. 173 | * 174 | *

Requires the {@link android.Manifest.permission#NFC} permission. 175 | * 176 | * @see #close() 177 | * @throws TagLostException if the tag leaves the field 178 | * @throws IOException if there is an I/O failure, or connect is canceled 179 | */ 180 | public void connect() throws IOException; 181 | 182 | /** 183 | * Re-connect to the {@link Tag} associated with this connection. Reconnecting to a tag can be 184 | * used to reset the state of the tag itself. 185 | * 186 | *

May cause RF activity and may block. Must not be called 187 | * from the main application thread. A blocked call will be canceled with 188 | * {@link IOException} by calling {@link #close} from another thread. 189 | * 190 | *

Requires the {@link android.Manifest.permission#NFC} permission. 191 | * 192 | * @see #connect() 193 | * @see #close() 194 | * @throws TagLostException if the tag leaves the field 195 | * @throws IOException if there is an I/O failure, or connect is canceled 196 | * @hide 197 | */ 198 | public void reconnect() throws IOException; 199 | 200 | /** 201 | * Disable I/O operations to the tag from this {@link TagTechnology} object, and release resources. 202 | *

Also causes all blocked I/O operations on other thread to be canceled and 203 | * return with {@link IOException}. 204 | * 205 | *

Requires the {@link android.Manifest.permission#NFC} permission. 206 | * 207 | * @see #connect() 208 | */ 209 | public void close() throws IOException; 210 | 211 | /** 212 | * Helper to indicate if I/O operations should be possible. 213 | * 214 | *

Returns true if {@link #connect} has completed, and {@link #close} has not been 215 | * called, and the {@link Tag} is not known to be out of range. 216 | *

Does not cause RF activity, and does not block. 217 | * 218 | * @return true if I/O operations should be possible 219 | */ 220 | public boolean isConnected(); 221 | } 222 | -------------------------------------------------------------------------------- /core/java/android/nfc/NdefMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc; 18 | 19 | import java.nio.ByteBuffer; 20 | import java.util.Arrays; 21 | 22 | import android.os.Parcel; 23 | import android.os.Parcelable; 24 | 25 | 26 | /** 27 | * Represents an immutable NDEF Message. 28 | *

29 | * NDEF (NFC Data Exchange Format) is a light-weight binary format, 30 | * used to encapsulate typed data. It is specified by the NFC Forum, 31 | * for transmission and storage with NFC, however it is transport agnostic. 32 | *

33 | * NDEF defines messages and records. An NDEF Record contains 34 | * typed data, such as MIME-type media, a URI, or a custom 35 | * application payload. An NDEF Message is a container for 36 | * one or more NDEF Records. 37 | *

38 | * When an Android device receives an NDEF Message 39 | * (for example by reading an NFC tag) it processes it through 40 | * a dispatch mechanism to determine an activity to launch. 41 | * The type of the first record in the message has 42 | * special importance for message dispatch, so design this record 43 | * carefully. 44 | *

45 | * Use {@link #NdefMessage(byte[])} to construct an NDEF Message from 46 | * binary data, or {@link #NdefMessage(NdefRecord[])} to 47 | * construct from one or more {@link NdefRecord}s. 48 | *

49 | * {@link NdefMessage} and {@link NdefRecord} implementations are 50 | * always available, even on Android devices that do not have NFC hardware. 51 | *

52 | * {@link NdefRecord}s are intended to be immutable (and thread-safe), 53 | * however they may contain mutable fields. So take care not to modify 54 | * mutable fields passed into constructors, or modify mutable fields 55 | * obtained by getter methods, unless such modification is explicitly 56 | * marked as safe. 57 | * 58 | * @see NfcAdapter#ACTION_NDEF_DISCOVERED 59 | * @see NdefRecord 60 | */ 61 | public final class NdefMessage implements Parcelable { 62 | private final NdefRecord[] mRecords; 63 | 64 | /** 65 | * Construct an NDEF Message by parsing raw bytes.

66 | * Strict validation of the NDEF binary structure is performed: 67 | * there must be at least one record, every record flag must 68 | * be correct, and the total length of the message must match 69 | * the length of the input data.

70 | * This parser can handle chunked records, and converts them 71 | * into logical {@link NdefRecord}s within the message.

72 | * Once the input data has been parsed to one or more logical 73 | * records, basic validation of the tnf, type, id, and payload fields 74 | * of each record is performed, as per the documentation on 75 | * on {@link NdefRecord#NdefRecord(short, byte[], byte[], byte[])}

76 | * If either strict validation of the binary format fails, or 77 | * basic validation during record construction fails, a 78 | * {@link FormatException} is thrown

79 | * Deep inspection of the type, id and payload fields of 80 | * each record is not performed, so it is possible to parse input 81 | * that has a valid binary format and confirms to the basic 82 | * validation requirements of 83 | * {@link NdefRecord#NdefRecord(short, byte[], byte[], byte[])}, 84 | * but fails more strict requirements as specified by the 85 | * NFC Forum. 86 | * 87 | *

88 | * It is safe to re-use the data byte array after construction: 89 | * this constructor will make an internal copy of all necessary fields. 90 | * 91 | * @param data raw bytes to parse 92 | * @throws FormatException if the data cannot be parsed 93 | */ 94 | public NdefMessage(byte[] data) throws FormatException { 95 | if (data == null) throw new NullPointerException("data is null"); 96 | ByteBuffer buffer = ByteBuffer.wrap(data); 97 | 98 | mRecords = NdefRecord.parse(buffer, false); 99 | 100 | if (buffer.remaining() > 0) { 101 | throw new FormatException("trailing data"); 102 | } 103 | } 104 | 105 | /** 106 | * Construct an NDEF Message from one or more NDEF Records. 107 | * 108 | * @param record first record (mandatory) 109 | * @param records additional records (optional) 110 | */ 111 | public NdefMessage(NdefRecord record, NdefRecord ... records) { 112 | // validate 113 | if (record == null) throw new NullPointerException("record cannot be null"); 114 | 115 | for (NdefRecord r : records) { 116 | if (r == null) { 117 | throw new NullPointerException("record cannot be null"); 118 | } 119 | } 120 | 121 | mRecords = new NdefRecord[1 + records.length]; 122 | mRecords[0] = record; 123 | System.arraycopy(records, 0, mRecords, 1, records.length); 124 | } 125 | 126 | /** 127 | * Construct an NDEF Message from one or more NDEF Records. 128 | * 129 | * @param records one or more records 130 | */ 131 | public NdefMessage(NdefRecord[] records) { 132 | // validate 133 | if (records.length < 1) { 134 | throw new IllegalArgumentException("must have at least one record"); 135 | } 136 | for (NdefRecord r : records) { 137 | if (r == null) { 138 | throw new NullPointerException("records cannot contain null"); 139 | } 140 | } 141 | 142 | mRecords = records; 143 | } 144 | 145 | /** 146 | * Get the NDEF Records inside this NDEF Message.

147 | * An {@link NdefMessage} always has one or more NDEF Records: so the 148 | * following code to retrieve the first record is always safe 149 | * (no need to check for null or array length >= 1): 150 | *

151 |      * NdefRecord firstRecord = ndefMessage.getRecords()[0];
152 |      * 
153 | * 154 | * @return array of one or more NDEF records. 155 | */ 156 | public NdefRecord[] getRecords() { 157 | return mRecords; 158 | } 159 | 160 | /** 161 | * Return the length of this NDEF Message if it is written to a byte array 162 | * with {@link #toByteArray}.

163 | * An NDEF Message can be formatted to bytes in different ways 164 | * depending on chunking, SR, and ID flags, so the length returned 165 | * by this method may not be equal to the length of the original 166 | * byte array used to construct this NDEF Message. However it will 167 | * always be equal to the length of the byte array produced by 168 | * {@link #toByteArray}. 169 | * 170 | * @return length of this NDEF Message when written to bytes with {@link #toByteArray} 171 | * @see #toByteArray 172 | */ 173 | public int getByteArrayLength() { 174 | int length = 0; 175 | for (NdefRecord r : mRecords) { 176 | length += r.getByteLength(); 177 | } 178 | return length; 179 | } 180 | 181 | /** 182 | * Return this NDEF Message as raw bytes.

183 | * The NDEF Message is formatted as per the NDEF 1.0 specification, 184 | * and the byte array is suitable for network transmission or storage 185 | * in an NFC Forum NDEF compatible tag.

186 | * This method will not chunk any records, and will always use the 187 | * short record (SR) format and omit the identifier field when possible. 188 | * 189 | * @return NDEF Message in binary format 190 | * @see getByteArrayLength 191 | */ 192 | public byte[] toByteArray() { 193 | int length = getByteArrayLength(); 194 | ByteBuffer buffer = ByteBuffer.allocate(length); 195 | 196 | for (int i=0; i CREATOR = 217 | new Parcelable.Creator() { 218 | @Override 219 | public NdefMessage createFromParcel(Parcel in) { 220 | int recordsLength = in.readInt(); 221 | NdefRecord[] records = new NdefRecord[recordsLength]; 222 | in.readTypedArray(records, NdefRecord.CREATOR); 223 | return new NdefMessage(records); 224 | } 225 | @Override 226 | public NdefMessage[] newArray(int size) { 227 | return new NdefMessage[size]; 228 | } 229 | }; 230 | 231 | @Override 232 | public int hashCode() { 233 | return Arrays.hashCode(mRecords); 234 | } 235 | 236 | /** 237 | * Returns true if the specified NDEF Message contains 238 | * identical NDEF Records. 239 | */ 240 | @Override 241 | public boolean equals(Object obj) { 242 | if (this == obj) return true; 243 | if (obj == null) return false; 244 | if (getClass() != obj.getClass()) return false; 245 | NdefMessage other = (NdefMessage) obj; 246 | return Arrays.equals(mRecords, other.mRecords); 247 | } 248 | 249 | @Override 250 | public String toString() { 251 | return "NdefMessage " + Arrays.toString(mRecords); 252 | } 253 | } -------------------------------------------------------------------------------- /core/java/android/se/omapi/SEService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | /* 17 | * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. 18 | */ 19 | /* 20 | * Contributed by: Giesecke & Devrient GmbH. 21 | */ 22 | /****************************************************************************** 23 | * 24 | * The original Work has been changed by NXP Semiconductors. 25 | * 26 | * Copyright 2018 NXP Semiconductors 27 | * 28 | * Licensed under the Apache License, Version 2.0 (the "License"); 29 | * you may not use this file except in compliance with the License. 30 | * You may obtain a copy of the License at 31 | * 32 | * http://www.apache.org/licenses/LICENSE-2.0 33 | * 34 | * Unless required by applicable law or agreed to in writing, software 35 | * distributed under the License is distributed on an "AS IS" BASIS, 36 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 37 | * See the License for the specific language governing permissions and 38 | * limitations under the License. 39 | * 40 | ******************************************************************************/ 41 | 42 | package android.se.omapi; 43 | 44 | import android.annotation.NonNull; 45 | import android.content.ComponentName; 46 | import android.content.Context; 47 | import android.content.Intent; 48 | import android.content.ServiceConnection; 49 | import android.os.IBinder; 50 | import android.os.RemoteException; 51 | import android.util.Log; 52 | 53 | import java.util.HashMap; 54 | import java.util.concurrent.Executor; 55 | 56 | /** 57 | * The SEService realises the communication to available Secure Elements on the 58 | * device. This is the entry point of this API. It is used to connect to the 59 | * infrastructure and get access to a list of Secure Element Readers. 60 | * 61 | * @see SIMalliance Open Mobile API v3.0 62 | */ 63 | public final class SEService { 64 | 65 | /** 66 | * Error code used with ServiceSpecificException. 67 | * Thrown if there was an error communicating with the Secure Element. 68 | * 69 | * @hide 70 | */ 71 | public static final int IO_ERROR = 1; 72 | 73 | /** 74 | * Error code used with ServiceSpecificException. 75 | * Thrown if AID cannot be selected or is not available when opening 76 | * a logical channel. 77 | * 78 | * @hide 79 | */ 80 | public static final int NO_SUCH_ELEMENT_ERROR = 2; 81 | 82 | /** 83 | * Error code used with ServiceSpecificException. 84 | * Thrown if RF is observed ON while opening connection to ESE over SPI. 85 | * 86 | * @hide 87 | */ 88 | public static final int NFC_IN_USE = 3; 89 | 90 | /** 91 | * Interface to send call-backs to the application when the service is connected. 92 | */ 93 | public interface OnConnectedListener { 94 | /** 95 | * Called by the framework when the service is connected. 96 | */ 97 | void onConnected(); 98 | } 99 | 100 | /** 101 | * Listener object that allows the notification of the caller if this 102 | * SEService could be bound to the backend. 103 | */ 104 | private class SEListener extends ISecureElementListener.Stub { 105 | public OnConnectedListener mListener = null; 106 | public Executor mExecutor = null; 107 | 108 | @Override 109 | public IBinder asBinder() { 110 | return this; 111 | } 112 | 113 | public void onConnected() { 114 | if (mListener != null && mExecutor != null) { 115 | mExecutor.execute(new Runnable() { 116 | @Override 117 | public void run() { 118 | mListener.onConnected(); 119 | } 120 | }); 121 | } 122 | } 123 | } 124 | private SEListener mSEListener = new SEListener(); 125 | 126 | private static final String TAG = "OMAPI.SEService"; 127 | 128 | private final Object mLock = new Object(); 129 | 130 | /** The client context (e.g. activity). */ 131 | private final Context mContext; 132 | 133 | /** The backend system. */ 134 | private volatile ISecureElementService mSecureElementService; 135 | 136 | /** 137 | * Class for interacting with the main interface of the backend. 138 | */ 139 | private ServiceConnection mConnection; 140 | 141 | /** 142 | * Collection of available readers 143 | */ 144 | private final HashMap mReaders = new HashMap(); 145 | 146 | /** 147 | * Establishes a new connection that can be used to connect to all the 148 | * Secure Elements available in the system. The connection process can be 149 | * quite long, so it happens in an asynchronous way. It is usable only if 150 | * the specified listener is called or if isConnected() returns 151 | * true.
152 | * The call-back object passed as a parameter will have its 153 | * onConnected() method called when the connection actually happen. 154 | * 155 | * @param context 156 | * the context of the calling application. Cannot be 157 | * null. 158 | * @param listener 159 | * a OnConnectedListener object. 160 | * @param executor 161 | * an Executor which will be used when invoking the callback. 162 | */ 163 | public SEService(@NonNull Context context, @NonNull Executor executor, 164 | @NonNull OnConnectedListener listener) { 165 | 166 | if (context == null || listener == null || executor == null) { 167 | throw new NullPointerException("Arguments must not be null"); 168 | } 169 | 170 | mContext = context; 171 | mSEListener.mListener = listener; 172 | mSEListener.mExecutor = executor; 173 | 174 | mConnection = new ServiceConnection() { 175 | 176 | public synchronized void onServiceConnected( 177 | ComponentName className, IBinder service) { 178 | 179 | mSecureElementService = ISecureElementService.Stub.asInterface(service); 180 | if (mSEListener != null) { 181 | mSEListener.onConnected(); 182 | } 183 | Log.i(TAG, "Service onServiceConnected"); 184 | } 185 | 186 | public void onServiceDisconnected(ComponentName className) { 187 | mSecureElementService = null; 188 | Log.i(TAG, "Service onServiceDisconnected"); 189 | } 190 | }; 191 | 192 | Intent intent = new Intent(ISecureElementService.class.getName()); 193 | intent.setClassName("com.android.se", 194 | "com.android.se.SecureElementService"); 195 | boolean bindingSuccessful = 196 | mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE); 197 | if (bindingSuccessful) { 198 | Log.i(TAG, "bindService successful"); 199 | } 200 | } 201 | 202 | /** 203 | * Tells whether or not the service is connected. 204 | * 205 | * @return true if the service is connected. 206 | */ 207 | public boolean isConnected() { 208 | return mSecureElementService != null; 209 | } 210 | 211 | /** 212 | * Returns an array of available Secure Element readers. 213 | * There must be no duplicated objects in the returned list. 214 | * All available readers shall be listed even if no card is inserted. 215 | * 216 | * @return An array of Readers. If there are no readers the returned array 217 | * is of length 0. 218 | */ 219 | public @NonNull Reader[] getReaders() { 220 | if (mSecureElementService == null) { 221 | throw new IllegalStateException("service not connected to system"); 222 | } 223 | String[] readerNames; 224 | try { 225 | readerNames = mSecureElementService.getReaders(); 226 | } catch (RemoteException e) { 227 | throw new RuntimeException(e); 228 | } 229 | 230 | Reader[] readers = new Reader[readerNames.length]; 231 | int i = 0; 232 | for (String readerName : readerNames) { 233 | if (mReaders.get(readerName) == null) { 234 | try { 235 | mReaders.put(readerName, new Reader(this, readerName, 236 | getReader(readerName))); 237 | readers[i++] = mReaders.get(readerName); 238 | } catch (Exception e) { 239 | Log.e(TAG, "Error adding Reader: " + readerName, e); 240 | } 241 | } else { 242 | readers[i++] = mReaders.get(readerName); 243 | } 244 | } 245 | return readers; 246 | } 247 | 248 | /** 249 | * Releases all Secure Elements resources allocated by this SEService 250 | * (including any binding to an underlying service). 251 | * As a result isConnected() will return false after shutdown() was called. 252 | * After this method call, the SEService object is not connected. 253 | * This method should be called when connection to the Secure Element is not needed 254 | * or in the termination method of the calling application 255 | * (or part of this application) which is bound to this SEService. 256 | */ 257 | public void shutdown() { 258 | synchronized (mLock) { 259 | if (mSecureElementService != null) { 260 | for (Reader reader : mReaders.values()) { 261 | try { 262 | reader.closeSessions(); 263 | } catch (Exception ignore) { } 264 | } 265 | } 266 | try { 267 | mContext.unbindService(mConnection); 268 | } catch (IllegalArgumentException e) { 269 | // Do nothing and fail silently since an error here indicates 270 | // that binding never succeeded in the first place. 271 | } 272 | mSecureElementService = null; 273 | } 274 | } 275 | 276 | /** 277 | * Returns the version of the OpenMobile API specification this 278 | * implementation is based on. 279 | * 280 | * @return String containing the OpenMobile API version (e.g. "3.0"). 281 | */ 282 | public @NonNull String getVersion() { 283 | return "3.3"; 284 | } 285 | 286 | @NonNull ISecureElementListener getListener() { 287 | return mSEListener; 288 | } 289 | 290 | /** 291 | * Obtain a Reader instance from the SecureElementService 292 | */ 293 | private @NonNull ISecureElementReader getReader(String name) { 294 | try { 295 | return mSecureElementService.getReader(name); 296 | } catch (RemoteException e) { 297 | throw new IllegalStateException(e.getMessage()); 298 | } 299 | } 300 | } 301 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NFCNCIHAL_base 2 | 3 | #### Git Repository 4 | 5 | | DESCRIPTION | CHECKOUT COMMAND | 6 | | :-------------: |:-------------:| 7 | | NFCNCIHAL_base | git clone https://github.com/NXPNFCProject/NFC_NCIHAL_base.git | 8 | 9 | 10 | #### Supported Version on "br_android_ncihalx_comm_16" branch 11 | | Android Version | NXP Release | NXP Tag | 12 | | :-------------: |:---------------------:| :-----:| 13 | | aosp-main | 16.02.00 (PN557/PN560/SN100/SN110/SN220/SN300) | NFC_AR_00_7E800_16.02.00_OpnSrc "This is a preliminary release for specific use. Please DO NOT USE/INTEGRATE for commercial purposes. Use it for engineering and test purposes only. For any other purposes stick to the communicated release plan." | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | #### Supported Version on "br_android_ncihalx_comm_15" branch 23 | | Android Version | NXP Release | NXP Tag | 24 | | :-------------: |:---------------------:| :-----:| 25 | | aosp-main | 15.02.00 (PN557/PN560/SN100/SN110/SN220) | NFC_AR_00_3E800_15.02.00_OpnSrc | 26 | | aosp-main | 15.04.00 (PN557/PN560/SN100/SN110/SN220/SN300) | NFC_AR_00_7E800_15.04.00_OpnSrc | 27 | | aosp-main | 15.0B.00 (PN557/PN560/SN100/SN110/SN220/SN300) | NFC_AR_00_7E800_15.0B.00_OpnSrc | 28 | | android-15.0.0_r1 | 15.0C.00 (PN557/PN560/SN100/SN110/SN220/SN300) | NFC_AR_00_7E800_15.0C.00_OpnSrc | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | #### Supported Version on "br_android_ncihalx_comm_14" branch 38 | | Android Version | NXP Release | NXP Tag | 39 | | :-------------: |:---------------------:| :-----:| 40 | | aosp-master | 14.02.00 (PN557/PN560/SN100/SN110/SN220) | NFC_AR_00_1E800_14.02.00_OpnSrc | 41 | | aosp-master | 14.03.00 (PN557/PN560/SN100/SN110/SN220) | NFC_AR_00_1E800_14.03.00_OpnSrc | 42 | | aosp-master | 14.04.00 (PN557/PN560/SN100/SN110/SN220) | NFC_AR_00_1E800_14.04.00_OpnSrc | 43 | | aosp-master | 14.05.00 (PN557/PN560/SN100/SN110/SN220) | NFC_AR_00_1E800_14.05.00_OpnSrc | 44 | | aosp-master | 14.08.00 (PN557/PN560/SN100/SN110/SN220) | NFC_AR_00_3E800_14.08.00_OpnSrc | 45 | | aosp-master | 14.0B.00 (PN557/PN560/SN100/SN110/SN220) | NFC_AR_00_3E800_14.0B.00_OpnSrc | 46 | | android-14.0.0_r2 | 14.0E.00 (PN557/PN560/SN100/SN110/SN220) | NFC_AR_00_3E800_14.0E.00_OpnSrc | 47 | | android-14.0.0_r2 | 14.0F.00 (PN557/PN560/SN100/SN110/SN220/SN300) | NFC_AR_00_3E800_14.0F.00_OpnSrc | 48 | 49 | 50 | 51 | 52 | #### Supported Version on "br_android_ncihalx_row_13" branch 53 | | Android Version | NXP Release | NXP Tag | 54 | | :-------------: |:---------------------:| :-----:| 55 | | android-13-preview-1 | 13.01.00 (PN80T/PN81T/PN553/PN557) | NFC_AR_00_18C0_13.01.00_OpnSrc | 56 | | android-13.0.0_r3 | 13.02.00 (PN80T/PN81T/PN553/PN557) | NFC_AR_00_18C0_13.02.00_OpnSrc | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | #### Supported Version on "br_android_ncihalx_comm_13" branch 65 | | Android Version | NXP Release | NXP Tag | 66 | | :-------------: |:---------------------:| :-----:| 67 | | aosp-master | 13.02.01 (SN100/SN110/SN220) | NFC_AR_00_E800_13.02.01_OpnSrc | 68 | | aosp-master | 13.03.00 (SN100/SN110/SN220) | NFC_AR_00_E800_13.03.00_OpnSrc | 69 | | android-13-preview-1 | 13.09.00 (PN557/PN560/SN100/SN110/SN220) | NFC_AR_00_1E800_13.09.00_OpnSrc | 70 | | android-13.0.0_r3 | 13.0B.00 (PN557/PN560/SN100/SN110/SN220) | NFC_AR_00_1E800_13.0B.00_OpnSrc | 71 | | android-13.0.0_r3 | 13.0D.01 (PN557/PN560/SN100/SN110/SN220) | NFC_AR_00_1E800_13.0D.01_OpnSrc | 72 | | android-13.0.0_r3 | 13.0E.00 (PN557/PN560/SN100/SN110/SN220) | NFC_AR_00_1E800_13.0E.00_OpnSrc | 73 | 74 | #### Supported Version on "br_android_ncihalx_row_12" branch 75 | | Android Version | NXP Release | NXP Tag | 76 | | :-------------: |:---------------------:| :-----:| 77 | | aosp-master | 12.01.00 (PN80T/PN81T/PN553/PN557) | NFC_AR_00_18C0_12.01.00_OpnSrc | 78 | | android-12.0.0_r2 | 12.02.00 (PN80T/PN81T/PN553/PN557) | NFC_AR_00_18C0_12.02.00_OpnSrc | 79 | 80 | 81 | 82 | 83 | 84 | 85 | #### Supported Version on "br_android_ncihalx_comm_12" branch 86 | | Android Version | NXP Release | NXP Tag | 87 | | :-------------: |:---------------------:| :-----:| 88 | | aosp-master | 12.51.00 (SN110) | NFC_AR_00_02.00_6000_12.51.00_OpnSrc | 89 | | aosp-master | 12.02.01 (SN100/SN110/SN220) | NFC_AR_00_E000_12.02.01_OpnSrc | 90 | | aosp-master | 12.04.01 (SN100/SN110/SN220) | NFC_AR_00_E000_12.04.01_OpnSrc | 91 | | aosp-master | 12.07.00 (SN100/SN110/SN220) | NFC_AR_00_E000_12.07.00_OpnSrc | 92 | | android-12.0.0_r2 | 12.0D.00 (SN100/SN110/PN557) | NFC_AR_00_E800_12.0D.00_OpnSrc | 93 | | android-12.0.0_r2 | 12.10.00 (SN100/SN110/SN220) | NFC_AR_00_E800_12.10.00_OpnSrc | 94 | | android-12.0.0_r2 | 12.12.00 (PN557/SN100/SN110/SN220) | NFC_AR_00_E800_12.12.00_OpnSrc | 95 | | android-12.0.0_r2 | 12.14.00 (PN557/PN560/SN100/SN110/SN220) | NFC_AR_00_1E800_12.14.00_OpnSrc | 96 | 97 | 98 | 99 | 100 | 101 | 102 | #### Supported Version on "br_android_ncihalx_row_11" branch 103 | | Android Version | NXP Release | NXP Tag | 104 | | :-------------: |:---------------------:| :-----:| 105 | | aosp-master | 11.01.00 (PN80T/PN81T/PN553/PN557) | NFC_AR_00_18C0_11.01.00_OpnSrc | 106 | | aosp-master | 11.01.01 (PN80T/PN81T/PN553/PN557) | NFC_AR_00_18C0_11.01.01_OpnSrc | 107 | | android-11.0.0_r3 | 11.02.00 (PN80T/PN81T/PN553/PN557) | NFC_AR_00_18C0_11.02.00_OpnSrc | 108 | | android-11.0.0_r3 | 11.03.00 (PN80T/PN81T/PN553/PN557) | NFC_AR_00_18C0_11.03.00_OpnSrc | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | #### Supported Version on "br_android_ncihalx_11" branch 119 | | Android Version | NXP Release | NXP Tag | 120 | | :-------------: |:---------------------:| :-----:| 121 | | aosp-master | 11.01.00 (SN110) | NFC_AR_00_6000_11.01.00_OpnSrc | 122 | | aosp-master | 11.02.00 (SN110) | NFC_AR_00_6000_11.02.00_OpnSrc | 123 | | aosp-master | 11.02.01 (SN110) | NFC_AR_00_6000_11.02.01_OpnSrc | 124 | | android-11.0.0_r3 | 11.51.01 (SN1xx) | NFC_AR_00_6000_11.51.01_OpnSrc | 125 | | android-11.0.0_r3 | 11.57.00 (SN1xx) | NFC_AR_00_6000_11.57.00_OpnSrc | 126 | | android-11.0.0_r3 | 11.59.00 (SN1xx) | NFC_AR_00_6000_11.59.00_OpnSrc | 127 | | android-11.0.0_r3 | 11.62.00 (PN557/SN1xx) | NFC_AR_00_6800_11.62.00_OpnSrc | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | #### Supported Versions on "br_android_ncihalx_q" branch 137 | 138 | | Android Version | NXP Release | NXP Tag | 139 | | :-------------: |:---------------------:| :-----:| 140 | | aosp-master | 10.00.04 (SN100x) | NFC_AR_00_2000_10.00.04_OpnSrc | 141 | | aosp-master | 10.00.06 (SN110x) | NFC_AR_00_6000_10.00.06_OpnSrc | 142 | | aosp-master | 10.00.08 (SN100x) | NFC_AR_00_6000_10.00.08_OpnSrc | 143 | | aosp-master | 10.00.0A (SN110) | NFC_AR_00_6000_10.00.0A_OpnSrc | 144 | | aosp-master | 10.00.0B (SN100) | NFC_AR_00_6000_10.00.0B_OpnSrc | 145 | | aosp-master | 10.00.0C (SN110) | NFC_AR_00_6000_10.00.0C_OpnSrc | 146 | | aosp-master | 10.00.0D (SN110) | NFC_AR_00_6000_10.00.0D_OpnSrc | 147 | | android-10.0.0_r2 | 10.00.0F (SN110) | NFC_AR_00_6000_10.00.0F_OpnSrc | 148 | | android-10.0.0_r2 | 10.00.14 (SN1xx) | NFC_AR_00_6000_10.00.14_OpnSrc | 149 | | android-10.0.0_r2 | 10.00.15 (SN1xx) | NFC_AR_00_6000_10.00.15_OpnSrc | 150 | | android-10.0.0_r2 | 10.00.17 (SN110) | NFC_AR_00_6000_10.00.17_OpnSrc | 151 | #### Supported Version on "br_android_ncihalx_row_q" branch 152 | | Android Version | NXP Release | NXP Tag | 153 | | :-------------: |:---------------------:| :-----:| 154 | | aosp-master | 10.01.00 (PN80T/PN81T/PN553/PN557) | NFC_AR_00_18C0_10.01.00_OpnSrc | 155 | | aosp-master | 10.02.00 (PN80T/PN81T/PN553/PN557) | NFC_AR_00_18C0_10.02.00_OpnSrc | 156 | | android-10.0.0_r2 | 10.03.00 (PN80T/PN81T/PN553/PN557) | NFC_AR_00_18C0_10.03.00_OpnSrc | 157 | | android-10.0.0_r2 | 10.04.00 (PN80T/PN81T/PN553/PN557) | NFC_AR_00_18C0_10.04.00_OpnSrc | 158 | 159 | 160 | 161 | 162 | #### Supported versions on "br_ar_p_sn1xx" branch 163 | | Android Version | NXP Release | NXP Tag | 164 | | :-------------: |:---------------------:| :-----:| 165 | | android-p-preview 2 | 9.00.08 (SN100x) | NFC_AR_00_2000_09.00.08_OpnSrc | 166 | | android-p-preview 2 | 9.00.09 (SN100x) | NFC_AR_00_2000_09.00.09_OpnSrc | 167 | 168 | 169 | 170 | 171 | 172 | #### Supported Versions on "br_android_ncihalx_row_p" Branch 173 | 174 | | Android Version | NXP Release | NXP Tag | 175 | | :-------------: |:-------------:| :-----:| 176 | | android-p-preview 2 | 9.0.D (PN553) | NFC_NCIHALx_AR00C0.9.0.D_OpnSrc | 177 | | android-9.0.0_r3 | 9.1.0 (PN557) | NFC_NCIHALx_AR0800.9.1.0_OpnSrc | 178 | | android-9.0.0_r3 | 9.2.0 (PN81T/PN557) | NFC_NCIHALx_AR1800.9.2.0_OpnSrc | 179 | | android-9.0.0_r3 | 9.3.0 (PN553) | NFC_NCIHALx_AR0040.9.3.0_OpnSrc | 180 | | android-9.0.0_r3 | 9.4.0 (PN553) | NFC_NCIHALx_AR00C0.9.4.0_OpnSrc | 181 | | android-9.0.0_r3 | 9.5.0 (PN557) | NFC_NCIHALx_AR1800.9.5.0_OpnSrc | 182 | | android-9.0.0_r3 | 9.6.0 (PN80T/PN81T) | NFC_NCIHALx_AR18C0.9.6.0_OpnSrc | 183 | | android-9.0.0_r3 | 9.6.0 (PN80T/PN81T) | NFC_NCIHALx_AR18C0.9.6.0_OpnSrc | 184 | | android-9.0.0_r3 | 9.6.0 (PN80T/PN81T) | NFC_NCIHALx_AR18C0.9.6.0_OpnSrc | 185 | 186 | #### Supported Android Versions on "br_android_ncihalx_p" Branch 187 | 188 | | Android Version | NXP Release | NXP Tag | 189 | | :-------------: |:-------------:| :-----:| 190 | | aosp-master | 9.00.02 (SN100x) | NFC_NCIHALx_AR2000.09.00.02_OpnSrc | 191 | | aosp-master | 9.00.03 (SN100x) | NFC_NCIHALx_AR2000.09.00.03_OpnSrc | 192 | | android-p-preview 2 | 9.00.06 (SN100x) | NFC_NCIHALx_AR2000.09.00.06_OpnSrc | 193 | | android-p-preview 2 | 9.00.07 (SN100x) | NFC_NCIHALx_AR2000.09.00.07_OpnSrc | 194 | | android-p-preview 2 | 9.00.08 (SN100x) | NFC_NCIHALx_AR2000.09.00.08_OpnSrc | 195 | | android-p-preview 2 | 9.00.0A (SN100x) | NFC_NCIHALx_AR2000.09.00.0A_OpnSrc | 196 | | android-p-preview 2 | 9.00.0C (SN100x) | NFC_NCIHALx_AR2000.09.00.0C_OpnSrc | 197 | | android-p-preview 2 | 9.00.0D (SN100x) | NFC_NCIHALx_AR2000.09.00.0D_OpnSrc | 198 | | android-p-preview 2 | 9.00.0F (SN100x) | NFC_NCIHALx_AR2000.09.00.0F_OpnSrc | 199 | | android-p-preview 2 | 9.00.11 (SN100x) | NFC_NCIHALx_AR2000.09.00.11_OpnSrc | 200 | | android-p-preview 2 | 9.00.13 (SN100x) | NFC_NCIHALx_AR2000.09.00.13_OpnSrc | 201 | | android-p-preview 2 | 9.00.15 (SN100x) | NFC_NCIHALx_AR2000.09.00.15_OpnSrc | 202 | | android-p-preview_2 | 9.00.07 (SN100) | NFC_NCIHALx_AR6000.09.00.07_OpnSrc | 203 | | android-p-preview 2 | 9.00.16 (SN100x) | NFC_NCIHALx_AR2000.09.00.16_OpnSrc | 204 | | android-p-preview 2 | 9.00.17 (SN100x) | NFC_NCIHALx_AR2000.09.00.17_OpnSrc | 205 | | android-p-preview 2 | 9.00.18 (SN100x) | NFC_NCIHALx_AR2000.09.00.18_OpnSrc | 206 | | android-p-preview 2 | 9.00.19 (SN100x) | NFC_NCIHALx_AR2000.09.00.19_OpnSrc | 207 | | android-p-preview_2 | 9.00.1A (SN110) | NFC_NCIHALx_AR2000.09.00.1A_OpnSrc | 208 | | android-p-preview_2 | 9.00.1B (SN100) | NFC_NCIHALx_AR2000.09.00.1B_OpnSrc | 209 | -------------------------------------------------------------------------------- /core/java/android/nfc/tech/MifareUltralight.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc.tech; 18 | 19 | import android.nfc.ErrorCodes; 20 | import android.nfc.Tag; 21 | import android.nfc.TagLostException; 22 | import android.os.Bundle; 23 | import android.os.RemoteException; 24 | import android.util.Log; 25 | 26 | import java.io.IOException; 27 | 28 | //TOOD: Ultralight C 3-DES authentication, one-way counter 29 | 30 | /** 31 | * Provides access to MIFARE Ultralight properties and I/O operations on a {@link Tag}. 32 | * 33 | *

Acquire a {@link MifareUltralight} object using {@link #get}. 34 | * 35 | *

MIFARE Ultralight compatible tags have 4 byte pages {@link #PAGE_SIZE}. 36 | * The primary operations on an Ultralight tag are {@link #readPages} and 37 | * {@link #writePage}. 38 | * 39 | *

The original MIFARE Ultralight consists of a 64 byte EEPROM. The first 40 | * 4 pages are for the OTP area, manufacturer data, and locking bits. They are 41 | * readable and some bits are writable. The final 12 pages are the user 42 | * read/write area. For more information see the NXP data sheet MF0ICU1. 43 | * 44 | *

The MIFARE Ultralight C consists of a 192 byte EEPROM. The first 4 pages 45 | * are for OTP, manufacturer data, and locking bits. The next 36 pages are the 46 | * user read/write area. The next 4 pages are additional locking bits, counters 47 | * and authentication configuration and are readable. The final 4 pages are for 48 | * the authentication key and are not readable. For more information see the 49 | * NXP data sheet MF0ICU2. 50 | * 51 | *

Implementation of this class on a Android NFC device is optional. 52 | * If it is not implemented, then 53 | * {@link MifareUltralight} will never be enumerated in {@link Tag#getTechList}. 54 | * If it is enumerated, then all {@link MifareUltralight} I/O operations will be supported. 55 | * In either case, {@link NfcA} will also be enumerated on the tag, 56 | * because all MIFARE Ultralight tags are also {@link NfcA} tags. 57 | * 58 | *

Note: Methods that perform I/O operations 59 | * require the {@link android.Manifest.permission#NFC} permission. 60 | */ 61 | public final class MifareUltralight extends BasicTagTechnology { 62 | private static final String TAG = "NFC"; 63 | 64 | /** A MIFARE Ultralight compatible tag of unknown type */ 65 | public static final int TYPE_UNKNOWN = -1; 66 | /** A MIFARE Ultralight tag */ 67 | public static final int TYPE_ULTRALIGHT = 1; 68 | /** A MIFARE Ultralight C tag */ 69 | public static final int TYPE_ULTRALIGHT_C = 2; 70 | 71 | /** Size of a MIFARE Ultralight page in bytes */ 72 | public static final int PAGE_SIZE = 4; 73 | 74 | private static final int NXP_MANUFACTURER_ID = 0x04; 75 | private static final int MAX_PAGE_COUNT = 256; 76 | 77 | /** @hide */ 78 | public static final String EXTRA_IS_UL_C = "isulc"; 79 | 80 | private int mType; 81 | 82 | /** 83 | * Get an instance of {@link MifareUltralight} for the given tag. 84 | *

Returns null if {@link MifareUltralight} was not enumerated in 85 | * {@link Tag#getTechList} - this indicates the tag is not MIFARE 86 | * Ultralight compatible, or that this Android 87 | * device does not implement MIFARE Ultralight. 88 | *

Does not cause any RF activity and does not block. 89 | * 90 | * @param tag an MIFARE Ultralight compatible tag 91 | * @return MIFARE Ultralight object 92 | */ 93 | public static MifareUltralight get(Tag tag) { 94 | if (!tag.hasTech(TagTechnology.MIFARE_ULTRALIGHT)) return null; 95 | try { 96 | return new MifareUltralight(tag); 97 | } catch (RemoteException e) { 98 | return null; 99 | } 100 | } 101 | 102 | /** @hide */ 103 | public MifareUltralight(Tag tag) throws RemoteException { 104 | super(tag, TagTechnology.MIFARE_ULTRALIGHT); 105 | 106 | // Check if this could actually be a MIFARE 107 | NfcA a = NfcA.get(tag); 108 | 109 | mType = TYPE_UNKNOWN; 110 | 111 | if (a.getSak() == 0x00 && tag.getId()[0] == NXP_MANUFACTURER_ID) { 112 | Bundle extras = tag.getTechExtras(TagTechnology.MIFARE_ULTRALIGHT); 113 | if (extras.getBoolean(EXTRA_IS_UL_C)) { 114 | mType = TYPE_ULTRALIGHT_C; 115 | } else { 116 | mType = TYPE_ULTRALIGHT; 117 | } 118 | } 119 | } 120 | 121 | /** 122 | * Return the MIFARE Ultralight type of the tag. 123 | *

One of {@link #TYPE_ULTRALIGHT} or {@link #TYPE_ULTRALIGHT_C} or 124 | * {@link #TYPE_UNKNOWN}. 125 | *

Depending on how the tag has been formatted, it can be impossible 126 | * to accurately classify between original MIFARE Ultralight and 127 | * Ultralight C. So treat this method as a hint. 128 | *

Does not cause any RF activity and does not block. 129 | * 130 | * @return the type 131 | */ 132 | public int getType() { 133 | return mType; 134 | } 135 | 136 | /** 137 | * Read 4 pages (16 bytes). 138 | * 139 | *

The MIFARE Ultralight protocol always reads 4 pages at a time, to 140 | * reduce the number of commands required to read an entire tag. 141 | *

If a read spans past the last readable block, then the tag will 142 | * return pages that have been wrapped back to the first blocks. MIFARE 143 | * Ultralight tags have readable blocks 0x00 through 0x0F. So a read to 144 | * block offset 0x0E would return blocks 0x0E, 0x0F, 0x00, 0x01. MIFARE 145 | * Ultralight C tags have readable blocks 0x00 through 0x2B. So a read to 146 | * block 0x2A would return blocks 0x2A, 0x2B, 0x00, 0x01. 147 | * 148 | *

This is an I/O operation and will block until complete. It must 149 | * not be called from the main application thread. A blocked call will be canceled with 150 | * {@link IOException} if {@link #close} is called from another thread. 151 | * 152 | *

Requires the {@link android.Manifest.permission#NFC} permission. 153 | * 154 | * @param pageOffset index of first page to read, starting from 0 155 | * @return 4 pages (16 bytes) 156 | * @throws TagLostException if the tag leaves the field 157 | * @throws IOException if there is an I/O failure, or the operation is canceled 158 | */ 159 | public byte[] readPages(int pageOffset) throws IOException { 160 | validatePageIndex(pageOffset); 161 | checkConnected(); 162 | 163 | byte[] cmd = { 0x30, (byte) pageOffset}; 164 | return transceive(cmd, false); 165 | } 166 | 167 | /** 168 | * Write 1 page (4 bytes). 169 | * 170 | *

The MIFARE Ultralight protocol always writes 1 page at a time, to 171 | * minimize EEPROM write cycles. 172 | * 173 | *

This is an I/O operation and will block until complete. It must 174 | * not be called from the main application thread. A blocked call will be canceled with 175 | * {@link IOException} if {@link #close} is called from another thread. 176 | * 177 | *

Requires the {@link android.Manifest.permission#NFC} permission. 178 | * 179 | * @param pageOffset index of page to write, starting from 0 180 | * @param data 4 bytes to write 181 | * @throws TagLostException if the tag leaves the field 182 | * @throws IOException if there is an I/O failure, or the operation is canceled 183 | */ 184 | public void writePage(int pageOffset, byte[] data) throws IOException { 185 | validatePageIndex(pageOffset); 186 | checkConnected(); 187 | 188 | byte[] cmd = new byte[data.length + 2]; 189 | cmd[0] = (byte) 0xA2; 190 | cmd[1] = (byte) pageOffset; 191 | System.arraycopy(data, 0, cmd, 2, data.length); 192 | 193 | transceive(cmd, false); 194 | } 195 | 196 | /** 197 | * Send raw NfcA data to a tag and receive the response. 198 | * 199 | *

This is equivalent to connecting to this tag via {@link NfcA} 200 | * and calling {@link NfcA#transceive}. Note that all MIFARE Classic 201 | * tags are based on {@link NfcA} technology. 202 | * 203 | *

Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes 204 | * that can be sent with {@link #transceive}. 205 | * 206 | *

This is an I/O operation and will block until complete. It must 207 | * not be called from the main application thread. A blocked call will be canceled with 208 | * {@link IOException} if {@link #close} is called from another thread. 209 | * 210 | *

Requires the {@link android.Manifest.permission#NFC} permission. 211 | * 212 | * @see NfcA#transceive 213 | */ 214 | public byte[] transceive(byte[] data) throws IOException { 215 | return transceive(data, true); 216 | } 217 | 218 | /** 219 | * Return the maximum number of bytes that can be sent with {@link #transceive}. 220 | * @return the maximum number of bytes that can be sent with {@link #transceive}. 221 | */ 222 | public int getMaxTransceiveLength() { 223 | return getMaxTransceiveLengthInternal(); 224 | } 225 | 226 | /** 227 | * Set the {@link #transceive} timeout in milliseconds. 228 | * 229 | *

The timeout only applies to {@link #transceive} on this object, 230 | * and is reset to a default value when {@link #close} is called. 231 | * 232 | *

Setting a longer timeout may be useful when performing 233 | * transactions that require a long processing time on the tag 234 | * such as key generation. 235 | * 236 | *

Requires the {@link android.Manifest.permission#NFC} permission. 237 | * 238 | * @param timeout timeout value in milliseconds 239 | */ 240 | public void setTimeout(int timeout) { 241 | try { 242 | int err = mTag.getTagService().setTimeout( 243 | TagTechnology.MIFARE_ULTRALIGHT, timeout); 244 | if (err != ErrorCodes.SUCCESS) { 245 | throw new IllegalArgumentException("The supplied timeout is not valid"); 246 | } 247 | } catch (RemoteException e) { 248 | Log.e(TAG, "NFC service dead", e); 249 | } 250 | } 251 | 252 | /** 253 | * Get the current {@link #transceive} timeout in milliseconds. 254 | * 255 | *

Requires the {@link android.Manifest.permission#NFC} permission. 256 | * 257 | * @return timeout value in milliseconds 258 | */ 259 | public int getTimeout() { 260 | try { 261 | return mTag.getTagService().getTimeout(TagTechnology.MIFARE_ULTRALIGHT); 262 | } catch (RemoteException e) { 263 | Log.e(TAG, "NFC service dead", e); 264 | return 0; 265 | } 266 | } 267 | 268 | private static void validatePageIndex(int pageIndex) { 269 | // Do not be too strict on upper bounds checking, since some cards 270 | // may have more addressable memory than they report. 271 | // Note that issuing a command to an out-of-bounds block is safe - the 272 | // tag will wrap the read to an addressable area. This validation is a 273 | // helper to guard against obvious programming mistakes. 274 | if (pageIndex < 0 || pageIndex >= MAX_PAGE_COUNT) { 275 | throw new IndexOutOfBoundsException("page out of bounds: " + pageIndex); 276 | } 277 | } 278 | } 279 | -------------------------------------------------------------------------------- /core/java/android/se/omapi/Channel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | /* 17 | * Copyright (c) 2015-2017, The Linux Foundation. 18 | */ 19 | /* 20 | * Contributed by: Giesecke & Devrient GmbH. 21 | */ 22 | 23 | package android.se.omapi; 24 | 25 | import android.annotation.NonNull; 26 | import android.annotation.Nullable; 27 | import android.os.RemoteException; 28 | import android.os.ServiceSpecificException; 29 | import android.util.Log; 30 | 31 | import java.io.IOException; 32 | 33 | /** 34 | * Instances of this class represent an ISO/IEC 7816-4 channel opened to a 35 | * Secure Element. It can be either a logical channel or the basic channel. They 36 | * can be used to send APDUs to the secure element. Channels are opened by 37 | * calling the Session.openBasicChannel(byte[]) or 38 | * Session.openLogicalChannel(byte[]) methods. 39 | * 40 | * @see GlobalPlatform Open Mobile API 41 | */ 42 | public final class Channel implements java.nio.channels.Channel { 43 | 44 | private static final String TAG = "OMAPI.Channel"; 45 | private Session mSession; 46 | private final ISecureElementChannel mChannel; 47 | private final SEService mService; 48 | private final Object mLock = new Object(); 49 | 50 | Channel(@NonNull SEService service, @NonNull Session session, 51 | @NonNull ISecureElementChannel channel) { 52 | if (service == null || session == null || channel == null) { 53 | throw new IllegalArgumentException("Parameters cannot be null"); 54 | } 55 | mService = service; 56 | mSession = session; 57 | mChannel = channel; 58 | } 59 | 60 | /** 61 | * Closes this channel to the Secure Element. If the method is called when 62 | * the channel is already closed, this method will be ignored. The close() 63 | * method shall wait for completion of any pending transmit(byte[] command) 64 | * before closing the channel. 65 | */ 66 | public void close() { 67 | if (isOpen()) { 68 | synchronized (mLock) { 69 | try { 70 | mChannel.close(); 71 | } catch (Exception e) { 72 | Log.e(TAG, "Error closing channel", e); 73 | } 74 | } 75 | } 76 | } 77 | 78 | /** 79 | * Tells if this channel is open. 80 | * 81 | * @return false if the channel is closed or in case of an error. 82 | * true otherwise. 83 | */ 84 | public boolean isOpen() { 85 | if (!mService.isConnected()) { 86 | Log.e(TAG, "service not connected to system"); 87 | return false; 88 | } 89 | try { 90 | return !mChannel.isClosed(); 91 | } catch (RemoteException e) { 92 | Log.e(TAG, "Exception in isClosed()"); 93 | return false; 94 | } 95 | } 96 | 97 | /** 98 | * Returns a boolean telling if this channel is the basic channel. 99 | * 100 | * @return true if this channel is a basic channel. false if 101 | * this channel is a logical channel. 102 | */ 103 | public boolean isBasicChannel() { 104 | if (!mService.isConnected()) { 105 | throw new IllegalStateException("service not connected to system"); 106 | } 107 | try { 108 | return mChannel.isBasicChannel(); 109 | } catch (RemoteException e) { 110 | throw new IllegalStateException(e.getMessage()); 111 | } 112 | } 113 | 114 | /** 115 | * Transmit an APDU command (as per ISO/IEC 7816-4) to the Secure Element. The 116 | * underlying layers generate as many TPDUs as necessary to transport this APDU. The 117 | * API shall ensure that all available data returned from Secure Element, including 118 | * concatenated responses, are retrieved and made available to the calling application. If a 119 | * warning status code is received the API wont check for further response data but will 120 | * return all data received so far and the warning status code.
121 | * The transport part is invisible from the application. The generated response is the 122 | * response of the APDU which means that all protocols related responses are handled 123 | * inside the API or the underlying implementation.
124 | * The transmit method shall support extended length APDU commands independently of 125 | * the coding within the ATR.
126 | * For status word '61 XX' the API or underlying implementation shall issue a GET 127 | * RESPONSE command as specified by ISO 7816-4 standard with LE=XX; for the status 128 | * word '6C XX', the API or underlying implementation shall reissue the input command 129 | * with LE=XX. For other status words, the API (or underlying implementation) shall return 130 | * the complete response including data and status word to the device application. The API 131 | * (or underlying implementation) shall not handle internally the received status words. The 132 | * channel shall not be closed even if the Secure Element answered with an error code. 133 | * The system ensures the synchronization between all the concurrent calls to this method, 134 | * and that only one APDU will be sent at a time, irrespective of the number of TPDUs that 135 | * might be required to transport it to the SE. The entire APDU communication to this SE is 136 | * locked to the APDU.
137 | * The channel information in the class byte in the APDU will be ignored. The system will 138 | * add any required information to ensure the APDU is transported on this channel. 139 | * The only restrictions on the set of commands that can be sent is defined below, the API 140 | * implementation shall be able to send all other commands:
141 | *

    142 | *
  • MANAGE_CHANNEL commands are not allowed.
  • 143 | *
  • SELECT by DF Name (p1=04) are not allowed.
  • 144 | *
  • CLA bytes with channel numbers are de-masked.
  • 145 | *
146 | * 147 | * @param command the APDU command to be transmitted, as a byte array. 148 | * 149 | * @return the response received, as a byte array. The returned byte array contains the data 150 | * bytes in the following order: 151 | * [<first data byte>, ..., <last data byte>, <sw1>, <sw2>] 152 | * 153 | * @throws IOException if there is a communication problem to the reader or the Secure Element. 154 | * @throws IllegalStateException if the channel is used after being closed. 155 | * @throws IllegalArgumentException if the command byte array is less than 4 bytes long. 156 | * @throws IllegalArgumentException if Lc byte is inconsistent with length of the byte array. 157 | * @throws IllegalArgumentException if CLA byte is invalid according to [2] (0xff). 158 | * @throws IllegalArgumentException if INS byte is invalid according to [2] (0x6x or 0x9x). 159 | * @throws SecurityException if the command is filtered by the security policy. 160 | * @throws NullPointerException if command is NULL. 161 | */ 162 | public @NonNull byte[] transmit(@NonNull byte[] command) throws IOException { 163 | if (!mService.isConnected()) { 164 | throw new IllegalStateException("service not connected to system"); 165 | } 166 | synchronized (mLock) { 167 | try { 168 | byte[] response = mChannel.transmit(command); 169 | if (response == null) { 170 | throw new IOException("Error in communicating with Secure Element"); 171 | } 172 | return response; 173 | } catch (ServiceSpecificException e) { 174 | throw new IOException(e.getMessage()); 175 | } catch (RemoteException e) { 176 | throw new IllegalStateException(e.getMessage()); 177 | } 178 | } 179 | } 180 | 181 | /** 182 | * Get the session that has opened this channel. 183 | * 184 | * @return the session object this channel is bound to. 185 | */ 186 | public @NonNull Session getSession() { 187 | return mSession; 188 | } 189 | 190 | /** 191 | * Returns the data as received from the application select command inclusively the status word 192 | * received at applet selection. 193 | * The returned byte array contains the data bytes in the following order: 194 | * [<first data byte>, ..., <last data byte>, <sw1>, <sw2>] 195 | * @return The data as returned by the application select command inclusively the status word. 196 | * Only the status word if the application select command has no returned data. 197 | * Returns null if an application select command has not been performed or the selection 198 | * response can not be retrieved by the reader implementation. 199 | */ 200 | public @Nullable byte[] getSelectResponse() { 201 | if (!mService.isConnected()) { 202 | throw new IllegalStateException("service not connected to system"); 203 | } 204 | 205 | byte[] response; 206 | try { 207 | response = mChannel.getSelectResponse(); 208 | } catch (RemoteException e) { 209 | throw new IllegalStateException(e.getMessage()); 210 | } 211 | 212 | if (response != null && response.length == 0) { 213 | response = null; 214 | } 215 | return response; 216 | } 217 | 218 | /** 219 | * Performs a selection of the next Applet on this channel that matches to the partial AID 220 | * specified in the openBasicChannel(byte[] aid) or openLogicalChannel(byte[] aid) method. 221 | * This mechanism can be used by a device application to iterate through all Applets 222 | * matching to the same partial AID. 223 | * If selectNext() returns true a new Applet was successfully selected on this channel. 224 | * If no further Applet exists with matches to the partial AID this method returns false 225 | * and the already selected Applet stays selected.
226 | * 227 | * Since the API cannot distinguish between a partial and full AID the API shall rely on the 228 | * response of the Secure Element for the return value of this method.
229 | * The implementation of the underlying SELECT command within this method shall use 230 | * the same values as the corresponding openBasicChannel(byte[] aid) or 231 | * openLogicalChannel(byte[] aid) command with the option:
232 | * P2='02' (Next occurrence)
233 | * The select response stored in the Channel object shall be updated with the APDU 234 | * response of the SELECT command. 235 | 236 | * @return true if new Applet was selected on this channel. 237 | false he already selected Applet stays selected on this channel. 238 | * 239 | * @throws IOException if there is a communication problem to the reader or the Secure Element. 240 | * @throws IllegalStateException if the channel is used after being closed. 241 | * @throws UnsupportedOperationException if this operation is not supported by the card. 242 | */ 243 | public boolean selectNext() throws IOException { 244 | if (!mService.isConnected()) { 245 | throw new IllegalStateException("service not connected to system"); 246 | } 247 | try { 248 | synchronized (mLock) { 249 | return mChannel.selectNext(); 250 | } 251 | } catch (ServiceSpecificException e) { 252 | throw new IOException(e.getMessage()); 253 | } catch (RemoteException e) { 254 | throw new IllegalStateException(e.getMessage()); 255 | } 256 | } 257 | } 258 | -------------------------------------------------------------------------------- /core/java/android/nfc/cardemulation/HostNfcFService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc.cardemulation; 18 | 19 | import android.annotation.SdkConstant; 20 | import android.annotation.SdkConstant.SdkConstantType; 21 | import android.app.Service; 22 | import android.content.ComponentName; 23 | import android.content.Intent; 24 | import android.os.Bundle; 25 | import android.os.Handler; 26 | import android.os.IBinder; 27 | import android.os.Message; 28 | import android.os.Messenger; 29 | import android.os.RemoteException; 30 | import android.util.Log; 31 | 32 | /** 33 | *

HostNfcFService is a convenience {@link Service} class that can be 34 | * extended to emulate an NFC-F card inside an Android service component. 35 | * 36 | *

NFC Protocols

37 | *

Cards emulated by this class are based on the NFC-Forum NFC-F 38 | * protocol (based on the JIS-X 6319-4 specification.)

39 | * 40 | *

System Code and NFCID2 registration

41 | *

A {@link HostNfcFService HostNfcFService service} can register 42 | * exactly one System Code and one NFCID2. For details about the use of 43 | * System Code and NFCID2, see the NFC Forum Digital specification.

44 | *

To statically register a System Code and NFCID2 with the service, a {@link #SERVICE_META_DATA} 45 | * entry must be included in the declaration of the service. 46 | * 47 | *

All {@link HostNfcFService HostNfcFService} declarations in the manifest must require the 48 | * {@link android.Manifest.permission#BIND_NFC_SERVICE} permission 49 | * in their <service> tag, to ensure that only the platform can bind to your service.

50 | * 51 | *

An example of a HostNfcFService manifest declaration is shown below: 52 | * 53 | *

 <service android:name=".MyHostNfcFService" android:exported="true" android:permission="android.permission.BIND_NFC_SERVICE">
 54 |  *     <intent-filter>
 55 |  *         <action android:name="android.nfc.cardemulation.action.HOST_NFCF_SERVICE"/>
 56 |  *     </intent-filter>
 57 |  *     <meta-data android:name="android.nfc.cardemulation.host_nfcf_service" android:resource="@xml/nfcfservice"/>
 58 |  * </service>
59 | * 60 | * This meta-data tag points to an nfcfservice.xml file. 61 | * An example of this file with a System Code and NFCID2 declaration is shown below: 62 | *
 63 |  * <host-nfcf-service xmlns:android="http://schemas.android.com/apk/res/android"
 64 |  *           android:description="@string/servicedesc">
 65 |  *       <system-code-filter android:name="4000"/>
 66 |  *       <nfcid2-filter android:name="02FE000000000000"/>
 67 |          <t3tPmm-filter android:name="FFFFFFFFFFFFFFFF"/>
 68 |  * </host-nfcf-service>
 69 |  * 
70 | * 71 | *

The {@link android.R.styleable#HostNfcFService <host-nfcf-service>} is required 72 | * to contain a 73 | * {@link android.R.styleable#HostApduService_description <android:description>} 74 | * attribute that contains a user-friendly description of the service that may be shown in UI. 75 | *

The {@link android.R.styleable#HostNfcFService <host-nfcf-service>} must 76 | * contain: 77 | *

    78 | *
  • Exactly one {@link android.R.styleable#SystemCodeFilter <system-code-filter>} tag.
  • 79 | *
  • Exactly one {@link android.R.styleable#Nfcid2Filter <nfcid2-filter>} tag.
  • 80 | *
  • Exactly on or zero {@link android.R.styleable#T3tPmmFilter <t3tPmm-filter>} tag.
  • 81 | *
82 | *

83 | * 84 | *

Alternatively, the System Code and NFCID2 can be dynamically registererd for a service 85 | * by using the {@link NfcFCardEmulation#registerSystemCodeForService(ComponentName, String)} and 86 | * {@link NfcFCardEmulation#setNfcid2ForService(ComponentName, String)} methods. 87 | *

88 | * 89 | *

Service selection

90 | *

When a remote NFC devices wants to communicate with your service, it 91 | * sends a SENSF_REQ command to the NFC controller, requesting a System Code. 92 | * If a {@link NfcFCardEmulation NfcFCardEmulation service} has registered 93 | * this system code and has been enabled by the foreground application, the 94 | * NFC controller will respond with the NFCID2 that is registered for this service. 95 | * The reader can then continue data exchange with this service by using the NFCID2.

96 | * 97 | *

Data exchange

98 | *

After service selection, all frames addressed to the NFCID2 of this service will 99 | * be sent through {@link #processNfcFPacket(byte[], Bundle)}, until the NFC link is 100 | * broken.

101 | * 102 | *

When the NFC link is broken, {@link #onDeactivated(int)} will be called.

103 | */ 104 | public abstract class HostNfcFService extends Service { 105 | /** 106 | * The {@link Intent} action that must be declared as handled by the service. 107 | */ 108 | @SdkConstant(SdkConstantType.SERVICE_ACTION) 109 | public static final String SERVICE_INTERFACE = 110 | "android.nfc.cardemulation.action.HOST_NFCF_SERVICE"; 111 | 112 | /** 113 | * The name of the meta-data element that contains 114 | * more information about this service. 115 | */ 116 | public static final String SERVICE_META_DATA = 117 | "android.nfc.cardemulation.host_nfcf_service"; 118 | 119 | /** 120 | * Reason for {@link #onDeactivated(int)}. 121 | * Indicates deactivation was due to the NFC link 122 | * being lost. 123 | */ 124 | public static final int DEACTIVATION_LINK_LOSS = 0; 125 | 126 | static final String TAG = "NfcFService"; 127 | 128 | /** 129 | * MSG_COMMAND_PACKET is sent by NfcService when 130 | * a NFC-F command packet has been received. 131 | * 132 | * @hide 133 | */ 134 | public static final int MSG_COMMAND_PACKET = 0; 135 | 136 | /** 137 | * MSG_RESPONSE_PACKET is sent to NfcService to send 138 | * a response packet back to the remote device. 139 | * 140 | * @hide 141 | */ 142 | public static final int MSG_RESPONSE_PACKET = 1; 143 | 144 | /** 145 | * MSG_DEACTIVATED is sent by NfcService when 146 | * the current session is finished; because 147 | * the NFC link was deactivated. 148 | * 149 | * @hide 150 | */ 151 | public static final int MSG_DEACTIVATED = 2; 152 | 153 | /** 154 | * @hide 155 | */ 156 | public static final String KEY_DATA = "data"; 157 | 158 | /** 159 | * @hide 160 | */ 161 | public static final String KEY_MESSENGER = "messenger"; 162 | 163 | /** 164 | * Messenger interface to NfcService for sending responses. 165 | * Only accessed on main thread by the message handler. 166 | * 167 | * @hide 168 | */ 169 | Messenger mNfcService = null; 170 | 171 | final Messenger mMessenger = new Messenger(new MsgHandler()); 172 | 173 | final class MsgHandler extends Handler { 174 | @Override 175 | public void handleMessage(Message msg) { 176 | switch (msg.what) { 177 | case MSG_COMMAND_PACKET: 178 | Bundle dataBundle = msg.getData(); 179 | if (dataBundle == null) { 180 | return; 181 | } 182 | if (mNfcService == null) mNfcService = msg.replyTo; 183 | 184 | byte[] packet = dataBundle.getByteArray(KEY_DATA); 185 | if (packet != null) { 186 | byte[] responsePacket = processNfcFPacket(packet, null); 187 | /* Comment for handle Empty DATA packet*/ 188 | //if (responsePacket != null) { 189 | if (mNfcService == null) { 190 | Log.e(TAG, "Response not sent; service was deactivated."); 191 | return; 192 | } 193 | Message responseMsg = Message.obtain(null, MSG_RESPONSE_PACKET); 194 | Bundle responseBundle = new Bundle(); 195 | responseBundle.putByteArray(KEY_DATA, responsePacket); 196 | responseMsg.setData(responseBundle); 197 | responseMsg.replyTo = mMessenger; 198 | try { 199 | mNfcService.send(responseMsg); 200 | } catch (RemoteException e) { 201 | Log.e("TAG", "Response not sent; RemoteException calling into " + 202 | "NfcService."); 203 | } 204 | //} else { 205 | // Log.e(TAG, "Received MSG_COMMAND_PACKET without data."); 206 | // } 207 | } else { 208 | Log.e(TAG, "Received MSG_COMMAND_PACKET without data."); 209 | } 210 | 211 | break; 212 | case MSG_RESPONSE_PACKET: 213 | if (mNfcService == null) { 214 | Log.e(TAG, "Response not sent; service was deactivated."); 215 | return; 216 | } 217 | try { 218 | msg.replyTo = mMessenger; 219 | mNfcService.send(msg); 220 | } catch (RemoteException e) { 221 | Log.e(TAG, "RemoteException calling into NfcService."); 222 | } 223 | break; 224 | case MSG_DEACTIVATED: 225 | // Make sure we won't call into NfcService again 226 | mNfcService = null; 227 | onDeactivated(msg.arg1); 228 | break; 229 | default: 230 | super.handleMessage(msg); 231 | } 232 | } 233 | } 234 | 235 | @Override 236 | public final IBinder onBind(Intent intent) { 237 | return mMessenger.getBinder(); 238 | } 239 | 240 | /** 241 | * Sends a response packet back to the remote device. 242 | * 243 | *

Note: this method may be called from any thread and will not block. 244 | * @param responsePacket A byte-array containing the response packet. 245 | */ 246 | public final void sendResponsePacket(byte[] responsePacket) { 247 | Message responseMsg = Message.obtain(null, MSG_RESPONSE_PACKET); 248 | Bundle dataBundle = new Bundle(); 249 | dataBundle.putByteArray(KEY_DATA, responsePacket); 250 | responseMsg.setData(dataBundle); 251 | try { 252 | mMessenger.send(responseMsg); 253 | } catch (RemoteException e) { 254 | Log.e("TAG", "Local messenger has died."); 255 | } 256 | } 257 | 258 | /** 259 | *

This method will be called when a NFC-F packet has been received 260 | * from a remote device. A response packet can be provided directly 261 | * by returning a byte-array in this method. Note that in general 262 | * response packets must be sent as quickly as possible, given the fact 263 | * that the user is likely holding his device over an NFC reader 264 | * when this method is called. 265 | * 266 | *

This method is running on the main thread of your application. 267 | * If you cannot return a response packet immediately, return null 268 | * and use the {@link #sendResponsePacket(byte[])} method later. 269 | * 270 | * @param commandPacket The NFC-F packet that was received from the remote device 271 | * @param extras A bundle containing extra data. May be null. 272 | * @return a byte-array containing the response packet, or null if no 273 | * response packet can be sent at this point. 274 | */ 275 | public abstract byte[] processNfcFPacket(byte[] commandPacket, Bundle extras); 276 | 277 | /** 278 | * This method will be called in following possible scenarios: 279 | *

  • The NFC link has been lost 280 | * @param reason {@link #DEACTIVATION_LINK_LOSS} 281 | */ 282 | public abstract void onDeactivated(int reason); 283 | } 284 | -------------------------------------------------------------------------------- /core/java/android/nfc/cardemulation/NfcFServiceInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package android.nfc.cardemulation; 18 | 19 | import android.content.ComponentName; 20 | import android.content.pm.PackageManager; 21 | import android.content.pm.ResolveInfo; 22 | import android.content.pm.ServiceInfo; 23 | import android.content.pm.PackageManager.NameNotFoundException; 24 | import android.content.res.Resources; 25 | import android.content.res.TypedArray; 26 | import android.content.res.XmlResourceParser; 27 | import android.graphics.drawable.Drawable; 28 | import android.os.Parcel; 29 | import android.os.Parcelable; 30 | import android.util.AttributeSet; 31 | import android.util.Log; 32 | import android.util.Xml; 33 | 34 | import org.xmlpull.v1.XmlPullParser; 35 | import org.xmlpull.v1.XmlPullParserException; 36 | 37 | import java.io.FileDescriptor; 38 | import java.io.IOException; 39 | import java.io.PrintWriter; 40 | 41 | /** 42 | * @hide 43 | */ 44 | public final class NfcFServiceInfo implements Parcelable { 45 | static final String TAG = "NfcFServiceInfo"; 46 | 47 | private static final String DEFAULT_T3T_PMM = "FFFFFFFFFFFFFFFF"; 48 | /** 49 | * The service that implements this 50 | */ 51 | final ResolveInfo mService; 52 | 53 | /** 54 | * Description of the service 55 | */ 56 | final String mDescription; 57 | 58 | /** 59 | * System Code of the service 60 | */ 61 | final String mSystemCode; 62 | 63 | /** 64 | * System Code of the service registered by API 65 | */ 66 | String mDynamicSystemCode; 67 | 68 | /** 69 | * NFCID2 of the service 70 | */ 71 | final String mNfcid2; 72 | 73 | /** 74 | * NFCID2 of the service registered by API 75 | */ 76 | String mDynamicNfcid2; 77 | 78 | /** 79 | * The uid of the package the service belongs to 80 | */ 81 | final int mUid; 82 | 83 | /** 84 | * LF_T3T_PMM of the service 85 | */ 86 | final String mT3tPmm; 87 | 88 | /** 89 | * @hide 90 | */ 91 | public NfcFServiceInfo(ResolveInfo info, String description, 92 | String systemCode, String dynamicSystemCode, String nfcid2, String dynamicNfcid2, 93 | int uid,String t3tPmm) { 94 | this.mService = info; 95 | this.mDescription = description; 96 | this.mSystemCode = systemCode; 97 | this.mDynamicSystemCode = dynamicSystemCode; 98 | this.mNfcid2 = nfcid2; 99 | this.mDynamicNfcid2 = dynamicNfcid2; 100 | this.mUid = uid; 101 | this.mT3tPmm = t3tPmm; 102 | } 103 | 104 | public NfcFServiceInfo(PackageManager pm, ResolveInfo info) 105 | throws XmlPullParserException, IOException { 106 | ServiceInfo si = info.serviceInfo; 107 | XmlResourceParser parser = null; 108 | try { 109 | parser = si.loadXmlMetaData(pm, HostNfcFService.SERVICE_META_DATA); 110 | if (parser == null) { 111 | throw new XmlPullParserException("No " + HostNfcFService.SERVICE_META_DATA + 112 | " meta-data"); 113 | } 114 | 115 | int eventType = parser.getEventType(); 116 | while (eventType != XmlPullParser.START_TAG && 117 | eventType != XmlPullParser.END_DOCUMENT) { 118 | eventType = parser.next(); 119 | } 120 | 121 | String tagName = parser.getName(); 122 | if (!"host-nfcf-service".equals(tagName)) { 123 | throw new XmlPullParserException( 124 | "Meta-data does not start with tag"); 125 | } 126 | 127 | Resources res = pm.getResourcesForApplication(si.applicationInfo); 128 | AttributeSet attrs = Xml.asAttributeSet(parser); 129 | TypedArray sa = res.obtainAttributes(attrs, 130 | com.android.internal.R.styleable.HostNfcFService); 131 | mService = info; 132 | mDescription = sa.getString( 133 | com.android.internal.R.styleable.HostNfcFService_description); 134 | mDynamicSystemCode = null; 135 | mDynamicNfcid2 = null; 136 | sa.recycle(); 137 | 138 | String systemCode = null; 139 | String nfcid2 = null; 140 | String t3tPmm = null; 141 | final int depth = parser.getDepth(); 142 | 143 | while (((eventType = parser.next()) != XmlPullParser.END_TAG || 144 | parser.getDepth() > depth) && eventType != XmlPullParser.END_DOCUMENT) { 145 | tagName = parser.getName(); 146 | if (eventType == XmlPullParser.START_TAG && 147 | "system-code-filter".equals(tagName) && systemCode == null) { 148 | final TypedArray a = res.obtainAttributes(attrs, 149 | com.android.internal.R.styleable.SystemCodeFilter); 150 | systemCode = a.getString( 151 | com.android.internal.R.styleable.SystemCodeFilter_name).toUpperCase(); 152 | Log.d(TAG, "systemCode: " + systemCode); 153 | if (!NfcFCardEmulation.isValidSystemCode(systemCode) && 154 | !systemCode.equalsIgnoreCase("NULL")) { 155 | Log.e(TAG, "Invalid System Code: " + systemCode); 156 | systemCode = null; 157 | } 158 | a.recycle(); 159 | } else if (eventType == XmlPullParser.START_TAG && 160 | "nfcid2-filter".equals(tagName) && nfcid2 == null) { 161 | final TypedArray a = res.obtainAttributes(attrs, 162 | com.android.internal.R.styleable.Nfcid2Filter); 163 | nfcid2 = a.getString( 164 | com.android.internal.R.styleable.Nfcid2Filter_name).toUpperCase(); 165 | if (!nfcid2.equalsIgnoreCase("RANDOM") && 166 | !nfcid2.equalsIgnoreCase("NULL") && 167 | !NfcFCardEmulation.isValidNfcid2(nfcid2)) { 168 | Log.e(TAG, "Invalid NFCID2: " + nfcid2); 169 | nfcid2 = null; 170 | } 171 | a.recycle(); 172 | } 173 | else if (eventType == XmlPullParser.START_TAG && 174 | "t3tPmm-filter".equals(tagName) && t3tPmm == null) { 175 | final TypedArray a = res.obtainAttributes(attrs, 176 | com.android.internal.R.styleable.T3tPmmFilter); 177 | t3tPmm = a.getString( 178 | com.android.internal.R.styleable.T3tPmmFilter_name).toUpperCase(); 179 | Log.e(TAG, "T3T PMM " + t3tPmm); 180 | a.recycle(); 181 | } 182 | } 183 | mSystemCode = (systemCode == null ? "NULL" : systemCode); 184 | mNfcid2 = (nfcid2 == null ? "NULL" : nfcid2); 185 | mT3tPmm = (t3tPmm == null ? DEFAULT_T3T_PMM : t3tPmm); 186 | } catch (NameNotFoundException e) { 187 | throw new XmlPullParserException("Unable to create context for: " + si.packageName); 188 | } finally { 189 | if (parser != null) parser.close(); 190 | } 191 | // Set uid 192 | mUid = si.applicationInfo.uid; 193 | } 194 | 195 | public ComponentName getComponent() { 196 | return new ComponentName(mService.serviceInfo.packageName, 197 | mService.serviceInfo.name); 198 | } 199 | 200 | public String getSystemCode() { 201 | return (mDynamicSystemCode == null ? mSystemCode : mDynamicSystemCode); 202 | } 203 | 204 | public void setOrReplaceDynamicSystemCode(String systemCode) { 205 | mDynamicSystemCode = systemCode; 206 | } 207 | 208 | public String getNfcid2() { 209 | return (mDynamicNfcid2 == null ? mNfcid2 : mDynamicNfcid2); 210 | } 211 | 212 | public void setOrReplaceDynamicNfcid2(String nfcid2) { 213 | mDynamicNfcid2 = nfcid2; 214 | } 215 | 216 | public String getDescription() { 217 | return mDescription; 218 | } 219 | 220 | public int getUid() { 221 | return mUid; 222 | } 223 | 224 | public String getT3tPmm() { 225 | return mT3tPmm; 226 | } 227 | 228 | public CharSequence loadLabel(PackageManager pm) { 229 | return mService.loadLabel(pm); 230 | } 231 | 232 | public Drawable loadIcon(PackageManager pm) { 233 | return mService.loadIcon(pm); 234 | } 235 | 236 | @Override 237 | public String toString() { 238 | StringBuilder out = new StringBuilder("NfcFService: "); 239 | out.append(getComponent()); 240 | out.append(", description: " + mDescription); 241 | out.append(", System Code: " + mSystemCode); 242 | if (mDynamicSystemCode != null) { 243 | out.append(", dynamic System Code: " + mDynamicSystemCode); 244 | } 245 | out.append(", NFCID2: " + mNfcid2); 246 | if (mDynamicNfcid2 != null) { 247 | out.append(", dynamic NFCID2: " + mDynamicNfcid2); 248 | } 249 | out.append(", T3T PMM:" + mT3tPmm); 250 | return out.toString(); 251 | } 252 | 253 | @Override 254 | public boolean equals(Object o) { 255 | if (this == o) return true; 256 | if (!(o instanceof NfcFServiceInfo)) return false; 257 | NfcFServiceInfo thatService = (NfcFServiceInfo) o; 258 | 259 | if (!thatService.getComponent().equals(this.getComponent())) return false; 260 | if (!thatService.mSystemCode.equalsIgnoreCase(this.mSystemCode)) return false; 261 | if (!thatService.mNfcid2.equalsIgnoreCase(this.mNfcid2)) return false; 262 | if (!thatService.mT3tPmm.equalsIgnoreCase(this.mT3tPmm)) return false; 263 | return true; 264 | } 265 | 266 | @Override 267 | public int hashCode() { 268 | return getComponent().hashCode(); 269 | } 270 | 271 | @Override 272 | public int describeContents() { 273 | return 0; 274 | } 275 | 276 | @Override 277 | public void writeToParcel(Parcel dest, int flags) { 278 | mService.writeToParcel(dest, flags); 279 | dest.writeString(mDescription); 280 | dest.writeString(mSystemCode); 281 | dest.writeInt(mDynamicSystemCode != null ? 1 : 0); 282 | if (mDynamicSystemCode != null) { 283 | dest.writeString(mDynamicSystemCode); 284 | } 285 | dest.writeString(mNfcid2); 286 | dest.writeInt(mDynamicNfcid2 != null ? 1 : 0); 287 | if (mDynamicNfcid2 != null) { 288 | dest.writeString(mDynamicNfcid2); 289 | } 290 | dest.writeInt(mUid); 291 | dest.writeString(mT3tPmm); 292 | }; 293 | 294 | public static final Parcelable.Creator CREATOR = 295 | new Parcelable.Creator() { 296 | @Override 297 | public NfcFServiceInfo createFromParcel(Parcel source) { 298 | ResolveInfo info = ResolveInfo.CREATOR.createFromParcel(source); 299 | String description = source.readString(); 300 | String systemCode = source.readString(); 301 | String dynamicSystemCode = null; 302 | if (source.readInt() != 0) { 303 | dynamicSystemCode = source.readString(); 304 | } 305 | String nfcid2 = source.readString(); 306 | String dynamicNfcid2 = null; 307 | if (source.readInt() != 0) { 308 | dynamicNfcid2 = source.readString(); 309 | } 310 | int uid = source.readInt(); 311 | String t3tPmm = source.readString(); 312 | NfcFServiceInfo service = new NfcFServiceInfo(info, description, 313 | systemCode, dynamicSystemCode, nfcid2, dynamicNfcid2, uid, t3tPmm); 314 | return service; 315 | } 316 | 317 | @Override 318 | public NfcFServiceInfo[] newArray(int size) { 319 | return new NfcFServiceInfo[size]; 320 | } 321 | }; 322 | 323 | public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 324 | pw.println(" " + getComponent() + 325 | " (Description: " + getDescription() + ")"); 326 | pw.println(" System Code: " + getSystemCode()); 327 | pw.println(" NFCID2: " + getNfcid2()); 328 | pw.println(" T3tPmm: " + getT3tPmm()); 329 | } 330 | } 331 | 332 | --------------------------------------------------------------------------------