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