blob: 0629f30fecbfbb5e8e2ca9126e61cd8b2168f4a7 [file] [log] [blame]
Pratap Reddy7e57f0d2018-03-15 16:54:33 +05301/******************************************************************************
2*
3* Licensed under the Apache License, Version 2.0 (the "License");
4* you may not use this file except in compliance with the License.
5* You may obtain a copy of the License at
6*
7* http://www.apache.org/licenses/LICENSE-2.0
8*
9* Unless required by applicable law or agreed to in writing, software
10* distributed under the License is distributed on an "AS IS" BASIS,
11* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12* See the License for the specific language governing permissions and
13* limitations under the License.
14*
15* Copyright 2018 NXP
16*
17******************************************************************************/
18#include "MposManager.h"
19#include <ScopedLocalRef.h>
20#include "_OverrideLog.h"
21#include "phNxpConfig.h"
22#include "config.h"
23#include "SecureElement.h"
24#include "TransactionController.h"
25
26using namespace android;
27
28namespace android {
29extern tNFA_STATUS EmvCo_dosetPoll(jboolean enable);
30extern bool isDiscoveryStarted ();
31extern void startRfDiscovery (bool isStart);
32}
33
34//#define ALOGV ALOGD
35
36MposManager MposManager::mMposMgr;
37int32_t MposManager::mDiscNtfTimeout = 10;
38int32_t MposManager::mRdrTagOpTimeout = 20;
Pratap Reddy7e57f0d2018-03-15 16:54:33 +053039jmethodID MposManager::gCachedMposManagerNotifyETSIReaderRequested;
40jmethodID MposManager::gCachedMposManagerNotifyETSIReaderRequestedFail;
Pratap Reddy7e57f0d2018-03-15 16:54:33 +053041jmethodID MposManager::gCachedMposManagerNotifyETSIReaderModeStartConfig;
42jmethodID MposManager::gCachedMposManagerNotifyETSIReaderModeStopConfig;
43jmethodID MposManager::gCachedMposManagerNotifyETSIReaderModeSwpTimeout;
44jmethodID MposManager::gCachedMposManagerNotifyETSIReaderRestart;
45
46/*******************************************************************************
47**
48** Function: initMposNativeStruct
49**
50** Description: Used to initialize the Native MPOS notification methods
51**
52** Returns: None.
53**
54*******************************************************************************/
55void MposManager::initMposNativeStruct(JNIEnv* e, jobject o)
56{
57 ScopedLocalRef<jclass> cls(e, e->GetObjectClass(o));
58
59 gCachedMposManagerNotifyETSIReaderRequested = e->GetMethodID (cls.get(),
60 "notifyETSIReaderRequested", "(ZZ)V");
61
62 gCachedMposManagerNotifyETSIReaderRequestedFail= e->GetMethodID (cls.get(),
63 "notifyETSIReaderRequestedFail", "(I)V");
64
Pratap Reddy7e57f0d2018-03-15 16:54:33 +053065 gCachedMposManagerNotifyETSIReaderModeStartConfig = e->GetMethodID (cls.get(),
66 "notifyonETSIReaderModeStartConfig", "(I)V");
67
68 gCachedMposManagerNotifyETSIReaderModeStopConfig = e->GetMethodID (cls.get(),
69 "notifyonETSIReaderModeStopConfig", "(I)V");
70
71 gCachedMposManagerNotifyETSIReaderModeSwpTimeout = e->GetMethodID (cls.get(),
72 "notifyonETSIReaderModeSwpTimeout", "(I)V");
73
74 gCachedMposManagerNotifyETSIReaderRestart = e->GetMethodID (cls.get(),
75 "notifyonETSIReaderModeRestart", "()V");
76
77}
78
79/*******************************************************************************
80**
81** Function: getInstance
82**
83** Description: Get the SecureElement singleton object.
84**
85** Returns: SecureElement object.
86**
87*******************************************************************************/
88MposManager& MposManager::getInstance()
89{
90 return mMposMgr;
91}
92
93/*******************************************************************************
94**
95** Function: initialize
96**
97** Description: Initialize all member variables.
98**
99** Returns: True if ok.
100**
101*******************************************************************************/
102bool MposManager::initialize(nfc_jni_native_data* native)
103{
104 mNativeData = native;
105 initializeReaderInfo();
106 GetNumValue(NAME_NFA_DM_DISC_NTF_TIMEOUT, &mDiscNtfTimeout, sizeof(mDiscNtfTimeout));
107 GetNxpNumValue(NAME_NXP_SWP_RD_TAG_OP_TIMEOUT, (void *) &mRdrTagOpTimeout, sizeof(mRdrTagOpTimeout));
Pratap Reddy7e57f0d2018-03-15 16:54:33 +0530108 return true;
109}
110
111/*******************************************************************************
112**
113** Function: initializeReaderInfo
114**
115** Description: Initialize all MPOS member variables.
116**
117** Returns: none.
118**
119*******************************************************************************/
120void MposManager::initializeReaderInfo()
121{
122 swp_rdr_req_ntf_info.mMutex.lock();
123 memset(&(swp_rdr_req_ntf_info.swp_rd_req_info), 0x00, sizeof(rd_swp_req_t));
124 memset(&(swp_rdr_req_ntf_info.swp_rd_req_current_info), 0x00, sizeof(rd_swp_req_t));
125 swp_rdr_req_ntf_info.swp_rd_req_current_info.src = NFA_HANDLE_INVALID;
126 swp_rdr_req_ntf_info.swp_rd_req_info.src = NFA_HANDLE_INVALID;
127 swp_rdr_req_ntf_info.swp_rd_state = STATE_SE_RDR_MODE_STOPPED;
128 swp_rdr_req_ntf_info.mMutex.unlock();
129}
130
131/*******************************************************************************
132**
133** Function: finalize
134**
135** Description: Release all resources.
136**
137** Returns: None
138**
139*******************************************************************************/
140void MposManager::finalize()
141{
142
143}
144
145/*******************************************************************************
146**
147** Function: setDedicatedReaderMode
148**
149** Description: Set/reset MPOS dedicated mode.
150**
151** Returns: SUCCESS/FAILED/BUSY
152**
153*******************************************************************************/
154tNFA_STATUS MposManager::setDedicatedReaderMode(bool on)
155{
156 tNFA_STATUS status = NFA_STATUS_OK;
157 bool rfStat = false;
158 int32_t state;
159 SecureElement &se = SecureElement::getInstance();
160
161 ALOGV("%s:enter, Reader Mode %s", __FUNCTION__, on?"ON":"OFF");
162 if(se.isRfFieldOn() || se.isActivatedInListenMode())
163 {
164 status = NFA_STATUS_BUSY;
165 }
166
167 if(status == NFA_STATUS_OK)
168 {
169 state = getEtsiReaederState();
170 rfStat = isDiscoveryStarted();
171 ALOGV("%x, rfStat=%x", on, rfStat);
172 if (on) {
173 if(rfStat)
174 {
175 startRfDiscovery(false);
176 }
177 }
178 else
179 {
180 if (state != STATE_SE_RDR_MODE_STOPPED) {
181 setEtsiReaederState (STATE_SE_RDR_MODE_STOP_CONFIG);
182 etsiInitConfig();
183 startRfDiscovery(false);
184 status = etsiResetReaderConfig();
185 setEtsiReaederState (STATE_SE_RDR_MODE_STOPPED);
186 }
187 initializeReaderInfo();
188 }
189 }
190 else
191 {
192 ALOGE("Payment is in progress, aborting reader mode start");
193 }
194 return status;
195}
196/*******************************************************************************
197**
198** Function: setEtsiReaederState
199**
200** Description: Set the current ETSI Reader state
201**
202** Returns: None
203**
204*******************************************************************************/
205void MposManager::setEtsiReaederState(se_rd_req_state_t newState)
206{
207 swp_rdr_req_ntf_info.mMutex.lock();
208 if (newState == STATE_SE_RDR_MODE_STOPPED) {
209 swp_rdr_req_ntf_info.swp_rd_req_current_info.tech_mask &= ~NFA_TECHNOLOGY_MASK_A;
210 swp_rdr_req_ntf_info.swp_rd_req_current_info.tech_mask &= ~NFA_TECHNOLOGY_MASK_B;
211
212 //If all the requested tech are removed, set the hande to invalid , so that next time poll add request can be handled
213
214 swp_rdr_req_ntf_info.swp_rd_req_current_info.src = NFA_HANDLE_INVALID;
215 swp_rdr_req_ntf_info.swp_rd_req_info = swp_rdr_req_ntf_info.swp_rd_req_current_info;
216 }
217 swp_rdr_req_ntf_info.swp_rd_state = newState;
218 swp_rdr_req_ntf_info.mMutex.unlock();
219}
220
221/*******************************************************************************
222**
223** Function: getEtsiReaederState
224**
225** Description: Get the current ETSI Reader state
226**
227** Returns: Current ETSI state
228**
229*******************************************************************************/
230se_rd_req_state_t MposManager::getEtsiReaederState()
231{
232 return swp_rdr_req_ntf_info.swp_rd_state;
233}
234
235/*******************************************************************************
236**
237** Function: etsiInitConfig
238**
239** Description: Chnage the ETSI state before start configuration
240**
241** Returns: None
242**
243*******************************************************************************/
244void MposManager::etsiInitConfig()
245{
246 ALOGV("%s: Enter", __func__);
247 swp_rdr_req_ntf_info.mMutex.lock();
248
249 if ((swp_rdr_req_ntf_info.swp_rd_state == STATE_SE_RDR_MODE_START_CONFIG)
250 && ((swp_rdr_req_ntf_info.swp_rd_req_info.tech_mask
251 & NFA_TECHNOLOGY_MASK_A)
252 || (swp_rdr_req_ntf_info.swp_rd_req_info.tech_mask
253 & NFA_TECHNOLOGY_MASK_B))) {
254 if ((swp_rdr_req_ntf_info.swp_rd_req_info.tech_mask & NFA_TECHNOLOGY_MASK_A)) {
255 swp_rdr_req_ntf_info.swp_rd_req_current_info.tech_mask |=
256 NFA_TECHNOLOGY_MASK_A;
257 }
258
259 if ((swp_rdr_req_ntf_info.swp_rd_req_info.tech_mask & NFA_TECHNOLOGY_MASK_B)) {
260 swp_rdr_req_ntf_info.swp_rd_req_current_info.tech_mask |=
261 NFA_TECHNOLOGY_MASK_B;
262 }
263
264 swp_rdr_req_ntf_info.swp_rd_req_current_info.src = swp_rdr_req_ntf_info.swp_rd_req_info.src;
265 swp_rdr_req_ntf_info.swp_rd_state = STATE_SE_RDR_MODE_START_IN_PROGRESS;
266 ALOGV("%s: new ETSI state : STATE_SE_RDR_MODE_START_IN_PROGRESS", __func__);
267 } else if ((swp_rdr_req_ntf_info.swp_rd_state == STATE_SE_RDR_MODE_STOP_CONFIG)
268 && (swp_rdr_req_ntf_info.swp_rd_req_current_info.src
269 == swp_rdr_req_ntf_info.swp_rd_req_info.src)) {
270 //pTransactionController->transactionEnd(TRANSACTION_REQUESTOR(etsiReader));
271 swp_rdr_req_ntf_info.swp_rd_state = STATE_SE_RDR_MODE_STOP_IN_PROGRESS;
272 ALOGV("%s: new ETSI state : STATE_SE_RDR_MODE_STOP_IN_PROGRESS", __func__);
273
274 }
275 swp_rdr_req_ntf_info.mMutex.unlock();
276}
277
278/*******************************************************************************
279**
280** Function: etsiReaderConfig
281**
282** Description: Configuring to Emvco Profile
283**
284** Returns: Status - NFA_STATUS_FAILED
285** NFA_STATUS_OK
286** NFA_STATUS_INVALID_PARAM
287**
288*******************************************************************************/
289tNFA_STATUS MposManager::etsiReaderConfig(int32_t eeHandle)
290{
291 tNFC_STATUS status = NFA_STATUS_FAILED;
292 SecureElement& se = SecureElement::getInstance();
293 jboolean enable = true;
294 const tNCI_DISCOVER_MAPS nfc_interface_mapping_uicc[NFC_SWP_RD_NUM_INTERFACE_MAP] =
295 {
296 /* Protocols that use Frame Interface do not need to be included in the interface mapping */
297 { NCI_PROTOCOL_ISO_DEP, NCI_INTERFACE_MODE_POLL, NCI_INTERFACE_UICC_DIRECT_STAT }
298 };
299
300 const tNCI_DISCOVER_MAPS nfc_interface_mapping_ese[NFC_SWP_RD_NUM_INTERFACE_MAP] =
301 {
302 /* Protocols that use Frame Interface do not need to be included in the interface mapping */
303 { NCI_PROTOCOL_ISO_DEP, NCI_INTERFACE_MODE_POLL, NCI_INTERFACE_ESE_DIRECT_STAT }
304 };
305
306 ALOGV("%s: Enter; eeHandle : 0x%4x", __func__, eeHandle);
307 /* Setting up the emvco poll profile*/
308 status = EmvCo_dosetPoll(enable);
309 if (status != NFA_STATUS_OK) {
310 ALOGE("%s: fail enable polling; error=0x%X", __func__, status);
311 return status;
312 }
313
314 if (eeHandle == se.EE_HANDLE_0xF4) //UICC
315 {
316 SyncEventGuard guard(mDiscMapEvent);
317 ALOGV("%s: mapping intf for UICC", __func__);
318 status = NFC_DiscoveryMap(NFC_SWP_RD_NUM_INTERFACE_MAP,
319 (tNCI_DISCOVER_MAPS *) nfc_interface_mapping_uicc,
320 MposManager::discoveryMapCb);
321 if (status != NFA_STATUS_OK) {
322 ALOGE("%s: fail intf mapping for UICC; error=0x%X", __func__, status);
323 return status;
324 }
325 status = mDiscMapEvent.wait(NFC_CMD_TIMEOUT)?NFA_STATUS_OK:NFA_STATUS_FAILED;
326 } else if (eeHandle == SecureElement::EE_HANDLE_0xF3) {//ESE
327 SyncEventGuard guard(mDiscMapEvent);
328 ALOGV("%s: mapping intf for ESE", __func__);
329 status = NFC_DiscoveryMap(NFC_SWP_RD_NUM_INTERFACE_MAP,
330 (tNCI_DISCOVER_MAPS *) nfc_interface_mapping_ese,
331 MposManager::discoveryMapCb);
332 if (status != NFA_STATUS_OK) {
333 ALOGE("%s: fail intf mapping for ESE; error=0x%X", __func__, status);
334 return status;
335 }
336 status = mDiscMapEvent.wait(NFC_CMD_TIMEOUT)?NFA_STATUS_OK:NFA_STATUS_FAILED;
337 } else {
338 ALOGV("%s: UNKNOWN SOURCE!!! ", __func__);
339 return NFA_STATUS_FAILED;
340 }
341
342 return NFA_STATUS_OK;
343}
344
345/*******************************************************************************
346**
347** Function: etsiResetReaderConfig
348**
349** Description: Configuring from Emvco profile to Nfc forum profile
350**
351** Returns: Status
352**
353*******************************************************************************/
354tNFA_STATUS MposManager::etsiResetReaderConfig()
355{
356 tNFC_STATUS status = NFA_STATUS_FAILED;
357 const tNCI_DISCOVER_MAPS nfc_interface_mapping_default[NFC_NUM_INTERFACE_MAP] =
358 {
359 /* Protocols that use Frame Interface do not need to be included in the interface mapping */
360 { NCI_PROTOCOL_ISO_DEP, NCI_INTERFACE_MODE_POLL_N_LISTEN, NCI_INTERFACE_ISO_DEP },
361 { NCI_PROTOCOL_NFC_DEP, NCI_INTERFACE_MODE_POLL_N_LISTEN, NCI_INTERFACE_NFC_DEP },
362 { NCI_PROTOCOL_MIFARE, NCI_INTERFACE_MODE_POLL, NCI_INTERFACE_MIFARE }
363 };
364 ALOGV("%s: Enter", __func__);
365
366 status = EmvCo_dosetPoll(false);
367 if (status != NFA_STATUS_OK) {
368 ALOGE("%s: fail enable polling; error=0x%X", __func__, status);
369 status = NFA_STATUS_FAILED;
370 } else {
371 SyncEventGuard guard(mDiscMapEvent);
372 ALOGV("%s: mapping intf for DH", __func__);
373 status = NFC_DiscoveryMap(NFC_NUM_INTERFACE_MAP,
374 (tNCI_DISCOVER_MAPS *) nfc_interface_mapping_default,
375 MposManager::discoveryMapCb);
376 if (status != NFA_STATUS_OK) {
377 ALOGE("%s: fail intf mapping for ESE; error=0x%X", __func__, status);
378 return status;
379 }
380 status = mDiscMapEvent.wait(NFC_CMD_TIMEOUT)?NFA_STATUS_OK:NFA_STATUS_FAILED;
381 }
382 return status;
383}
384
385/*******************************************************************************
386**
387** Function: notifyEEReaderEvent
388**
389** Description: Notify with the Reader event
390**
391** Returns: None
392**
393*******************************************************************************/
394void MposManager::notifyEEReaderEvent (etsi_rd_event_t evt)
395{
396 SecureElement& se = SecureElement::getInstance();
397 struct timespec mLastRfFieldToggle = se.getLastRfFiledToggleTime();
398
399 ALOGV("%s: enter; event=%x", __func__, evt);
400
401 swp_rdr_req_ntf_info.mMutex.lock();
402 int ret = clock_gettime(CLOCK_MONOTONIC, &mLastRfFieldToggle);
403 if (ret == -1) {
404 ALOGE("%s: clock_gettime failed", __func__);
405 // There is no good choice here...
406 }
407 switch (evt) {
Pratap Reddy49abbe32018-03-27 16:51:59 +0530408 case ETSI_READER_START_SUCCESS:
409 ALOGV("%s: ETSI_READER_START_SUCCESS", __func__);
Pratap Reddy7e57f0d2018-03-15 16:54:33 +0530410 {
Pratap Reddy7e57f0d2018-03-15 16:54:33 +0530411 mSwpReaderTimer.kill();
412 /*
Pratap Reddy49abbe32018-03-27 16:51:59 +0530413 * This is to give user a specific time window to wait for card to be found and
414 * Notify to user if no card found within the give interval of timeout.
Pratap Reddy7e57f0d2018-03-15 16:54:33 +0530415 *
416 * configuring timeout.
417 * */
418 if (mRdrTagOpTimeout > 0)
419 mSwpReaderTimer.set(ONE_SECOND_MS * mRdrTagOpTimeout, MposManager::startStopSwpReaderProc);
Pratap Reddy7e57f0d2018-03-15 16:54:33 +0530420 }
421 break;
Pratap Reddy49abbe32018-03-27 16:51:59 +0530422 case ETSI_READER_ACTIVATED:
423 ALOGV("%s: ETSI_READER_ACTIVATED", __func__);
424 break;
Pratap Reddy7e57f0d2018-03-15 16:54:33 +0530425 case ETSI_READER_STOP:
Pratap Reddy49abbe32018-03-27 16:51:59 +0530426 ALOGV("%s: ETSI_READER_STOP", __func__);
Pratap Reddy7e57f0d2018-03-15 16:54:33 +0530427 pTransactionController->transactionEnd(TRANSACTION_REQUESTOR(etsiReader));
428
429 if (se.mIsWiredModeOpen)
430 se.NfccStandByOperation (STANDBY_TIMER_START);
431 break;
432 default:
433 ALOGV("%s: UNKNOWN EVENT ??", __func__);
434 break;
435 }
436
437 swp_rdr_req_ntf_info.mMutex.unlock();
438
439 ALOGV("%s: exit", __func__);
440}
441
442/*******************************************************************************
443**
444** Function: notifyMPOSReaderEvent
445**
446** Description: Notify the Reader current status event to NFC service
447**
448** Returns: None
449**
450*******************************************************************************/
451void MposManager::notifyMPOSReaderEvent(mpos_rd_state_t aEvent)
452{
453 ALOGV("%s: enter; event type is %s", __FUNCTION__, convertMposEventToString(aEvent));
454 JNIEnv* e = NULL;
455
456 ScopedAttach attach(mNativeData->vm, &e);
457 if (e == NULL) {
458 ALOGE("%s: jni env is null", __FUNCTION__);
459 return;
460 }
461
462 switch(aEvent)
463 {
464 case MPOS_READER_MODE_START:
465 e->CallVoidMethod(mNativeData->manager,
466 gCachedMposManagerNotifyETSIReaderModeStartConfig,
467 (uint16_t) swp_rdr_req_ntf_info.swp_rd_req_info.src);
468 break;
469 case MPOS_READER_MODE_STOP:
470 mSwpReaderTimer.kill();
471 e->CallVoidMethod(mNativeData->manager,
472 gCachedMposManagerNotifyETSIReaderModeStopConfig,
473 mDiscNtfTimeout);
474 break;
475 case MPOS_READER_MODE_TIMEOUT:
476 e->CallVoidMethod(mNativeData->manager,
477 gCachedMposManagerNotifyETSIReaderModeSwpTimeout,
478 mDiscNtfTimeout);
479 break;
480 case MPOS_READER_MODE_RESTART:
481 e->CallVoidMethod(mNativeData->manager,
482 gCachedMposManagerNotifyETSIReaderRestart);
483 break;
484 default:
485
486 break;
487 }
Pratap Reddy7e57f0d2018-03-15 16:54:33 +0530488}
Pratap Reddy49abbe32018-03-27 16:51:59 +0530489
Pratap Reddy7e57f0d2018-03-15 16:54:33 +0530490void MposManager::hanldeEtsiReaderReqEvent (tNFA_EE_DISCOVER_REQ* aInfo)
491{
492 /* Handle Reader over SWP.
493 * 1. Check if the event is for Reader over SWP.
494 * 2. IF yes than send this info(READER_REQUESTED_EVENT) till FWK level.
495 * 3. Stop the discovery.
496 * 4. MAP the proprietary interface for Reader over SWP.NFC_DiscoveryMap, nfc_api.h
497 * 5. start the discovery with reader req, type and DH configuration.
498 *
499 * 6. IF yes than send this info(STOP_READER_EVENT) till FWK level.
500 * 7. MAP the DH interface for Reader over SWP. NFC_DiscoveryMap, nfc_api.h
501 * 8. start the discovery with DH configuration.
502 */
503 swp_rdr_req_ntf_info.mMutex.lock();
504 for (unsigned char xx = 0; xx < aInfo->num_ee; xx++) {
505 //for each technology (A, B, F, B'), print the bit field that shows
506 //what protocol(s) is support by that technology
507 ALOGV("EE[%u] Handle: 0x%04x PA: 0x%02x PB: 0x%02x",
508 xx, aInfo->ee_disc_info[xx].ee_handle, aInfo->ee_disc_info[xx].pa_protocol, aInfo->ee_disc_info[xx].pb_protocol);
509
510 ALOGV("swp_rd_state is %s", convertRdrStateToString(swp_rdr_req_ntf_info.swp_rd_state));
511 if ((aInfo->ee_disc_info[xx].ee_req_op == NFC_EE_DISC_OP_ADD)
512 && (swp_rdr_req_ntf_info.swp_rd_state == STATE_SE_RDR_MODE_STOPPED
513 || swp_rdr_req_ntf_info.swp_rd_state == STATE_SE_RDR_MODE_START_CONFIG
514 || swp_rdr_req_ntf_info.swp_rd_state == STATE_SE_RDR_MODE_STOP_CONFIG)
515 && (aInfo->ee_disc_info[xx].pa_protocol == NCI_PROTOCOL_ISO_DEP
516 || aInfo->ee_disc_info[xx].pb_protocol == NCI_PROTOCOL_ISO_DEP)) {
517 ALOGV( "NFA_RD_SWP_READER_REQUESTED EE[%u] Handle: 0x%04x PA: 0x%02x PB: 0x%02x",
518 xx, aInfo->ee_disc_info[xx].ee_handle, aInfo->ee_disc_info[xx].pa_protocol, aInfo->ee_disc_info[xx].pb_protocol);
519
520 swp_rdr_req_ntf_info.swp_rd_req_info.src = aInfo->ee_disc_info[xx].ee_handle;
521 swp_rdr_req_ntf_info.swp_rd_req_info.tech_mask = 0;
522 swp_rdr_req_ntf_info.swp_rd_req_info.reCfg = false;
523
524 if (!(swp_rdr_req_ntf_info.swp_rd_req_info.tech_mask & NFA_TECHNOLOGY_MASK_A)) {
525 if (aInfo->ee_disc_info[xx].pa_protocol == NCI_PROTOCOL_ISO_DEP) {
526 swp_rdr_req_ntf_info.swp_rd_req_info.tech_mask |= NFA_TECHNOLOGY_MASK_A;
527 swp_rdr_req_ntf_info.swp_rd_req_info.reCfg = true;
528 }
529 }
530
531 if (!(swp_rdr_req_ntf_info.swp_rd_req_info.tech_mask & NFA_TECHNOLOGY_MASK_B)) {
532 if (aInfo->ee_disc_info[xx].pb_protocol == NCI_PROTOCOL_ISO_DEP) {
533 swp_rdr_req_ntf_info.swp_rd_req_info.tech_mask |= NFA_TECHNOLOGY_MASK_B;
534 swp_rdr_req_ntf_info.swp_rd_req_info.reCfg = true;
535 }
536 }
537
538 if (swp_rdr_req_ntf_info.swp_rd_req_info.reCfg) {
539 mSwpRdrReqTimer.kill();
540 if (swp_rdr_req_ntf_info.swp_rd_state != STATE_SE_RDR_MODE_STOP_CONFIG) {
541 if(swp_rdr_req_ntf_info.swp_rd_req_info.tech_mask != (NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B)) {
542 ALOGV( "swp_rd_state is %s evt: NFA_RD_SWP_READER_REQUESTED mSwpRdrReqTimer start",
543 convertRdrStateToString(swp_rdr_req_ntf_info.swp_rd_state));
544 mSwpRdrReqTimer.set(rdr_req_handling_timeout, readerReqEventNtf);
545 swp_rdr_req_ntf_info.swp_rd_state = STATE_SE_RDR_MODE_START_CONFIG;
546 }
547 }
548 /*RestartReadermode procedure special case should not de-activate*/
549 else if (swp_rdr_req_ntf_info.swp_rd_state == STATE_SE_RDR_MODE_STOP_CONFIG) {
550 swp_rdr_req_ntf_info.swp_rd_state = STATE_SE_RDR_MODE_STARTED;
551 /*RFDEACTIVATE_DISCOVERY*/
552 NFA_Deactivate(false);
553 }
554 swp_rdr_req_ntf_info.swp_rd_req_info.reCfg = false;
555 }
556 break;
557 } else if ((aInfo->ee_disc_info[xx].ee_req_op == NFC_EE_DISC_OP_REMOVE)
558 && ((swp_rdr_req_ntf_info.swp_rd_state == STATE_SE_RDR_MODE_STARTED)
559 || (swp_rdr_req_ntf_info.swp_rd_state == STATE_SE_RDR_MODE_START_CONFIG)
560 || (swp_rdr_req_ntf_info.swp_rd_state == STATE_SE_RDR_MODE_STOP_CONFIG)
561 || (swp_rdr_req_ntf_info.swp_rd_state == STATE_SE_RDR_MODE_ACTIVATED))
562 && (aInfo->ee_disc_info[xx].pa_protocol == 0xFF
563 || aInfo->ee_disc_info[xx].pb_protocol == 0xFF)) {
564 ALOGV( "NFA_RD_SWP_READER_STOP EE[%u] Handle: 0x%04x PA: 0x%02x PB: 0x%02x",
565 xx, aInfo->ee_disc_info[xx].ee_handle, aInfo->ee_disc_info[xx].pa_protocol, aInfo->ee_disc_info[xx].pb_protocol);
566
567 if (swp_rdr_req_ntf_info.swp_rd_req_info.src == aInfo->ee_disc_info[xx].ee_handle) {
568 if (aInfo->ee_disc_info[xx].pa_protocol == 0xFF) {
569 if (swp_rdr_req_ntf_info.swp_rd_req_info.tech_mask & NFA_TECHNOLOGY_MASK_A) {
570 swp_rdr_req_ntf_info.swp_rd_req_info.tech_mask &= ~NFA_TECHNOLOGY_MASK_A;
571 swp_rdr_req_ntf_info.swp_rd_req_info.reCfg = true;
572 }
573 }
574
575 if (aInfo->ee_disc_info[xx].pb_protocol == 0xFF) {
576 if (swp_rdr_req_ntf_info.swp_rd_req_info.tech_mask & NFA_TECHNOLOGY_MASK_B) {
577 swp_rdr_req_ntf_info.swp_rd_req_info.tech_mask &= ~NFA_TECHNOLOGY_MASK_B;
578 swp_rdr_req_ntf_info.swp_rd_req_info.reCfg = true;
579 }
580
581 }
582
583 if (swp_rdr_req_ntf_info.swp_rd_req_info.reCfg) {
584 swp_rdr_req_ntf_info.swp_rd_state = STATE_SE_RDR_MODE_STOP_CONFIG;
585 mSwpRdrReqTimer.kill();
586 if(swp_rdr_req_ntf_info.swp_rd_req_info.tech_mask)
587 {
588 ALOGV("swp_rd_state is %s evt: NFA_RD_SWP_READER_STOP mSwpRdrReqTimer start",
589 convertRdrStateToString(swp_rdr_req_ntf_info.swp_rd_state));
590 mSwpRdrReqTimer.set(rdr_req_handling_timeout, readerReqEventNtf);
591 }
592 swp_rdr_req_ntf_info.swp_rd_req_info.reCfg = false;
593 }
594 }
595 break;
596 }
597 }
598 swp_rdr_req_ntf_info.mMutex.unlock();
599 if ((swp_rdr_req_ntf_info.swp_rd_req_info.tech_mask == 0) ||
600 (swp_rdr_req_ntf_info.swp_rd_req_info.tech_mask == (NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B)))
601 {
602 if(swp_rdr_req_ntf_info.swp_rd_state == STATE_SE_RDR_MODE_STOP_CONFIG) {
603 notifyMPOSReaderEvent(MPOS_READER_MODE_STOP);
604 }
605 else if(swp_rdr_req_ntf_info.swp_rd_state == STATE_SE_RDR_MODE_START_CONFIG) {
606 notifyMPOSReaderEvent(MPOS_READER_MODE_START);
607 }
608 }
609}
610
611void MposManager::discoveryMapCb (tNFC_DISCOVER_EVT event, tNFC_DISCOVER *p_data)
612{
613 (void) event;
614 (void) p_data;
615 SyncEventGuard guard(mMposMgr.mDiscMapEvent);
616 mMposMgr.mDiscMapEvent.notifyOne();
617}
618
619/*******************************************************************************
620**
621** Function: getSwpRrdReqInfo
622**
623** Description: get swp_rdr_req_ntf_info
624**
625** Returns: swp_rdr_req_ntf_info
626**
627*******************************************************************************/
628Rdr_req_ntf_info_t MposManager::getSwpRrdReqInfo()
629{
630 ALOGE("%s Enter", __func__);
631 if (!nfcFL.nfcNxpEse || !nfcFL.eseFL._ESE_ETSI_READER_ENABLE) {
632 ALOGV("%s : nfcNxpEse or ETSI_READER not avaialble.Returning", __func__);
633 }
634 return swp_rdr_req_ntf_info;
635}
636
637/*******************************************************************************
638**
639** Function: readerReqEventNtf
640**
641** Description: This is used to send the reader start or stop request
642** event to service
643**
644** Returns: None
645**
646*******************************************************************************/
647void MposManager::readerReqEventNtf (union sigval)
648{
649 if (!nfcFL.nfcNxpEse || !nfcFL.eseFL._ESE_ETSI_READER_ENABLE) {
650 ALOGV("%s: nfcNxpEse or ETSI_READER not available. Returning", __func__);
651 return;
652 }
653 ALOGV("%s: ", __func__);
654 JNIEnv* e = NULL;
655
656 ScopedAttach attach(mMposMgr.mNativeData->vm, &e);
657 if (e == NULL) {
658 ALOGE("%s: jni env is null", __func__);
659 return;
660 }
661
662 Rdr_req_ntf_info_t mSwp_info = mMposMgr.getSwpRrdReqInfo();
663
664 ALOGV("%s: swp_rdr_req_ntf_info.swp_rd_req_info.src = 0x%4x ", __func__,
665 mSwp_info.swp_rd_req_info.src);
666
667 if (mMposMgr.getEtsiReaederState() == STATE_SE_RDR_MODE_START_CONFIG) {
668 e->CallVoidMethod(mMposMgr.mNativeData->manager,
669 mMposMgr.gCachedMposManagerNotifyETSIReaderModeStartConfig,
670 (uint16_t) mSwp_info.swp_rd_req_info.src);
671 } else if (mMposMgr.getEtsiReaederState() == STATE_SE_RDR_MODE_STOP_CONFIG) {
672 ALOGV("%s: mSwpReaderTimer.kill() ", __func__);
673 mMposMgr.mSwpReaderTimer.kill();
674 e->CallVoidMethod(mMposMgr.mNativeData->manager,
675 mMposMgr.gCachedMposManagerNotifyETSIReaderModeStopConfig,
676 mDiscNtfTimeout);
677 }
678}
679
680/*******************************************************************************
681**
682** Function: startStopSwpReaderProc
683**
684** Description: Notify the reader timeout
685**
686** Returns: None
687**
688*******************************************************************************/
689void MposManager::startStopSwpReaderProc (union sigval)
690{
691 if (!nfcFL.nfcNxpEse || !nfcFL.eseFL._ESE_ETSI_READER_ENABLE) {
692 ALOGV("%s: nfcNxpEse or ETSI_READER not enabled. Returning", __func__);
693 return;
694 }
695 ALOGV("%s: Timeout!!!", __func__);
696
697 mMposMgr.notifyMPOSReaderEvent(MPOS_READER_MODE_TIMEOUT);
698}
699
700/*******************************************************************************
701**
702** Function: etsiReaderReStart
703**
704** Description: Notify's the mPOS restart event
705**
706** Returns: void.
707**
708*******************************************************************************/
709void MposManager::etsiReaderReStart()
710{
711 ALOGV (" %s: Enter",__FUNCTION__);
712 pTransactionController->transactionEnd(TRANSACTION_REQUESTOR(etsiReader));
713 notifyMPOSReaderEvent(MPOS_READER_MODE_RESTART);
714}
715
716/*******************************************************************************
717**
718** Function: validateHCITransactionEventParams
719**
720** Description: Decodes the HCI_TRANSACTION_EVT to check for
721** reader restart and POWER_OFF evt
722**
723** Returns: OK/FAILED.
724**
725*******************************************************************************/
726tNFA_STATUS MposManager::validateHCITransactionEventParams(uint8_t *aData, int32_t aDatalen)
727{
728 tNFA_STATUS status = NFA_STATUS_OK;
729 uint8_t Event, Version, Code;
730 if(aData != NULL && aDatalen >= 3)
731 {
732 Event = *aData++;
733 Version = *aData++;
734 Code = *aData;
735 if(Event == EVENT_RF_ERROR && Version == EVENT_RF_VERSION)
736 {
737 if(Code == EVENT_RDR_MODE_RESTART)
738 {
739 status = NFA_STATUS_FAILED;
740 etsiReaderReStart();
741 }
742 else
743 {
744
745 }
746 }
747 }
748 else if (aData != NULL && aDatalen == 0x01 && *aData == EVENT_EMV_POWER_OFF)
749 {
750 ALOGV ("Power off procedure to be triggered");
751 unsigned long num;
752 if(GetNumValue(NAME_NFA_CONFIG_FORMAT, (void *)&num, sizeof(num)))
753 {
754 if (num == 0x05)
755 {
756 ALOGV ("Power off procedure is triggered");
757 NFA_Deactivate(false);
758 }
759 else
760 {
761 //DO nothing
762 }
763 }
764 else
765 {
766 ALOGV ("NAME_NFA_CONFIG_FORMAT not found");
767 }
768 }
769 else
770 {
771
772 }
773 return status;
774}
775
776/*******************************************************************************
777**
778** Function: convertMposEventToString
779**
780** Description: Converts the MPOS status events to String format
781**
782** Returns: Name of the event
783**
784*******************************************************************************/
785const char* MposManager::convertMposEventToString(mpos_rd_state_t aEvent)
786{
787 switch(aEvent)
788 {
789 case MPOS_READER_MODE_INVALID:
790 return "MPOS_READER_MODE_INVALID";
791 case MPOS_READER_MODE_START:
792 return "MPOS_READER_MODE_START";
793 case MPOS_READER_MODE_START_SUCCESS:
794 return "MPOS_READER_MODE_START_SUCCESS";
795 case MPOS_READER_MODE_RESTART:
796 return "MPOS_READER_MODE_RESTART";
797 case MPOS_READER_MODE_STOP:
798 return "MPOS_READER_MODE_STOP";
799 case MPOS_READER_MODE_STOP_SUCCESS:
800 return "MPOS_READER_MODE_STOP_SUCCESS";
801 case MPOS_READER_MODE_TIMEOUT:
802 return "MPOS_READER_MODE_TIMEOUT";
803 case MPOS_READER_MODE_REMOVE_CARD:
804 return "MPOS_READER_MODE_REMOVE_CARD";
805 case MPOS_READER_MODE_RECOVERY:
806 return "MPOS_READER_MODE_RECOVERY";
807 case MPOS_READER_MODE_FAIL:
808 return "MPOS_READER_MODE_FAIL";
809
810 default:
811 return "UNKNOWN";
812 }
813}
814
815/*******************************************************************************
816**
817** Function: convertRdrStateToString
818**
819** Description: Converts the MPOS state to String format
820**
821** Returns: Name of the event
822**
823*******************************************************************************/
824const char* MposManager::convertRdrStateToString(se_rd_req_state_t aState)
825{
826 switch(aState)
827 {
828 case STATE_SE_RDR_MODE_INVALID:
829 return "STATE_SE_RDR_MODE_INVALID";
830 case STATE_SE_RDR_MODE_START_CONFIG:
831 return "STATE_SE_RDR_MODE_START_CONFIG";
832 case STATE_SE_RDR_MODE_START_IN_PROGRESS:
833 return "STATE_SE_RDR_MODE_START_IN_PROGRESS";
834 case STATE_SE_RDR_MODE_STARTED:
835 return "STATE_SE_RDR_MODE_STARTED";
836 case STATE_SE_RDR_MODE_ACTIVATED:
837 return "STATE_SE_RDR_MODE_ACTIVATED";
838 case STATE_SE_RDR_MODE_STOP_CONFIG:
839 return "STATE_SE_RDR_MODE_STOP_CONFIG";
840 case STATE_SE_RDR_MODE_STOP_IN_PROGRESS:
841 return "STATE_SE_RDR_MODE_STOP_IN_PROGRESS";
842 case STATE_SE_RDR_MODE_STOPPED:
843 return "STATE_SE_RDR_MODE_STOPPED";
844
845 default:
846 return "UNKNOWN";
847 }
848}