www.pudn.com > linuxcchuankou.rar > comm.cpp


#include "global.h"
#include "fn_comm.h"

//comm baud rate
int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300,
B38400, B19200, B9600, B4800, B2400, B1200, B300, };
int name_arr[] = {38400,  19200,  9600,  4800,  2400,  1200,  300,
38400,  19200,  9600, 4800, 2400, 1200,  300, };

#ifdef FN_SWITCHAUDIO

#define		MAXSWITCHPACKAGEBUFFSIZE	1024
#define		COMMREADBUFFSIZE					(10*1024)

#endif

//constructor
comm::comm(int port,char *conf,int databits,int stopbits,char parity)
{
#ifdef FN_SWITCHAUDIO
    m_pProtocol = NULL;
#endif

	m_fd=0;
	char dev[300];
	port--;
	sprintf(dev, "/dev/ttyS%d", port);
	PRINTF("%s -- %s\n", dev, conf);
	m_fd=open(dev, O_RDWR);         //| O_NOCTTY | O_NDELAY

	if(-1 == m_fd){
		m_fd=0;
		bOpenDevFlag = false;
		PRINTF("open comm error\n");
		return ;
	}

	set_speed(atoi(conf));				//atoi将字符串转换成整型
	set_parity(databits,stopbits,parity);
	bOpenDevFlag = true;

#ifdef FN_SWITCHAUDIO    
    m_dwFrameLen = 0;
	m_dwBufSize = 0;
	m_pReadBuf = NULL;
	
	SetQueueSize(COMMREADBUFFSIZE);

	m_pSendBuff = (char *)malloc(TCP_PACK_MAX_LEN);
	if(m_pSendBuff == NULL)
	{
		printf("malloc sendbuf is error\n");
		return;
	}
#endif

	return ;
}
//destructor
comm::~comm()
{
	if(m_fd){
		close(m_fd);
		m_fd=0;
	}

#ifdef FN_SWITCHAUDIO 
    if(m_pReadBuf)
	{
		free(m_pReadBuf);
	}
	if(m_pSendBuff)
	{
		free(m_pSendBuff);
	}
#endif

}

#ifdef FN_SWITCHAUDIO 

int comm::SetQueueSize(DWORD	dwSize)
{
	if(m_dwBufSize >= dwSize)
	{
		m_dwFrameLen= 0;
		return 1;
	}
	if(m_pReadBuf != NULL)
	{
		free(m_pReadBuf);			
	}
	
	m_pReadBuf = (BYTE *)malloc(dwSize);
	if(m_pReadBuf == NULL)
	{
		return -1;
	}
	m_dwBufSize = dwSize;
	m_dwFrameLen = 0;
	return 1;
}
#endif

bool comm::Open()
{
	return bOpenDevFlag;	
}

void comm::Close()
{	
}

int comm::Getfd()
{
	return m_fd;
}
//read from comm to buf,the lenth for read is len,and return actually read lenth
int comm::Read(char *buf,int len)
{
	return m_fd?::read(m_fd,buf,len):-1;
}
//write certain lenth data in buf to comm port,return actually write lenth
int comm::Send(char *buf,int len)
{
	return m_fd?::write(m_fd,buf,len):-1;
}
//set comm port baud rate
int comm::set_speed(int speed)
{
	int   i;
	int   status;
	termios   options;
	
	if(tcgetattr(m_fd,&options)!=0){
		perror("tcgetattr error");
		return -1;
	}
	
	for(i= 0;i 0)
    {
	    if(Hexstr[0]>=0x30 && Hexstr[0]<=0x39)
	    {
	      tmp=(BYTE)(Hexstr[0]-0x30);
	    }
	    else
	    {
		      if(Hexstr[0]>='a' && Hexstr[0]<='f')
		      {
		           tmp=(BYTE)(Hexstr[0]-'a'+ 10);
		      }
		      else
		      if(Hexstr[0]>='A' && Hexstr[0]<='F')
		      {
		          tmp=(BYTE)(Hexstr[0]-'A'+ 10);
		      }
		      else
		      {
		           return -1;
		      }
	    }
	    if(iLen > 1)
	   {
		    if(Hexstr[1]>=0x30 && Hexstr[1]<=0x39)
		    {
		      	tmp1=(BYTE)(Hexstr[1]-0x30);
		    }
		    else
		    {
			      if(Hexstr[1]>='a' && Hexstr[1]<='f')
			      {
			           tmp1=(BYTE)(Hexstr[1]-'a'+ 10);
			      }
			      else
			      if(Hexstr[1]>='A' && Hexstr[1]<='F')
			      {
			          tmp1=(BYTE)(Hexstr[1]-'A'+ 10);
			      }
			      else
			      {
			       return -1;
			      }
		      }

			*bRtByte = (tmp << 4) + tmp1;
			return 1;
			
	    }
	    else
	    {
		  *bRtByte = tmp;
		  return 1;
	    }
   }
	
   return -1;
}

