/*
- Frame_Queue.c
-
Author: Administrator
*/
#include"Frame_Queue.h"
PT_QUEUE_Frame QUEUE_Frame_Open(SX_S32 depth)
{
PT_QUEUE_Frame handle = (PT_QUEUE_Frame)xine_xmalloc(sizeof(T_QUEUE_Frame));
if( handle == NULL )
{
TRACE(DL_ERROR, “DL_ERROR\n”);
return NULL;
}
if (pthread_mutex_init( &handle->mutex, NULL ) != 0)
{
TRACE(DL_ERROR, "DL_ERROR\n");
QUEUE_Frame_Close( handle );
return NULL;
}
if( pthread_cond_init(&handle->cond, NULL) != 0 )
{
TRACE(DL_ERROR, "DL_ERROR\n");
QUEUE_Frame_Close( handle );
return NULL;
}
handle->PtFrame = (PT_Frame_Pkt)xine_xmalloc(sizeof(T_Frame_Pkt) * depth);
if( handle->PtFrame == NULL )
{
TRACE(DL_ERROR, "DL_ERROR\n");
QUEUE_Frame_Close( handle );
return NULL;
}
handle->s32QueueDepth = depth;
handle->s32IndexR = 0;
handle->s32IndexW = 0;
handle->s32Count = 0;
handle->bAbortRequest = SX_FALSE;
return handle;
}
void QUEUE_Frame_Close( PT_QUEUE_Frame handle )
{
if( handle )
{
if( handle->PtFrame )
{
xine_freep( (void *)&(handle->PtFrame) );
}
pthread_mutex_destroy( &handle->mutex );
pthread_cond_destroy(&handle->cond);
xine_freep( (void *)&handle);
}
return;
}
SX_S32 QUEUE_Frame_Send( PT_QUEUE_Frame handle, PT_Frame_Pkt Frame)
{
if( handle == NULL || Frame == NULL )
{
TRACE(DL_ERROR, “DL_ERROR\n”);
return -1;
}
pthread_mutex_lock( &(handle->mutex) );
if( (handle->s32IndexW + 1) % handle->s32QueueDepth == handle->s32IndexR )
{
pthread_mutex_unlock( &(handle->mutex) );
//TRACE(DL_WARNING, "queue full\n"); //tx bus_send_cmd fifo is always full in working phase
return 0;
}
PT_Frame_Pkt PtFrame = handle->PtFrame + handle->s32IndexW;
#if 1
*PtFrame = *Frame;
#else
memcpy( ptCmd->szSync, cmd->szSync, sizeof(ptCmd->szSync) );
ptCmd->s8ChNo = cmd->s8ChNo;
ptCmd->s8CmdIndex = cmd->s8CmdIndex;
ptCmd->s16CmdPeriod = cmd->s16CmdPeriod;
ptCmd->s8LibIndex = cmd->s8LibIndex;
ptCmd->u8CmdLength = cmd->u8CmdLength;
ptCmd->s8CmdFormat = cmd->s8CmdFormat;
memcpy( ptCmd->szReserved1, cmd->szReserved1, sizeof(cmd->szReserved1) );
memcpy( ptCmd->szCmd, cmd->szCmd, MIN(ptCmd->u8CmdLength, sizeof(ptCmd->szCmd)) );
ptCmd->s32StatusLength = cmd->s32StatusLength;
memcpy( ptCmd->szStatus, cmd->szStatus, MIN(ptCmd->s32StatusLength, sizeof(ptCmd->szStatus)) );
ptCmd->s32LastTime = cmd->s32LastTime;
ptCmd->s32Sn = cmd->s32Sn;
ptCmd->ptBk = cmd->ptBk;
ptCmd->ptCh = cmd->ptCh;
ptCmd->ptCmd_Myself = cmd->ptCmd_Myself;
ptCmd->next = cmd->next;
#endif
handle->s32IndexW = (handle->s32IndexW+1) % handle->s32QueueDepth;
handle->s32Count++;
pthread_cond_signal( &handle->cond );
pthread_mutex_unlock( &handle->mutex );
return 1;
}
SX_S32 QUEUE_Frame_Receive(PT_QUEUE_Frame handle, PT_Frame_Pkt Frame, SX_BOOL block)
{
if( handle == NULL || Frame == NULL )
{
TRACE(DL_ERROR, “DL_ERROR\n”);
return -1;
}
SX_S32 ret = 1;
pthread_mutex_lock( &(handle->mutex) );
for (;;)
{
if (handle->bAbortRequest)
{
ret = -1; // 异常
break;
}
if( handle->s32IndexW == handle->s32IndexR) //empty //if( _s32Count == 0 )
{
if ( !block) // 阻塞标记,1(阻塞模式),0(非阻塞模式)
{
ret = 0; // 非阻塞模式,没东西直接返回0
break;
}
else
{
pthread_cond_wait(&handle->cond, &handle->mutex);
}
}
else
{
PT_Frame_Pkt PtFrame = handle->PtFrame + handle->s32IndexR;
#if 1
*Frame = *PtFrame;
#else
memcpy( cmd->szSync, ptCmd->szSync, sizeof(cmd->szSync) );
cmd->s8ChNo = ptCmd->s8ChNo;
cmd->s8CmdIndex = ptCmd->s8CmdIndex;
cmd->s16CmdPeriod = ptCmd->s16CmdPeriod;
cmd->s8LibIndex = ptCmd->s8LibIndex;
cmd->u8CmdLength = ptCmd->u8CmdLength;
cmd->s8CmdFormat = ptCmd->s8CmdFormat;
memcpy( cmd->szReserved1, ptCmd->szReserved1, sizeof(ptCmd->szReserved1) );
memcpy( cmd->szCmd, ptCmd->szCmd, MIN(cmd->u8CmdLength, sizeof(cmd->szCmd)) );
cmd->s32StatusLength = ptCmd->s32StatusLength;
memcpy( cmd->szStatus, ptCmd->szStatus, MIN(cmd->s32StatusLength, sizeof(cmd->szStatus)) );
cmd->s32LastTime = ptCmd->s32LastTime;
cmd->s32Sn = ptCmd->s32Sn;
cmd->ptBk = ptCmd->ptBk;
cmd->ptCh = ptCmd->ptCh;
cmd->ptCmd_Myself = ptCmd->ptCmd_Myself;
cmd->next = ptCmd->next;
#endif
handle->s32IndexR = (handle->s32IndexR + 1) % handle->s32QueueDepth;
if( handle->s32Count > 0 )
{
handle->s32Count–;
}
ret = 1;
break;
}
}
pthread_mutex_unlock( &(handle->mutex) );
return ret;
}
void QUEUE_Frame_Abort(PT_QUEUE_Frame handle)
{
if( handle == NULL )
{
TRACE(DL_ERROR, “DL_ERROR\n”);
return;
}
pthread_mutex_lock( &(handle->mutex) );
handle->bAbortRequest = SX_TRUE;
pthread_cond_signal(&handle->cond);
pthread_mutex_unlock( &handle->mutex);
return;
}
void QUEUE_Frame_Flush(PT_QUEUE_Frame handle)
{
if( handle == NULL )
{
TRACE(DL_ERROR, “DL_ERROR\n”);
return;
}
pthread_mutex_lock( &(handle->mutex) );
handle->s32IndexR = 0;
handle->s32IndexW = 0;
handle->s32Count = 0;
handle->bAbortRequest = 0;
pthread_mutex_unlock( &(handle->mutex) );
return;
}
/Frame_Queue.h/
#ifndef QUEUE_Frame_H_
#define QUEUE_Frame_H_
#include “global.h”
#define MAX_PKT_NUM 1500
#pragma pack(1)
typedef struct Frame_Pkt
{
//SX_U16 u16SyncHead;
//SX_U8 u8Cmd;
//SX_U8 u8Reserved1;
//SX_U8 u8Reserved2;
//SX_U8 u8Reserved3;
SX_U8 data[1500];
} T_Frame_Pkt, *PT_Frame_Pkt;
#pragma pack()
typedef struct QUEUE_Frame{
PT_Frame_Pkt PtFrame;
SX_S32 s32QueueDepth;
SX_S32 s32IndexR;
SX_S32 s32IndexW;
SX_S32 s32Count;
SX_BOOL bAbortRequest;
pthread_mutex_t mutex;
pthread_cond_t cond;
}T_QUEUE_Frame, *PT_QUEUE_Frame;
extern PT_QUEUE_Frame QUEUE_Frame_Open( SX_S32 depth );
extern void QUEUE_Frame_Close( PT_QUEUE_Frame handle );
extern SX_S32 QUEUE_Frame_Receive(PT_QUEUE_Frame handle, PT_Frame_Pkt Frame, SX_BOOL block);
extern SX_S32 QUEUE_Frame_Send( PT_QUEUE_Frame handle, PT_Frame_Pkt Frame);
extern void QUEUE_Frame_Abort( PT_QUEUE_Frame handle );
extern void QUEUE_Frame_Flush( PT_QUEUE_Frame handle );
#endif
//static SX_U32 cnt = 0;
SX_S32 Frame_Receiver_Rcv(PT_Receiver handle, void *buf, SX_S32 timeoutMs )
{
if( handle == NULL )
{
TRACE(DL_ERROR, “DL_ERROR\n”);
return 0;
}
SX_U8 *pDst = NULL;
SX_S32 ret, sret, retval;
SX_S64 max_fd;
fd_set readfds;
struct timeval tv;
int i = 0;
FD_ZERO(&readfds);
FD_SET( handle->sockfd, &readfds );
max_fd = handle->sockfd;
tv.tv_sec = timeoutMs/1000;
tv.tv_usec = (timeoutMs%1000)*1000;
retval = select( max_fd + 1, &readfds, NULL, NULL, &tv );
if ( retval > 0 )
{
//printf("++++ decoder Server Receive data ++++\r\n");
if( buf ){
sret = recvfrom( handle->sockfd, (SX_S8 *)buf, UDP_MAX_LEN, 0, (struct sockaddr *)&(handle->cliaddr), &(handle->cliaddr_len) );
}
else{
sret = recvfrom( handle->sockfd, handle->pszRecvBuf, UDP_MAX_LEN, 0, (struct sockaddr *)&(handle->cliaddr), &(handle->cliaddr_len) );
handle->s32RecvLen = sret;
}
if ( sret > 0 )
{
ret = sret;
pDst = (SX_U8 *)&handle->FrameSendQueue.data;
memcpy( (SX_S8 *)pDst, (SX_S8 *)buf,sret);
//printf("+ recvfrom %ld +\r\n",sret);
if(handle->ptFrameQueue == NULL || &(handle->FrameSendQueue) == NULL)
return -1;
QUEUE_Frame_Send(handle->ptFrameQueue,&(handle->FrameSendQueue));
//cnt ++;
//tset
//QUEUE_Frame_Receive(handle->ptFrameQueue,&(handle->FrameRcvQueue),1);
//for(i = 0; i< sret;i++)
//printf("%x",handle->FrameRcvQueue.data[i]);
//printf("\r\n");
}
else
{
ret = 0; // no data;
}
}
else if ( retval == 0 )
{
// timeout
ret = 0;
}
else
{
// error
ret = -1;
}
return ret;
}
ret = QUEUE_Frame_Receive(handle->ptFrameQueue,&(handle->FrameRcvQueue),1);
if(ret < 0)
{
usleep(1000);
continue;
}
PT_QUEUE_Frame ptFrameQueue;
T_Frame_Pkt FrameRcvQueue;
T_Frame_Pkt FrameSendQueue;