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 <pthread.h>
23#include <semaphore.h>
24#include <phNfcStatus.h>
25#include <assert.h>
26
27/********************* Definitions and structures *****************************/
28
29/* List structures */
30struct listNode
31{
32    void* pData;
33    struct listNode* pNext;
34};
35
36struct listHead
37{
38    struct listNode* pFirst;
39    pthread_mutex_t mutex;
40};
41
42
43/* Semaphore handling structure */
44typedef struct phNxpNciHal_Sem
45{
46    /* Semaphore used to wait for callback */
47    sem_t sem;
48
49    /* Used to store the status sent by the callback */
50    NFCSTATUS status;
51
52    /* Used to provide a local context to the callback */
53    void* pContext;
54
55} phNxpNciHal_Sem_t;
56
57/* Semaphore helper macros */
58#define SEM_WAIT(cb_data) sem_wait(&((cb_data).sem))
59#define SEM_POST(p_cb_data) sem_post(&((p_cb_data)->sem))
60
61/* Semaphore and mutex monitor */
62typedef struct phNxpNciHal_Monitor
63{
64    /* Mutex protecting native library against reentrance */
65    pthread_mutex_t reentrance_mutex;
66
67    /* Mutex protecting native library against concurrency */
68    pthread_mutex_t concurrency_mutex;
69
70    /* List used to track pending semaphores waiting for callback */
71    struct listHead sem_list;
72
73} phNxpNciHal_Monitor_t;
74
75/************************ Exposed functions ***********************************/
76/* List functions */
77int listInit(struct listHead* pList);
78int listDestroy(struct listHead* pList);
79int listAdd(struct listHead* pList, void* pData);
80int listRemove(struct listHead* pList, void* pData);
81int listGetAndRemoveNext(struct listHead* pList, void** ppData);
82void listDump(struct listHead* pList);
83
84/* NXP NCI HAL utility functions */
85phNxpNciHal_Monitor_t* phNxpNciHal_init_monitor(void);
86void phNxpNciHal_cleanup_monitor(void);
87phNxpNciHal_Monitor_t* phNxpNciHal_get_monitor(void);
88NFCSTATUS phNxpNciHal_init_cb_data(phNxpNciHal_Sem_t *pCallbackData,
89        void *pContext);
90void phNxpNciHal_cleanup_cb_data(phNxpNciHal_Sem_t* pCallbackData);
91void phNxpNciHal_releaseall_cb_data(void);
92void phNxpNciHal_print_packet(const char *pString, const uint8_t *p_data,
93        uint16_t len);
94void phNxpNciHal_emergency_recovery(void);
95
96/* Lock unlock helper macros */
97/* Lock unlock helper macros */
98#define REENTRANCE_LOCK()      if (phNxpNciHal_get_monitor()) pthread_mutex_lock(&phNxpNciHal_get_monitor()->reentrance_mutex)
99#define REENTRANCE_UNLOCK()    if (phNxpNciHal_get_monitor()) pthread_mutex_unlock(&phNxpNciHal_get_monitor()->reentrance_mutex)
100#define CONCURRENCY_LOCK()     if (phNxpNciHal_get_monitor()) pthread_mutex_lock(&phNxpNciHal_get_monitor()->concurrency_mutex)
101#define CONCURRENCY_UNLOCK()   if (phNxpNciHal_get_monitor()) pthread_mutex_unlock(&phNxpNciHal_get_monitor()->concurrency_mutex)
102
103#endif /* _PHNXPNCIHAL_UTILS_H_ */
104