void comm::PrintMemBufInfo(BYTE *pBuf,int iLen)
{
	int i;
	if(iLen <= 0)
	{
		return;
	}	
	
	for(i = 0;i < iLen;i++)
	{
		//
		printf("%02X ",pBuf[i]);
		if((i != 0) && ((i % 20) == 0))
		{
			printf("\n");
		}
	}
	printf("\n");
}

int	comm::OnReadData(const BYTE *pReadBuf,int iLen)
{
	int					 	iCopyLen;
	SWITCHRETURNPACKINFO	*pFrameHead;
	BYTE					*pCurrent;
	WORD					wLength;
	int						iReturn;
	int						iLeftLen;
	int						i;
	int						iHeadSize;
	bool 					bFindFlag;
	BYTE					TmpByte1,TmpByte2;
				
	if((pReadBuf == NULL) || (iLen <= 0))
	{
		return -1;
	}

	pCurrent = (BYTE *)pReadBuf;
	iLeftLen = iLen;
	iHeadSize = sizeof(SWITCHRETURNPACKINFO);
	
	if(m_dwFrameLen > 0)
	{
		//
		
		if(m_dwFrameLen >= sizeof(SWITCHRETURNPACKINFO))
		{
			//
			pFrameHead = (SWITCHRETURNPACKINFO *)(m_pReadBuf);
			
			if(pFrameHead->Header == 0x7E)
			{
				//

				ULENGTHCHKINFO LengthInfo;
				HexStrtoAsc((char *)&pFrameHead->Length1,&TmpByte1);
				HexStrtoAsc((char *)&pFrameHead->Length2,&TmpByte2);
				LengthInfo.wLengthAndChk = (TmpByte1 << 8) + TmpByte2;
				
				wLength = (LengthInfo.LengthChkInfo.Length) + sizeof(SWITCHRETURNPACKINFO) + 5;
					//
				if(wLength <= m_dwBufSize)
				{
					//
					if(wLength <= m_dwFrameLen)
					{
						//如果里面有一包数据

                        if(CheckFrame((BYTE *)(pFrameHead)) > 0)
						{
							iReturn = OnValidateGetCmds(pFrameHead,wLength);
						}
						m_dwFrameLen = 0;
					}
					else
					{
						//
						iCopyLen = wLength - m_dwFrameLen;
						if(iCopyLen > (int)(m_dwBufSize - m_dwFrameLen))
						{
							m_dwFrameLen = 0;	
						}
						else
						{
							//
							if(iLen >= iCopyLen)
							{
								//
								memcpy(&m_pReadBuf[m_dwFrameLen],pCurrent,iCopyLen);
								iLeftLen -= iCopyLen;
			

								if(CheckFrame((BYTE *)(pFrameHead)) > 0)
								{
									iReturn = OnValidateGetCmds(pFrameHead,wLength);
								}
								m_dwFrameLen = 0;
							}							
							else
							{
								//
								iCopyLen = iLen;
								memcpy(&m_pReadBuf[m_dwFrameLen],pCurrent,iCopyLen);
								iLeftLen -= iCopyLen;
								m_dwFrameLen += iCopyLen;
							}
						}
					}
				}
				else
				{
					m_dwFrameLen = 0;			
				}					
							
			}
			else
			{
				m_dwFrameLen = 0;			
			}			
		}
		else
		{
			//只有一个eb 90
			iCopyLen = sizeof(SWITCHRETURNPACKINFO) - m_dwFrameLen;
			if(iLen < iCopyLen)
			{
				//
				iCopyLen = iLen;
				memcpy(&m_pReadBuf[m_dwFrameLen],pCurrent,iCopyLen);
				iLeftLen -= iCopyLen;
				m_dwFrameLen += iCopyLen;
				
			}
			else
			{
				memcpy(&m_pReadBuf[m_dwFrameLen],pCurrent,iCopyLen);
				iLeftLen -= iCopyLen;
				m_dwFrameLen += iCopyLen;
				pFrameHead = (SWITCHRETURNPACKINFO *)(m_pReadBuf);
				pCurrent = (BYTE *)(&pReadBuf[iLen - iLeftLen]);
					
				if(pFrameHead->Header == 0x7E)
				{
					//

					ULENGTHCHKINFO LengthInfo;
					HexStrtoAsc((char *)&pFrameHead->Length1,&TmpByte1);
					HexStrtoAsc((char *)&pFrameHead->Length2,&TmpByte2);
					LengthInfo.wLengthAndChk = (TmpByte1 << 8) + TmpByte2;
					
					wLength = (LengthInfo.LengthChkInfo.Length) + sizeof(SWITCHRETURNPACKINFO) + 5;
						//
					if(wLength <= m_dwBufSize)
					{
						//
						if(wLength <= m_dwFrameLen)
						{
							//如果里面有一包数据

							if(CheckFrame((BYTE *)(pFrameHead)) > 0)
							{
								iReturn = OnValidateGetCmds(pFrameHead,wLength);
							}
							m_dwFrameLen = 0;
						}
						else
						{
							//
							iCopyLen = wLength - m_dwFrameLen;
							if(iCopyLen > (int)(m_dwBufSize - m_dwFrameLen))
							{
								m_dwFrameLen = 0;	
							}
							else
							{
								//
								if(iLen >= iCopyLen)
								{
									//
									memcpy(&m_pReadBuf[m_dwFrameLen],pCurrent,iCopyLen);
									iLeftLen -= iCopyLen;
									
									if(CheckFrame((BYTE *)(pFrameHead)) > 0)
									{							
										iReturn = OnValidateGetCmds(pFrameHead,wLength);
									}
									m_dwFrameLen = 0;
								}							
								else
								{
									//
									iCopyLen = iLen;
									memcpy(&m_pReadBuf[m_dwFrameLen],pCurrent,iCopyLen);
									iLeftLen -= iCopyLen;
									m_dwFrameLen += iCopyLen;
								}
							}
						}
					}
					else
					{
						m_dwFrameLen = 0;			
					}						
				}
			}				
		}
	}
	while(iLeftLen > 0)
	{
		pCurrent = (BYTE *)(&pReadBuf[iLen - iLeftLen]);
		if(iLeftLen < 1)
		{
			//
			bFindFlag = false;
			
			for(i = 0;i < iLeftLen;i++)
			{
				//
				if(pCurrent[i] == 0x7E)
				{
					memcpy(&m_pReadBuf[0],&pCurrent[i],iLeftLen - i);
					m_dwFrameLen = iLeftLen - i;
					bFindFlag = true;
					break;
				}
			}
			if(bFindFlag)
			{				
				m_dwFrameLen = 0;	
			}
			iLeftLen = 0;
			break;
		}
		else
		{
			//
			for(i = 0;i < iLeftLen - 1;i++)
			{
				//				
				if(pCurrent[i] == 0x7E)				
				{
					//					
					break;
				}
			}
			if(i == (iLeftLen - 1))
			{
				//					
				return -1;
			}
			
			pCurrent += i;			
			iLeftLen -= i;

			if(iLeftLen >= iHeadSize)
			{
				//
				pFrameHead = (SWITCHRETURNPACKINFO *)(pCurrent);
								
				ULENGTHCHKINFO LengthInfo;
				HexStrtoAsc((char *)&pFrameHead->Length1,&TmpByte1);
				HexStrtoAsc((char *)&pFrameHead->Length2,&TmpByte2);
				LengthInfo.wLengthAndChk = (TmpByte1 << 8) + TmpByte2;
				
				wLength = (LengthInfo.LengthChkInfo.Length) + sizeof(SWITCHRETURNPACKINFO) + 5;

				if(iLeftLen < wLength)
				{
					//
					memcpy(&m_pReadBuf[0],pCurrent,iLeftLen);
					m_dwFrameLen = iLeftLen;
					iLeftLen = 0;
					break;
				}
				else
				{
					//				
					
					if(CheckFrame((BYTE *)(pFrameHead)) > 0)
					{

						iReturn = OnValidateGetCmds(pFrameHead,wLength);								
					}
					m_dwFrameLen = 0;
					iLeftLen -= wLength;											
				}							
			}			
			else
			{
				//
				memcpy(&m_pReadBuf[0],pCurrent,iLeftLen);
				m_dwFrameLen = iLeftLen;
				iLeftLen = 0;
			}
		}
	}
	
	return 1;
}

