BasicTagTechnology.java revision d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0
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 17package android.nfc.tech; 18 19import android.nfc.ErrorCodes; 20import android.nfc.Tag; 21import android.nfc.TagLostException; 22import android.nfc.TransceiveResult; 23import android.os.RemoteException; 24import android.util.Log; 25 26import java.io.IOException; 27 28/** 29 * A base class for tag technologies that are built on top of transceive(). 30 */ 31/* package */ abstract class BasicTagTechnology implements TagTechnology { 32 private static final String TAG = "NFC"; 33 34 /*package*/ final Tag mTag; 35 /*package*/ boolean mIsConnected; 36 /*package*/ 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 /** 57 * Helper to indicate if {@link #connect} has succeeded. 58 * <p> 59 * Does not cause RF activity, and does not block. 60 * @return true if {@link #connect} has completed successfully and the {@link Tag} is believed 61 * to be within range. Applications must still handle {@link java.io.IOException} 62 * while using methods that require a connection in case the connection is lost after this 63 * method returns. 64 */ 65 public boolean isConnected() { 66 if (!mIsConnected) { 67 return false; 68 } 69 70 try { 71 return mTag.getTagService().isPresent(mTag.getServiceHandle()); 72 } catch (RemoteException e) { 73 Log.e(TAG, "NFC service dead", e); 74 return false; 75 } 76 } 77 78 @Override 79 public void connect() throws IOException { 80 try { 81 int errorCode = mTag.getTagService().connect(mTag.getServiceHandle(), 82 mSelectedTechnology); 83 84 if (errorCode == ErrorCodes.SUCCESS) { 85 // Store this in the tag object 86 mTag.setConnectedTechnology(mSelectedTechnology); 87 mIsConnected = true; 88 } else { 89 throw new IOException(); 90 } 91 } catch (RemoteException e) { 92 Log.e(TAG, "NFC service dead", e); 93 throw new IOException("NFC service died"); 94 } 95 } 96 97 @Override 98 public void reconnect() throws IOException { 99 if (!mIsConnected) { 100 throw new IllegalStateException("Technology not connected yet"); 101 } 102 103 try { 104 int errorCode = mTag.getTagService().reconnect(mTag.getServiceHandle()); 105 106 if (errorCode != ErrorCodes.SUCCESS) { 107 mIsConnected = false; 108 mTag.setTechnologyDisconnected(); 109 throw new IOException(); 110 } 111 } catch (RemoteException e) { 112 mIsConnected = false; 113 mTag.setTechnologyDisconnected(); 114 Log.e(TAG, "NFC service dead", e); 115 throw new IOException("NFC service died"); 116 } 117 } 118 119 @Override 120 public void close() { 121 try { 122 /* Note that we don't want to physically disconnect the tag, 123 * but just reconnect to it to reset its state 124 */ 125 mTag.getTagService().reconnect(mTag.getServiceHandle()); 126 } catch (RemoteException e) { 127 Log.e(TAG, "NFC service dead", e); 128 } finally { 129 mIsConnected = false; 130 mTag.setTechnologyDisconnected(); 131 } 132 } 133 134 /** Internal transceive */ 135 /*package*/ byte[] transceive(byte[] data, boolean raw) throws IOException { 136 checkConnected(); 137 138 try { 139 TransceiveResult result = mTag.getTagService().transceive(mTag.getServiceHandle(), 140 data, raw); 141 if (result == null) { 142 throw new IOException("transceive failed"); 143 } else { 144 if (result.isSuccessful()) { 145 return result.getResponseData(); 146 } else { 147 if (result.isTagLost()) { 148 throw new TagLostException("Tag was lost."); 149 } 150 else { 151 throw new IOException("transceive failed"); 152 } 153 } 154 } 155 } catch (RemoteException e) { 156 Log.e(TAG, "NFC service dead", e); 157 throw new IOException("NFC service died"); 158 } 159 } 160} 161