2 * Copyright (C) 2010 NXP Semiconductors
3 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 * \file phDalNfc_messageQueueLib.c
20 * \brief DAL independant message queue implementation for android (can be used under linux too)
22 * Project: Trusted NFC Linux Lignt
25 * $Author: Jonathan roux
32 #include <linux/ipc.h>
37 #include <semaphore.h>
39 #include <phDal4Nfc.h>
40 #include <phOsalNfc.h>
41 #include <phDal4Nfc_DeferredCall.h>
42 #include <phDal4Nfc_messageQueueLib.h>
44 typedef struct phDal4Nfc_message_queue_item
46 phLibNfc_Message_t nMsg;
47 struct phDal4Nfc_message_queue_item * pPrev;
48 struct phDal4Nfc_message_queue_item * pNext;
49 } phDal4Nfc_message_queue_item_t;
52 typedef struct phDal4Nfc_message_queue
54 phDal4Nfc_message_queue_item_t * pItems;
55 pthread_mutex_t nCriticalSectionMutex;
56 sem_t nProcessSemaphore;
58 } phDal4Nfc_message_queue_t;
62 * \ingroup grp_nfc_dal
64 * \brief DAL message get function
65 * This function allocates the message queue. The parameters are ignored, this is
66 * just to keep the same api as Linux queue.
68 * \retval -1 Can not allocate memory or can not init mutex.
69 * \retval handle The handle on the message queue.
71 int phDal4Nfc_msgget ( key_t key, int msgflg )
73 phDal4Nfc_message_queue_t * pQueue;
74 pQueue = (phDal4Nfc_message_queue_t *) phOsalNfc_GetMemory(sizeof(phDal4Nfc_message_queue_t));
77 memset(pQueue, 0, sizeof(phDal4Nfc_message_queue_t));
78 if (pthread_mutex_init (&pQueue->nCriticalSectionMutex, NULL) == -1){
79 phOsalNfc_FreeMemory (pQueue); /* prevent fix */
82 if (sem_init (&pQueue->nProcessSemaphore, 0, 0) == -1){
83 phOsalNfc_FreeMemory (pQueue); /* prevent fix */
90 * \ingroup grp_nfc_dal
92 * \brief DAL message control function
93 * This function destroys the message queue. The cmd and buf parameters are ignored,
94 * this is just to keep the same api as Linux queue.
96 * \param[in] msqid The handle of the message queue.
98 * \retval 0 If success.
99 * \retval -1 Bad passed parameter
101 int phDal4Nfc_msgctl ( int msqid, int cmd, void *buf )
103 phDal4Nfc_message_queue_t * pQueue;
104 phDal4Nfc_message_queue_item_t * p;
109 pQueue = (phDal4Nfc_message_queue_t *)msqid;
110 pthread_mutex_lock(&pQueue->nCriticalSectionMutex);
111 if (pQueue->pItems != NULL)
114 while(p->pNext != NULL) { p = p->pNext; }
115 while(p->pPrev != NULL)
118 phOsalNfc_FreeMemory(p->pNext);
121 phOsalNfc_FreeMemory(p);
123 pQueue->pItems = NULL;
124 pthread_mutex_unlock(&pQueue->nCriticalSectionMutex);
125 pthread_mutex_destroy(&pQueue->nCriticalSectionMutex);
126 phOsalNfc_FreeMemory(pQueue);
131 * \ingroup grp_nfc_dal
133 * \brief DAL message send function
134 * Use this function to send a message to the queue. The message will be added at the end of
135 * the queue with respect to FIFO policy. The msgflg parameter is ignored.
137 * \param[in] msqid The handle of the message queue.
138 * \param[in] msgp The message to send.
139 * \param[in] msgsz The message size.
141 * \retval 0 If success.
142 * \retval -1 Bad passed parameter, or can not allocate memory
144 int phDal4Nfc_msgsnd (int msqid, void * msgp, size_t msgsz, int msgflg)
146 phDal4Nfc_message_queue_t * pQueue;
147 phDal4Nfc_message_queue_item_t * p;
148 phDal4Nfc_message_queue_item_t * pNew;
150 if ((msqid == 0) || (msgp == NULL) || (msgsz == 0))
153 if (msgsz != sizeof(phLibNfc_Message_t))
156 pQueue = (phDal4Nfc_message_queue_t *)msqid;
157 pNew = (phDal4Nfc_message_queue_item_t *)phOsalNfc_GetMemory(sizeof(phDal4Nfc_message_queue_item_t));
160 memset(pNew, 0, sizeof(phDal4Nfc_message_queue_item_t));
161 memcpy(&pNew->nMsg, &((phDal4Nfc_Message_Wrapper_t*)msgp)->msg, sizeof(phLibNfc_Message_t));
162 pthread_mutex_lock(&pQueue->nCriticalSectionMutex);
163 if (pQueue->pItems != NULL)
166 while(p->pNext != NULL) { p = p->pNext; }
172 pQueue->pItems = pNew;
174 pthread_mutex_unlock(&pQueue->nCriticalSectionMutex);
176 sem_post(&pQueue->nProcessSemaphore);
181 * \ingroup grp_nfc_dal
183 * \brief DAL message receive function
184 * The call to this function will get the older message from the queue. If the queue is empty the function waits
185 * (blocks on a mutex) until a message is posted to the queue with phDal4Nfc_msgsnd.
186 * The msgtyp and msgflg parameters are ignored.
188 * \param[in] msqid The handle of the message queue.
189 * \param[out] msgp The received message.
190 * \param[in] msgsz The message size.
192 * \retval 0 If success.
193 * \retval -1 Bad passed parameter.
195 int phDal4Nfc_msgrcv (int msqid, void * msgp, size_t msgsz, long msgtyp, int msgflg)
197 phDal4Nfc_message_queue_t * pQueue;
198 phDal4Nfc_message_queue_item_t * p;
200 if ((msqid == 0) || (msgp == NULL))
203 if (msgsz != sizeof(phLibNfc_Message_t))
206 pQueue = (phDal4Nfc_message_queue_t *)msqid;
207 sem_wait(&pQueue->nProcessSemaphore);
208 pthread_mutex_lock(&pQueue->nCriticalSectionMutex);
209 if (pQueue->pItems != NULL)
211 memcpy(&((phDal4Nfc_Message_Wrapper_t*)msgp)->msg, &(pQueue->pItems)->nMsg, sizeof(phLibNfc_Message_t));
212 p = pQueue->pItems->pNext;
213 phOsalNfc_FreeMemory(pQueue->pItems);
216 pthread_mutex_unlock(&pQueue->nCriticalSectionMutex);