/* includes */
#include "vxWorks.h"
#include "sockLib.h"
#include "inetLib.h"
#include "stdioLib.h"
#include "strLib.h"
#include "ioLib.h"
#include "fioLib.h"
#include "Udp.h"
tagUdpCtrl g_tUdpCtrl;
tagQueueUdpMsg g_tQueueUdpMsg;
unsigned int g_uiLogUdp = 0; // for print logmsg
//=============================================================================
void Udp_Initial( void )
{
tagUdpConn *ptConn;
tagPQueueCtrl ptQueueCtrl;
tagPUdpMsgCtrl ptUdpMsgCtrl;
short iLoop;
g_tUdpCtrl.nConnNum = 0;
g_tUdpCtrl.nServerNum = 0;
g_tUdpCtrl.nGroupNum = 0;
// initial
for( iLoop=0;iLoop<C_UDP_NUM_CONN;iLoop++ )
{
ptConn = &(g_tUdpCtrl.tConnArray[iLoop]);
ptConn->iSvrNo = -1;
ptConn->iGroupNo = -1;
}
ptQueueCtrl = &g_tQueueUdpMsg.tQueueCtrl;
ptQueueCtrl->ptSemID = semMCreate( (SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE) );
ptQueueCtrl->bFull = FALSE;
ptQueueCtrl->wSave = 0;
ptQueueCtrl->wQueueIDSave = 0;
for( iLoop=0; iLoop<(CONST_NUM_HOST+2); iLoop++ )
{
ptQueueCtrl->wRead[iLoop] = 0;
ptQueueCtrl->wQueueIDRead[iLoop] = 0;
ptQueueCtrl->wQueueIDAck[ iLoop] = 0;
}
for( iLoop=0; iLoop<CONST_NUM_RPTU; iLoop++ )
{
ptUdpMsgCtrl = &g_tQueueUdpMsg.tUdpMsgCtrl[iLoop];
ptUdpMsgCtrl->wQueueID = 0;
ptUdpMsgCtrl->wConnNo = 0;
ptUdpMsgCtrl->wGroupNo = -1;
ptUdpMsgCtrl->wLength = 0;
ptUdpMsgCtrl->wHead = 0;
ptUdpMsgCtrl->wRear = 0;
ptUdpMsgCtrl->wCRC = 0;
ptUdpMsgCtrl->wTag = 0;
}
return;
}
//==========================================================
// Save Udp Message to Common Buffer
BOOLEAN Udp_SaveMsg( short iGroupNo, short iConnNo, BYTE *pbyMsgBuf, WORD wMsgLen )
{
tagWord_Byte2 m_WB2;
tagPQueueCtrl ptQueueCtrl;
tagUdpMsgCtrl* ptUdpMsgCtrl;
WORD wSave, wStartPos, wWritePos;
BYTE *pbyReportBuf;
ptQueueCtrl = &g_tQueueUdpMsg.tQueueCtrl;
pbyReportBuf = g_tQueueUdpMsg.byReportBuf;
semTake( ptQueueCtrl->ptSemID, WAIT_FOREVER ); // 获取写权限
wSave = ptQueueCtrl->wSave;
if( wSave >=CONST_NUM_REPORT_CTRL_UP ) wSave = 0; // !!! ERROR
ptUdpMsgCtrl = &g_tQueueUdpMsg.tUdpMsgCtrl[wSave];
wStartPos = ptUdpMsgCtrl->wHead;
if( wStartPos >=CONST_VOL_REPORT_BUF_UP ) wStartPos = 0; // !!! ERROR
if( TRUE==Fun_QueueBufSave(pbyReportBuf, pbyMsgBuf, wStartPos, wMsgLen, CONST_VOL_REPORT_BUF_UP) )
{
// update the control flag
wWritePos = (wStartPos + wMsgLen - 1) % CONST_VOL_REPORT_BUF_UP;
ptUdpMsgCtrl->wCRC = Fun_CreateCrc16( pbyMsgBuf, wMsgLen );
ptUdpMsgCtrl->wHead = wStartPos; // maybe have been changed
ptUdpMsgCtrl->wRear = wWritePos;
ptUdpMsgCtrl->wGroupNo= iGroupNo;
ptUdpMsgCtrl->wConnNo = iConnNo;
ptUdpMsgCtrl->wLength = wMsgLen;
ptUdpMsgCtrl->wQueueID = ptQueueCtrl->wQueueIDSave;
// make ready for the message coming next
wSave++;
wWritePos++;
if( wSave >=CONST_NUM_REPORT_CTRL_UP ) wSave = 0;
if( wWritePos >=CONST_VOL_REPORT_BUF_UP ) wWritePos = 0;
ptQueueCtrl->wQueueIDSave++;
ptQueueCtrl->wSave = wSave;
ptUdpMsgCtrl = &g_tQueueUdpMsg.tUdpMsgCtrl[wSave];
ptUdpMsgCtrl->wHead = wWritePos;
ptUdpMsgCtrl->wRear = wWritePos;
ptUdpMsgCtrl->wLength = 0;
ptUdpMsgCtrl->wQueueID = ptQueueCtrl->wQueueIDSave;
}
semGive( ptQueueCtrl->ptSemID ); // 释放写权限
return TRUE;
}
/*********************************************************************
* Start UdpServer, read from UDP socket */
int Udp_ServerStart( short iSvrNo )
{
struct sockaddr_in tServerAddr,tClientAddr; /* server/client's socket address */
char inetAddr[INET_ADDR_LEN]; /* buffer for client's inet addr */
BYTE byMsgBuf[C_UDP_VOL_BUF]; /* Message from client */
int sockAddrSize; /* size of socket address structure */
int sFd; /* socket file descriptor */
int iMsgLen; // the length of mesage received from client
WORD wClientPort;
short iConnNo, iGroupNo;
tagUdpServer* ptServer=&(g_tUdpCtrl.tSvrArray[iSvrNo]);
if( iSvrNo >=g_tUdpCtrl.nServerNum ) return -1;
/* set up the local address */
sockAddrSize = sizeof (struct sockaddr_in);
bzero ((char *) &tServerAddr, sockAddrSize);
tServerAddr.sin_len = (u_char) sockAddrSize;
tServerAddr.sin_family = AF_INET;
tServerAddr.sin_port = htons (ptServer->wPort);
tServerAddr.sin_addr.s_addr = ptServer->dwServerIP;
/* create a UDP-based socket */
if ((sFd = socket (AF_INET, SOCK_DGRAM, 0)) == ERROR)
{
if( g_uiLogUdp ) printf("udp socket Create Error\n");
return -1;
}
/* bind socket to local address */
if (bind (sFd, (tagPSockAddr) &tServerAddr, sockAddrSize) == ERROR)
{
if( g_uiLogUdp ) printf("Tcp Bind Error %x:%d\n",ptServer->dwServerIP,ptServer->wPort);
close (sFd);
return -1;
}
/* read data from a socket and satisfy requests */
ptServer->iSockFD = sFd;
for( ; ; )
{
iMsgLen = recvfrom( sFd, byMsgBuf, C_UDP_VOL_BUF, 0, (struct sockaddr *)&tClientAddr, &sockAddrSize );
if( ERROR == iMsgLen )
{
if( g_uiLogUdp )
{
Dbg_RtcClock( );
printf("udp server recv Error\n");
}
close (sFd);
ptServer->iSockFD = ERROR;
return -1;
}
/* convert inet address to dot notation */
inet_ntoa_b( tClientAddr.sin_addr, inetAddr );
wClientPort = ntohs( tClientAddr.sin_port ); // 网络端口号
if( Udp_GetConnNo(iSvrNo,tClientAddr.sin_addr.s_addr,wClientPort,&iConnNo,&iGroupNo) ) // 查找属于哪一组
{// save the msg to the buffer
Udp_SaveMsg( iGroupNo, iConnNo, byMsgBuf, iMsgLen );
}
}
ptServer->iSockFD = ERROR;
return -1;
}
//=======================================
// 增加服务器,返回序号
short Udp_AddServer( BYTE *ServerIP, WORD wPort )
{
tagUdpServer *ptServer, *ptSvrTmp;
char szTxt[20];
WORD nSvrNo;
short iLoop;
if(g_tUdpCtrl.nServerNum >=C_UDP_NUM_SVR)
{// 队列已满
g_tUdpCtrl.nServerNum = C_UDP_NUM_SVR;
return -1;
}
ptServer = &(g_tUdpCtrl.tSvrArray[g_tUdpCtrl.nServerNum]);
sprintf( szTxt, "%d.%d.%d.%d", ServerIP[0], ServerIP[1], ServerIP[2], ServerIP[3] );
ptServer->dwServerIP = inet_addr(szTxt);
// 检查服务器是否已经在列表中
for( iLoop=0;iLoop<g_tUdpCtrl.nServerNum;iLoop++ )
{
ptSvrTmp = &(g_tUdpCtrl.tSvrArray[iLoop]);
if( (ptSvrTmp->wPort==wPort) && (ptServer->dwServerIP ==ptSvrTmp->dwServerIP) )
{
if( g_uiLogUdp ) printf( "Duplicate Server[%d]=%d.%d.%d.%d:%d!\n", iLoop,
ServerIP[0], ServerIP[1], ServerIP[2], ServerIP[3], wPort );
return iLoop;
}
}
if( g_uiLogUdp ) printf( "Server[%d]=%d.%d.%d.%d:%d Add!\n", g_tUdpCtrl.nServerNum,
ServerIP[0], ServerIP[1], ServerIP[2], ServerIP[3], wPort );
ptServer->wPort = wPort;
ptServer->iSockFD = ERROR;
nSvrNo = g_tUdpCtrl.nServerNum;
g_tUdpCtrl.nServerNum++;
// 启动服务器任务
sprintf(szTxt,"t_udpsvr_%d", nSvr