Implement multi-tech connect, enfore tech exclusivity.
- The NfcService now allows for connecting to a specific technology; - The "active" parts of technology classes may not be used at the same time. Change-Id: Ibb569f51cc6da4f3e24df9d0850c6f49a022b0c2
This commit is contained in:
committed by
Jeff Hamilton
parent
b094b0c4a4
commit
4049f9d00a
@ -24,7 +24,7 @@ import android.nfc.NdefMessage;
|
||||
interface INfcTag
|
||||
{
|
||||
int close(int nativeHandle);
|
||||
int connect(int nativeHandle);
|
||||
int connect(int nativeHandle, int technology);
|
||||
int reconnect(int nativeHandle);
|
||||
int[] getTechList(int nativeHandle);
|
||||
byte[] getUid(int nativeHandle);
|
||||
|
@ -63,6 +63,8 @@ public class Tag implements Parcelable {
|
||||
/*package*/ final Bundle[] mTechExtras;
|
||||
/*package*/ final int mServiceHandle; // for use by NFC service, 0 indicates a mock
|
||||
|
||||
/*package*/ int mConnectedTechnology;
|
||||
|
||||
/**
|
||||
* Hidden constructor to be used by NFC service and internal classes.
|
||||
* @hide
|
||||
@ -76,6 +78,8 @@ public class Tag implements Parcelable {
|
||||
// Ensure mTechExtras is as long as mTechList
|
||||
mTechExtras = Arrays.copyOf(techListExtras, techList.length);
|
||||
mServiceHandle = serviceHandle;
|
||||
|
||||
mConnectedTechnology = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -244,4 +248,29 @@ public class Tag implements Parcelable {
|
||||
return new Tag[size];
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* @hide
|
||||
*/
|
||||
public synchronized void setConnectedTechnology(int technology) {
|
||||
if (mConnectedTechnology == -1) {
|
||||
mConnectedTechnology = technology;
|
||||
} else {
|
||||
throw new IllegalStateException("Close other technology first!");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @hide
|
||||
*/
|
||||
public int getConnectedTechnology() {
|
||||
return mConnectedTechnology;
|
||||
}
|
||||
|
||||
/*
|
||||
* @hide
|
||||
*/
|
||||
public void setTechnologyDisconnected() {
|
||||
mConnectedTechnology = -1;
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import android.nfc.INfcAdapter;
|
||||
import android.nfc.INfcTag;
|
||||
import android.nfc.NfcAdapter;
|
||||
import android.nfc.Tag;
|
||||
import android.nfc.ErrorCodes;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
@ -101,6 +102,13 @@ import android.util.Log;
|
||||
return mTag;
|
||||
}
|
||||
|
||||
public void checkConnected() {
|
||||
if ((mTag.getConnectedTechnology() != getTechnologyId()) ||
|
||||
(mTag.getConnectedTechnology() == -1)) {
|
||||
throw new IllegalStateException("Call connect() first!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Requires {@link android.Manifest.permission#NFC} permission.
|
||||
*/
|
||||
@ -144,8 +152,19 @@ import android.util.Log;
|
||||
*/
|
||||
@Override
|
||||
public void connect() throws IOException {
|
||||
//TODO(nxp): enforce exclusivity
|
||||
mIsConnected = true;
|
||||
try {
|
||||
int errorCode = mTagService.connect(mTag.getServiceHandle(), getTechnologyId());
|
||||
|
||||
if (errorCode == ErrorCodes.SUCCESS) {
|
||||
// Store this in the tag object
|
||||
mTag.setConnectedTechnology(getTechnologyId());
|
||||
mIsConnected = true;
|
||||
} else {
|
||||
throw new IOException();
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
attemptDeadServiceRecovery(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -160,7 +179,6 @@ import android.util.Log;
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
mIsConnected = false;
|
||||
try {
|
||||
/* Note that we don't want to physically disconnect the tag,
|
||||
* but just reconnect to it to reset its state
|
||||
@ -168,6 +186,9 @@ import android.util.Log;
|
||||
mTagService.reconnect(mTag.getServiceHandle());
|
||||
} catch (RemoteException e) {
|
||||
attemptDeadServiceRecovery(e);
|
||||
} finally {
|
||||
mIsConnected = false;
|
||||
mTag.setTechnologyDisconnected();
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,6 +204,8 @@ import android.util.Log;
|
||||
* @throws IOException if the target is lost or connection closed
|
||||
*/
|
||||
public byte[] transceive(byte[] data) throws IOException {
|
||||
checkConnected();
|
||||
|
||||
try {
|
||||
byte[] response = mTagService.transceive(mTag.getServiceHandle(), data, true);
|
||||
if (response == null) {
|
||||
|
@ -75,6 +75,8 @@ public final class IsoDep extends BasicTagTechnology {
|
||||
* @throws IOException, UnsupportedOperationException
|
||||
*/
|
||||
public void selectAid(byte[] aid) throws IOException, UnsupportedOperationException {
|
||||
checkConnected();
|
||||
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
@ -229,6 +229,8 @@ public final class MifareClassic extends BasicTagTechnology {
|
||||
* Authenticate for a given sector.
|
||||
*/
|
||||
public boolean authenticateSector(int sector, byte[] key, boolean keyA) {
|
||||
checkConnected();
|
||||
|
||||
byte[] cmd = new byte[12];
|
||||
|
||||
// First byte is the command
|
||||
@ -264,6 +266,8 @@ public final class MifareClassic extends BasicTagTechnology {
|
||||
* @throws IOException
|
||||
*/
|
||||
public byte[] readBlock(int sector, int block) throws IOException {
|
||||
checkConnected();
|
||||
|
||||
byte addr = (byte) ((firstBlockInSector(sector) + block) & 0xff);
|
||||
byte[] blockread_cmd = { 0x30, addr }; // phHal_eMifareRead
|
||||
|
||||
@ -300,6 +304,8 @@ public final class MifareClassic extends BasicTagTechnology {
|
||||
*/
|
||||
@Override
|
||||
public byte[] transceive(byte[] data) throws IOException {
|
||||
checkConnected();
|
||||
|
||||
try {
|
||||
byte[] response = mTagService.transceive(mTag.getServiceHandle(), data, false);
|
||||
if (response == null) {
|
||||
|
@ -66,6 +66,8 @@ public final class MifareUltralight extends BasicTagTechnology {
|
||||
* @throws IOException
|
||||
*/
|
||||
public byte[] readBlock(int block) throws IOException {
|
||||
checkConnected();
|
||||
|
||||
byte[] blockread_cmd = { 0x30, (byte)block }; // phHal_eMifareRead
|
||||
return transceive(blockread_cmd);
|
||||
}
|
||||
@ -83,6 +85,8 @@ public final class MifareUltralight extends BasicTagTechnology {
|
||||
*/
|
||||
@Override
|
||||
public byte[] transceive(byte[] data) throws IOException {
|
||||
checkConnected();
|
||||
|
||||
try {
|
||||
byte[] response = mTagService.transceive(mTag.getServiceHandle(), data, false);
|
||||
if (response == null) {
|
||||
|
@ -113,6 +113,8 @@ public final class Ndef extends BasicTagTechnology {
|
||||
* and requires a connection.
|
||||
*/
|
||||
public NdefMessage getNdefMessage() throws IOException, FormatException {
|
||||
checkConnected();
|
||||
|
||||
try {
|
||||
int serviceHandle = mTag.getServiceHandle();
|
||||
if (mTagService.isNdef(serviceHandle)) {
|
||||
@ -143,6 +145,8 @@ public final class Ndef extends BasicTagTechnology {
|
||||
* @throws IOException
|
||||
*/
|
||||
public void writeNdefMessage(NdefMessage msg) throws IOException, FormatException {
|
||||
checkConnected();
|
||||
|
||||
try {
|
||||
int errorCode = mTagService.ndefWrite(mTag.getServiceHandle(), msg);
|
||||
switch (errorCode) {
|
||||
@ -172,6 +176,8 @@ public final class Ndef extends BasicTagTechnology {
|
||||
* @throws IOException
|
||||
*/
|
||||
public void writeExtraNdefMessage(int i, NdefMessage msg) throws IOException, FormatException {
|
||||
checkConnected();
|
||||
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@ -180,6 +186,8 @@ public final class Ndef extends BasicTagTechnology {
|
||||
* @throws IOException
|
||||
*/
|
||||
public boolean makeReadonly() throws IOException {
|
||||
checkConnected();
|
||||
|
||||
try {
|
||||
int errorCode = mTagService.ndefMakeReadOnly(mTag.getServiceHandle());
|
||||
switch (errorCode) {
|
||||
@ -205,11 +213,15 @@ public final class Ndef extends BasicTagTechnology {
|
||||
* For NFC Forum Type 1 and 2 only.
|
||||
*/
|
||||
public void makeLowLevelReadonly() {
|
||||
checkConnected();
|
||||
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] transceive(byte[] data) {
|
||||
checkConnected();
|
||||
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +49,9 @@ public final class NdefFormatable extends BasicTagTechnology {
|
||||
* NdefFormatable#format(NdefMessage)}
|
||||
*/
|
||||
public boolean canBeFormatted() throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
checkConnected();
|
||||
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -57,6 +59,8 @@ public final class NdefFormatable extends BasicTagTechnology {
|
||||
* NdefMessage to be written on the tag.
|
||||
*/
|
||||
public void format(NdefMessage firstMessage) throws IOException, FormatException {
|
||||
checkConnected();
|
||||
|
||||
try {
|
||||
byte[] DEFAULT_KEY = {(byte)0xFF,(byte)0xFF,(byte)0xFF,
|
||||
(byte)0xFF,(byte)0xFF,(byte)0xFF};
|
||||
@ -97,6 +101,8 @@ public final class NdefFormatable extends BasicTagTechnology {
|
||||
|
||||
@Override
|
||||
public byte[] transceive(byte[] data) {
|
||||
checkConnected();
|
||||
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user