RoutingManager.cpp revision 8e147262068865ee69157ab2249040fd1db16ff1
1/*
2 * Copyright (C) 2013 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/*
18 *  Manage the listen-mode routing table.
19 */
20
21#include <cutils/log.h>
22#include <ScopedLocalRef.h>
23#include "config.h"
24#include "JavaClassConstants.h"
25#include "RoutingManager.h"
26
27extern "C"
28{
29    #include "nfa_ee_api.h"
30    #include "nfa_ce_api.h"
31}
32
33RoutingManager::RoutingManager ()
34{
35}
36
37RoutingManager::~RoutingManager ()
38{
39    NFA_EeDeregister (nfaEeCallback);
40}
41
42bool RoutingManager::initialize (nfc_jni_native_data* native)
43{
44    static const char fn [] = "RoutingManager::initialize()";
45    unsigned long num = 0;
46    mNativeData = native;
47
48    tNFA_STATUS nfaStat;
49    {
50        SyncEventGuard guard (mEeRegisterEvent);
51        ALOGD ("%s: try ee register", fn);
52        nfaStat = NFA_EeRegister (nfaEeCallback);
53        if (nfaStat != NFA_STATUS_OK)
54        {
55            ALOGE ("%s: fail ee register; error=0x%X", fn, nfaStat);
56            return false;
57        }
58        mEeRegisterEvent.wait ();
59    }
60
61    // Get the "default" route
62    if (GetNumValue("DEFAULT_ISODEP_ROUTE", &num, sizeof(num)))
63        mDefaultEe = num;
64    else
65        mDefaultEe = 0x00;
66
67    ALOGD("%s: default route is 0x%02X", fn, mDefaultEe);
68    setDefaultRouting();
69    return true;
70}
71
72RoutingManager& RoutingManager::getInstance ()
73{
74    static RoutingManager manager;
75    return manager;
76}
77
78void RoutingManager::setDefaultRouting()
79{
80    tNFA_STATUS nfaStat;
81    SyncEventGuard guard (mRoutingEvent);
82    // Default routing for NFC-A technology
83    nfaStat = NFA_EeSetDefaultTechRouting (mDefaultEe, 0x01, 0, 0);
84    if (nfaStat == NFA_STATUS_OK)
85        mRoutingEvent.wait ();
86    else
87        ALOGE ("Fail to set default tech routing");
88
89    // Default routing for IsoDep protocol
90    nfaStat = NFA_EeSetDefaultProtoRouting(mDefaultEe, NFA_PROTOCOL_MASK_ISO_DEP, 0, 0);
91    if (nfaStat == NFA_STATUS_OK)
92        mRoutingEvent.wait ();
93    else
94        ALOGE ("Fail to set default proto routing");
95
96    // Tell the UICC to only listen on Nfc-A
97    nfaStat = NFA_CeConfigureUiccListenTech (mDefaultEe, 0x01);
98    if (nfaStat != NFA_STATUS_OK)
99        ALOGE ("Failed to configure UICC listen technologies");
100
101    // Tell the host-routing to only listen on Nfc-A
102    nfaStat = NFA_CeSetIsoDepListenTech(0x01);
103    if (nfaStat != NFA_STATUS_OK)
104        ALOGE ("Failed to configure CE IsoDep technologies");
105
106    // Register a wild-card for AIDs routed to the host
107    nfaStat = NFA_CeRegisterAidOnDH (NULL, 0, stackCallback);
108    if (nfaStat != NFA_STATUS_OK)
109        ALOGE("Failed to register wildcard AID for DH");
110
111    {
112        SyncEventGuard guard (mEeUpdateEvent);
113        // Commit the routing configuration
114        nfaStat = NFA_EeUpdateNow();
115        if (nfaStat == NFA_STATUS_OK)
116        {
117            mEeUpdateEvent.wait (); //wait for NFA_EE_UPDATED_EVT
118        }
119        else
120            ALOGE("Failed to commit routing configuration");
121    }
122}
123
124bool RoutingManager::addAidRouting(const UINT8* aid, UINT8 aidLen, int route)
125{
126    static const char fn [] = "RoutingManager::addAidRouting";
127    ALOGD ("%s: enter", fn);
128    tNFA_STATUS nfaStat = NFA_EeAddAidRouting(route, aidLen, (UINT8*) aid, 0x01);
129    if (nfaStat == NFA_STATUS_OK)
130    {
131        ALOGD ("%s: routed AID", fn);
132        return true;
133    } else
134    {
135        ALOGE ("%s: failed to route AID", fn);
136        return false;
137    }
138}
139
140bool RoutingManager::removeAidRouting(const UINT8* aid, UINT8 aidLen)
141{
142    static const char fn [] = "RoutingManager::removeAidRouting";
143    ALOGD ("%s: enter", fn);
144    tNFA_STATUS nfaStat = NFA_EeRemoveAidRouting(aidLen, (UINT8*) aid);
145    if (nfaStat == NFA_STATUS_OK)
146    {
147        ALOGD ("%s: removed AID", fn);
148        return true;
149    } else
150    {
151        ALOGE ("%s: failed to remove AID", fn);
152        return false;
153    }
154}
155
156bool RoutingManager::commitRouting()
157{
158    static const char fn [] = "RoutingManager::commitRouting";
159    tNFA_STATUS nfaStat = 0;
160    ALOGD ("%s", fn);
161    {
162        SyncEventGuard guard (mEeUpdateEvent);
163        nfaStat = NFA_EeUpdateNow();
164        if (nfaStat == NFA_STATUS_OK)
165        {
166            mEeUpdateEvent.wait (); //wait for NFA_EE_UPDATED_EVT
167        }
168    }
169    return (nfaStat == NFA_STATUS_OK);
170}
171
172void RoutingManager::notifyActivated ()
173{
174    JNIEnv* e = NULL;
175    ScopedAttach attach(mNativeData->vm, &e);
176    if (e == NULL)
177    {
178        ALOGE ("jni env is null");
179        return;
180    }
181
182    e->CallVoidMethod (mNativeData->manager, android::gCachedNfcManagerNotifyHostEmuActivated);
183    if (e->ExceptionCheck())
184    {
185        e->ExceptionClear();
186        ALOGE ("fail notify");
187    }
188}
189
190void RoutingManager::notifyDeactivated ()
191{
192    JNIEnv* e = NULL;
193    ScopedAttach attach(mNativeData->vm, &e);
194    if (e == NULL)
195    {
196        ALOGE ("jni env is null");
197        return;
198    }
199
200    e->CallVoidMethod (mNativeData->manager, android::gCachedNfcManagerNotifyHostEmuDeactivated);
201    if (e->ExceptionCheck())
202    {
203        e->ExceptionClear();
204        ALOGE ("fail notify");
205    }
206}
207
208void RoutingManager::handleData (const UINT8* data, UINT8 dataLen)
209{
210    if (dataLen <= 0)
211    {
212        ALOGE("no data");
213        return;
214    }
215
216    JNIEnv* e = NULL;
217    ScopedAttach attach(mNativeData->vm, &e);
218    if (e == NULL)
219    {
220        ALOGE ("jni env is null");
221        return;
222    }
223
224    ScopedLocalRef<jobject> dataJavaArray(e, e->NewByteArray(dataLen));
225    if (dataJavaArray.get() == NULL)
226    {
227        ALOGE ("fail allocate array");
228        return;
229    }
230
231    e->SetByteArrayRegion ((jbyteArray)dataJavaArray.get(), 0, dataLen, (jbyte *)data);
232    if (e->ExceptionCheck())
233    {
234        e->ExceptionClear();
235        ALOGE ("fail fill array");
236        return;
237    }
238
239    e->CallVoidMethod (mNativeData->manager, android::gCachedNfcManagerNotifyHostEmuData, dataJavaArray.get());
240    if (e->ExceptionCheck())
241    {
242        e->ExceptionClear();
243        ALOGE ("fail notify");
244    }
245}
246
247void RoutingManager::stackCallback (UINT8 event, tNFA_CONN_EVT_DATA* eventData)
248{
249    static const char fn [] = "RoutingManager::stackCallback";
250    ALOGD("%s: event=0x%X", fn, event);
251    RoutingManager& routingManager = RoutingManager::getInstance();
252
253    switch (event)
254    {
255    case NFA_CE_REGISTERED_EVT:
256        {
257            tNFA_CE_REGISTERED& ce_registered = eventData->ce_registered;
258            ALOGD("%s: NFA_CE_REGISTERED_EVT; status=0x%X; h=0x%X", fn, ce_registered.status, ce_registered.handle);
259        }
260        break;
261
262    case NFA_CE_DEREGISTERED_EVT:
263        {
264            tNFA_CE_DEREGISTERED& ce_deregistered = eventData->ce_deregistered;
265            ALOGD("%s: NFA_CE_DEREGISTERED_EVT; h=0x%X", fn, ce_deregistered.handle);
266        }
267        break;
268
269    case NFA_CE_ACTIVATED_EVT:
270        {
271            routingManager.notifyActivated();
272        }
273        break;
274    case NFA_DEACTIVATED_EVT:
275    case NFA_CE_DEACTIVATED_EVT:
276        {
277            routingManager.notifyDeactivated();
278        }
279        break;
280    case NFA_CE_DATA_EVT:
281        {
282            tNFA_CE_DATA& ce_data = eventData->ce_data;
283            ALOGD("%s: NFA_CE_DATA_EVT; h=0x%X; data len=%u", fn, ce_data.handle, ce_data.len);
284            getInstance().handleData(ce_data.p_data, ce_data.len);
285        }
286        break;
287    }
288}
289/*******************************************************************************
290**
291** Function:        nfaEeCallback
292**
293** Description:     Receive execution environment-related events from stack.
294**                  event: Event code.
295**                  eventData: Event data.
296**
297** Returns:         None
298**
299*******************************************************************************/
300void RoutingManager::nfaEeCallback (tNFA_EE_EVT event, tNFA_EE_CBACK_DATA* eventData)
301{
302    static const char fn [] = "RoutingManager::nfaEeCallback";
303
304    RoutingManager& routingManager = RoutingManager::getInstance();
305
306    switch (event)
307    {
308    case NFA_EE_REGISTER_EVT:
309        {
310            SyncEventGuard guard (routingManager.mEeRegisterEvent);
311            ALOGD ("%s: NFA_EE_REGISTER_EVT; status=%u", fn, eventData->ee_register);
312            routingManager.mEeRegisterEvent.notifyOne();
313        }
314        break;
315
316    case NFA_EE_MODE_SET_EVT:
317        {
318            ALOGD ("%s: NFA_EE_MODE_SET_EVT; status: 0x%04X  handle: 0x%04X  ", fn,
319                    eventData->mode_set.status, eventData->mode_set.ee_handle);
320        }
321        break;
322
323    case NFA_EE_SET_TECH_CFG_EVT:
324        {
325            ALOGD ("%s: NFA_EE_SET_TECH_CFG_EVT; status=0x%X", fn, eventData->status);
326            SyncEventGuard guard(routingManager.mRoutingEvent);
327            routingManager.mRoutingEvent.notifyOne();
328        }
329        break;
330
331    case NFA_EE_SET_PROTO_CFG_EVT:
332        {
333            ALOGD ("%s: NFA_EE_SET_PROTO_CFG_EVT; status=0x%X", fn, eventData->status);
334            SyncEventGuard guard(routingManager.mRoutingEvent);
335            routingManager.mRoutingEvent.notifyOne();
336        }
337        break;
338
339    case NFA_EE_ACTION_EVT:
340        {
341            tNFA_EE_ACTION& action = eventData->action;
342            if (action.trigger == NFC_EE_TRIG_SELECT)
343                ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=select (0x%X)", fn, action.ee_handle, action.trigger);
344            else if (action.trigger == NFC_EE_TRIG_APP_INIT)
345            {
346                tNFC_APP_INIT& app_init = action.param.app_init;
347                ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=app-init (0x%X); aid len=%u; data len=%u", fn,
348                        action.ee_handle, action.trigger, app_init.len_aid, app_init.len_data);
349            }
350            else if (action.trigger == NFC_EE_TRIG_RF_PROTOCOL)
351                ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=rf protocol (0x%X)", fn, action.ee_handle, action.trigger);
352            else if (action.trigger == NFC_EE_TRIG_RF_TECHNOLOGY)
353                ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=rf tech (0x%X)", fn, action.ee_handle, action.trigger);
354            else
355                ALOGE ("%s: NFA_EE_ACTION_EVT; h=0x%X; unknown trigger (0x%X)", fn, action.ee_handle, action.trigger);
356        }
357        break;
358
359    case NFA_EE_DISCOVER_REQ_EVT:
360        ALOGD ("%s: NFA_EE_DISCOVER_REQ_EVT; status=0x%X; num ee=%u", __FUNCTION__,
361                eventData->discover_req.status, eventData->discover_req.num_ee);
362        break;
363
364    case NFA_EE_NO_CB_ERR_EVT:
365        ALOGD ("%s: NFA_EE_NO_CB_ERR_EVT  status=%u", fn, eventData->status);
366        break;
367
368    case NFA_EE_ADD_AID_EVT:
369        {
370            ALOGD ("%s: NFA_EE_ADD_AID_EVT  status=%u", fn, eventData->status);
371        }
372        break;
373
374    case NFA_EE_REMOVE_AID_EVT:
375        {
376            ALOGD ("%s: NFA_EE_REMOVE_AID_EVT  status=%u", fn, eventData->status);
377        }
378        break;
379
380    case NFA_EE_NEW_EE_EVT:
381        {
382            ALOGD ("%s: NFA_EE_NEW_EE_EVT  h=0x%X; status=%u", fn,
383                eventData->new_ee.ee_handle, eventData->new_ee.ee_status);
384        }
385        break;
386
387    case NFA_EE_UPDATED_EVT:
388        {
389            ALOGD("%s: NFA_EE_UPDATED_EVT", fn);
390            SyncEventGuard guard(routingManager.mEeUpdateEvent);
391            routingManager.mEeUpdateEvent.notifyOne();
392        }
393        break;
394
395    default:
396        ALOGE ("%s: unknown event=%u ????", fn, event);
397        break;
398    }
399}
400