16493859b424f65af79e3e13835f7dfed38495c00Martijn Coenen/* 26493859b424f65af79e3e13835f7dfed38495c00Martijn Coenen * Copyright (C) 2013 The Android Open Source Project 36493859b424f65af79e3e13835f7dfed38495c00Martijn Coenen * 46493859b424f65af79e3e13835f7dfed38495c00Martijn Coenen * Licensed under the Apache License, Version 2.0 (the "License"); 56493859b424f65af79e3e13835f7dfed38495c00Martijn Coenen * you may not use this file except in compliance with the License. 66493859b424f65af79e3e13835f7dfed38495c00Martijn Coenen * You may obtain a copy of the License at 76493859b424f65af79e3e13835f7dfed38495c00Martijn Coenen * 86493859b424f65af79e3e13835f7dfed38495c00Martijn Coenen * http://www.apache.org/licenses/LICENSE-2.0 96493859b424f65af79e3e13835f7dfed38495c00Martijn Coenen * 106493859b424f65af79e3e13835f7dfed38495c00Martijn Coenen * Unless required by applicable law or agreed to in writing, software 116493859b424f65af79e3e13835f7dfed38495c00Martijn Coenen * distributed under the License is distributed on an "AS IS" BASIS, 126493859b424f65af79e3e13835f7dfed38495c00Martijn Coenen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136493859b424f65af79e3e13835f7dfed38495c00Martijn Coenen * See the License for the specific language governing permissions and 146493859b424f65af79e3e13835f7dfed38495c00Martijn Coenen * limitations under the License. 156493859b424f65af79e3e13835f7dfed38495c00Martijn Coenen */ 16d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenenpackage com.android.nfc.cardemulation; 17d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen 18d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenenimport android.util.Log; 19d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenenimport android.util.SparseArray; 20d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen 21d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenenimport com.android.nfc.NfcService; 22d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen 23af3e301d7820bc0a2447db8af16ab5335e6bd520Martijn Coenenimport java.io.FileDescriptor; 24af3e301d7820bc0a2447db8af16ab5335e6bd520Martijn Coenenimport java.io.PrintWriter; 25d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenenimport java.util.HashMap; 26d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenenimport java.util.HashSet; 27d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenenimport java.util.Map; 28d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenenimport java.util.Set; 29d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen 30d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenenpublic class AidRoutingManager { 31d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen static final String TAG = "AidRoutingManager"; 32d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen 33410f4b955283be0187cd2933bdea07c66e101639Martijn Coenen static final boolean DBG = false; 3431208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen 3531208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen static final int ROUTE_HOST = 0x00; 3631208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen 3731208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen // Every routing table entry is matched exact 3831208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen static final int AID_MATCHING_EXACT_ONLY = 0x00; 3931208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen // Every routing table entry can be matched either exact or prefix 4031208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen static final int AID_MATCHING_EXACT_OR_PREFIX = 0x01; 4131208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen // Every routing table entry is matched as a prefix 4231208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen static final int AID_MATCHING_PREFIX_ONLY = 0x02; 43341b2c02da8b4d2a681f3fbcc5657921ad421e32Martijn Coenen 446a707e75739696dde62201047158913411e8cd81Martijn Coenen // This is the default IsoDep protocol route; it means 456a707e75739696dde62201047158913411e8cd81Martijn Coenen // that for any AID that needs to be routed to this 466a707e75739696dde62201047158913411e8cd81Martijn Coenen // destination, we won't need to add a rule to the routing 476a707e75739696dde62201047158913411e8cd81Martijn Coenen // table, because this destination is already the default route. 486a707e75739696dde62201047158913411e8cd81Martijn Coenen // 496a707e75739696dde62201047158913411e8cd81Martijn Coenen // For Nexus devices, the default route is always 0x00. 50ea8f37ee5376e296c3b67f57946b73e48ad88c5cEvan Chu final int mDefaultRoute; 516a707e75739696dde62201047158913411e8cd81Martijn Coenen 52451ba48faa87d78bfbec0597ff06af1747cf6acbMartijn Coenen // For Nexus devices, just a static route to the eSE 5389c893312d524f50c47b0d32071f3de8631197f3Martijn Coenen // OEMs/Carriers could manually map off-host AIDs 544358172f18871d58d5bc2050e4d9d0bf9bc2d5e5Martijn Coenen // to the correct eSE/UICC based on state they keep. 55ea8f37ee5376e296c3b67f57946b73e48ad88c5cEvan Chu final int mDefaultOffHostRoute; 5689c893312d524f50c47b0d32071f3de8631197f3Martijn Coenen 5731208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen // How the NFC controller can match AIDs in the routing table; 5831208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen // see AID_MATCHING constants 5931208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen final int mAidMatchingSupport; 6031208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen 614358172f18871d58d5bc2050e4d9d0bf9bc2d5e5Martijn Coenen final Object mLock = new Object(); 624358172f18871d58d5bc2050e4d9d0bf9bc2d5e5Martijn Coenen 63d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen // mAidRoutingTable contains the current routing table. The index is the route ID. 64d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen // The route can include routes to a eSE/UICC. 6531208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen SparseArray<Set<String>> mAidRoutingTable = 6631208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen new SparseArray<Set<String>>(); 67d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen 68d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen // Easy look-up what the route is for a certain AID 6931208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen HashMap<String, Integer> mRouteForAid = new HashMap<String, Integer>(); 70d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen 71ea8f37ee5376e296c3b67f57946b73e48ad88c5cEvan Chu private native int doGetDefaultRouteDestination(); 72ea8f37ee5376e296c3b67f57946b73e48ad88c5cEvan Chu private native int doGetDefaultOffHostRouteDestination(); 7331208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen private native int doGetAidMatchingMode(); 7431208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen 75d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen public AidRoutingManager() { 76ea8f37ee5376e296c3b67f57946b73e48ad88c5cEvan Chu mDefaultRoute = doGetDefaultRouteDestination(); 77ea8f37ee5376e296c3b67f57946b73e48ad88c5cEvan Chu if (DBG) Log.d(TAG, "mDefaultRoute=0x" + Integer.toHexString(mDefaultRoute)); 78ea8f37ee5376e296c3b67f57946b73e48ad88c5cEvan Chu mDefaultOffHostRoute = doGetDefaultOffHostRouteDestination(); 79ea8f37ee5376e296c3b67f57946b73e48ad88c5cEvan Chu if (DBG) Log.d(TAG, "mDefaultOffHostRoute=0x" + Integer.toHexString(mDefaultOffHostRoute)); 8031208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen mAidMatchingSupport = doGetAidMatchingMode(); 8131208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen if (DBG) Log.d(TAG, "mAidMatchingSupport=0x" + Integer.toHexString(mAidMatchingSupport)); 82d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen } 83d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen 8431208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen public boolean supportsAidPrefixRouting() { 8531208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen return mAidMatchingSupport == AID_MATCHING_EXACT_OR_PREFIX || 8631208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen mAidMatchingSupport == AID_MATCHING_PREFIX_ONLY; 87d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen } 88d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen 8931208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen void clearNfcRoutingTableLocked() { 9031208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen for (Map.Entry<String, Integer> aidEntry : mRouteForAid.entrySet()) { 91c5d3a21bf654bb84f69302bba84acfe42c745b84Paul Chaisson String aid = aidEntry.getKey(); 92c5d3a21bf654bb84f69302bba84acfe42c745b84Paul Chaisson if (aid.endsWith("*")) { 93c5d3a21bf654bb84f69302bba84acfe42c745b84Paul Chaisson if (mAidMatchingSupport == AID_MATCHING_EXACT_ONLY) { 94c5d3a21bf654bb84f69302bba84acfe42c745b84Paul Chaisson Log.e(TAG, "Device does not support prefix AIDs but AID [" + aid 95c5d3a21bf654bb84f69302bba84acfe42c745b84Paul Chaisson + "] is registered"); 96c5d3a21bf654bb84f69302bba84acfe42c745b84Paul Chaisson } else if (mAidMatchingSupport == AID_MATCHING_PREFIX_ONLY) { 97c5d3a21bf654bb84f69302bba84acfe42c745b84Paul Chaisson if (DBG) Log.d(TAG, "Unrouting prefix AID " + aid); 98c5d3a21bf654bb84f69302bba84acfe42c745b84Paul Chaisson // Cut off '*' since controller anyway treats all AIDs as a prefix 99c5d3a21bf654bb84f69302bba84acfe42c745b84Paul Chaisson aid = aid.substring(0, aid.length() - 1); 100c5d3a21bf654bb84f69302bba84acfe42c745b84Paul Chaisson } else if (mAidMatchingSupport == AID_MATCHING_EXACT_OR_PREFIX) { 101c5d3a21bf654bb84f69302bba84acfe42c745b84Paul Chaisson if (DBG) Log.d(TAG, "Unrouting prefix AID " + aid); 102c5d3a21bf654bb84f69302bba84acfe42c745b84Paul Chaisson } 103c5d3a21bf654bb84f69302bba84acfe42c745b84Paul Chaisson } else { 104c5d3a21bf654bb84f69302bba84acfe42c745b84Paul Chaisson if (DBG) Log.d(TAG, "Unrouting exact AID " + aid); 105c5d3a21bf654bb84f69302bba84acfe42c745b84Paul Chaisson } 106c5d3a21bf654bb84f69302bba84acfe42c745b84Paul Chaisson 107c5d3a21bf654bb84f69302bba84acfe42c745b84Paul Chaisson NfcService.getInstance().unrouteAids(aid); 108d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen } 109d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen } 110d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen 11131208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen public boolean configureRouting(HashMap<String, Boolean> aidMap) { 11231208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen SparseArray<Set<String>> aidRoutingTable = new SparseArray<Set<String>>(aidMap.size()); 11331208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen HashMap<String, Integer> routeForAid = new HashMap<String, Integer>(aidMap.size()); 11431208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen // Then, populate internal data structures first 11531208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen for (Map.Entry<String, Boolean> aidEntry : aidMap.entrySet()) { 11631208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen int route = aidEntry.getValue() ? ROUTE_HOST : mDefaultOffHostRoute; 11731208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen String aid = aidEntry.getKey(); 11831208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen Set<String> entries = aidRoutingTable.get(route, new HashSet<String>()); 11931208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen entries.add(aid); 12031208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen aidRoutingTable.put(route, entries); 12131208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen routeForAid.put(aid, route); 12231208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen } 12331208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen 1244358172f18871d58d5bc2050e4d9d0bf9bc2d5e5Martijn Coenen synchronized (mLock) { 12531208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen if (routeForAid.equals(mRouteForAid)) { 12631208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen if (DBG) Log.d(TAG, "Routing table unchanged, not updating"); 12731208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen return false; 1284358172f18871d58d5bc2050e4d9d0bf9bc2d5e5Martijn Coenen } 12931208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen 13031208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen // Otherwise, update internal structures and commit new routing 13131208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen clearNfcRoutingTableLocked(); 13231208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen mRouteForAid = routeForAid; 13331208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen mAidRoutingTable = aidRoutingTable; 13431208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen if (mAidMatchingSupport == AID_MATCHING_PREFIX_ONLY) { 13531208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen /* If a non-default route registers an exact AID which is shorter 13631208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen * than this exact AID, this will create a problem with controllers 13731208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen * that treat every AID in the routing table as a prefix. 13831208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen * For example, if App A registers F0000000041010 as an exact AID, 13931208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen * and App B registers F000000004 as an exact AID, and App B is not 14031208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen * the default route, the following would be added to the routing table: 14131208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen * F000000004 -> non-default destination 14231208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen * However, because in this mode, the controller treats every routing table 14331208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen * entry as a prefix, it means F0000000041010 would suddenly go to the non-default 14431208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen * destination too, whereas it should have gone to the default. 14531208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen * 14631208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen * The only way to prevent this is to add the longer AIDs of the 14731208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen * default route at the top of the table, so they will be matched first. 14831208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen */ 14931208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen Set<String> defaultRouteAids = mAidRoutingTable.get(mDefaultRoute); 15031208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen if (defaultRouteAids != null) { 15131208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen for (String defaultRouteAid : defaultRouteAids) { 15231208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen // Check whether there are any shorted AIDs routed to non-default 15331208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen // TODO this is O(N^2) run-time complexity... 15431208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen for (Map.Entry<String, Integer> aidEntry : mRouteForAid.entrySet()) { 15531208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen String aid = aidEntry.getKey(); 15631208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen int route = aidEntry.getValue(); 15731208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen if (defaultRouteAid.startsWith(aid) && route != mDefaultRoute) { 15831208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen if (DBG) 15931208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen Log.d(TAG, "Adding AID " + defaultRouteAid + " for default " + 16031208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen "route, because a conflicting shorter AID will be " + 16131208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen "added to the routing table"); 16231208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen NfcService.getInstance().routeAids(defaultRouteAid, mDefaultRoute); 16331208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen } 16431208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen } 16531208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen } 16631208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen } 1674358172f18871d58d5bc2050e4d9d0bf9bc2d5e5Martijn Coenen } 16831208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen 16931208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen // Add AID entries for all non-default routes 17031208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen for (int i = 0; i < mAidRoutingTable.size(); i++) { 17131208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen int route = mAidRoutingTable.keyAt(i); 17231208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen if (route != mDefaultRoute) { 17331208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen Set<String> aidsForRoute = mAidRoutingTable.get(route); 17431208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen for (String aid : aidsForRoute) { 17531208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen if (aid.endsWith("*")) { 17631208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen if (mAidMatchingSupport == AID_MATCHING_EXACT_ONLY) { 17731208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen Log.e(TAG, "This device does not support prefix AIDs."); 17831208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen } else if (mAidMatchingSupport == AID_MATCHING_PREFIX_ONLY) { 17931208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen if (DBG) Log.d(TAG, "Routing prefix AID " + aid + " to route " 18031208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen + Integer.toString(route)); 18131208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen // Cut off '*' since controller anyway treats all AIDs as a prefix 18231208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen NfcService.getInstance().routeAids(aid.substring(0, 18331208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen aid.length() - 1), route); 18431208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen } else if (mAidMatchingSupport == AID_MATCHING_EXACT_OR_PREFIX) { 18531208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen if (DBG) Log.d(TAG, "Routing prefix AID " + aid + " to route " 18631208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen + Integer.toString(route)); 18731208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen NfcService.getInstance().routeAids(aid, route); 18831208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen } 18931208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen } else { 19031208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen if (DBG) Log.d(TAG, "Routing exact AID " + aid + " to route " 19131208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen + Integer.toString(route)); 19231208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen NfcService.getInstance().routeAids(aid, route); 19331208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen } 19431208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen } 19531208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen } 1966a707e75739696dde62201047158913411e8cd81Martijn Coenen } 197d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen } 19831208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen 19931208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen // And finally commit the routing 20031208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen NfcService.getInstance().commitRouting(); 20131208d3ee36f583fd998c89508a3e93bb550cb29Martijn Coenen 202d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen return true; 203d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen } 204d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen 205d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen /** 206d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen * This notifies that the AID routing table in the controller 207d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen * has been cleared (usually due to NFC being turned off). 208d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen */ 209d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen public void onNfccRoutingTableCleared() { 210d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen // The routing table in the controller was cleared 211d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen // To stay in sync, clear our own tables. 2124358172f18871d58d5bc2050e4d9d0bf9bc2d5e5Martijn Coenen synchronized (mLock) { 2134358172f18871d58d5bc2050e4d9d0bf9bc2d5e5Martijn Coenen mAidRoutingTable.clear(); 2144358172f18871d58d5bc2050e4d9d0bf9bc2d5e5Martijn Coenen mRouteForAid.clear(); 2154358172f18871d58d5bc2050e4d9d0bf9bc2d5e5Martijn Coenen } 216d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen } 217d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen 218af3e301d7820bc0a2447db8af16ab5335e6bd520Martijn Coenen public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 219af3e301d7820bc0a2447db8af16ab5335e6bd520Martijn Coenen pw.println("Routing table:"); 220ea8f37ee5376e296c3b67f57946b73e48ad88c5cEvan Chu pw.println(" Default route: " + ((mDefaultRoute == 0x00) ? "host" : "secure element")); 221af3e301d7820bc0a2447db8af16ab5335e6bd520Martijn Coenen synchronized (mLock) { 222af3e301d7820bc0a2447db8af16ab5335e6bd520Martijn Coenen for (int i = 0; i < mAidRoutingTable.size(); i++) { 223af3e301d7820bc0a2447db8af16ab5335e6bd520Martijn Coenen Set<String> aids = mAidRoutingTable.valueAt(i); 224af3e301d7820bc0a2447db8af16ab5335e6bd520Martijn Coenen pw.println(" Routed to 0x" + Integer.toHexString(mAidRoutingTable.keyAt(i)) + ":"); 225af3e301d7820bc0a2447db8af16ab5335e6bd520Martijn Coenen for (String aid : aids) { 226af3e301d7820bc0a2447db8af16ab5335e6bd520Martijn Coenen pw.println(" \"" + aid + "\""); 227af3e301d7820bc0a2447db8af16ab5335e6bd520Martijn Coenen } 228af3e301d7820bc0a2447db8af16ab5335e6bd520Martijn Coenen } 229af3e301d7820bc0a2447db8af16ab5335e6bd520Martijn Coenen } 230af3e301d7820bc0a2447db8af16ab5335e6bd520Martijn Coenen } 231d53c2b599c73f7404b5a604be4d9a5449cafdd72Martijn Coenen} 232