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 
21 import com.android.nfc.NfcService;
22 import com.android.nfc.cardemulation.RegisteredT3tIdentifiersCache.T3tIdentifier;
23 
24 import java.io.FileDescriptor;
25 import java.io.PrintWriter;
26 import java.util.ArrayList;
27 import java.util.List;
28 
29 public class SystemCodeRoutingManager {
30     static final String TAG = "SystemCodeRoutingManager";
31 
32     static final boolean DBG = false;
33 
34     final Object mLock = new Object();
35 
36     List<T3tIdentifier> mConfiguredT3tIdentifiers =
37             new ArrayList<T3tIdentifier>();
38 
configureRouting(List<T3tIdentifier> t3tIdentifiers)39     public boolean configureRouting(List<T3tIdentifier> t3tIdentifiers) {
40         if (DBG) Log.d(TAG, "configureRouting");
41         List<T3tIdentifier> toBeAdded = new ArrayList<T3tIdentifier>();
42         List<T3tIdentifier> toBeRemoved = new ArrayList<T3tIdentifier>();
43         synchronized (mLock) {
44             for (T3tIdentifier t3tIdentifier : t3tIdentifiers) {
45                 if (!mConfiguredT3tIdentifiers.contains(t3tIdentifier)) {
46                     toBeAdded.add(t3tIdentifier);
47                 }
48             }
49             for (T3tIdentifier t3tIdentifier : mConfiguredT3tIdentifiers) {
50                 if (!t3tIdentifiers.contains(t3tIdentifier)) {
51                     toBeRemoved.add(t3tIdentifier);
52                 }
53             }
54             if (toBeAdded.size() <= 0 && toBeRemoved.size() <= 0) {
55                 Log.d(TAG, "Routing table unchanged, not updating");
56                 return false;
57             }
58             // Update internal structures
59             for (T3tIdentifier t3tIdentifier : toBeRemoved) {
60                 if (DBG) Log.d(TAG, "deregisterNfcFSystemCodeonDh:");
61                 NfcService.getInstance().deregisterT3tIdentifier(
62                         t3tIdentifier.systemCode, t3tIdentifier.nfcid2, t3tIdentifier.t3tPmm);
63             }
64             for (T3tIdentifier t3tIdentifier : toBeAdded) {
65                 if (DBG) Log.d(TAG, "registerNfcFSystemCodeonDh:");
66                 NfcService.getInstance().registerT3tIdentifier(
67                         t3tIdentifier.systemCode, t3tIdentifier.nfcid2 , t3tIdentifier.t3tPmm);
68             }
69             if (DBG) {
70                 Log.d(TAG, "(Before) mConfiguredT3tIdentifiers: size=" +
71                         mConfiguredT3tIdentifiers.size());
72                 for (T3tIdentifier t3tIdentifier : mConfiguredT3tIdentifiers) {
73                     Log.d(TAG, "    " + t3tIdentifier.systemCode +
74                             "/" + t3tIdentifier.t3tPmm);
75                 }
76                 Log.d(TAG, "(After) mConfiguredT3tIdentifiers: size=" +
77                         t3tIdentifiers.size());
78                 for (T3tIdentifier t3tIdentifier : t3tIdentifiers) {
79                     Log.d(TAG, "    " + t3tIdentifier.systemCode +
80                             "/" + t3tIdentifier.nfcid2 +
81                             "/" + t3tIdentifier.t3tPmm);
82                 }
83             }
84             mConfiguredT3tIdentifiers = t3tIdentifiers;
85         }
86 
87         // And finally commit the routing
88         NfcService.getInstance().commitRouting();
89 
90         return true;
91     }
92 
93     /**
94      * This notifies that the SystemCode routing table in the controller
95      * has been cleared (usually due to NFC being turned off).
96      */
onNfccRoutingTableCleared()97     public void onNfccRoutingTableCleared() {
98         // The routing table in the controller was cleared
99         // To stay in sync, clear our own tables.
100         synchronized (mLock) {
101             if (DBG) Log.d(TAG, "onNfccRoutingTableCleared");
102             NfcService.getInstance().clearT3tIdentifiersCache();
103             mConfiguredT3tIdentifiers.clear();
104         }
105     }
106 
dump(FileDescriptor fd, PrintWriter pw, String[] args)107     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
108         pw.println("HCE-F routing table:");
109         synchronized (mLock) {
110             for (T3tIdentifier t3tIdentifier : mConfiguredT3tIdentifiers) {
111                 pw.println("    " + t3tIdentifier.systemCode +
112                         "/" + t3tIdentifier.nfcid2);
113             }
114         }
115     }
116 }
117