diff options
Diffstat (limited to 'Linux_x86/phDal4Nfc_messageQueueLib.c')
-rw-r--r-- | Linux_x86/phDal4Nfc_messageQueueLib.c | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/Linux_x86/phDal4Nfc_messageQueueLib.c b/Linux_x86/phDal4Nfc_messageQueueLib.c new file mode 100644 index 0000000..30d389b --- /dev/null +++ b/Linux_x86/phDal4Nfc_messageQueueLib.c @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2010 NXP Semiconductors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file phDalNfc_messageQueueLib.c + * \brief DAL independant message queue implementation for android (can be used under linux too) + * + * Project: Trusted NFC Linux Lignt + * + * $Date: 13 aug 2009 + * $Author: Jonathan roux + * $Revision: 1.0 $ + * + */ + +#include <pthread.h> +#ifdef ANDROID +#include <linux/ipc.h> +#else +#include <sys/msg.h> +#endif + +#include <semaphore.h> + +#include <phDal4Nfc.h> +#include <phOsalNfc.h> +#include <phDal4Nfc_DeferredCall.h> +#include <phDal4Nfc_messageQueueLib.h> + +typedef struct phDal4Nfc_message_queue_item +{ + phLibNfc_Message_t nMsg; + struct phDal4Nfc_message_queue_item * pPrev; + struct phDal4Nfc_message_queue_item * pNext; +} phDal4Nfc_message_queue_item_t; + + +typedef struct phDal4Nfc_message_queue +{ + phDal4Nfc_message_queue_item_t * pItems; + pthread_mutex_t nCriticalSectionMutex; + sem_t nProcessSemaphore; + +} phDal4Nfc_message_queue_t; + + +/** + * \ingroup grp_nfc_dal + * + * \brief DAL message get function + * This function allocates the message queue. The parameters are ignored, this is + * just to keep the same api as Linux queue. + * + * \retval -1 Can not allocate memory or can not init mutex. +* \retval handle The handle on the message queue. + */ +int phDal4Nfc_msgget ( key_t key, int msgflg ) +{ + phDal4Nfc_message_queue_t * pQueue; + pQueue = (phDal4Nfc_message_queue_t *) phOsalNfc_GetMemory(sizeof(phDal4Nfc_message_queue_t)); + if (pQueue == NULL) + return -1; + memset(pQueue, 0, sizeof(phDal4Nfc_message_queue_t)); + if (pthread_mutex_init (&pQueue->nCriticalSectionMutex, NULL) == -1) + return -1; + if (sem_init (&pQueue->nProcessSemaphore, 0, 0) == -1) + return -1; + return ((int)pQueue); +} + +/** + * \ingroup grp_nfc_dal + * + * \brief DAL message control function + * This function destroys the message queue. The cmd and buf parameters are ignored, + * this is just to keep the same api as Linux queue. + * + * \param[in] msqid The handle of the message queue. + * + * \retval 0 If success. + * \retval -1 Bad passed parameter + */ +int phDal4Nfc_msgctl ( int msqid, int cmd, void *buf ) +{ + phDal4Nfc_message_queue_t * pQueue; + phDal4Nfc_message_queue_item_t * p; + + if (msqid == 0) + return -1; + + pQueue = (phDal4Nfc_message_queue_t *)msqid; + pthread_mutex_lock(&pQueue->nCriticalSectionMutex); + if (pQueue->pItems != NULL) + { + p = pQueue->pItems; + while(p->pNext != NULL) { p = p->pNext; } + while(p->pPrev != NULL) + { + p = p->pPrev; + phOsalNfc_FreeMemory(p->pNext); + p->pNext = NULL; + } + phOsalNfc_FreeMemory(p); + } + pQueue->pItems = NULL; + pthread_mutex_unlock(&pQueue->nCriticalSectionMutex); + pthread_mutex_destroy(&pQueue->nCriticalSectionMutex); + phOsalNfc_FreeMemory(pQueue); + return 0; +} + +/** + * \ingroup grp_nfc_dal + * + * \brief DAL message send function + * Use this function to send a message to the queue. The message will be added at the end of + * the queue with respect to FIFO policy. The msgflg parameter is ignored. + * + * \param[in] msqid The handle of the message queue. + * \param[in] msgp The message to send. + * \param[in] msgsz The message size. + * + * \retval 0 If success. + * \retval -1 Bad passed parameter, or can not allocate memory + */ +int phDal4Nfc_msgsnd (int msqid, void * msgp, size_t msgsz, int msgflg) +{ + phDal4Nfc_message_queue_t * pQueue; + phDal4Nfc_message_queue_item_t * p; + phDal4Nfc_message_queue_item_t * pNew; + + if ((msqid == 0) || (msgp == NULL) || (msgsz == 0)) + return -1; + + if (msgsz != sizeof(phLibNfc_Message_t)) + return -1; + + pQueue = (phDal4Nfc_message_queue_t *)msqid; + pNew = (phDal4Nfc_message_queue_item_t *)phOsalNfc_GetMemory(sizeof(phDal4Nfc_message_queue_item_t)); + if (pNew == NULL) + return -1; + memset(pNew, 0, sizeof(phDal4Nfc_message_queue_item_t)); + memcpy(&pNew->nMsg, &((phDal4Nfc_Message_Wrapper_t*)msgp)->msg, sizeof(phLibNfc_Message_t)); + pthread_mutex_lock(&pQueue->nCriticalSectionMutex); + if (pQueue->pItems != NULL) + { + p = pQueue->pItems; + while(p->pNext != NULL) { p = p->pNext; } + p->pNext = pNew; + pNew->pPrev = p; + } + else + { + pQueue->pItems = pNew; + } + pthread_mutex_unlock(&pQueue->nCriticalSectionMutex); + + sem_post(&pQueue->nProcessSemaphore); + return 0; +} + +/** + * \ingroup grp_nfc_dal + * + * \brief DAL message receive function + * The call to this function will get the older message from the queue. If the queue is empty the function waits + * (blocks on a mutex) until a message is posted to the queue with phDal4Nfc_msgsnd. + * The msgtyp and msgflg parameters are ignored. + * + * \param[in] msqid The handle of the message queue. + * \param[out] msgp The received message. + * \param[in] msgsz The message size. + * + * \retval 0 If success. + * \retval -1 Bad passed parameter. + */ +int phDal4Nfc_msgrcv (int msqid, void * msgp, size_t msgsz, long msgtyp, int msgflg) +{ + phDal4Nfc_message_queue_t * pQueue; + phDal4Nfc_message_queue_item_t * p; + + if ((msqid == 0) || (msgp == NULL)) + return -1; + + if (msgsz != sizeof(phLibNfc_Message_t)) + return -1; + + pQueue = (phDal4Nfc_message_queue_t *)msqid; + sem_wait(&pQueue->nProcessSemaphore); + pthread_mutex_lock(&pQueue->nCriticalSectionMutex); + if (pQueue->pItems != NULL) + { + memcpy(&((phDal4Nfc_Message_Wrapper_t*)msgp)->msg, &(pQueue->pItems)->nMsg, sizeof(phLibNfc_Message_t)); + p = pQueue->pItems->pNext; + phOsalNfc_FreeMemory(pQueue->pItems); + pQueue->pItems = p; + } + pthread_mutex_unlock(&pQueue->nCriticalSectionMutex); + return 0; +} + + + + + |