/*
 * 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;
}





