1 /*
2 * Copyright 2010-2024 NXP
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 * TML Implementation.
19 */
20
21 #include <phDal4Nfc_messageQueueLib.h>
22 #include <phNxpConfig.h>
23 #include <phNxpLog.h>
24 #include <phNxpNciHal_utils.h>
25 #include <phOsalNfc_Timer.h>
26 #include <phTmlNfc.h>
27 #include "NfccTransportFactory.h"
28
29 /*
30 * Duration of Timer to wait after sending an Nci packet
31 */
32 #define PHTMLNFC_MAXTIME_RETRANSMIT (200U)
33 #define MAX_WRITE_RETRY_COUNT 0x03
34 #define MAX_READ_RETRY_DELAY_IN_MILLISEC (150U)
35 /* Retry Count = Standby Recovery time of NFCC / Retransmission time + 1 */
36 static uint8_t bCurrentRetryCount = (2000 / PHTMLNFC_MAXTIME_RETRANSMIT) + 1;
37
38 /* Value to reset variables of TML */
39 #define PH_TMLNFC_RESET_VALUE (0x00)
40
41 /* Indicates a Initial or offset value */
42 #define PH_TMLNFC_VALUE_ONE (0x01)
43
44 spTransport gpTransportObj;
45 extern bool_t gsIsFirstHalMinOpen;
46
47 /* Initialize Context structure pointer used to access context structure */
48 phTmlNfc_Context_t* gpphTmlNfc_Context = NULL;
49 /* Local Function prototypes */
50 static NFCSTATUS phTmlNfc_StartThread(void);
51 static void phTmlNfc_ReadDeferredCb(void* pParams);
52 static void phTmlNfc_WriteDeferredCb(void* pParams);
53 static void* phTmlNfc_TmlThread(void* pParam);
54 static void* phTmlNfc_TmlWriterThread(void* pParam);
55 static void phTmlNfc_SignalWriteComplete(void);
56 static int phTmlNfc_WaitReadInit(void);
57
58 /* Function definitions */
59
60 /*******************************************************************************
61 **
62 ** Function phTmlNfc_Init
63 **
64 ** Description Provides initialization of TML layer and hardware interface
65 ** Configures given hardware interface and sends handle to the
66 ** caller
67 **
68 ** Parameters pConfig - TML configuration details as provided by the upper
69 ** layer
70 **
71 ** Returns NFC status:
72 ** NFCSTATUS_SUCCESS - initialization successful
73 ** NFCSTATUS_INVALID_PARAMETER - at least one parameter is
74 ** invalid
75 ** NFCSTATUS_FAILED - initialization failed (for example,
76 ** unable to open hardware interface)
77 ** NFCSTATUS_INVALID_DEVICE - device has not been opened or has
78 ** been disconnected
79 **
80 *******************************************************************************/
phTmlNfc_Init(pphTmlNfc_Config_t pConfig)81 NFCSTATUS phTmlNfc_Init(pphTmlNfc_Config_t pConfig) {
82 NFCSTATUS wInitStatus = NFCSTATUS_SUCCESS;
83
84 /* Check if TML layer is already Initialized */
85 if (NULL != gpphTmlNfc_Context) {
86 /* TML initialization is already completed */
87 wInitStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_ALREADY_INITIALISED);
88 }
89 /* Validate Input parameters */
90 else if ((NULL == pConfig) ||
91 (PH_TMLNFC_RESET_VALUE == pConfig->dwGetMsgThreadId)) {
92 /*Parameters passed to TML init are wrong */
93 wInitStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_INVALID_PARAMETER);
94 } else {
95 /* Allocate memory for TML context */
96 gpphTmlNfc_Context =
97 (phTmlNfc_Context_t*)malloc(sizeof(phTmlNfc_Context_t));
98
99 if (NULL == gpphTmlNfc_Context) {
100 wInitStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_FAILED);
101 } else {
102 /*Configure transport layer for communication*/
103 if ((gpTransportObj == NULL) &&
104 (NFCSTATUS_SUCCESS != phTmlNfc_ConfigTransport()))
105 return NFCSTATUS_FAILED;
106
107 if (gsIsFirstHalMinOpen) {
108 if (!gpTransportObj->Flushdata(pConfig)) {
109 NXPLOG_NCIHAL_E("Flushdata Failed");
110 }
111 }
112 /* Initialise all the internal TML variables */
113 memset(gpphTmlNfc_Context, PH_TMLNFC_RESET_VALUE,
114 sizeof(phTmlNfc_Context_t));
115 /* Make sure that the thread runs once it is created */
116 gpphTmlNfc_Context->bThreadDone = 1;
117 /* Open the device file to which data is read/written */
118 wInitStatus = gpTransportObj->OpenAndConfigure(
119 pConfig, &(gpphTmlNfc_Context->pDevHandle));
120
121 if (NFCSTATUS_SUCCESS != wInitStatus) {
122 wInitStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_INVALID_DEVICE);
123 gpphTmlNfc_Context->pDevHandle = NULL;
124 } else {
125 phTmlNfc_IoCtl(phTmlNfc_e_SetNfcState);
126 gpphTmlNfc_Context->tReadInfo.bEnable = 0;
127 gpphTmlNfc_Context->tWriteInfo.bEnable = 0;
128 gpphTmlNfc_Context->tReadInfo.bThreadBusy = false;
129 gpphTmlNfc_Context->tWriteInfo.bThreadBusy = false;
130 if (pConfig->fragment_len == 0x00)
131 pConfig->fragment_len = PH_TMLNFC_FRGMENT_SIZE_PN557;
132 gpphTmlNfc_Context->fragment_len = pConfig->fragment_len;
133
134 if (0 != sem_init(&gpphTmlNfc_Context->rxSemaphore, 0, 0)) {
135 wInitStatus = NFCSTATUS_FAILED;
136 } else if (0 != phTmlNfc_WaitReadInit()) {
137 wInitStatus = NFCSTATUS_FAILED;
138 } else if (0 != sem_init(&gpphTmlNfc_Context->txSemaphore, 0, 0)) {
139 wInitStatus = NFCSTATUS_FAILED;
140 } else if (0 != sem_init(&gpphTmlNfc_Context->postMsgSemaphore, 0, 0)) {
141 wInitStatus = NFCSTATUS_FAILED;
142 } else {
143 sem_post(&gpphTmlNfc_Context->postMsgSemaphore);
144 /* Start TML thread (to handle write and read operations) */
145 if (NFCSTATUS_SUCCESS != phTmlNfc_StartThread()) {
146 wInitStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_FAILED);
147 } else {
148 /* Create Timer used for Retransmission of NCI packets */
149 gpphTmlNfc_Context->dwTimerId = phOsalNfc_Timer_Create();
150 if (PH_OSALNFC_TIMER_ID_INVALID != gpphTmlNfc_Context->dwTimerId) {
151 /* Store the Thread Identifier to which Message is to be posted */
152 gpphTmlNfc_Context->dwCallbackThreadId =
153 pConfig->dwGetMsgThreadId;
154 /* Enable retransmission of Nci packet & set retry count to
155 * default */
156 gpphTmlNfc_Context->eConfig = phTmlNfc_e_DisableRetrans;
157 /* Retry Count = Standby Recovery time of NFCC / Retransmission
158 * time + 1 */
159 gpphTmlNfc_Context->bRetryCount =
160 (2000 / PHTMLNFC_MAXTIME_RETRANSMIT) + 1;
161 gpphTmlNfc_Context->bWriteCbInvoked = false;
162 } else {
163 wInitStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_FAILED);
164 }
165 }
166 }
167 }
168 }
169 }
170 /* Clean up all the TML resources if any error */
171 if (NFCSTATUS_SUCCESS != wInitStatus) {
172 /* Clear all handles and memory locations initialized during init */
173 phTmlNfc_Shutdown_CleanUp();
174 }
175
176 return wInitStatus;
177 }
178
179 /*******************************************************************************
180 **
181 ** Function phTmlNfc_ConfigTransport
182 **
183 ** Description Configure Transport channel based on transport type provided
184 ** in config file
185 **
186 ** Returns NFCSTATUS_SUCCESS If transport channel is configured
187 ** NFCSTATUS_FAILED If transport channel configuration failed
188 **
189 *******************************************************************************/
phTmlNfc_ConfigTransport()190 NFCSTATUS phTmlNfc_ConfigTransport() {
191 unsigned long transportType = UNKNOWN;
192 unsigned long value = 0;
193 int isfound = GetNxpNumValue(NAME_NXP_TRANSPORT, &value, sizeof(value));
194 if (isfound > 0) {
195 transportType = value;
196 }
197 gpTransportObj = transportFactory.getTransport((transportIntf)transportType);
198 if (gpTransportObj == nullptr) {
199 NXPLOG_TML_E("No Transport channel available \n");
200 return NFCSTATUS_FAILED;
201 }
202 return NFCSTATUS_SUCCESS;
203 }
204 /*******************************************************************************
205 **
206 ** Function phTmlNfc_ConfigNciPktReTx
207 **
208 ** Description Provides Enable/Disable Retransmission of NCI packets
209 ** Needed in case of Timeout between Transmission and Reception
210 ** of NCI packets. Retransmission can be enabled only if
211 ** standby mode is enabled
212 **
213 ** Parameters eConfig - values from phTmlNfc_ConfigRetrans_t
214 ** bRetryCount - Number of times Nci packets shall be
215 ** retransmitted (default = 3)
216 **
217 ** Returns None
218 **
219 *******************************************************************************/
phTmlNfc_ConfigNciPktReTx(phTmlNfc_ConfigRetrans_t eConfiguration,uint8_t bRetryCounter)220 void phTmlNfc_ConfigNciPktReTx(phTmlNfc_ConfigRetrans_t eConfiguration,
221 uint8_t bRetryCounter) {
222 /* Enable/Disable Retransmission */
223
224 gpphTmlNfc_Context->eConfig = eConfiguration;
225 if (phTmlNfc_e_EnableRetrans == eConfiguration) {
226 /* Check whether Retry counter passed is valid */
227 if (0 != bRetryCounter) {
228 gpphTmlNfc_Context->bRetryCount = bRetryCounter;
229 }
230 /* Set retry counter to its default value */
231 else {
232 /* Retry Count = Standby Recovery time of NFCC / Retransmission time + 1
233 */
234 gpphTmlNfc_Context->bRetryCount =
235 (2000 / PHTMLNFC_MAXTIME_RETRANSMIT) + 1;
236 }
237 }
238
239 return;
240 }
241
242 /*******************************************************************************
243 **
244 ** Function phTmlNfc_StartThread
245 **
246 ** Description Initializes comport, reader and writer threads
247 **
248 ** Parameters None
249 **
250 ** Returns NFC status:
251 ** NFCSTATUS_SUCCESS - threads initialized successfully
252 ** NFCSTATUS_FAILED - initialization failed due to system error
253 **
254 *******************************************************************************/
phTmlNfc_StartThread(void)255 static NFCSTATUS phTmlNfc_StartThread(void) {
256 NFCSTATUS wStartStatus = NFCSTATUS_SUCCESS;
257 void* h_threadsEvent = 0x00;
258 int pthread_create_status = 0;
259
260 /* Create Reader and Writer threads */
261 pthread_create_status =
262 pthread_create(&gpphTmlNfc_Context->readerThread, NULL,
263 &phTmlNfc_TmlThread, (void*)h_threadsEvent);
264 if (0 != pthread_create_status) {
265 wStartStatus = NFCSTATUS_FAILED;
266 } else {
267 /*Start Writer Thread*/
268 pthread_create_status =
269 pthread_create(&gpphTmlNfc_Context->writerThread, NULL,
270 &phTmlNfc_TmlWriterThread, (void*)h_threadsEvent);
271 if (0 != pthread_create_status) {
272 wStartStatus = NFCSTATUS_FAILED;
273 }
274 }
275
276 return wStartStatus;
277 }
278
279 /*******************************************************************************
280 **
281 ** Function phTmlNfc_TmlThread
282 **
283 ** Description Read the data from the lower layer driver
284 **
285 ** Parameters pParam - parameters for Writer thread function
286 **
287 ** Returns None
288 **
289 *******************************************************************************/
phTmlNfc_TmlThread(void * pParam)290 static void* phTmlNfc_TmlThread(void* pParam) {
291 NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
292 int32_t dwNoBytesWrRd = PH_TMLNFC_RESET_VALUE;
293 uint8_t temp[PH_TMLNFC_MAX_READ_NCI_BUFF_LEN];
294 uint8_t readRetryDelay = 0;
295 /* Transaction info buffer to be passed to Callback Thread */
296 static phTmlNfc_TransactInfo_t tTransactionInfo;
297 /* Structure containing Tml callback function and parameters to be invoked
298 by the callback thread */
299 static phLibNfc_DeferredCall_t tDeferredInfo;
300 /* Initialize Message structure to post message onto Callback Thread */
301 static phLibNfc_Message_t tMsg;
302 UNUSED_PROP(pParam);
303 NXPLOG_TML_D("NFCC - Tml Reader Thread Started................\n");
304
305 /* Reader thread loop shall be running till shutdown is invoked */
306 while (gpphTmlNfc_Context->bThreadDone) {
307 /* If Tml read is requested */
308 /* Set the variable to success initially */
309 wStatus = NFCSTATUS_SUCCESS;
310 if (-1 == sem_wait(&gpphTmlNfc_Context->rxSemaphore)) {
311 NXPLOG_TML_E("sem_wait didn't return success \n");
312 }
313
314 /* If Tml read is requested */
315 if (1 == gpphTmlNfc_Context->tReadInfo.bEnable) {
316 NXPLOG_TML_D("NFCC - Read requested.....\n");
317 /* Set the variable to success initially */
318 wStatus = NFCSTATUS_SUCCESS;
319
320 /* Variable to fetch the actual number of bytes read */
321 dwNoBytesWrRd = PH_TMLNFC_RESET_VALUE;
322
323 /* Read the data from the file onto the buffer */
324 if (NULL != gpphTmlNfc_Context->pDevHandle) {
325 NXPLOG_TML_D("NFCC - Invoking Read.....\n");
326 dwNoBytesWrRd =
327 gpTransportObj->Read(gpphTmlNfc_Context->pDevHandle, temp,
328 PH_TMLNFC_MAX_READ_NCI_BUFF_LEN);
329
330 if (-1 == dwNoBytesWrRd) {
331 NXPLOG_TML_E("NFCC - Error in Read.....\n");
332 if (readRetryDelay < MAX_READ_RETRY_DELAY_IN_MILLISEC) {
333 /*sleep for 30/60/90/120/150 msec between each read trial incase of
334 * read error*/
335 readRetryDelay += 30;
336 }
337 usleep(readRetryDelay * 1000);
338 sem_post(&gpphTmlNfc_Context->rxSemaphore);
339 } else if (dwNoBytesWrRd == PH_TMNFC_VBAT_LOW_ERROR) {
340 NXPLOG_TML_E(
341 "Platform VBAT Error detected by NFCC "
342 "NFC restart... : %d\n",
343 dwNoBytesWrRd);
344 abort();
345 } else if (dwNoBytesWrRd > PH_TMLNFC_MAX_READ_NCI_BUFF_LEN) {
346 NXPLOG_TML_E("Numer of bytes read exceeds the limit 260.....\n");
347 readRetryDelay = 0;
348 sem_post(&gpphTmlNfc_Context->rxSemaphore);
349 } else {
350 memcpy(gpphTmlNfc_Context->tReadInfo.pBuffer, temp, dwNoBytesWrRd);
351 readRetryDelay = 0;
352
353 NXPLOG_TML_D("NFCC - Read successful.....\n");
354 /* This has to be reset only after a successful read */
355 gpphTmlNfc_Context->tReadInfo.bEnable = 0;
356 if ((phTmlNfc_e_EnableRetrans == gpphTmlNfc_Context->eConfig) &&
357 (0x00 != (gpphTmlNfc_Context->tReadInfo.pBuffer[0] & 0xE0))) {
358 NXPLOG_TML_D("NFCC - Retransmission timer stopped.....\n");
359 /* Stop Timer to prevent Retransmission */
360 uint32_t timerStatus =
361 phOsalNfc_Timer_Stop(gpphTmlNfc_Context->dwTimerId);
362 if (NFCSTATUS_SUCCESS != timerStatus) {
363 NXPLOG_TML_E("NFCC - timer stopped returned failure.....\n");
364 } else {
365 gpphTmlNfc_Context->bWriteCbInvoked = false;
366 }
367 }
368 /* Update the actual number of bytes read including header */
369 gpphTmlNfc_Context->tReadInfo.wLength = (uint16_t)(dwNoBytesWrRd);
370 phNxpNciHal_print_packet("RECV",
371 gpphTmlNfc_Context->tReadInfo.pBuffer,
372 gpphTmlNfc_Context->tReadInfo.wLength);
373
374 dwNoBytesWrRd = PH_TMLNFC_RESET_VALUE;
375
376 /* Fill the Transaction info structure to be passed to Callback
377 * Function */
378 tTransactionInfo.wStatus = wStatus;
379 tTransactionInfo.pBuff = gpphTmlNfc_Context->tReadInfo.pBuffer;
380 /* Actual number of bytes read is filled in the structure */
381 tTransactionInfo.wLength = gpphTmlNfc_Context->tReadInfo.wLength;
382
383 /* Read operation completed successfully. Post a Message onto Callback
384 * Thread*/
385 /* Prepare the message to be posted on User thread */
386 tDeferredInfo.pCallback = &phTmlNfc_ReadDeferredCb;
387 tDeferredInfo.pParameter = &tTransactionInfo;
388 tMsg.eMsgType = PH_LIBNFC_DEFERREDCALL_MSG;
389 tMsg.pMsgData = &tDeferredInfo;
390 tMsg.Size = sizeof(tDeferredInfo);
391 NXPLOG_TML_D("NFCC - Posting read message.....\n");
392 phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &tMsg);
393 }
394 } else {
395 NXPLOG_TML_D("NFCC -gpphTmlNfc_Context->pDevHandle is NULL");
396 }
397 } else {
398 NXPLOG_TML_D("NFCC - read request NOT enabled");
399 usleep(10 * 1000);
400 }
401 } /* End of While loop */
402
403 return NULL;
404 }
405
406 /*******************************************************************************
407 **
408 ** Function phTmlNfc_TmlWriterThread
409 **
410 ** Description Writes the requested data onto the lower layer driver
411 **
412 ** Parameters pParam - context provided by upper layer
413 **
414 ** Returns None
415 **
416 *******************************************************************************/
phTmlNfc_TmlWriterThread(void * pParam)417 static void* phTmlNfc_TmlWriterThread(void* pParam) {
418 NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
419 int32_t dwNoBytesWrRd = PH_TMLNFC_RESET_VALUE;
420 /* Transaction info buffer to be passed to Callback Thread */
421 static phTmlNfc_TransactInfo_t tTransactionInfo;
422 /* Structure containing Tml callback function and parameters to be invoked
423 by the callback thread */
424 static phLibNfc_DeferredCall_t tDeferredInfo;
425 /* Initialize Message structure to post message onto Callback Thread */
426 static phLibNfc_Message_t tMsg;
427 /* In case of I2C Write Retry */
428 static uint16_t retry_cnt;
429 UNUSED_PROP(pParam);
430 NXPLOG_TML_D("NFCC - Tml Writer Thread Started................\n");
431
432 /* Writer thread loop shall be running till shutdown is invoked */
433 while (gpphTmlNfc_Context->bThreadDone) {
434 NXPLOG_TML_D("NFCC - Tml Writer Thread Running................\n");
435 if (-1 == sem_wait(&gpphTmlNfc_Context->txSemaphore)) {
436 NXPLOG_TML_E("sem_wait didn't return success \n");
437 }
438 /* If Tml write is requested */
439 if (1 == gpphTmlNfc_Context->tWriteInfo.bEnable) {
440 NXPLOG_TML_D("NFCC - Write requested.....\n");
441 /* Set the variable to success initially */
442 wStatus = NFCSTATUS_SUCCESS;
443 if (NULL != gpphTmlNfc_Context->pDevHandle) {
444 retry:
445 gpphTmlNfc_Context->tWriteInfo.bEnable = 0;
446 /* Variable to fetch the actual number of bytes written */
447 dwNoBytesWrRd = PH_TMLNFC_RESET_VALUE;
448 /* Write the data in the buffer onto the file */
449 NXPLOG_TML_D("NFCC - Invoking Write.....\n");
450 /* TML reader writer callback synchronization mutex lock --- START */
451 pthread_mutex_lock(&gpphTmlNfc_Context->wait_busy_lock);
452 gpphTmlNfc_Context->gWriterCbflag = false;
453 dwNoBytesWrRd =
454 gpTransportObj->Write(gpphTmlNfc_Context->pDevHandle,
455 gpphTmlNfc_Context->tWriteInfo.pBuffer,
456 gpphTmlNfc_Context->tWriteInfo.wLength);
457 /* TML reader writer callback synchronization mutex lock --- END */
458 pthread_mutex_unlock(&gpphTmlNfc_Context->wait_busy_lock);
459
460 /* Try NFCC Write Five Times, if it fails: */
461 if (-1 == dwNoBytesWrRd) {
462 if (gpTransportObj->IsFwDnldModeEnabled()) {
463 if (retry_cnt++ < MAX_WRITE_RETRY_COUNT) {
464 NXPLOG_TML_D("NFCC - Error in Write - Retry 0x%x", retry_cnt);
465 // Add a 10 ms delay to ensure NFCC is not still in stand by mode.
466 usleep(10 * 1000);
467 goto retry;
468 }
469 }
470 NXPLOG_TML_D("NFCC - Error in Write.....\n");
471 wStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_FAILED);
472 } else {
473 phNxpNciHal_print_packet("SEND",
474 gpphTmlNfc_Context->tWriteInfo.pBuffer,
475 gpphTmlNfc_Context->tWriteInfo.wLength);
476 }
477 retry_cnt = 0;
478 if (NFCSTATUS_SUCCESS == wStatus) {
479 NXPLOG_TML_D("NFCC - Write successful.....\n");
480 dwNoBytesWrRd = PH_TMLNFC_VALUE_ONE;
481 }
482 /* Fill the Transaction info structure to be passed to Callback Function
483 */
484 tTransactionInfo.wStatus = wStatus;
485 tTransactionInfo.pBuff = gpphTmlNfc_Context->tWriteInfo.pBuffer;
486 /* Actual number of bytes written is filled in the structure */
487 tTransactionInfo.wLength = (uint16_t)dwNoBytesWrRd;
488
489 /* Prepare the message to be posted on the User thread */
490 tDeferredInfo.pCallback = &phTmlNfc_WriteDeferredCb;
491 tDeferredInfo.pParameter = &tTransactionInfo;
492 /* Write operation completed successfully. Post a Message onto Callback
493 * Thread*/
494 tMsg.eMsgType = PH_LIBNFC_DEFERREDCALL_MSG;
495 tMsg.pMsgData = &tDeferredInfo;
496 tMsg.Size = sizeof(tDeferredInfo);
497
498 /* Check whether Retransmission needs to be started,
499 * If yes, Post message only if
500 * case 1. Message is not posted &&
501 * case 11. Write status is success ||
502 * case 12. Last retry of write is also failure
503 */
504 if ((phTmlNfc_e_EnableRetrans == gpphTmlNfc_Context->eConfig) &&
505 (0x00 != (gpphTmlNfc_Context->tWriteInfo.pBuffer[0] & 0xE0))) {
506 if (gpphTmlNfc_Context->bWriteCbInvoked == false) {
507 if ((NFCSTATUS_SUCCESS == wStatus) || (bCurrentRetryCount == 0)) {
508 NXPLOG_TML_D("NFCC - Posting Write message.....\n");
509 phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
510 &tMsg);
511 gpphTmlNfc_Context->bWriteCbInvoked = true;
512 }
513 }
514 } else {
515 NXPLOG_TML_D("NFCC - Posting Fresh Write message.....\n");
516 phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &tMsg);
517 if (NFCSTATUS_SUCCESS == wStatus) {
518 /*TML reader writer thread callback synchronization---START*/
519 pthread_mutex_lock(&gpphTmlNfc_Context->wait_busy_lock);
520 gpphTmlNfc_Context->gWriterCbflag = true;
521 phTmlNfc_SignalWriteComplete();
522 /*TML reader writer thread callback synchronization---END*/
523 pthread_mutex_unlock(&gpphTmlNfc_Context->wait_busy_lock);
524 }
525 }
526 } else {
527 NXPLOG_TML_D("NFCC - gpphTmlNfc_Context->pDevHandle is NULL");
528 }
529 } else {
530 NXPLOG_TML_D("NFCC - Write request NOT enabled");
531 usleep(10000);
532 }
533
534 } /* End of While loop */
535
536 return NULL;
537 }
538
539 /*******************************************************************************
540 **
541 ** Function phTmlNfc_CleanUp
542 **
543 ** Description Clears all handles opened during TML initialization
544 **
545 ** Parameters None
546 **
547 ** Returns None
548 **
549 *******************************************************************************/
phTmlNfc_CleanUp(void)550 void phTmlNfc_CleanUp(void) {
551 if (NULL == gpphTmlNfc_Context) {
552 return;
553 }
554 sem_destroy(&gpphTmlNfc_Context->rxSemaphore);
555 sem_destroy(&gpphTmlNfc_Context->txSemaphore);
556 sem_destroy(&gpphTmlNfc_Context->postMsgSemaphore);
557 pthread_mutex_destroy(&gpphTmlNfc_Context->wait_busy_lock);
558 pthread_cond_destroy(&gpphTmlNfc_Context->wait_busy_condition);
559 gpTransportObj = NULL;
560 /* Clear memory allocated for storing Context variables */
561 free((void*)gpphTmlNfc_Context);
562 /* Set the pointer to NULL to indicate De-Initialization */
563 gpphTmlNfc_Context = NULL;
564
565 return;
566 }
567
568 /*******************************************************************************
569 **
570 ** Function phTmlNfc_Shutdown
571 **
572 ** Description Uninitializes TML layer and hardware interface
573 **
574 ** Parameters None
575 **
576 ** Returns NFC status:
577 ** NFCSTATUS_SUCCESS - TML configuration released successfully
578 ** NFCSTATUS_INVALID_PARAMETER - at least one parameter is
579 ** invalid
580 ** NFCSTATUS_FAILED - un-initialization failed (example: unable
581 ** to close interface)
582 **
583 *******************************************************************************/
phTmlNfc_Shutdown(void)584 NFCSTATUS phTmlNfc_Shutdown(void) {
585 NFCSTATUS wShutdownStatus = NFCSTATUS_SUCCESS;
586
587 /* Check whether TML is Initialized */
588 if (NULL != gpphTmlNfc_Context) {
589 /* Reset thread variable to terminate the thread */
590 gpphTmlNfc_Context->bThreadDone = 0;
591 usleep(1000);
592 /* Clear All the resources allocated during initialization */
593 sem_post(&gpphTmlNfc_Context->rxSemaphore);
594 usleep(1000);
595 sem_post(&gpphTmlNfc_Context->txSemaphore);
596 usleep(1000);
597 sem_post(&gpphTmlNfc_Context->postMsgSemaphore);
598 usleep(1000);
599 sem_post(&gpphTmlNfc_Context->postMsgSemaphore);
600 usleep(1000);
601
602 if (IS_CHIP_TYPE_L(sn100u)) {
603 (void)gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
604 MODE_POWER_OFF);
605 }
606 phTmlNfc_IoCtl(phTmlNfc_e_ResetNfcState);
607 gpTransportObj->Close(gpphTmlNfc_Context->pDevHandle);
608 gpphTmlNfc_Context->pDevHandle = NULL;
609 if (0 != pthread_join(gpphTmlNfc_Context->readerThread, (void**)NULL)) {
610 NXPLOG_TML_E("Fail to kill reader thread!");
611 }
612 if (0 != pthread_join(gpphTmlNfc_Context->writerThread, (void**)NULL)) {
613 NXPLOG_TML_E("Fail to kill writer thread!");
614 }
615 NXPLOG_TML_D("bThreadDone == 0");
616
617 } else {
618 wShutdownStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_NOT_INITIALISED);
619 }
620
621 return wShutdownStatus;
622 }
623
624 /*******************************************************************************
625 **
626 ** Function phTmlNfc_Write
627 **
628 ** Description Asynchronously writes given data block to hardware
629 ** interface/driver. Enables writer thread if there are no
630 ** write requests pending. Returns successfully once writer
631 ** thread completes write operation. Notifies upper layer using
632 ** callback mechanism.
633 **
634 ** NOTE:
635 ** * it is important to post a message with id
636 ** PH_TMLNFC_WRITE_MESSAGE to IntegrationThread after data
637 ** has been written to NFCC
638 ** * if CRC needs to be computed, then input buffer should be
639 ** capable to store two more bytes apart from length of
640 ** packet
641 **
642 ** Parameters pBuffer - data to be sent
643 ** wLength - length of data buffer
644 ** pTmlWriteComplete - pointer to the function to be invoked
645 ** upon completion
646 ** pContext - context provided by upper layer
647 **
648 ** Returns NFC status:
649 ** NFCSTATUS_PENDING - command is yet to be processed
650 ** NFCSTATUS_INVALID_PARAMETER - at least one parameter is
651 ** invalid
652 ** NFCSTATUS_BUSY - write request is already in progress
653 **
654 *******************************************************************************/
phTmlNfc_Write(uint8_t * pBuffer,uint16_t wLength,pphTmlNfc_TransactCompletionCb_t pTmlWriteComplete,void * pContext)655 NFCSTATUS phTmlNfc_Write(uint8_t* pBuffer, uint16_t wLength,
656 pphTmlNfc_TransactCompletionCb_t pTmlWriteComplete,
657 void* pContext) {
658 NFCSTATUS wWriteStatus;
659
660 /* Check whether TML is Initialized */
661
662 if (NULL != gpphTmlNfc_Context) {
663 if ((NULL != gpphTmlNfc_Context->pDevHandle) && (NULL != pBuffer) &&
664 (PH_TMLNFC_RESET_VALUE != wLength) && (NULL != pTmlWriteComplete)) {
665 if (!gpphTmlNfc_Context->tWriteInfo.bThreadBusy) {
666 /* Setting the flag marks beginning of a Write Operation */
667 gpphTmlNfc_Context->tWriteInfo.bThreadBusy = true;
668 /* Copy the buffer, length and Callback function,
669 This shall be utilized while invoking the Callback function in thread
670 */
671 gpphTmlNfc_Context->tWriteInfo.pBuffer = pBuffer;
672 gpphTmlNfc_Context->tWriteInfo.wLength = wLength;
673 gpphTmlNfc_Context->tWriteInfo.pThread_Callback = pTmlWriteComplete;
674 gpphTmlNfc_Context->tWriteInfo.pContext = pContext;
675
676 wWriteStatus = NFCSTATUS_PENDING;
677 // FIXME: If retry is going on. Stop the retry thread/timer
678 if (phTmlNfc_e_EnableRetrans == gpphTmlNfc_Context->eConfig) {
679 /* Set retry count to default value */
680 // FIXME: If the timer expired there, and meanwhile we have created
681 // a new request. The expired timer will think that retry is still
682 // ongoing.
683 bCurrentRetryCount = gpphTmlNfc_Context->bRetryCount;
684 gpphTmlNfc_Context->bWriteCbInvoked = false;
685 }
686 /* Set event to invoke Writer Thread */
687 gpphTmlNfc_Context->tWriteInfo.bEnable = 1;
688 sem_post(&gpphTmlNfc_Context->txSemaphore);
689 } else {
690 wWriteStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_BUSY);
691 }
692 } else {
693 wWriteStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_INVALID_PARAMETER);
694 }
695 } else {
696 wWriteStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_NOT_INITIALISED);
697 }
698
699 return wWriteStatus;
700 }
701
702 /*******************************************************************************
703 **
704 ** Function phTmlNfc_Read
705 **
706 ** Description Asynchronously reads data from the driver
707 ** Number of bytes to be read and buffer are passed by upper
708 ** layer.
709 ** Enables reader thread if there are no read requests pending
710 ** Returns successfully once read operation is completed
711 ** Notifies upper layer using callback mechanism
712 **
713 ** Parameters pBuffer - location to send read data to the upper layer via
714 ** callback
715 ** wLength - length of read data buffer passed by upper layer
716 ** pTmlReadComplete - pointer to the function to be invoked
717 ** upon completion of read operation
718 ** pContext - context provided by upper layer
719 **
720 ** Returns NFC status:
721 ** NFCSTATUS_PENDING - command is yet to be processed
722 ** NFCSTATUS_INVALID_PARAMETER - at least one parameter is
723 ** invalid
724 ** NFCSTATUS_BUSY - read request is already in progress
725 **
726 *******************************************************************************/
phTmlNfc_Read(uint8_t * pBuffer,uint16_t wLength,pphTmlNfc_TransactCompletionCb_t pTmlReadComplete,void * pContext)727 NFCSTATUS phTmlNfc_Read(uint8_t* pBuffer, uint16_t wLength,
728 pphTmlNfc_TransactCompletionCb_t pTmlReadComplete,
729 void* pContext) {
730 NFCSTATUS wReadStatus;
731 int rxSemVal = 0, ret = 0;
732
733 /* Check whether TML is Initialized */
734 if (NULL != gpphTmlNfc_Context) {
735 if ((gpphTmlNfc_Context->pDevHandle != NULL) && (NULL != pBuffer) &&
736 (PH_TMLNFC_RESET_VALUE != wLength) && (NULL != pTmlReadComplete)) {
737 if (!gpphTmlNfc_Context->tReadInfo.bThreadBusy) {
738 /* Setting the flag marks beginning of a Read Operation */
739 gpphTmlNfc_Context->tReadInfo.bThreadBusy = true;
740 /* Copy the buffer, length and Callback function,
741 This shall be utilized while invoking the Callback function in thread
742 */
743 gpphTmlNfc_Context->tReadInfo.pBuffer = pBuffer;
744 gpphTmlNfc_Context->tReadInfo.wLength = wLength;
745 gpphTmlNfc_Context->tReadInfo.pThread_Callback = pTmlReadComplete;
746 gpphTmlNfc_Context->tReadInfo.pContext = pContext;
747 wReadStatus = NFCSTATUS_PENDING;
748
749 /* Set event to invoke Reader Thread */
750 gpphTmlNfc_Context->tReadInfo.bEnable = 1;
751 ret = sem_getvalue(&gpphTmlNfc_Context->rxSemaphore, &rxSemVal);
752 /* Post rxSemaphore either if sem_getvalue() is failed or rxSemVal is 0
753 */
754 if (ret || !rxSemVal) {
755 sem_post(&gpphTmlNfc_Context->rxSemaphore);
756 } else {
757 NXPLOG_TML_D(
758 "%s: skip reader thread scheduling, ret=%x, rxSemaVal=%x",
759 __func__, ret, rxSemVal);
760 }
761 } else {
762 wReadStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_BUSY);
763 }
764 } else {
765 wReadStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_INVALID_PARAMETER);
766 }
767 } else {
768 wReadStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_NOT_INITIALISED);
769 }
770
771 return wReadStatus;
772 }
773
774 /*******************************************************************************
775 **
776 ** Function phTmlNfc_ReadAbort
777 **
778 ** Description Aborts pending read request (if any)
779 **
780 ** Parameters None
781 **
782 ** Returns NFC status:
783 ** NFCSTATUS_SUCCESS - ongoing read operation aborted
784 ** NFCSTATUS_INVALID_PARAMETER - at least one parameter is
785 ** invalid
786 ** NFCSTATUS_NOT_INITIALIZED - TML layer is not initialized
787 ** NFCSTATUS_BOARD_COMMUNICATION_ERROR - unable to cancel read
788 ** operation
789 **
790 *******************************************************************************/
phTmlNfc_ReadAbort(void)791 NFCSTATUS phTmlNfc_ReadAbort(void) {
792 NFCSTATUS wStatus = NFCSTATUS_INVALID_PARAMETER;
793 gpphTmlNfc_Context->tReadInfo.bEnable = 0;
794
795 /*Reset the flag to accept another Read Request */
796 gpphTmlNfc_Context->tReadInfo.bThreadBusy = false;
797 wStatus = NFCSTATUS_SUCCESS;
798
799 return wStatus;
800 }
801
802 /*******************************************************************************
803 **
804 ** Function phTmlNfc_WriteAbort
805 **
806 ** Description Aborts pending write request (if any)
807 **
808 ** Parameters None
809 **
810 ** Returns NFC status:
811 ** NFCSTATUS_SUCCESS - ongoing write operation aborted
812 ** NFCSTATUS_INVALID_PARAMETER - at least one parameter is
813 ** invalid
814 ** NFCSTATUS_NOT_INITIALIZED - TML layer is not initialized
815 ** NFCSTATUS_BOARD_COMMUNICATION_ERROR - unable to cancel write
816 ** operation
817 **
818 *******************************************************************************/
phTmlNfc_WriteAbort(void)819 NFCSTATUS phTmlNfc_WriteAbort(void) {
820 NFCSTATUS wStatus = NFCSTATUS_INVALID_PARAMETER;
821
822 gpphTmlNfc_Context->tWriteInfo.bEnable = 0;
823 /* Stop if any retransmission is in progress */
824 bCurrentRetryCount = 0;
825
826 /* Reset the flag to accept another Write Request */
827 gpphTmlNfc_Context->tWriteInfo.bThreadBusy = false;
828 wStatus = NFCSTATUS_SUCCESS;
829
830 return wStatus;
831 }
832
833 /*******************************************************************************
834 **
835 ** Function phTmlNfc_IoCtl
836 **
837 ** Description Resets device when insisted by upper layer
838 ** Number of bytes to be read and buffer are passed by upper
839 ** layer
840 ** Enables reader thread if there are no read requests pending
841 ** Returns successfully once read operation is completed
842 ** Notifies upper layer using callback mechanism
843 **
844 ** Parameters eControlCode - control code for a specific operation
845 **
846 ** Returns NFC status:
847 ** NFCSTATUS_SUCCESS - ioctl command completed successfully
848 ** NFCSTATUS_FAILED - ioctl command request failed
849 **
850 *******************************************************************************/
phTmlNfc_IoCtl(phTmlNfc_ControlCode_t eControlCode)851 NFCSTATUS phTmlNfc_IoCtl(phTmlNfc_ControlCode_t eControlCode) {
852 NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
853
854 if (NULL == gpphTmlNfc_Context) {
855 wStatus = NFCSTATUS_FAILED;
856 } else {
857 uint8_t read_flag = (gpphTmlNfc_Context->tReadInfo.bEnable > 0);
858
859 switch (eControlCode) {
860 case phTmlNfc_e_PowerReset: {
861 if (IS_CHIP_TYPE_GE(sn100u)) {
862 /*VEN_RESET*/
863 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
864 MODE_POWER_RESET);
865 } else {
866 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
867 MODE_POWER_ON);
868 usleep(100 * 1000);
869 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
870 MODE_POWER_OFF);
871 usleep(100 * 1000);
872 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
873 MODE_POWER_ON);
874 }
875 break;
876 }
877 case phTmlNfc_e_EnableVen: {
878 if (IS_CHIP_TYPE_L(sn100u)) {
879 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
880 MODE_POWER_ON);
881 usleep(100 * 1000);
882 }
883 break;
884 }
885 case phTmlNfc_e_ResetDevice:
886
887 {
888 if (IS_CHIP_TYPE_L(sn100u)) {
889 /*Reset NFCC*/
890 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
891 MODE_POWER_ON);
892 usleep(100 * 1000);
893 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
894 MODE_POWER_OFF);
895 usleep(100 * 1000);
896 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
897 MODE_POWER_ON);
898 }
899 break;
900 }
901 case phTmlNfc_e_EnableNormalMode: {
902 /*Reset NFCC*/
903 gpphTmlNfc_Context->tReadInfo.bEnable = 0;
904 if (nfcFL.nfccFL._NFCC_DWNLD_MODE == NFCC_DWNLD_WITH_VEN_RESET) {
905 NXPLOG_TML_D(" phTmlNfc_e_EnableNormalMode complete with VEN RESET ");
906 if (IS_CHIP_TYPE_L(sn100u)) {
907 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
908 MODE_POWER_OFF);
909 usleep(10 * 1000);
910 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
911 MODE_POWER_ON);
912 usleep(100 * 1000);
913 } else {
914 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
915 MODE_FW_GPIO_LOW);
916 }
917 } else if (nfcFL.nfccFL._NFCC_DWNLD_MODE == NFCC_DWNLD_WITH_NCI_CMD) {
918 NXPLOG_TML_D(" phTmlNfc_e_EnableNormalMode complete with NCI CMD ");
919 if (IS_CHIP_TYPE_L(sn100u)) {
920 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
921 MODE_POWER_ON);
922 } else {
923 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
924 MODE_FW_GPIO_LOW);
925 }
926 }
927 break;
928 }
929 case phTmlNfc_e_EnableDownloadMode: {
930 phTmlNfc_ConfigNciPktReTx(phTmlNfc_e_DisableRetrans, 0);
931 gpphTmlNfc_Context->tReadInfo.bEnable = 0;
932 if (nfcFL.nfccFL._NFCC_DWNLD_MODE == NFCC_DWNLD_WITH_VEN_RESET) {
933 NXPLOG_TML_D(
934 " phTmlNfc_e_EnableDownloadMode complete with VEN RESET ");
935 wStatus = gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
936 MODE_FW_DWNLD_WITH_VEN);
937 } else if (nfcFL.nfccFL._NFCC_DWNLD_MODE == NFCC_DWNLD_WITH_NCI_CMD) {
938 NXPLOG_TML_D(" phTmlNfc_e_EnableDownloadMode complete with NCI CMD ");
939 wStatus = gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
940 MODE_FW_DWND_HIGH);
941 }
942 break;
943 }
944 case phTmlNfc_e_EnableDownloadModeWithVenRst: {
945 phTmlNfc_ConfigNciPktReTx(phTmlNfc_e_DisableRetrans, 0);
946 gpphTmlNfc_Context->tReadInfo.bEnable = 0;
947 NXPLOG_TML_D(
948 " phTmlNfc_e_EnableDownloadModewithVenRst complete with "
949 "VEN RESET ");
950 wStatus = gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
951 MODE_FW_DWNLD_WITH_VEN);
952 break;
953 }
954 case phTmlNfc_e_setFragmentSize: {
955 if (IS_CHIP_TYPE_EQ(sn300u)) {
956 if (phTmlNfc_IsFwDnldModeEnabled() && IS_4K_SUPPORT) {
957 gpphTmlNfc_Context->fragment_len = PH_TMLNFC_FRGMENT_SIZE_SN300;
958 } else {
959 gpphTmlNfc_Context->fragment_len = PH_TMLNFC_FRGMENT_SIZE_SNXXX;
960 }
961 } else if (IS_CHIP_TYPE_NE(pn557)) {
962 gpphTmlNfc_Context->fragment_len = PH_TMLNFC_FRGMENT_SIZE_SNXXX;
963 } else {
964 gpphTmlNfc_Context->fragment_len = PH_TMLNFC_FRGMENT_SIZE_PN557;
965 }
966 NXPLOG_TML_D("Set FragmentSize: %u", gpphTmlNfc_Context->fragment_len);
967 break;
968 }
969 case phTmlNfc_e_SetNfcState: {
970 gpTransportObj->UpdateReadPending(gpphTmlNfc_Context->pDevHandle,
971 MODE_NFC_SET_READ_PENDING);
972 break;
973 }
974 case phTmlNfc_e_ResetNfcState: {
975 gpTransportObj->UpdateReadPending(gpphTmlNfc_Context->pDevHandle,
976 MODE_NFC_RESET_READ_PENDING);
977 break;
978 }
979 case phTmlNfc_e_PullVenLow: {
980 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
981 MODE_POWER_OFF);
982 break;
983 }
984 case phTmlNfc_e_PullVenHigh: {
985 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
986 MODE_POWER_ON);
987 break;
988 }
989 default: {
990 wStatus = NFCSTATUS_INVALID_PARAMETER;
991 break;
992 }
993 }
994 if (read_flag && (gpphTmlNfc_Context->tReadInfo.bEnable == 0x00)) {
995 gpphTmlNfc_Context->tReadInfo.bEnable = 1;
996 sem_post(&gpphTmlNfc_Context->rxSemaphore);
997 }
998 }
999
1000 return wStatus;
1001 }
1002
1003 /*******************************************************************************
1004 **
1005 ** Function phTmlNfc_DeferredCall
1006 **
1007 ** Description Posts message on upper layer thread
1008 ** upon successful read or write operation
1009 **
1010 ** Parameters dwThreadId - id of the thread posting message
1011 ** ptWorkerMsg - message to be posted
1012 **
1013 ** Returns None
1014 **
1015 *******************************************************************************/
phTmlNfc_DeferredCall(uintptr_t dwThreadId,phLibNfc_Message_t * ptWorkerMsg)1016 void phTmlNfc_DeferredCall(uintptr_t dwThreadId,
1017 phLibNfc_Message_t* ptWorkerMsg) {
1018 UNUSED_PROP(dwThreadId);
1019 /* Post message on the user thread to invoke the callback function */
1020 if (-1 == sem_wait(&gpphTmlNfc_Context->postMsgSemaphore)) {
1021 NXPLOG_TML_E("sem_wait didn't return success \n");
1022 }
1023 phDal4Nfc_msgsnd(gpphTmlNfc_Context->dwCallbackThreadId, ptWorkerMsg, 0);
1024 sem_post(&gpphTmlNfc_Context->postMsgSemaphore);
1025 }
1026
1027 /*******************************************************************************
1028 **
1029 ** Function phTmlNfc_ReadDeferredCb
1030 **
1031 ** Description Read thread call back function
1032 **
1033 ** Parameters pParams - context provided by upper layer
1034 **
1035 ** Returns None
1036 **
1037 *******************************************************************************/
phTmlNfc_ReadDeferredCb(void * pParams)1038 static void phTmlNfc_ReadDeferredCb(void* pParams) {
1039 /* Transaction info buffer to be passed to Callback Function */
1040 phTmlNfc_TransactInfo_t* pTransactionInfo = (phTmlNfc_TransactInfo_t*)pParams;
1041
1042 /* Reset the flag to accept another Read Request */
1043 gpphTmlNfc_Context->tReadInfo.bThreadBusy = false;
1044 gpphTmlNfc_Context->tReadInfo.pThread_Callback(
1045 gpphTmlNfc_Context->tReadInfo.pContext, pTransactionInfo);
1046
1047 return;
1048 }
1049
1050 /*******************************************************************************
1051 **
1052 ** Function phTmlNfc_WriteDeferredCb
1053 **
1054 ** Description Write thread call back function
1055 **
1056 ** Parameters pParams - context provided by upper layer
1057 **
1058 ** Returns None
1059 **
1060 *******************************************************************************/
phTmlNfc_WriteDeferredCb(void * pParams)1061 static void phTmlNfc_WriteDeferredCb(void* pParams) {
1062 /* Transaction info buffer to be passed to Callback Function */
1063 phTmlNfc_TransactInfo_t* pTransactionInfo = (phTmlNfc_TransactInfo_t*)pParams;
1064
1065 /* Reset the flag to accept another Write Request */
1066 gpphTmlNfc_Context->tWriteInfo.bThreadBusy = false;
1067 gpphTmlNfc_Context->tWriteInfo.pThread_Callback(
1068 gpphTmlNfc_Context->tWriteInfo.pContext, pTransactionInfo);
1069
1070 return;
1071 }
1072
phTmlNfc_set_fragmentation_enabled(phTmlNfc_i2cfragmentation_t result)1073 void phTmlNfc_set_fragmentation_enabled(phTmlNfc_i2cfragmentation_t result) {
1074 fragmentation_enabled = result;
1075 }
1076
1077 /*******************************************************************************
1078 **
1079 ** Function phTmlNfc_SignalWriteComplete
1080 **
1081 ** Description function to invoke reader thread
1082 **
1083 ** Parameters None
1084 **
1085 ** Returns None
1086 **
1087 *******************************************************************************/
phTmlNfc_SignalWriteComplete(void)1088 static void phTmlNfc_SignalWriteComplete(void) {
1089 int ret = -1;
1090 if (gpphTmlNfc_Context->wait_busy_flag == true) {
1091 NXPLOG_TML_D("phTmlNfc_SignalWriteComplete - enter");
1092 gpphTmlNfc_Context->wait_busy_flag = false;
1093
1094 ret = pthread_cond_signal(&gpphTmlNfc_Context->wait_busy_condition);
1095 if (ret) {
1096 NXPLOG_TML_E(" phTmlNfc_SignalWriteComplete failed, error = 0x%X", ret);
1097 }
1098 NXPLOG_TML_D("phTmlNfc_SignalWriteComplete - exit");
1099 }
1100 }
1101
1102 /*******************************************************************************
1103 **
1104 ** Function phTmlNfc_WaitReadInit
1105 **
1106 ** Description init function for reader thread
1107 **
1108 ** Parameters None
1109 **
1110 ** Returns int
1111 **
1112 *******************************************************************************/
phTmlNfc_WaitReadInit(void)1113 static int phTmlNfc_WaitReadInit(void) {
1114 int ret = -1;
1115 pthread_condattr_t attr;
1116 pthread_condattr_init(&attr);
1117 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
1118 memset(&gpphTmlNfc_Context->wait_busy_condition, 0,
1119 sizeof(gpphTmlNfc_Context->wait_busy_condition));
1120 pthread_mutex_init(&gpphTmlNfc_Context->wait_busy_lock, NULL);
1121 ret = pthread_cond_init(&gpphTmlNfc_Context->wait_busy_condition, &attr);
1122 if (ret) {
1123 NXPLOG_TML_E(" phTphTmlNfc_WaitReadInit failed, error = 0x%X", ret);
1124 }
1125 return ret;
1126 }
1127
1128 /*******************************************************************************
1129 **
1130 ** Function phTmlNfc_EnableFwDnldMode
1131 **
1132 ** Description wrapper function for enabling/disabling FW download mode
1133 **
1134 ** Parameters True/False
1135 **
1136 ** Returns NFCSTATUS
1137 **
1138 *******************************************************************************/
phTmlNfc_EnableFwDnldMode(bool mode)1139 void phTmlNfc_EnableFwDnldMode(bool mode) {
1140 gpTransportObj->EnableFwDnldMode(mode);
1141 }
1142
1143 /*******************************************************************************
1144 **
1145 ** Function phTmlNfc_IsFwDnldModeEnabled
1146 **
1147 ** Description wrapper function to get the FW download flag
1148 **
1149 ** Parameters None
1150 **
1151 ** Returns True/False status of FW download flag
1152 **
1153 *******************************************************************************/
phTmlNfc_IsFwDnldModeEnabled(void)1154 bool phTmlNfc_IsFwDnldModeEnabled(void) {
1155 return gpTransportObj->IsFwDnldModeEnabled();
1156 }
1157
1158 /*******************************************************************************
1159 **
1160 ** Function phTmlNfc_Shutdown_CleanUp
1161 **
1162 ** Description wrapper function for shutdown and cleanup of resources
1163 **
1164 ** Parameters None
1165 **
1166 ** Returns NFCSTATUS
1167 **
1168 *******************************************************************************/
phTmlNfc_Shutdown_CleanUp()1169 NFCSTATUS phTmlNfc_Shutdown_CleanUp() {
1170 NFCSTATUS wShutdownStatus = phTmlNfc_Shutdown();
1171 phTmlNfc_CleanUp();
1172 return wShutdownStatus;
1173 }
1174