218 lines
6.4 KiB
C
218 lines
6.4 KiB
C
/*
|
|
* 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.
|
|
*/
|
|
intptr_t 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 ((intptr_t)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 ( intptr_t 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 (intptr_t 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 (intptr_t 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;
|
|
}
|
|
|
|
|
|
|
|
|
|
|