1 /*
2  *
3  *  Copyright (C) 2013-2014 NXP Semiconductors
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 #ifndef _PHNXPNCIHAL_UTILS_H_
20 #define _PHNXPNCIHAL_UTILS_H_
21 
22 #include <assert.h>
23 #include <phNfcStatus.h>
24 #include <pthread.h>
25 #include <semaphore.h>
26 
27 /********************* Definitions and structures *****************************/
28 
29 /* List structures */
30 struct listNode {
31   void* pData;
32   struct listNode* pNext;
33 };
34 
35 struct listHead {
36   struct listNode* pFirst;
37   pthread_mutex_t mutex;
38 };
39 
40 /* Semaphore handling structure */
41 typedef struct phNxpNciHal_Sem {
42   /* Semaphore used to wait for callback */
43   sem_t sem;
44 
45   /* Used to store the status sent by the callback */
46   NFCSTATUS status;
47 
48   /* Used to provide a local context to the callback */
49   void* pContext;
50 
51 } phNxpNciHal_Sem_t;
52 
53 /* Semaphore helper macros */
54 #define SEM_WAIT(cb_data) sem_wait(&((cb_data).sem))
55 #define SEM_POST(p_cb_data) sem_post(&((p_cb_data)->sem))
56 
57 /* Semaphore and mutex monitor */
58 typedef struct phNxpNciHal_Monitor {
59   /* Mutex protecting native library against reentrance */
60   pthread_mutex_t reentrance_mutex;
61 
62   /* Mutex protecting native library against concurrency */
63   pthread_mutex_t concurrency_mutex;
64 
65   /* List used to track pending semaphores waiting for callback */
66   struct listHead sem_list;
67 
68 } phNxpNciHal_Monitor_t;
69 
70 /************************ Exposed functions ***********************************/
71 /* List functions */
72 int listInit(struct listHead* pList);
73 int listDestroy(struct listHead* pList);
74 int listAdd(struct listHead* pList, void* pData);
75 int listRemove(struct listHead* pList, void* pData);
76 int listGetAndRemoveNext(struct listHead* pList, void** ppData);
77 void listDump(struct listHead* pList);
78 
79 /* NXP NCI HAL utility functions */
80 phNxpNciHal_Monitor_t* phNxpNciHal_init_monitor(void);
81 void phNxpNciHal_cleanup_monitor(void);
82 phNxpNciHal_Monitor_t* phNxpNciHal_get_monitor(void);
83 NFCSTATUS phNxpNciHal_init_cb_data(phNxpNciHal_Sem_t* pCallbackData,
84                                    void* pContext);
85 void phNxpNciHal_cleanup_cb_data(phNxpNciHal_Sem_t* pCallbackData);
86 void phNxpNciHal_releaseall_cb_data(void);
87 void phNxpNciHal_print_packet(const char* pString, const uint8_t* p_data,
88                               uint16_t len);
89 void phNxpNciHal_emergency_recovery(void);
90 
91 /* Lock unlock helper macros */
92 /* Lock unlock helper macros */
93 #define REENTRANCE_LOCK()        \
94   if (phNxpNciHal_get_monitor()) \
95   pthread_mutex_lock(&phNxpNciHal_get_monitor()->reentrance_mutex)
96 #define REENTRANCE_UNLOCK()      \
97   if (phNxpNciHal_get_monitor()) \
98   pthread_mutex_unlock(&phNxpNciHal_get_monitor()->reentrance_mutex)
99 #define CONCURRENCY_LOCK()       \
100   if (phNxpNciHal_get_monitor()) \
101   pthread_mutex_lock(&phNxpNciHal_get_monitor()->concurrency_mutex)
102 #define CONCURRENCY_UNLOCK()     \
103   if (phNxpNciHal_get_monitor()) \
104   pthread_mutex_unlock(&phNxpNciHal_get_monitor()->concurrency_mutex)
105 
106 #endif /* _PHNXPNCIHAL_UTILS_H_ */
107