/* XSD_SNTP for X-Server Light. test with XS_09313.LIB */ #include #include #include #include #include "../lib/8000a.h" #include "../lib/tcpip32.h" #include "../lib/MFW.h" #define DEBUG 1 #define _SHOW_IP_ADDRESS_ void NTP_Fun( int skt); #define BUFSIZE 1460 /* read/write buffer size */ #define SNTP_ID 1 int TimeZone=8; /* for xs_09001.lib ~ xs_09003.lib need the next line. int TcpServerNumber=sizeof(TcpServer)/sizeof(TCP_SERVER); */ void MyUdpFun(int skt); UDP_SOCKET UdpNTP={ -1, //int socket; 0, //unsigned MyPort; "220.130.158.51", //char *RemoteIp; //"192.43.244.18" 123, //unsigned RemotePort; 1, //int fNonBlock; 0, //int fEnableBroadcast; 0, //int status; NTP_Fun //void (*CallBackFun)(int skt); }; //------------------------------------------------------------------------------ #define EPOCH_DIFF ((unsigned long) 86400*(365*70+17)) /* typedef struct { int year; char month,day,weekday; char hour,minute,sec; }TIME_DATE; void GetTimeDate(TIME_DATE *timedate); int SetTimeDate(TIME_DATE *timedate); */ // synctime: Synchronize the time. See RFC 1361 // return: Time offset that is synchronized unsigned long ttNTP_1, ttNTP_2; long T1,T4,T2,T3,Toff; void EpochToOSTime(unsigned long Val) { TIME_DATE td; struct time d_time; struct date d_date; unixtodos(Val, &d_date, &d_time); if(Toff > 1 || Toff < -1){ td.minute=d_time.ti_min; td.hour=d_time.ti_hour; td.sec=d_time.ti_sec; td.year=d_date.da_year; td.day=d_date.da_day; td.month=d_date.da_mon; SetTimeDate(&td); Print("\r\nSet new time to RTC"); } Print("\r\n-->[%04d/%02d/%02d %02d:%02d:%02d]", d_date.da_year, d_date.da_mon, d_date.da_day, d_time.ti_hour, d_time.ti_min, d_time.ti_sec); } /*----------------------------------------------------------------------------*/ long OSToEpochTime(void) { TIME_DATE td; int year, month, day, hour, min, sec; time_t t; /* The time_t value will not work after the hour of 3:14:07 on the year 01/19/2038. */ struct time d_time; struct date d_date; GetTimeDate(&td); d_time.ti_min=td.minute; d_time.ti_hour=td.hour; d_time.ti_hund=0; d_time.ti_sec=td.sec; d_date.da_year=td.year; d_date.da_day=td.day; d_date.da_mon=td.month; t=dostounix(&d_date, &d_time); // t = number of seconds since 00:00:00 on January 1, 1970 (GMT) return t; } /*----------------------------------------------------------------------------*/ //RFC 1361 : Simple Network Time Protocol (SNTP) int SNTP_Cli_send(int skt,int TimeZone) { int iRet; unsigned char buf[48]; // Send to the server memset(buf, 0x0, sizeof(buf)); // 00 001 011 - leap, ntp ver, client. See RFC 1361 buf[0]=(0<<6)|(1<<3)|3; // Get the local sent time - Originate Timestamp T1=OSToEpochTime()+EPOCH_DIFF-(TimeZone+4)*3600L; // Send to the server // memcpy(&buf[40], tonetnum((unsigned long) t1), 4); // Print("[%02X %02X %02X %02X]",buf[40],buf[41],buf[42],buf[43]); *(long *)(buf+40)=SwapLong(T1); // Print("[%02X %02X %02X %02X]\r\n",buf[40],buf[41],buf[42],buf[43]); // memset(&buf[44], 0x0, 4); // *(long *)(buf+44)=0L; // buf is already reset to 0 ttNTP_1=GetTimeTicks(); iRet=XS_WriteSocket(skt, buf, 48); return (iRet==48?0:-1); } /*----------------------------------------------------------------------------*/ unsigned CvtTime(unsigned char t) { return 10000L*t/256; } /*----------------------------------------------------------------------------*/ int SNTP_Cli_recv(int skt, int TimeZone) { int i, len; char NTPdata[64]; long Tnew,dT; /* Read from the server */ len=recv(skt, NTPdata, 64, 0); if(len<0) { #if DEBUG > 0 Print("recv error:%d,errno=%d\r\n", len,errno); #endif return 0; } // Get the local received time ttNTP_2=GetTimeTicks(); #if DEBUG > 0 Print("",(dT=ttNTP_2-ttNTP_1)); #endif T4=OSToEpochTime()+EPOCH_DIFF-(TimeZone+4)*3600L;; // Get the remote Receive Timestamp #if DEBUG > 0 Print("\r\nReference time=%lu.%04u ",SwapLong(*(long *)(NTPdata+16)),CvtTime(NTPdata[20])); Print("\r\nOriginate time=%lu.%04u ",SwapLong(*(long *)(NTPdata+24)),CvtTime(NTPdata[28])); Print("\r\nT1 =%lu ",T1); Print("\r\nT4 =%lu ",T4); #endif // T2=(unsigned long) fromnetnum(&NTPdata[32]); T2=SwapLong(*(long *)(NTPdata+32)); //Print("\r\nReceived time=%lu.%lu ",tv2.tv_sec,SwapLong(*(long *)(NTPdata+36))); #if DEBUG > 0 Print("\r\nReceived time=%lu.%04u ",T2,CvtTime(NTPdata[36])); #endif // Get the remote Transmit Timestamp // T3=fromnetnum(&NTPdata[40]); T3=SwapLong(*(long *)(NTPdata+40)); #if DEBUG > 0 Print("\r\nTransmit time=%lu.%04u ",T3,CvtTime(NTPdata[44])); #endif // Calculate the time offset Toff=(T2+T3-T1-T4)/2; if((CvtTime(NTPdata[44])+dT*5)>5000) Toff++; #if DEBUG > 0 Print("[Toff=%ld]",Toff); #endif // Calculate the new time Tnew=T4+Toff+(4*60*60)-EPOCH_DIFF+(TimeZone*60*60); EpochToOSTime(Tnew); return Toff; } //------------------------------------------------------------------------------ void StartNTP(void) { int err; Print("<%lu:SNTP>\r\n",GetTimeTicks()); if(UdpNTP.socket>=0){ Print (" test1 "); err=SNTP_Cli_send(UdpNTP.socket,TimeZone); Print (" test2,err=%d ",err); if (err < 0) { /* write error */ Print( "UDP write error %d,errno=%d\r\n", err,errno ); XS_RemoveUdpSocket(&UdpNTP); } } else { Print("skt=%d\r\n",UdpNTP.socket); } DT_AddTimer(1,30000,SNTP_ID,StartNTP); } //------------------------------------------------------------------------------ unsigned char MyIp[4]; long LedTime; /*----------------------------------------------------------------------------*/ void ShowIp(void) { static int idx=0; int data; LedToggle(); data=MyIp[idx]; idx++; #ifndef _NO_LED5_ Show5DigitLedWithDot(1,idx); Show5DigitLed(5,data%10); data/=10; if(data){ Show5DigitLed(4,data%10); data/=10; if(data) Show5DigitLed(3,data); else Show5DigitLed(3,16); } else { Show5DigitLed(4,16); Show5DigitLed(3,16); } Show5DigitLed(2,16); #endif if(idx>=4) idx=0; } /*----------------------------------------------------------------------------*/ char *GetModuleName(void) /* User's program must support this function for UDP search */ { return "i-7186E-XS" ; } char *GetAliasName(void) /* User's program must support this function for UDP search */ { return "test1" ; } /*----------------------------------------------------------------------------*/ void XS_UserInit(int argc,char *argv[]) { extern int bAcceptBroadcast; extern unsigned long ACKDELAY; /* vaariable in tcp.c */ extern long MAXTXTOUT; void UserLoop(void); char version[20]; char MsgTest[]="command"; int MsgTest_len=sizeof(MsgTest); InitLib(); Print("[%lu]\r\n",GetTimeTicks()); Print("sizeof(MsgTest)=%d\r\n",MsgTest_len); bAcceptBroadcast=0; ACKDELAY=200; XS_GetVersion(version); Print("[X-Server library]: version=%s ",version); XS_GetLibDate(version); Print("date=%s\r\n",version); GetTcpipLibDate(version); Print("Tcpip library version:%X, Library Date is %s\r\n",GetTcpipLibVer(),version); GetIp(MyIp); Print("IP=%d.%d.%d.%d\r\n",MyIp[0],MyIp[1],MyIp[2],MyIp[3]); LedTime=GetTimeTicks(); /* for xs_09001.lib ~ xs_09003.lib NEED NOT the next 4 lines. */ XS_AddSystemLoopFun(UserLoop); /* need add this line for the library 0.9.100 date after 2004/06/02 */ /* Add UDP search function */ XS_AddUdpSocket(&XS_UdpSearch); bAcceptBroadcast=1; // 記得要設定成可以接收廣播封包 /* Add UDP telnet client */ XS_AddUdpSocket(&UdpNTP); DT_AddTimer(1,3000,SNTP_ID,StartNTP); #ifdef _SHOW_IP_ADDRESS_ //DT2_AddTimer(500,2,ShowIp); DT_AddTimer(20,500,2,ShowIp); #endif EnableWDT(); MAXTXTOUT=6000UL; /* For Ver. 0.9.3.00 must add the following 2 lines. */ XS_AddSystemLoopFun(XS_SocketLoopFun); XS_StartSocket(); /* function for */ } /*----------------------------------------------------------------------------*/ void XS_UserEnd(void) { XS_StopSocket();/* For Ver. 0.9.3.00 must add this line. */ DisableWDT(); } /*----------------------------------------------------------------------------*/ extern int errno; void UserLoop(void) { long tmpt; int key,err; RefreshWDT(); if(Kbhit()){ switch((key=Getch())){ case 27: QuitMain=1; break; case 't': StartNTP(); break; } } } void NTP_Fun(int skt) { SNTP_Cli_recv(skt, TimeZone); } /* XS 0.9.200 or later must add the function main() */ void main(int argc,char *argv[]) { XS_main(argc,argv); /* call the XS library main function. */ }