int comm::OnValidateGetCmds(SWITCHRETURNPACKINFO *pFrameHead,WORD wFrameLen)
{
	BYTE					TmpByte1,TmpByte2;
	BYTE					CID1,CID2;
	WORD					wDataTmp;
	WORD					wLength;
	char					MsgString[64];

	HexStrtoAsc((char *)&pFrameHead->CID1,&TmpByte1);
	CID1 = TmpByte1;
	HexStrtoAsc((char *)&pFrameHead->CID2,&TmpByte1);
	CID2 = TmpByte1;

	ULENGTHCHKINFO LengthInfo;
	HexStrtoAsc((char *)&pFrameHead->Length1,&TmpByte1);
	HexStrtoAsc((char *)&pFrameHead->Length2,&TmpByte2);
	wDataTmp = TmpByte1;
	LengthInfo.wLengthAndChk = (wDataTmp<<8) | TmpByte2;

	wLength = (LengthInfo.LengthChkInfo.Length) + sizeof(SWITCHRETURNPACKINFO) + 5;
	
	PRINTF("CID1=%02X,CID2=%02X\n",CID1,CID2);
	if(CID1 != 0xDD)
	{
		PRINTF("CID1=%02X is error[not 0xDD]\n",CID1);
		return -1;
	}
	switch(CID2)
	{		
		default:
		{
			break;
		}
	}
	return 1;
}
int	comm::CheckFrame(BYTE *pFrame)
{
	WORD					wLength;
	BYTE					*pFrame1 ;
	WORD					wSum;
	int						i ;
	WORD					wData;
	SWITCHRETURNPACKINFO	*pFrameHead;	
	WORD					wDataLen;
	BYTE					TmpByte1,TmpByte2;
	WORD					wDataSum;
	WORD					wDataTmp;

	pFrameHead = (SWITCHRETURNPACKINFO *)(pFrame);

	//wDataLen = SwabWorkData(pFrameHead->DataLen);
	ULENGTHCHKINFO LengthInfo;
	HexStrtoAsc((char *)&pFrameHead->Length1,&TmpByte1);
	HexStrtoAsc((char *)&pFrameHead->Length2,&TmpByte2);
	wDataTmp = TmpByte1;
	LengthInfo.wLengthAndChk = (wDataTmp<<8) | TmpByte2;

	wLength = (LengthInfo.LengthChkInfo.Length) + sizeof(SWITCHRETURNPACKINFO) + 5;
	
	if((pFrameHead->Header != 0x7E) || (*((BYTE *)pFrameHead + wLength - 1) != 0x0D))
	{
		return -1;
	}

	if((wLength <= MAXSWITCHPACKAGEBUFFSIZE) && (LengthInfo.LengthChkInfo.Length % 2 == 0))
    {
		BYTE bTemp = (~((LengthInfo.OthLengthChkInfo.Length1 + LengthInfo.OthLengthChkInfo.Length2 + LengthInfo.OthLengthChkInfo.Length3) % 16) + 1);
		
		if((bTemp & 0x0F) != (LengthInfo.LengthChkInfo.ChkSum))
		{
			PRINTF("check length is error\n");
			return -1;
		}
				
    	pFrame1 = pFrame + 1;
		wSum = 0;

		for(i = 0;i < wLength-6;i++)
		{
			wSum += pFrame1[i];		
		}        
				
		wSum = (~(wSum % 65536)) + 1;

		HexStrtoAsc((char *)pFrame + (LengthInfo.LengthChkInfo.Length) + sizeof(SWITCHRETURNPACKINFO),&TmpByte1);
		
		HexStrtoAsc((char *)pFrame + (LengthInfo.LengthChkInfo.Length) + sizeof(SWITCHRETURNPACKINFO) + 2,&TmpByte2);
		
		wDataTmp = TmpByte1;
		wDataSum = (wDataTmp<<8) | TmpByte2;
				       
        if(wDataSum != wSum)
        {        	
        
			return -1;
		}   
        return 1;
		
    }
	
    return -1;	
}

