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