窜口通信-读取时间码
/*******************************************************************************
* 功能:读取时间码,设置本地时间 *
* 文件: *
* 日期: 2007-08-30 *
* 版本: 1.0 *
* 作者: *
* 网站: *
********************************************************************************/
#include <sys/types.h>
#include <sys/socket.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <stdio.h>
#include <time.h>
#include <signal.h>
#include <sys/errno.h>
#include <string.h>
#include <sys/time.h>
#include <stdlib.h>
int fd;
/********************************************************************
函 数 名:gps_open()
功 能:打开指定的串口设备,设置波特率
说 明:lpDevice 对应串口n为/dev/ttySn-1,也可以用
mknod -m 660 /dev/gps1 c 4 65 创建
入口参数:lpDevice 串口设备文件 nSpeed 波特率B+speed
返 回 值:成功 0 失败 -1
设 计:太福特电子
***********************************************************************/
int gps_open(char *lpDevice,int nSpeed)
{
struct termios oldios,newios;
int fd;
char log[80];
fd = open(lpDevice, O_RDWR | O_NOCTTY);
if (fd < 0)
{
sprintf(log,"Open device %s error!",lpDevice);
perror(log);
return -1;
}
tcgetattr(fd,&oldios);
bzero(&newios,sizeof(newios));
newios.c_cflag = nSpeed | CS8 | CLOCAL | CREAD;
//newios.c_cflag &=~CRTSCTS;
newios.c_iflag = IGNPAR;
newios.c_oflag = 0;
newios.c_lflag = 0;
newios.c_cc[VTIME] = 0;
newios.c_cc[VMIN] = 1;
tcflush(fd,TCIFLUSH);
tcsetattr(fd,TCSANOW,&newios);
return fd;
}
/********************************************************************
函 数 名:gps_read()
功 能:读取串口gps时间电文信息
说 明:每次返回一种类型的电文
入口参数:fd 文件句柄 pData 数据缓存地址 nSize 最大长度
返 回 值:成功 实际长度 失败 -1
设 计:太福特电子
***********************************************************************/
int gps_read(int fd,char *pData,int nSize)
{
int nRet;
int nRead;
nRead=0;
while (nRead<nSize)
{
nRet = read(fd,pData+nRead,1);
if(nRet<0)
{
if(errno==EINTR)
continue;
else
continue;
}
if(pData[0]!='$')
{
nRead=0;
memset(pData,0,nSize);
continue;
}
if(nRead > 1)
{
if(pData[nRead-1]==0x0d&&pData[nRead]==0x0a)
{
nRet=nRead;
break;
}
}
nRead++;
}
return nRet;
}
/********************************************************************
函 数 名:gps_write()
功 能:写入串口ntp状态信息
说 明:
入口参数:fd 文件句柄 pData 数据缓存地址 nSize 写入长度
返 回 值:成功 实际长度 失败 -1
设 计:太福特电子
***********************************************************************/
int gps_write(int fd,char *pData,int nSize)
{
int nRet;
nRet=write(fd,pData,nSize);
return nRet;
}
/********************************************************************
函 数 名:gps_close()
功 能:关闭串口
说 明:
入口参数:fd 文件句柄
返 回 值:
设 计:太福特电子
***********************************************************************/
int gps_close(int fd)
{
return close(fd);
}
static char *
field_parse(
char *cp,
int fn
)
{
char *tp;
int i = fn;
for (tp = cp; *tp != '\0'; tp++) {
if (*tp == ',')
i--;
if (i == 0)
break;
}
return (++tp);
}
int gps_settime(char *timecode)
{
char *cp;
char *dp;
char lptime[256];
int bRet=1;
char acDay[8];
char acMonth[8];
char acYear[8];
char acHour[8];
char acMin[8];
char acSec[8];
int nDays;
int nYear;
int nMonth;
int nDay;
int nHour;
int nMin;
int nSec;
struct tm tmgps;
time_t codetime;
struct timeval tv;
struct timezone tz;
cp = timecode;
dp = field_parse(cp,3);
if( dp[0] != '0')
{
bRet=0;
}
if(bRet==1)
{
dp = field_parse(cp,1);
memset(acDay,0,8);
strncpy(acDay,dp+2,2);
nDay=atoi(acDay);
memset(acMonth,0,8);
strncpy(acMonth,dp,2);
nMonth=atoi(acMonth);
memset(acYear,0,8);
strncpy(acYear,dp+4,2);
nYear=atoi(acYear)+2000;
dp = field_parse(cp,2);
memset(acHour,0,8);
memset(acMin,0,8);
memset(acSec,0,8);
strncpy(acHour,dp,2);
strncpy(acMin,dp+2,2);
strncpy(acSec,dp+4,2);
nHour=atoi(acHour);
nMin=atoi(acMin);
nSec=atoi(acSec);
sprintf(lptime,"%04d-%02d-%02d %02d:%02d:%02d",nYear,nMonth,nDay,nHour,nMin,nSec);
strptime(lptime, "%Y-%m-%d %H:%M:%S", &tmgps);
codetime = mktime(&tmgps);
gettimeofday(&tv, &tz);
tv.tv_sec=codetime+tz.tz_minuteswest*-60;
tv.tv_usec = 399000;
settimeofday(&tv, &tz);
/*sprintf(lptime,"$datetime,%02d%02d%02d,%02d%02d%02d,*hh\r\n",nDay,nMonth,nYear-2000,nHour,nMin,nSec);
gps_write(fd,lptime,strlen(lptime));*/
}
return bRet;
}
int
main()
{
int nRet,i;
int ncount=0;
char buf[256];
fd=gps_open("/dev/ttyS3",B115200);/*根据实际情况修改串口*/
if(fd<0)
{
perror("Open gps error!");
return -1;
}
// daemon(0, 0);/*以后台方式运行*/
while(1)
{
memset(buf,0,256);
nRet=gps_read(fd,buf,256);
//nRet = read(fd,buf,256);
printf("get word=%s",buf);
if(nRet<0)
{
if(errno==EINTR)
continue;
else
break;
}
else
{
if(strncmp(buf,"$SYS",4)==0)
{
printf("%s\r\n",buf);
nRet=gps_settime(buf);
if(nRet==1)
{
ncount++;
if( ncount > 30 )
{
gps_close(fd);
system("/sbin/hwclock -w");
system("/usr/local/bin/ntpd");
break;
}
}
}
}
}
return 0;
}