int comm::FillChkFrame(BYTE *pFrame,int FrameLen)
{
	SWITCHPACKINFO	*pFrameHead;
	WORD			wLength;
	BYTE			TmpByte1,TmpByte2;
	BYTE			*pFrame1;
	WORD			wDataTmp;
	WORD			wSum;
	int				i;
	
	pFrameHead = (SWITCHPACKINFO *)(pFrame);
	
	ULENGTHCHKINFO LengthInfo;
	HexStrtoAsc((char *)&pFrameHead->Length1,&TmpByte1);
	HexStrtoAsc((char *)&pFrameHead->Length2,&TmpByte2);
	wDataTmp = TmpByte1;
	LengthInfo.wLengthAndChk = (wDataTmp<<8) | TmpByte2;

	wLength = (LengthInfo.LengthChkInfo.Length) + sizeof(SWITCHPACKINFO) + 5;

	if(FrameLen < wLength)
	{
		return -1;
	}
	
	LengthInfo.LengthChkInfo.ChkSum = ((~((LengthInfo.OthLengthChkInfo.Length1 + LengthInfo.OthLengthChkInfo.Length2 + LengthInfo.OthLengthChkInfo.Length3) % 16)) + 1) & 0x0F;
	
	TmpByte2 = LengthInfo.LengthChkInfo.ChkSum;

    if(TmpByte2 > 9)
    {
        TmpByte1=(BYTE)(TmpByte2-10+0x41);
    }
	else
    {
        TmpByte1=(BYTE)(TmpByte2+0x30);
    }

    BYTE *pSumData;
    pSumData = (BYTE *)(&pFrameHead->Length1);
    *pSumData = TmpByte1;

	pFrame1 = pFrame + 1;
	wSum = 0;

	for(i = 0;i < wLength-6;i++)
	{
		wSum += pFrame1[i];		
	}        
			
	wSum = (~(wSum % 65536)) + 1;
	
	TmpByte1 = (wSum >> 8);
	
	wDataTmp = HexToAsc(TmpByte1);
	
	memcpy(((char *)pFrame + (LengthInfo.LengthChkInfo.Length) + sizeof(SWITCHPACKINFO)),&wDataTmp,2);

	TmpByte1 = wSum;
	
	wDataTmp = HexToAsc(TmpByte1);
	
	memcpy(((char *)pFrame + (LengthInfo.LengthChkInfo.Length) + sizeof(SWITCHPACKINFO) + 2),&wDataTmp,2);	
	
    pFrame[FrameLen-1] = 0x0D;
	return 1;
}

