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
17package com.android.nfc.cardemulation;
18
19import android.util.Log;
20
21import com.android.nfc.NfcService;
22import com.android.nfc.cardemulation.RegisteredT3tIdentifiersCache.T3tIdentifier;
23
24import java.io.FileDescriptor;
25import java.io.PrintWriter;
26import java.util.ArrayList;
27import java.util.List;
28
29public 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
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);
63            }
64            for (T3tIdentifier t3tIdentifier : toBeAdded) {
65                if (DBG) Log.d(TAG, "registerNfcFSystemCodeonDh:");
66                NfcService.getInstance().registerT3tIdentifier(
67                        t3tIdentifier.systemCode, t3tIdentifier.nfcid2);
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.nfcid2);
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                }
82            }
83            mConfiguredT3tIdentifiers = t3tIdentifiers;
84        }
85
86        // And finally commit the routing
87        NfcService.getInstance().commitRouting();
88
89        return true;
90    }
91
92    /**
93     * This notifies that the SystemCode routing table in the controller
94     * has been cleared (usually due to NFC being turned off).
95     */
96    public void onNfccRoutingTableCleared() {
97        // The routing table in the controller was cleared
98        // To stay in sync, clear our own tables.
99        synchronized (mLock) {
100            if (DBG) Log.d(TAG, "onNfccRoutingTableCleared");
101            NfcService.getInstance().clearT3tIdentifiersCache();
102            mConfiguredT3tIdentifiers.clear();
103        }
104    }
105
106    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
107        pw.println("Routing table:");
108        synchronized (mLock) {
109            for (T3tIdentifier t3tIdentifier : mConfiguredT3tIdentifiers) {
110                pw.println("    " + t3tIdentifier.systemCode +
111                        "/" + t3tIdentifier.nfcid2);
112            }
113        }
114    }
115}
116