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 com.android.nfc.cardemulation; 18 19 import android.util.Log; 20 import android.util.proto.ProtoOutputStream; 21 22 import com.android.nfc.NfcService; 23 import com.android.nfc.cardemulation.RegisteredT3tIdentifiersCache.T3tIdentifier; 24 25 import java.io.FileDescriptor; 26 import java.io.PrintWriter; 27 import java.util.ArrayList; 28 import java.util.List; 29 30 public class SystemCodeRoutingManager { 31 static final String TAG = "SystemCodeRoutingManager"; 32 33 static final boolean DBG = false; 34 35 final Object mLock = new Object(); 36 37 List<T3tIdentifier> mConfiguredT3tIdentifiers = 38 new ArrayList<T3tIdentifier>(); 39 configureRouting(List<T3tIdentifier> t3tIdentifiers)40 public boolean configureRouting(List<T3tIdentifier> t3tIdentifiers) { 41 if (DBG) Log.d(TAG, "configureRouting"); 42 List<T3tIdentifier> toBeAdded = new ArrayList<T3tIdentifier>(); 43 List<T3tIdentifier> toBeRemoved = new ArrayList<T3tIdentifier>(); 44 synchronized (mLock) { 45 for (T3tIdentifier t3tIdentifier : t3tIdentifiers) { 46 if (!mConfiguredT3tIdentifiers.contains(t3tIdentifier)) { 47 toBeAdded.add(t3tIdentifier); 48 } 49 } 50 for (T3tIdentifier t3tIdentifier : mConfiguredT3tIdentifiers) { 51 if (!t3tIdentifiers.contains(t3tIdentifier)) { 52 toBeRemoved.add(t3tIdentifier); 53 } 54 } 55 if (toBeAdded.size() <= 0 && toBeRemoved.size() <= 0) { 56 Log.d(TAG, "Routing table unchanged, not updating"); 57 return false; 58 } 59 // Update internal structures 60 for (T3tIdentifier t3tIdentifier : toBeRemoved) { 61 if (DBG) Log.d(TAG, "deregisterNfcFSystemCodeonDh:"); 62 NfcService.getInstance().deregisterT3tIdentifier( 63 t3tIdentifier.systemCode, t3tIdentifier.nfcid2, t3tIdentifier.t3tPmm); 64 } 65 for (T3tIdentifier t3tIdentifier : toBeAdded) { 66 if (DBG) Log.d(TAG, "registerNfcFSystemCodeonDh:"); 67 NfcService.getInstance().registerT3tIdentifier( 68 t3tIdentifier.systemCode, t3tIdentifier.nfcid2 , t3tIdentifier.t3tPmm); 69 } 70 if (DBG) { 71 Log.d(TAG, "(Before) mConfiguredT3tIdentifiers: size=" + 72 mConfiguredT3tIdentifiers.size()); 73 for (T3tIdentifier t3tIdentifier : mConfiguredT3tIdentifiers) { 74 Log.d(TAG, " " + t3tIdentifier.systemCode + 75 "/" + t3tIdentifier.t3tPmm); 76 } 77 Log.d(TAG, "(After) mConfiguredT3tIdentifiers: size=" + 78 t3tIdentifiers.size()); 79 for (T3tIdentifier t3tIdentifier : t3tIdentifiers) { 80 Log.d(TAG, " " + t3tIdentifier.systemCode + 81 "/" + t3tIdentifier.nfcid2 + 82 "/" + t3tIdentifier.t3tPmm); 83 } 84 } 85 mConfiguredT3tIdentifiers = t3tIdentifiers; 86 } 87 88 // And finally commit the routing 89 NfcService.getInstance().commitRouting(); 90 91 return true; 92 } 93 94 /** 95 * This notifies that the SystemCode routing table in the controller 96 * has been cleared (usually due to NFC being turned off). 97 */ onNfccRoutingTableCleared()98 public void onNfccRoutingTableCleared() { 99 // The routing table in the controller was cleared 100 // To stay in sync, clear our own tables. 101 synchronized (mLock) { 102 if (DBG) Log.d(TAG, "onNfccRoutingTableCleared"); 103 NfcService.getInstance().clearT3tIdentifiersCache(); 104 mConfiguredT3tIdentifiers.clear(); 105 } 106 } 107 dump(FileDescriptor fd, PrintWriter pw, String[] args)108 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 109 pw.println("HCE-F routing table:"); 110 synchronized (mLock) { 111 for (T3tIdentifier t3tIdentifier : mConfiguredT3tIdentifiers) { 112 pw.println(" " + t3tIdentifier.systemCode + 113 "/" + t3tIdentifier.nfcid2); 114 } 115 } 116 } 117 118 /** 119 * Dump debugging information as a SystemCodeRoutingManagerProto 120 * 121 * Note: 122 * See proto definition in frameworks/base/core/proto/android/nfc/card_emulation.proto 123 * When writing a nested message, must call {@link ProtoOutputStream#start(long)} before and 124 * {@link ProtoOutputStream#end(long)} after. 125 * Never reuse a proto field number. When removing a field, mark it as reserved. 126 */ dumpDebug(ProtoOutputStream proto)127 void dumpDebug(ProtoOutputStream proto) { 128 synchronized (mLock) { 129 for (T3tIdentifier t3tIdentifier : mConfiguredT3tIdentifiers) { 130 long token = proto.start(SystemCodeRoutingManagerProto.T3T_IDENTIFIERS); 131 proto.write(SystemCodeRoutingManagerProto.T3tIdentifier.SYSTEM_CODE, 132 t3tIdentifier.systemCode); 133 proto.write(SystemCodeRoutingManagerProto.T3tIdentifier.NFCID2, 134 t3tIdentifier.nfcid2); 135 proto.end(token); 136 } 137 } 138 } 139 } 140