int comm::SendSwitchAudio(bool SingleSwitch,unsigned char AudioPort)
{
    SWITCHAUDIOINFO     *pSwitchInfo;
    SWITCHPACKINFO	    *pFrameHead;
	WORD			    wDataTemp;
    pFrameHead = (SWITCHPACKINFO *)m_pSendBuff;
    
    printf("comm::SendSwitchAudio,SingleSwitch=%d,AudioPort=%d\n",SingleSwitch,AudioPort);
    pFrameHead->Header = 0x7E;

    wDataTemp = HexToAsc(0x10);
    pFrameHead->Version = wDataTemp;

    wDataTemp = HexToAsc(0x01);
    pFrameHead->Addr = wDataTemp;

    wDataTemp = HexToAsc(0xDD);
    pFrameHead->CID1 = wDataTemp;

    wDataTemp = HexToAsc(0x81);
    pFrameHead->CID2 = wDataTemp;

    wDataTemp = HexToAsc(0x00);
    pFrameHead->Length1 = wDataTemp;

    wDataTemp = HexToAsc(0x04);
    pFrameHead->Length2 = wDataTemp;

    pSwitchInfo = (SWITCHAUDIOINFO *)(m_pSendBuff + sizeof(SWITCHPACKINFO));
    if(SingleSwitch)
    {
        wDataTemp = HexToAsc(0x00);
    }
    else
    {
        wDataTemp = HexToAsc(0x01);   
    }
    pSwitchInfo->SingleFlag = wDataTemp;

    wDataTemp = HexToAsc(AudioPort);
    pSwitchInfo->AudioInfo = wDataTemp;
    
    FillChkFrame((BYTE *)m_pSendBuff,sizeof(SWITCHPACKINFO) + sizeof(SWITCHAUDIOINFO) + 5);
    printf("comm send\n");
    for(int i = 0;i < (sizeof(SWITCHPACKINFO) + sizeof(SWITCHAUDIOINFO) + 5);i++)
    {   
        printf("%02X ",m_pSendBuff[i]);
        if((i + 1) % 20 == 0)
        {
            printf("\n");
        }
    }
    printf("\n");
    Send(m_pSendBuff,sizeof(SWITCHPACKINFO) + sizeof(SWITCHAUDIOINFO) + 5);

    return 1;
}

