1 /*
2 * Copyright 2010-2023 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[260];
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("PN54X - 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("PN54X - 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("PN54X - Invoking I2C Read.....\n");
326 dwNoBytesWrRd =
327 gpTransportObj->Read(gpphTmlNfc_Context->pDevHandle, temp, 260);
328
329 if (-1 == dwNoBytesWrRd) {
330 NXPLOG_TML_E("PN54X - Error in I2C Read.....\n");
331 if (readRetryDelay < MAX_READ_RETRY_DELAY_IN_MILLISEC) {
332 /*sleep for 30/60/90/120/150 msec between each read trial incase of
333 * read error*/
334 readRetryDelay += 30;
335 }
336 usleep(readRetryDelay * 1000);
337 sem_post(&gpphTmlNfc_Context->rxSemaphore);
338 } else if (dwNoBytesWrRd > 260) {
339 NXPLOG_TML_E("Numer of bytes read exceeds the limit 260.....\n");
340 readRetryDelay = 0;
341 sem_post(&gpphTmlNfc_Context->rxSemaphore);
342 } else {
343 memcpy(gpphTmlNfc_Context->tReadInfo.pBuffer, temp, dwNoBytesWrRd);
344 readRetryDelay = 0;
345
346 NXPLOG_TML_D("PN54X - I2C Read successful.....\n");
347 /* This has to be reset only after a successful read */
348 gpphTmlNfc_Context->tReadInfo.bEnable = 0;
349 if ((phTmlNfc_e_EnableRetrans == gpphTmlNfc_Context->eConfig) &&
350 (0x00 != (gpphTmlNfc_Context->tReadInfo.pBuffer[0] & 0xE0))) {
351 NXPLOG_TML_D("PN54X - Retransmission timer stopped.....\n");
352 /* Stop Timer to prevent Retransmission */
353 uint32_t timerStatus =
354 phOsalNfc_Timer_Stop(gpphTmlNfc_Context->dwTimerId);
355 if (NFCSTATUS_SUCCESS != timerStatus) {
356 NXPLOG_TML_E("PN54X - timer stopped returned failure.....\n");
357 } else {
358 gpphTmlNfc_Context->bWriteCbInvoked = false;
359 }
360 }
361 /* Update the actual number of bytes read including header */
362 gpphTmlNfc_Context->tReadInfo.wLength = (uint16_t)(dwNoBytesWrRd);
363 phNxpNciHal_print_packet("RECV",
364 gpphTmlNfc_Context->tReadInfo.pBuffer,
365 gpphTmlNfc_Context->tReadInfo.wLength);
366
367 dwNoBytesWrRd = PH_TMLNFC_RESET_VALUE;
368
369 /* Fill the Transaction info structure to be passed to Callback
370 * Function */
371 tTransactionInfo.wStatus = wStatus;
372 tTransactionInfo.pBuff = gpphTmlNfc_Context->tReadInfo.pBuffer;
373 /* Actual number of bytes read is filled in the structure */
374 tTransactionInfo.wLength = gpphTmlNfc_Context->tReadInfo.wLength;
375
376 /* Read operation completed successfully. Post a Message onto Callback
377 * Thread*/
378 /* Prepare the message to be posted on User thread */
379 tDeferredInfo.pCallback = &phTmlNfc_ReadDeferredCb;
380 tDeferredInfo.pParameter = &tTransactionInfo;
381 tMsg.eMsgType = PH_LIBNFC_DEFERREDCALL_MSG;
382 tMsg.pMsgData = &tDeferredInfo;
383 tMsg.Size = sizeof(tDeferredInfo);
384 NXPLOG_TML_D("PN54X - Posting read message.....\n");
385 phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &tMsg);
386 }
387 } else {
388 NXPLOG_TML_D("PN54X -gpphTmlNfc_Context->pDevHandle is NULL");
389 }
390 } else {
391 NXPLOG_TML_D("PN54X - read request NOT enabled");
392 usleep(10 * 1000);
393 }
394 } /* End of While loop */
395
396 return NULL;
397 }
398
399 /*******************************************************************************
400 **
401 ** Function phTmlNfc_TmlWriterThread
402 **
403 ** Description Writes the requested data onto the lower layer driver
404 **
405 ** Parameters pParam - context provided by upper layer
406 **
407 ** Returns None
408 **
409 *******************************************************************************/
phTmlNfc_TmlWriterThread(void * pParam)410 static void* phTmlNfc_TmlWriterThread(void* pParam) {
411 NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
412 int32_t dwNoBytesWrRd = PH_TMLNFC_RESET_VALUE;
413 /* Transaction info buffer to be passed to Callback Thread */
414 static phTmlNfc_TransactInfo_t tTransactionInfo;
415 /* Structure containing Tml callback function and parameters to be invoked
416 by the callback thread */
417 static phLibNfc_DeferredCall_t tDeferredInfo;
418 /* Initialize Message structure to post message onto Callback Thread */
419 static phLibNfc_Message_t tMsg;
420 /* In case of I2C Write Retry */
421 static uint16_t retry_cnt;
422 UNUSED_PROP(pParam);
423 NXPLOG_TML_D("PN54X - Tml Writer Thread Started................\n");
424
425 /* Writer thread loop shall be running till shutdown is invoked */
426 while (gpphTmlNfc_Context->bThreadDone) {
427 NXPLOG_TML_D("PN54X - Tml Writer Thread Running................\n");
428 if (-1 == sem_wait(&gpphTmlNfc_Context->txSemaphore)) {
429 NXPLOG_TML_E("sem_wait didn't return success \n");
430 }
431 /* If Tml write is requested */
432 if (1 == gpphTmlNfc_Context->tWriteInfo.bEnable) {
433 NXPLOG_TML_D("PN54X - Write requested.....\n");
434 /* Set the variable to success initially */
435 wStatus = NFCSTATUS_SUCCESS;
436 if (NULL != gpphTmlNfc_Context->pDevHandle) {
437 retry:
438 gpphTmlNfc_Context->tWriteInfo.bEnable = 0;
439 /* Variable to fetch the actual number of bytes written */
440 dwNoBytesWrRd = PH_TMLNFC_RESET_VALUE;
441 /* Write the data in the buffer onto the file */
442 NXPLOG_TML_D("PN54X - Invoking I2C Write.....\n");
443 /* TML reader writer callback synchronization mutex lock --- START */
444 pthread_mutex_lock(&gpphTmlNfc_Context->wait_busy_lock);
445 gpphTmlNfc_Context->gWriterCbflag = false;
446 dwNoBytesWrRd =
447 gpTransportObj->Write(gpphTmlNfc_Context->pDevHandle,
448 gpphTmlNfc_Context->tWriteInfo.pBuffer,
449 gpphTmlNfc_Context->tWriteInfo.wLength);
450 /* TML reader writer callback synchronization mutex lock --- END */
451 pthread_mutex_unlock(&gpphTmlNfc_Context->wait_busy_lock);
452
453 /* Try I2C Write Five Times, if it fails : Raju */
454 if (-1 == dwNoBytesWrRd) {
455 if (gpTransportObj->IsFwDnldModeEnabled()) {
456 if (retry_cnt++ < MAX_WRITE_RETRY_COUNT) {
457 NXPLOG_TML_D("PN54X - Error in I2C Write - Retry 0x%x",
458 retry_cnt);
459 // Add a 10 ms delay to ensure NFCC is not still in stand by mode.
460 usleep(10 * 1000);
461 goto retry;
462 }
463 }
464 NXPLOG_TML_D("PN54X - Error in I2C Write.....\n");
465 wStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_FAILED);
466 } else {
467 phNxpNciHal_print_packet("SEND",
468 gpphTmlNfc_Context->tWriteInfo.pBuffer,
469 gpphTmlNfc_Context->tWriteInfo.wLength);
470 }
471 retry_cnt = 0;
472 if (NFCSTATUS_SUCCESS == wStatus) {
473 NXPLOG_TML_D("PN54X - I2C Write successful.....\n");
474 dwNoBytesWrRd = PH_TMLNFC_VALUE_ONE;
475 }
476 /* Fill the Transaction info structure to be passed to Callback Function
477 */
478 tTransactionInfo.wStatus = wStatus;
479 tTransactionInfo.pBuff = gpphTmlNfc_Context->tWriteInfo.pBuffer;
480 /* Actual number of bytes written is filled in the structure */
481 tTransactionInfo.wLength = (uint16_t)dwNoBytesWrRd;
482
483 /* Prepare the message to be posted on the User thread */
484 tDeferredInfo.pCallback = &phTmlNfc_WriteDeferredCb;
485 tDeferredInfo.pParameter = &tTransactionInfo;
486 /* Write operation completed successfully. Post a Message onto Callback
487 * Thread*/
488 tMsg.eMsgType = PH_LIBNFC_DEFERREDCALL_MSG;
489 tMsg.pMsgData = &tDeferredInfo;
490 tMsg.Size = sizeof(tDeferredInfo);
491
492 /* Check whether Retransmission needs to be started,
493 * If yes, Post message only if
494 * case 1. Message is not posted &&
495 * case 11. Write status is success ||
496 * case 12. Last retry of write is also failure
497 */
498 if ((phTmlNfc_e_EnableRetrans == gpphTmlNfc_Context->eConfig) &&
499 (0x00 != (gpphTmlNfc_Context->tWriteInfo.pBuffer[0] & 0xE0))) {
500 if (gpphTmlNfc_Context->bWriteCbInvoked == false) {
501 if ((NFCSTATUS_SUCCESS == wStatus) || (bCurrentRetryCount == 0)) {
502 NXPLOG_TML_D("PN54X - Posting Write message.....\n");
503 phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
504 &tMsg);
505 gpphTmlNfc_Context->bWriteCbInvoked = true;
506 }
507 }
508 } else {
509 NXPLOG_TML_D("PN54X - Posting Fresh Write message.....\n");
510 phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId, &tMsg);
511 if (NFCSTATUS_SUCCESS == wStatus) {
512 /*TML reader writer thread callback synchronization---START*/
513 pthread_mutex_lock(&gpphTmlNfc_Context->wait_busy_lock);
514 gpphTmlNfc_Context->gWriterCbflag = true;
515 phTmlNfc_SignalWriteComplete();
516 /*TML reader writer thread callback synchronization---END*/
517 pthread_mutex_unlock(&gpphTmlNfc_Context->wait_busy_lock);
518 }
519 }
520 } else {
521 NXPLOG_TML_D("PN54X - gpphTmlNfc_Context->pDevHandle is NULL");
522 }
523 } else {
524 NXPLOG_TML_D("PN54X - Write request NOT enabled");
525 usleep(10000);
526 }
527
528 } /* End of While loop */
529
530 return NULL;
531 }
532
533 /*******************************************************************************
534 **
535 ** Function phTmlNfc_CleanUp
536 **
537 ** Description Clears all handles opened during TML initialization
538 **
539 ** Parameters None
540 **
541 ** Returns None
542 **
543 *******************************************************************************/
phTmlNfc_CleanUp(void)544 void phTmlNfc_CleanUp(void) {
545 if (NULL == gpphTmlNfc_Context) {
546 return;
547 }
548 sem_destroy(&gpphTmlNfc_Context->rxSemaphore);
549 sem_destroy(&gpphTmlNfc_Context->txSemaphore);
550 sem_destroy(&gpphTmlNfc_Context->postMsgSemaphore);
551 pthread_mutex_destroy(&gpphTmlNfc_Context->wait_busy_lock);
552 pthread_cond_destroy(&gpphTmlNfc_Context->wait_busy_condition);
553 gpTransportObj = NULL;
554 /* Clear memory allocated for storing Context variables */
555 free((void*)gpphTmlNfc_Context);
556 /* Set the pointer to NULL to indicate De-Initialization */
557 gpphTmlNfc_Context = NULL;
558
559 return;
560 }
561
562 /*******************************************************************************
563 **
564 ** Function phTmlNfc_Shutdown
565 **
566 ** Description Uninitializes TML layer and hardware interface
567 **
568 ** Parameters None
569 **
570 ** Returns NFC status:
571 ** NFCSTATUS_SUCCESS - TML configuration released successfully
572 ** NFCSTATUS_INVALID_PARAMETER - at least one parameter is
573 ** invalid
574 ** NFCSTATUS_FAILED - un-initialization failed (example: unable
575 ** to close interface)
576 **
577 *******************************************************************************/
phTmlNfc_Shutdown(void)578 NFCSTATUS phTmlNfc_Shutdown(void) {
579 NFCSTATUS wShutdownStatus = NFCSTATUS_SUCCESS;
580
581 /* Check whether TML is Initialized */
582 if (NULL != gpphTmlNfc_Context) {
583 /* Reset thread variable to terminate the thread */
584 gpphTmlNfc_Context->bThreadDone = 0;
585 usleep(1000);
586 /* Clear All the resources allocated during initialization */
587 sem_post(&gpphTmlNfc_Context->rxSemaphore);
588 usleep(1000);
589 sem_post(&gpphTmlNfc_Context->txSemaphore);
590 usleep(1000);
591 sem_post(&gpphTmlNfc_Context->postMsgSemaphore);
592 usleep(1000);
593 sem_post(&gpphTmlNfc_Context->postMsgSemaphore);
594 usleep(1000);
595
596 if (IS_CHIP_TYPE_L(sn100u)) {
597 (void)gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
598 MODE_POWER_OFF);
599 }
600 phTmlNfc_IoCtl(phTmlNfc_e_ResetNfcState);
601 gpTransportObj->Close(gpphTmlNfc_Context->pDevHandle);
602 gpphTmlNfc_Context->pDevHandle = NULL;
603 if (0 != pthread_join(gpphTmlNfc_Context->readerThread, (void**)NULL)) {
604 NXPLOG_TML_E("Fail to kill reader thread!");
605 }
606 if (0 != pthread_join(gpphTmlNfc_Context->writerThread, (void**)NULL)) {
607 NXPLOG_TML_E("Fail to kill writer thread!");
608 }
609 NXPLOG_TML_D("bThreadDone == 0");
610
611 } else {
612 wShutdownStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_NOT_INITIALISED);
613 }
614
615 return wShutdownStatus;
616 }
617
618 /*******************************************************************************
619 **
620 ** Function phTmlNfc_Write
621 **
622 ** Description Asynchronously writes given data block to hardware
623 ** interface/driver. Enables writer thread if there are no
624 ** write requests pending. Returns successfully once writer
625 ** thread completes write operation. Notifies upper layer using
626 ** callback mechanism.
627 **
628 ** NOTE:
629 ** * it is important to post a message with id
630 ** PH_TMLNFC_WRITE_MESSAGE to IntegrationThread after data
631 ** has been written to PN54X
632 ** * if CRC needs to be computed, then input buffer should be
633 ** capable to store two more bytes apart from length of
634 ** packet
635 **
636 ** Parameters pBuffer - data to be sent
637 ** wLength - length of data buffer
638 ** pTmlWriteComplete - pointer to the function to be invoked
639 ** upon completion
640 ** pContext - context provided by upper layer
641 **
642 ** Returns NFC status:
643 ** NFCSTATUS_PENDING - command is yet to be processed
644 ** NFCSTATUS_INVALID_PARAMETER - at least one parameter is
645 ** invalid
646 ** NFCSTATUS_BUSY - write request is already in progress
647 **
648 *******************************************************************************/
phTmlNfc_Write(uint8_t * pBuffer,uint16_t wLength,pphTmlNfc_TransactCompletionCb_t pTmlWriteComplete,void * pContext)649 NFCSTATUS phTmlNfc_Write(uint8_t* pBuffer, uint16_t wLength,
650 pphTmlNfc_TransactCompletionCb_t pTmlWriteComplete,
651 void* pContext) {
652 NFCSTATUS wWriteStatus;
653
654 /* Check whether TML is Initialized */
655
656 if (NULL != gpphTmlNfc_Context) {
657 if ((NULL != gpphTmlNfc_Context->pDevHandle) && (NULL != pBuffer) &&
658 (PH_TMLNFC_RESET_VALUE != wLength) && (NULL != pTmlWriteComplete)) {
659 if (!gpphTmlNfc_Context->tWriteInfo.bThreadBusy) {
660 /* Setting the flag marks beginning of a Write Operation */
661 gpphTmlNfc_Context->tWriteInfo.bThreadBusy = true;
662 /* Copy the buffer, length and Callback function,
663 This shall be utilized while invoking the Callback function in thread
664 */
665 gpphTmlNfc_Context->tWriteInfo.pBuffer = pBuffer;
666 gpphTmlNfc_Context->tWriteInfo.wLength = wLength;
667 gpphTmlNfc_Context->tWriteInfo.pThread_Callback = pTmlWriteComplete;
668 gpphTmlNfc_Context->tWriteInfo.pContext = pContext;
669
670 wWriteStatus = NFCSTATUS_PENDING;
671 // FIXME: If retry is going on. Stop the retry thread/timer
672 if (phTmlNfc_e_EnableRetrans == gpphTmlNfc_Context->eConfig) {
673 /* Set retry count to default value */
674 // FIXME: If the timer expired there, and meanwhile we have created
675 // a new request. The expired timer will think that retry is still
676 // ongoing.
677 bCurrentRetryCount = gpphTmlNfc_Context->bRetryCount;
678 gpphTmlNfc_Context->bWriteCbInvoked = false;
679 }
680 /* Set event to invoke Writer Thread */
681 gpphTmlNfc_Context->tWriteInfo.bEnable = 1;
682 sem_post(&gpphTmlNfc_Context->txSemaphore);
683 } else {
684 wWriteStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_BUSY);
685 }
686 } else {
687 wWriteStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_INVALID_PARAMETER);
688 }
689 } else {
690 wWriteStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_NOT_INITIALISED);
691 }
692
693 return wWriteStatus;
694 }
695
696 /*******************************************************************************
697 **
698 ** Function phTmlNfc_Read
699 **
700 ** Description Asynchronously reads data from the driver
701 ** Number of bytes to be read and buffer are passed by upper
702 ** layer.
703 ** Enables reader thread if there are no read requests pending
704 ** Returns successfully once read operation is completed
705 ** Notifies upper layer using callback mechanism
706 **
707 ** Parameters pBuffer - location to send read data to the upper layer via
708 ** callback
709 ** wLength - length of read data buffer passed by upper layer
710 ** pTmlReadComplete - pointer to the function to be invoked
711 ** upon completion of read operation
712 ** pContext - context provided by upper layer
713 **
714 ** Returns NFC status:
715 ** NFCSTATUS_PENDING - command is yet to be processed
716 ** NFCSTATUS_INVALID_PARAMETER - at least one parameter is
717 ** invalid
718 ** NFCSTATUS_BUSY - read request is already in progress
719 **
720 *******************************************************************************/
phTmlNfc_Read(uint8_t * pBuffer,uint16_t wLength,pphTmlNfc_TransactCompletionCb_t pTmlReadComplete,void * pContext)721 NFCSTATUS phTmlNfc_Read(uint8_t* pBuffer, uint16_t wLength,
722 pphTmlNfc_TransactCompletionCb_t pTmlReadComplete,
723 void* pContext) {
724 NFCSTATUS wReadStatus;
725 int rxSemVal = 0, ret = 0;
726
727 /* Check whether TML is Initialized */
728 if (NULL != gpphTmlNfc_Context) {
729 if ((gpphTmlNfc_Context->pDevHandle != NULL) && (NULL != pBuffer) &&
730 (PH_TMLNFC_RESET_VALUE != wLength) && (NULL != pTmlReadComplete)) {
731 if (!gpphTmlNfc_Context->tReadInfo.bThreadBusy) {
732 /* Setting the flag marks beginning of a Read Operation */
733 gpphTmlNfc_Context->tReadInfo.bThreadBusy = true;
734 /* Copy the buffer, length and Callback function,
735 This shall be utilized while invoking the Callback function in thread
736 */
737 gpphTmlNfc_Context->tReadInfo.pBuffer = pBuffer;
738 gpphTmlNfc_Context->tReadInfo.wLength = wLength;
739 gpphTmlNfc_Context->tReadInfo.pThread_Callback = pTmlReadComplete;
740 gpphTmlNfc_Context->tReadInfo.pContext = pContext;
741 wReadStatus = NFCSTATUS_PENDING;
742
743 /* Set event to invoke Reader Thread */
744 gpphTmlNfc_Context->tReadInfo.bEnable = 1;
745 ret = sem_getvalue(&gpphTmlNfc_Context->rxSemaphore, &rxSemVal);
746 /* Post rxSemaphore either if sem_getvalue() is failed or rxSemVal is 0
747 */
748 if (ret || !rxSemVal) {
749 sem_post(&gpphTmlNfc_Context->rxSemaphore);
750 } else {
751 NXPLOG_TML_D(
752 "%s: skip reader thread scheduling, ret=%x, rxSemaVal=%x",
753 __func__, ret, rxSemVal);
754 }
755 } else {
756 wReadStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_BUSY);
757 }
758 } else {
759 wReadStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_INVALID_PARAMETER);
760 }
761 } else {
762 wReadStatus = PHNFCSTVAL(CID_NFC_TML, NFCSTATUS_NOT_INITIALISED);
763 }
764
765 return wReadStatus;
766 }
767
768 /*******************************************************************************
769 **
770 ** Function phTmlNfc_ReadAbort
771 **
772 ** Description Aborts pending read request (if any)
773 **
774 ** Parameters None
775 **
776 ** Returns NFC status:
777 ** NFCSTATUS_SUCCESS - ongoing read operation aborted
778 ** NFCSTATUS_INVALID_PARAMETER - at least one parameter is
779 ** invalid
780 ** NFCSTATUS_NOT_INITIALIZED - TML layer is not initialized
781 ** NFCSTATUS_BOARD_COMMUNICATION_ERROR - unable to cancel read
782 ** operation
783 **
784 *******************************************************************************/
phTmlNfc_ReadAbort(void)785 NFCSTATUS phTmlNfc_ReadAbort(void) {
786 NFCSTATUS wStatus = NFCSTATUS_INVALID_PARAMETER;
787 gpphTmlNfc_Context->tReadInfo.bEnable = 0;
788
789 /*Reset the flag to accept another Read Request */
790 gpphTmlNfc_Context->tReadInfo.bThreadBusy = false;
791 wStatus = NFCSTATUS_SUCCESS;
792
793 return wStatus;
794 }
795
796 /*******************************************************************************
797 **
798 ** Function phTmlNfc_WriteAbort
799 **
800 ** Description Aborts pending write request (if any)
801 **
802 ** Parameters None
803 **
804 ** Returns NFC status:
805 ** NFCSTATUS_SUCCESS - ongoing write operation aborted
806 ** NFCSTATUS_INVALID_PARAMETER - at least one parameter is
807 ** invalid
808 ** NFCSTATUS_NOT_INITIALIZED - TML layer is not initialized
809 ** NFCSTATUS_BOARD_COMMUNICATION_ERROR - unable to cancel write
810 ** operation
811 **
812 *******************************************************************************/
phTmlNfc_WriteAbort(void)813 NFCSTATUS phTmlNfc_WriteAbort(void) {
814 NFCSTATUS wStatus = NFCSTATUS_INVALID_PARAMETER;
815
816 gpphTmlNfc_Context->tWriteInfo.bEnable = 0;
817 /* Stop if any retransmission is in progress */
818 bCurrentRetryCount = 0;
819
820 /* Reset the flag to accept another Write Request */
821 gpphTmlNfc_Context->tWriteInfo.bThreadBusy = false;
822 wStatus = NFCSTATUS_SUCCESS;
823
824 return wStatus;
825 }
826
827 /*******************************************************************************
828 **
829 ** Function phTmlNfc_IoCtl
830 **
831 ** Description Resets device when insisted by upper layer
832 ** Number of bytes to be read and buffer are passed by upper
833 ** layer
834 ** Enables reader thread if there are no read requests pending
835 ** Returns successfully once read operation is completed
836 ** Notifies upper layer using callback mechanism
837 **
838 ** Parameters eControlCode - control code for a specific operation
839 **
840 ** Returns NFC status:
841 ** NFCSTATUS_SUCCESS - ioctl command completed successfully
842 ** NFCSTATUS_FAILED - ioctl command request failed
843 **
844 *******************************************************************************/
phTmlNfc_IoCtl(phTmlNfc_ControlCode_t eControlCode)845 NFCSTATUS phTmlNfc_IoCtl(phTmlNfc_ControlCode_t eControlCode) {
846 NFCSTATUS wStatus = NFCSTATUS_SUCCESS;
847
848 if (NULL == gpphTmlNfc_Context) {
849 wStatus = NFCSTATUS_FAILED;
850 } else {
851 uint8_t read_flag = (gpphTmlNfc_Context->tReadInfo.bEnable > 0);
852
853 switch (eControlCode) {
854 case phTmlNfc_e_PowerReset: {
855 if (IS_CHIP_TYPE_GE(sn100u)) {
856 /*VEN_RESET*/
857 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
858 MODE_POWER_RESET);
859 } else {
860 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
861 MODE_POWER_ON);
862 usleep(100 * 1000);
863 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
864 MODE_POWER_OFF);
865 usleep(100 * 1000);
866 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
867 MODE_POWER_ON);
868 }
869 break;
870 }
871 case phTmlNfc_e_EnableVen: {
872 if (IS_CHIP_TYPE_L(sn100u)) {
873 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
874 MODE_POWER_ON);
875 usleep(100 * 1000);
876 }
877 break;
878 }
879 case phTmlNfc_e_ResetDevice:
880
881 {
882 if (IS_CHIP_TYPE_L(sn100u)) {
883 /*Reset PN54X*/
884 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
885 MODE_POWER_ON);
886 usleep(100 * 1000);
887 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
888 MODE_POWER_OFF);
889 usleep(100 * 1000);
890 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
891 MODE_POWER_ON);
892 }
893 break;
894 }
895 case phTmlNfc_e_EnableNormalMode: {
896 /*Reset PN54X*/
897 gpphTmlNfc_Context->tReadInfo.bEnable = 0;
898 if (nfcFL.nfccFL._NFCC_DWNLD_MODE == NFCC_DWNLD_WITH_VEN_RESET) {
899 NXPLOG_TML_D(" phTmlNfc_e_EnableNormalMode complete with VEN RESET ");
900 if (IS_CHIP_TYPE_L(sn100u)) {
901 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
902 MODE_POWER_OFF);
903 usleep(10 * 1000);
904 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
905 MODE_POWER_ON);
906 usleep(100 * 1000);
907 } else {
908 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
909 MODE_FW_GPIO_LOW);
910 }
911 } else if (nfcFL.nfccFL._NFCC_DWNLD_MODE == NFCC_DWNLD_WITH_NCI_CMD) {
912 NXPLOG_TML_D(" phTmlNfc_e_EnableNormalMode complete with NCI CMD ");
913 if (IS_CHIP_TYPE_L(sn100u)) {
914 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
915 MODE_POWER_ON);
916 } else {
917 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
918 MODE_FW_GPIO_LOW);
919 }
920 }
921 break;
922 }
923 case phTmlNfc_e_EnableDownloadMode: {
924 phTmlNfc_ConfigNciPktReTx(phTmlNfc_e_DisableRetrans, 0);
925 gpphTmlNfc_Context->tReadInfo.bEnable = 0;
926 if (nfcFL.nfccFL._NFCC_DWNLD_MODE == NFCC_DWNLD_WITH_VEN_RESET) {
927 NXPLOG_TML_D(
928 " phTmlNfc_e_EnableDownloadMode complete with VEN RESET ");
929 wStatus = gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
930 MODE_FW_DWNLD_WITH_VEN);
931 } else if (nfcFL.nfccFL._NFCC_DWNLD_MODE == NFCC_DWNLD_WITH_NCI_CMD) {
932 NXPLOG_TML_D(" phTmlNfc_e_EnableDownloadMode complete with NCI CMD ");
933 wStatus = gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
934 MODE_FW_DWND_HIGH);
935 }
936 break;
937 }
938 case phTmlNfc_e_EnableDownloadModeWithVenRst: {
939 phTmlNfc_ConfigNciPktReTx(phTmlNfc_e_DisableRetrans, 0);
940 gpphTmlNfc_Context->tReadInfo.bEnable = 0;
941 NXPLOG_TML_D(
942 " phTmlNfc_e_EnableDownloadModewithVenRst complete with "
943 "VEN RESET ");
944 wStatus = gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
945 MODE_FW_DWNLD_WITH_VEN);
946 break;
947 }
948 case phTmlNfc_e_setFragmentSize: {
949 if (IS_CHIP_TYPE_EQ(sn300u)) {
950 if (phTmlNfc_IsFwDnldModeEnabled()) {
951 gpphTmlNfc_Context->fragment_len = PH_TMLNFC_FRGMENT_SIZE_SN300;
952 } else {
953 gpphTmlNfc_Context->fragment_len = PH_TMLNFC_FRGMENT_SIZE_SNXXX;
954 }
955 } else if (IS_CHIP_TYPE_NE(pn557)) {
956 gpphTmlNfc_Context->fragment_len = PH_TMLNFC_FRGMENT_SIZE_SNXXX;
957 } else {
958 gpphTmlNfc_Context->fragment_len = PH_TMLNFC_FRGMENT_SIZE_PN557;
959 }
960 NXPLOG_TML_D("Set FragmentSize: %u", gpphTmlNfc_Context->fragment_len);
961 break;
962 }
963 case phTmlNfc_e_SetNfcState: {
964 gpTransportObj->UpdateReadPending(gpphTmlNfc_Context->pDevHandle,
965 MODE_NFC_SET_READ_PENDING);
966 break;
967 }
968 case phTmlNfc_e_ResetNfcState: {
969 gpTransportObj->UpdateReadPending(gpphTmlNfc_Context->pDevHandle,
970 MODE_NFC_RESET_READ_PENDING);
971 break;
972 }
973 case phTmlNfc_e_PullVenLow: {
974 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
975 MODE_POWER_OFF);
976 break;
977 }
978 case phTmlNfc_e_PullVenHigh: {
979 gpTransportObj->NfccReset(gpphTmlNfc_Context->pDevHandle,
980 MODE_POWER_ON);
981 break;
982 }
983 default: {
984 wStatus = NFCSTATUS_INVALID_PARAMETER;
985 break;
986 }
987 }
988 if (read_flag && (gpphTmlNfc_Context->tReadInfo.bEnable == 0x00)) {
989 gpphTmlNfc_Context->tReadInfo.bEnable = 1;
990 sem_post(&gpphTmlNfc_Context->rxSemaphore);
991 }
992 }
993
994 return wStatus;
995 }
996
997 /*******************************************************************************
998 **
999 ** Function phTmlNfc_DeferredCall
1000 **
1001 ** Description Posts message on upper layer thread
1002 ** upon successful read or write operation
1003 **
1004 ** Parameters dwThreadId - id of the thread posting message
1005 ** ptWorkerMsg - message to be posted
1006 **
1007 ** Returns None
1008 **
1009 *******************************************************************************/
phTmlNfc_DeferredCall(uintptr_t dwThreadId,phLibNfc_Message_t * ptWorkerMsg)1010 void phTmlNfc_DeferredCall(uintptr_t dwThreadId,
1011 phLibNfc_Message_t* ptWorkerMsg) {
1012 UNUSED_PROP(dwThreadId);
1013 /* Post message on the user thread to invoke the callback function */
1014 if (-1 == sem_wait(&gpphTmlNfc_Context->postMsgSemaphore)) {
1015 NXPLOG_TML_E("sem_wait didn't return success \n");
1016 }
1017 phDal4Nfc_msgsnd(gpphTmlNfc_Context->dwCallbackThreadId, ptWorkerMsg, 0);
1018 sem_post(&gpphTmlNfc_Context->postMsgSemaphore);
1019 }
1020
1021 /*******************************************************************************
1022 **
1023 ** Function phTmlNfc_ReadDeferredCb
1024 **
1025 ** Description Read thread call back function
1026 **
1027 ** Parameters pParams - context provided by upper layer
1028 **
1029 ** Returns None
1030 **
1031 *******************************************************************************/
phTmlNfc_ReadDeferredCb(void * pParams)1032 static void phTmlNfc_ReadDeferredCb(void* pParams) {
1033 /* Transaction info buffer to be passed to Callback Function */
1034 phTmlNfc_TransactInfo_t* pTransactionInfo = (phTmlNfc_TransactInfo_t*)pParams;
1035
1036 /* Reset the flag to accept another Read Request */
1037 gpphTmlNfc_Context->tReadInfo.bThreadBusy = false;
1038 gpphTmlNfc_Context->tReadInfo.pThread_Callback(
1039 gpphTmlNfc_Context->tReadInfo.pContext, pTransactionInfo);
1040
1041 return;
1042 }
1043
1044 /*******************************************************************************
1045 **
1046 ** Function phTmlNfc_WriteDeferredCb
1047 **
1048 ** Description Write thread call back function
1049 **
1050 ** Parameters pParams - context provided by upper layer
1051 **
1052 ** Returns None
1053 **
1054 *******************************************************************************/
phTmlNfc_WriteDeferredCb(void * pParams)1055 static void phTmlNfc_WriteDeferredCb(void* pParams) {
1056 /* Transaction info buffer to be passed to Callback Function */
1057 phTmlNfc_TransactInfo_t* pTransactionInfo = (phTmlNfc_TransactInfo_t*)pParams;
1058
1059 /* Reset the flag to accept another Write Request */
1060 gpphTmlNfc_Context->tWriteInfo.bThreadBusy = false;
1061 gpphTmlNfc_Context->tWriteInfo.pThread_Callback(
1062 gpphTmlNfc_Context->tWriteInfo.pContext, pTransactionInfo);
1063
1064 return;
1065 }
1066
phTmlNfc_set_fragmentation_enabled(phTmlNfc_i2cfragmentation_t result)1067 void phTmlNfc_set_fragmentation_enabled(phTmlNfc_i2cfragmentation_t result) {
1068 fragmentation_enabled = result;
1069 }
1070
1071 /*******************************************************************************
1072 **
1073 ** Function phTmlNfc_SignalWriteComplete
1074 **
1075 ** Description function to invoke reader thread
1076 **
1077 ** Parameters None
1078 **
1079 ** Returns None
1080 **
1081 *******************************************************************************/
phTmlNfc_SignalWriteComplete(void)1082 static void phTmlNfc_SignalWriteComplete(void) {
1083 int ret = -1;
1084 if (gpphTmlNfc_Context->wait_busy_flag == true) {
1085 NXPLOG_TML_D("phTmlNfc_SignalWriteComplete - enter");
1086 gpphTmlNfc_Context->wait_busy_flag = false;
1087
1088 ret = pthread_cond_signal(&gpphTmlNfc_Context->wait_busy_condition);
1089 if (ret) {
1090 NXPLOG_TML_E(" phTmlNfc_SignalWriteComplete failed, error = 0x%X", ret);
1091 }
1092 NXPLOG_TML_D("phTmlNfc_SignalWriteComplete - exit");
1093 }
1094 }
1095
1096 /*******************************************************************************
1097 **
1098 ** Function phTmlNfc_WaitReadInit
1099 **
1100 ** Description init function for reader thread
1101 **
1102 ** Parameters None
1103 **
1104 ** Returns int
1105 **
1106 *******************************************************************************/
phTmlNfc_WaitReadInit(void)1107 static int phTmlNfc_WaitReadInit(void) {
1108 int ret = -1;
1109 pthread_condattr_t attr;
1110 pthread_condattr_init(&attr);
1111 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
1112 memset(&gpphTmlNfc_Context->wait_busy_condition, 0,
1113 sizeof(gpphTmlNfc_Context->wait_busy_condition));
1114 pthread_mutex_init(&gpphTmlNfc_Context->wait_busy_lock, NULL);
1115 ret = pthread_cond_init(&gpphTmlNfc_Context->wait_busy_condition, &attr);
1116 if (ret) {
1117 NXPLOG_TML_E(" phTphTmlNfc_WaitReadInit failed, error = 0x%X", ret);
1118 }
1119 return ret;
1120 }
1121
1122 /*******************************************************************************
1123 **
1124 ** Function phTmlNfc_EnableFwDnldMode
1125 **
1126 ** Description wrapper function for enabling/disabling FW download mode
1127 **
1128 ** Parameters True/False
1129 **
1130 ** Returns NFCSTATUS
1131 **
1132 *******************************************************************************/
phTmlNfc_EnableFwDnldMode(bool mode)1133 void phTmlNfc_EnableFwDnldMode(bool mode) {
1134 gpTransportObj->EnableFwDnldMode(mode);
1135 }
1136
1137 /*******************************************************************************
1138 **
1139 ** Function phTmlNfc_IsFwDnldModeEnabled
1140 **
1141 ** Description wrapper function to get the FW download flag
1142 **
1143 ** Parameters None
1144 **
1145 ** Returns True/False status of FW download flag
1146 **
1147 *******************************************************************************/
phTmlNfc_IsFwDnldModeEnabled(void)1148 bool phTmlNfc_IsFwDnldModeEnabled(void) {
1149 return gpTransportObj->IsFwDnldModeEnabled();
1150 }
1151
1152 /*******************************************************************************
1153 **
1154 ** Function phTmlNfc_Shutdown_CleanUp
1155 **
1156 ** Description wrapper function for shutdown and cleanup of resources
1157 **
1158 ** Parameters None
1159 **
1160 ** Returns NFCSTATUS
1161 **
1162 *******************************************************************************/
phTmlNfc_Shutdown_CleanUp()1163 NFCSTATUS phTmlNfc_Shutdown_CleanUp() {
1164 NFCSTATUS wShutdownStatus = phTmlNfc_Shutdown();
1165 phTmlNfc_CleanUp();
1166 return wShutdownStatus;
1167 }
1168