#include <semaphore.h>
#include "../bmc_type.h"
#include <unistd.h>  
#include <stdlib.h>  
#include <fcntl.h>  
#include <limits.h>  
#include <sys/types.h>  
#include <sys/stat.h>  
#include <stdio.h>  
#include <string.h>  

int AddToQueue (void* pBuf, INT8S *Queuepath,INT32U Size);
int AddQueue(INT8S *Queuepath);
int GetQueue(INT8S *Queuepath,int flags);
int GetQueueHandle(INT8S *Queuepath,HQueue_T *IfcQ);
int PostMsg (MsgPkt_T* pMsgPkt, INT8S *Queuepath );
int GetMsg (_FAR_ MsgPkt_T* pMsgPkt, INT8S *Queuepath, INT16S Timeout);


/*-----------------------------------------------------------------
 *  * Queue specific macros, functions and typedefs
 *   *-----------------------------------------------------------------*/

/*------ Allocate memory to hold the queue -------------------------*/
#define OS_ALLOC_Q(QueueName, Size)

#define OS_CREATE_Q(Key)                      \
    AddQueue(Key);                                                                                    \
    if (-1 == mkfifo (Key, 0777) && (errno != EEXIST))      \
    {                                                       \
        printf("Error creating named pipe %s\n", Key);     \
    }


#define OS_GET_Q(Key, RDWR)                         		\
    if (GetQueue(Key,RDWR) == -1)                     		\
    {                                                           \
        printf ("Attempt to open before creating pipe %s\n", Key);    \
    } 

#define OS_CLOSE_Q(hQueue)                                  	\
    close (hQueue);

#define POST_TO_Q(pBuf,Size,key,pErr)     			\
{                                                 		\
     AddToQueue(pBuf,key,Size);    				\
}

/*------- Add this message to the queue ----------------------------*/
#define OS_ADD_TO_Q(pBuf, Size, hQueue, pErr)               \
    *pErr = write (hQueue, pBuf, Size)                      \

/*------ Get the message from the queue -----------------------------*/
#define OS_GET_FROM_Q(pBuf, Size, hQueue, timeout, pErr) 	\
{                                                           \
    int ReadLen = 0, Left, Len;                             \
    Left = Size;                                            \
    while( Left > 0 )                                       \
    {                                                       \
        Len = read (hQueue, (INT8U*)pBuf + ReadLen, Left ); \
        if( Len < 0 )                                       \
        {                                                   \
            if( errno == EINTR || errno == EAGAIN )         \
            {                                               \
                continue;                                   \
            }                                               \
            else                                            \
            {                                               \
                *pErr = -1;                                 \
                break;                                      \
            }                                               \
        }                                                   \
        ReadLen += Len;                                     \
        Left -= Len;                                        \
    }                                                       \
    *pErr = ReadLen;                                        \
}

/*-------- Get the number of messages in the Queue --------------------*/
#define OS_GET_Q_DEPTH(hQueue, Depth, Size)                 \
 do                                                         \
 {                                                          \
    struct  stat Stat;                                      \
    if(0 == fstat (hQueue, &Stat))                          \
    {                                                       \
        Depth = Stat.st_size/Size;                          \
    }                                                       \
    else { Depth = 0; }                                     \
 } while (0)

/*----------------Locking mechanism for Queue-----------------------*/
#define LOCK_QUEUE(hQueue)                              \
if (-1 == file_lock_write (hQueue))                     \
{                                                       \
    IPMI_WARNING ("Error locking Queue\n");       \
}

#define UNLOCK_QUEUE(hQueue)                            \
if (-1 == file_unlock (hQueue))                         \
{                                                       \
    IPMI_WARNING ("Error unlocking Queue\n");     \
} 