int comm::SendAudioBroadcast()
{
    SWITCHAUDIOINFO     *pSwitchInfo;
    SWITCHPACKINFO	    *pFrameHead;
	WORD			    wDataTemp;
    pFrameHead = (SWITCHPACKINFO *)m_pSendBuff;
    
    pFrameHead->Header = 0x7E;

    wDataTemp = HexToAsc(0x10);
    pFrameHead->Version = wDataTemp;

    wDataTemp = HexToAsc(0x01);
    pFrameHead->Addr = wDataTemp;

    wDataTemp = HexToAsc(0xDD);
    pFrameHead->CID1 = wDataTemp;

    wDataTemp = HexToAsc(0x82);
    pFrameHead->CID2 = wDataTemp;

    wDataTemp = HexToAsc(0x00);
    pFrameHead->Length1 = wDataTemp;

    wDataTemp = HexToAsc(0x04);
    pFrameHead->Length2 = wDataTemp;
    
    FillChkFrame((BYTE *)m_pSendBuff,sizeof(SWITCHPACKINFO) + 5);

    Send(m_pSendBuff,sizeof(SWITCHPACKINFO) + 5);

    return 1;
}

WORD comm::HexToAsc(BYTE bAsc)
{
    //TODO: Add your source code here
    BYTE    bTemp;
    BYTE    bDataTmp[2];
	WORD	wReturn;
    if((bTemp=((bAsc & 0xf0)/16)) > 9)
    {
        bDataTmp[0]=(BYTE)(bTemp-10+0x41);
    }
	else
    {
        bDataTmp[0]=(BYTE)(bTemp+0x30);
    }

	if((bTemp = (bAsc & 0x0f))>9)
    {
        bDataTmp[1]=(BYTE)(bTemp-10+0x41);
    }
	else
    {
        bDataTmp[1]=(BYTE)(bTemp+0x30);
    }
	
	wReturn = (bDataTmp[0]) + (bDataTmp[1]<<8);
	return wReturn;
}

void	comm::SetProtocolThread(class PROTOCOL *pProtocol)
{
	m_pProtocol = pProtocol;
}
#endif