#include "phycom.h"
#if (ACTUAL_OS == OS_LINUX) || (ACTUAL_OS == OS_UCLINUX) || (ACTUAL_OS == OS_UNIX)
#ifndef WIN32
/*
PhyChnlConfig comConfig;
comConfig.speed = para->comConfig.baudrate;
comConfig.databits = 8;
comConfig.stopbits = 1;
comConfig.parity = para->comConfig.parity;
comConfig.timeout = 500;
sprintf(comConfig.dev,"/dev/ttyO%d",5 - para->comConfig.phyPort);
PhysicalCom* pPhy = new PhysicalCom(&comConfig,para->comConfig.port);
*/
PhysicalCom::PhysicalCom(PhyChnlConfig* pConfig,int channelId):TPhyLayer(channelId)
{
fd = open( pConfig->dev, O_RDWR|O_NDELAY);
phyConfig=pConfig;
InitDev(fd,pConfig->speed,pConfig->databits,pConfig->stopbits,pConfig->parity,pConfig->timeout);
chnlOpened=false;
//maxConnetTime = 3;
}
//////////////////////////////////////////////////////////////////////
int PhysicalCom::InitDev(int fd,int speed, int databits, int stopbits, int parity, int timeout)
{
setSpeed(fd,speed);
if (setParity(fd, databits, stopbits, parity, timeout) < 0)
{
//printf("Set Parity Error\n");
initialized = false;
return -1;
}
setRawIo( fd );
initialized = true;
//printf("Set Parity right %d\n",initialized);
return 0;
}
//////////////////////////////////////////////////////////////////////
void PhysicalCom::setSpeed(int fd, int speed)
{
int speedArr[]={B57600,B38400,B19200,B9600,B4800,B2400,B1200, B300, B57600, B38400, B19200, B9600, B4800, B2400, B1200, B300};
int nameArr[]={57600, 38400, 19200, 9600, 4800, 2400, 1200, 300,57600, 38400, 19200,9600, 4800, 2400, 1200, 300};
int i;
int status;
struct termios Opt;
tcgetattr(fd, &Opt);
for ( i= 0; i < sizeof(speedArr) / sizeof(int); i++)
{
if (speed == nameArr[i])
{
tcflush(fd, TCIOFLUSH);
cfsetispeed(&Opt, speedArr[i]);
cfsetospeed(&Opt, speedArr[i]);
status = tcsetattr(fd, TCSANOW, &Opt);
if (status != 0)
{
initialized = false;
//perror("tcsetattr fd1");
}
return;
}
tcflush(fd,TCIOFLUSH);
}
}
//////////////////////////////////////////////////////////////////////
int PhysicalCom::setParity(int fd,int databits,int stopbits,int parity, int timeout)
{
struct termios options;
if( tcgetattr( fd,&options) != 0)
{
//perror("SetupSerial 1");
return -1;
}
options.c_cflag &= ~CSIZE;
switch (databits) /*设置数据位数*/
{
case 7:
options.c_cflag |= CS7;
break;
case 8:
options.c_cflag |= CS8;
break;
default:
//fprintf(stderr,"Unsupported data size\n");
return -1;
}
switch (parity)
{
case 0:
options.c_cflag &= ~PARENB; /* Clear parity enable */
options.c_iflag &= ~INPCK; /* Enable parity checking */
break;
case 1:
options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/
options.c_iflag |= INPCK; /* Disnable parity checking */
break;
case 2:
options.c_cflag |= PARENB; /* Enable parity */
options.c_cflag &= ~PARODD; /* 转换为偶效验*/
options.c_iflag |= INPCK; /* Disnable parity checking */
break;
case 3:
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
break;
default:
//fprintf(stderr,"Unsupported parity\n");
return -1;
}
/* 设置停止仿/
switch (stopbits)
{
case 1:
options.c_cflag &= ~CSTOPB;
break;
case 2:
options.c_cflag |= CSTOPB;
break;
default:
//fprintf(stderr,"Unsupported stop bits\n");
return -1;
}
/* Set input parity option */
options.c_cc[VTIME] = timeout; /* 不使用分割字元組的計時器 */
options.c_cc[VMIN] = 0; /* 在讀取到 1 個字元前先停櫿*/
options.c_cc[VINTR] = 0; /* Ctrl-c */
options.c_cc[VQUIT] = 0; /* Ctrl-\ */
options.c_cc[VERASE] = 0; /* del */
options.c_cc[VKILL] = 0; /* @ */
options.c_cc[VEOF] = 4; /* Ctrl-d */
options.c_cc[VSWTC] = 0; /* '\0' */
options.c_cc[VSTART] = 0; /* Ctrl-q */
options.c_cc[VSTOP] = 0; /* Ctrl-s */
options.c_cc[VSUSP] = 0; /* Ctrl-z */
options.c_cc[VEOL] = 0; /* '\0' */
options.c_cc[VREPRINT] = 0; /* Ctrl-r */
options.c_cc[VDISCARD] = 0; /* Ctrl-u */
options.c_cc[VWERASE] = 0; /* Ctrl-w */
options.c_cc[VLNEXT] = 0; /* Ctrl-v */
options.c_cc[VEOL2] = 0; /* '\0' */
tcflush(fd,TCIFLUSH); /* Update the options and do it NOW */
if (tcsetattr(fd,TCSANOW,&options) != 0)
{
//perror("SetupSerial 3");
return -1;
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////
void PhysicalCom::setRawIo( int fd ) //set input and output in raw mode
{
struct termios options;
if ( tcgetattr( fd,&options) != 0)
{
initialized = false;
//perror("SetupSerial 4");
return;
}
options.c_iflag &=~(IXON|IXOFF|IXANY|ICRNL);
options.c_lflag=0;
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*Input*/
options.c_oflag &= ~OPOST; /*Output*/
tcflush(fd,TCIFLUSH); /* Update the options and do it NOW */
if (tcsetattr(fd,TCSANOW,&options) != 0)
{
initialized = false;
//perror("SetupSerial 5");
return;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////
bool PhysicalCom::openChannel()
{
//printf("physical openchannel");
if(chnlOpened)
{
return true;
}
if(!initialized)
{
fd = open( phyConfig->dev, O_RDWR);
InitDev(fd,phyConfig->speed,phyConfig->databits,phyConfig->stopbits,phyConfig->parity,phyConfig->timeout);
}
if(initialized)
{
chnlOpened=true;
//printf("open channel succeed!\n");
return true;
}
else
{
//printf("open channel failed!\n");
return false;
}
}
//////////////////////////////////////////////////////////////////////////////////////
void PhysicalCom::closeChannel()
{
close(fd);
initialized=false;
chnlOpened=false;
}
/////////////////////////////////////////////////////////////////////////////////////
int PhysicalCom::recv(char *buf,int length)
{
int nTemp;
if (chnlOpened)
{
nTemp = read(fd,buf,length);
if(nTemp>0)
{
/*
printf("phy rec:");
for(int i=0;i<nTemp;i++)
{
printf("%02x",buf[i]);
}
printf("\n");*/
return nTemp;
}
else
{
return 0;
}
}
else
return 0;
}
//////////////////////////////////////////////////////////////////////////////
bool PhysicalCom::send(char *buf,int length)
{
int nWrite=0;
if (chnlOpened)
{
while(nWrite!=length)
{
nWrite+=write(fd,buf+nWrite,length-nWrite);
}
/*
printf("phy send:");
for(int i=0;i<length;i++)
{
printf("%02x",buf[i]);
}
printf("\n");*/
return true;
}
else
{
return false;
}
}
PhysicalCom::~PhysicalCom()
{
if(chnlOpened)
{
closeChannel();
}
}
#endif
#endif
///////////////////////////////////////////////////////////////////////////////