TwlToolsRED/build/tools/sctools/copy_dst/src/ntp.c

370 lines
10 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <twl.h>
#include <nitroWiFi.h>
#include "ntp.h"
#include "font.h"
#include "text.h"
#include "mprintf.h"
#include "logprintf.h"
#include "mywlan.h"
#define BUFSIZE 256 /* バッファサイズ */
#define RECVSIZE 4096 /* 受信バッファサイズ */
#define TIMEOUT 3 /* タイムアウト秒数 */
struct NTP_Packet{ /* NTPパケット */
int Control_Word;
int root_delay;
int root_dispersion;
int reference_identifier;
s64 reference_timestamp;
s64 originate_timestamp;
s64 receive_timestamp;
int transmit_timestamp_seconds;
int transmit_timestamp_fractions;
};
struct rtc_time {
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
};
#define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400)
#define LEAP_YEAR(year) ((!(year % 4) && (year % 100)) || !(year % 400))
static const unsigned char rtc_days_in_month[] = {
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
static int rtc_month_days(unsigned int month, unsigned int year)
{
return rtc_days_in_month[month] + (LEAP_YEAR(year) && month == 1);
}
/* Convert seconds since 01-01-1970 00:00:00 to Gregorian date. */
static void rtc_time_to_tm(unsigned long time, struct rtc_time *tm)
{
unsigned int month, year;
int days;
days = (int)(time / 86400 );
time -= (unsigned int) days * 86400;
/* day of the week, 1970-01-01 was a Thursday */
tm->tm_wday = (days + 4) % 7;
year = (unsigned int)(1970 + days / 365);
days -= (year - 1970) * 365
+ LEAPS_THRU_END_OF(year - 1)
- LEAPS_THRU_END_OF(1970 - 1);
if (days < 0) {
year -= 1;
days += 365 + LEAP_YEAR(year);
}
tm->tm_year = (int)(year - 1900);
tm->tm_yday = days + 1;
for (month = 0; month < 11; month++) {
int newdays;
newdays = days - rtc_month_days(month, year);
if (newdays < 0)
break;
days = newdays;
}
tm->tm_mon = (int)month;
tm->tm_mday = days + 1;
tm->tm_hour = (int)(time / 3600);
time -= tm->tm_hour * 3600;
tm->tm_min = (int)(time / 60);
tm->tm_sec = (int)(time - tm->tm_min * 60);
}
static char svName[BUFSIZE]; /* サーバのドメイン名 */
static unsigned short port = 123; /* サーバのポート番号 */
static unsigned short local_port = 1024; /* 受信するポート番号 */
static int soc; /* ソケットSoket Descriptor */
static unsigned long serveraddr; /* サーバのIPアドレス */
//static struct hostent *serverhostent; /* サーバの情報を指すポインタ */
static SOCHostEnt *serverhostent; /* サーバの情報を指すポインタ */
//static struct sockaddr_in sockname; /* ソケットのアドレス */
static SOCSockAddrIn sockname;
// static struct sockaddr_in serversockaddr; /* サーバのアドレス */
static SOCSockAddrIn serversockaddr; /* サーバのアドレス */
static int sockaddr_Size; /* サーバのアドレスのサイズ */
static struct NTP_Packet NTP_Send; /* 送信するNTPパケット */
static struct NTP_Packet NTP_Recv; /* 受信するNTPパケット */
static u32 ntp_time; /* NTPサーバから取得した時刻 */
static struct rtc_time tm;
int my_ntp_get_year(void)
{
return tm.tm_year+1900;
}
int my_ntp_get_month(void)
{
return tm.tm_mon;
}
int my_ntp_get_day(void)
{
return tm.tm_mday;
}
int my_ntp_get_weekday(void)
{
return tm.tm_wday;
}
int my_ntp_get_hour(void)
{
return tm.tm_hour;
}
int my_ntp_get_min(void)
{
return tm.tm_min;
}
int my_ntp_get_sec(void)
{
return tm.tm_sec;
}
BOOL my_ntp_init(void)
{
SOCPollFD pfds[1];
BOOL ret_flag = TRUE;
if( GetNTPSRV() == NULL ) {
OS_TPrintf("no NTP server entry\n");
mprintf("no NTP server entry\n");
return FALSE;
}
OS_TPrintf("NTP srv %s\n",GetNTPSRV() );
mprintf("NTP server: %s\n",GetNTPSRV() );
// STD_StrCpy(svName, "ntp.jst.mfeed.ad.jp" );
STD_StrCpy(svName, GetNTPSRV() );
/* ソケットを作成する処理 */
/* UDPモードでsocにソケットを作成します */
soc = SOC_Socket(SOC_PF_INET, SOC_SOCK_DGRAM, 0);
if(soc < 0 ){
OS_TPrintf("Error: create Socket\n");
mprintf("Error: create Socket\n");
return FALSE;
}
/* 受信ポートを指定する処理 */
/* ソケットのアドレスの構造体にサーバのIPアドレスとポート番号を設定します */
// SOSockAddrIn;
// int SOC_Bind(int s, const void* sockAddr);
// SOC_HtoNs(hostshort)
sockname.family = SOC_AF_INET; /* インターネットの場合 */
sockname.addr.addr = SOC_INADDR_ANY; /* 自分のIPアドレスを使うようにする */
sockname.port = SOC_HtoNs((unsigned short)local_port); /* 受信するポート番号 */
// STD_MemSet((void *)sockname.zero,(int)0,sizeof(sockname.zero));
if(SOC_Bind(soc, (void *)&sockname) < 0 ){
OS_TPrintf("Error: specify recv port\n");
mprintf("Error: invalid recv port %d\n",local_port);
ret_flag = FALSE;
goto exit_label1;
}
/* サーバのIPアドレスを取得する処理 */
/* svNameにドットで区切った10進数のIPアドレスが入っている場合、serveraddrに32bit整数のIPアドレスが返ります */
// SOCHostEnt* SOC_GetHostByName(const char* name);
// typedef struct SOCHostEnt
// {
// char* name; // official name of host
// char ** aliases; // alias list (zero-terminated)
// s16 addrType; // always SO_PF_INET
// s16 length; // length of address
// u8 ** addrList; // list of addresses
// } SOCHostEnt;
//
// int SOC_InetAtoN(const char* cp, SOCInAddr* inp);
//
// typedef struct SOCInAddr
// {
// u32 addr;
// } SOCInAddr;
//
// int SOC_Close(int s);
// serveraddr = (210) | (173 << 8) | (160 << 16) | (57 << 24);
// Addresses: 210.173.160.57, 210.173.160.87, 210.173.160.27
/* サーバ名(svName)からサーバのホスト情報を取得します */
serverhostent = SOC_GetHostByName(svName);
if(serverhostent == NULL) {
OS_TPrintf("Error: SOC_GetHostByName %s\n",svName);
mprintf("Error: SOC_GetHostByName %s\n",svName);
ret_flag = FALSE;
goto exit_label1;
}
else{
/* サーバのホスト情報からIPアドレスをserveraddrにコピーします */
serveraddr = *((unsigned long *)((serverhostent->addrList)[0]));
}
#if 1
OS_TPrintf("serveraddr = %d.%d.%d.%d\n",
((serveraddr >> 0) & 0xff),
((serveraddr >> 8) & 0xff),
((serveraddr >> 16) & 0xff),
((serveraddr >> 24) & 0xff) );
mprintf(" IP addr : %d.%d.%d.%d\n",
((serveraddr >> 0) & 0xff),
((serveraddr >> 8) & 0xff),
((serveraddr >> 16) & 0xff),
((serveraddr >> 24) & 0xff) );
#endif
/* サーバのアドレスの構造体にサーバのIPアドレスとポート番号を設定します */
serversockaddr.family = SOC_AF_INET; /* インターネットの場合 */
serversockaddr.addr.addr = serveraddr; /* サーバのIPアドレス */
serversockaddr.port = SOC_HtoNs((unsigned short)port); /* ポート番号 */
/* サーバにパケットを送信する処理 */
/* NTPパケットをSNTP用に初期化する */
// NTP_Send.Control_Word = htonl(0x0B000000);
NTP_Send.Control_Word = SOC_HtoNl(0x0B000000);
NTP_Send.root_delay = 0;
NTP_Send.root_dispersion = 0;
NTP_Send.reference_identifier = 0;
NTP_Send.reference_timestamp = 0;
NTP_Send.originate_timestamp = 0;
NTP_Send.receive_timestamp = 0;
NTP_Send.transmit_timestamp_seconds = 0;
NTP_Send.transmit_timestamp_fractions = 0;
/* サーバを指定してNTPパケットを送信する */
if(SOC_SendTo(soc,(const void *)&NTP_Send, sizeof( NTP_Send ),0,(const void *)&serversockaddr) < 0 ) {
OS_TPrintf("Error: サーバへの送信失敗\n");
mprintf("Error: SOC_SendTo\n");
ret_flag = FALSE;
goto exit_label1;
}
/* タイムアウトを行う処理 */
/* select関数を使ってタイムアウトを設定する */
//
// typedef struct SOCPollFD
// {
// int fd;
// short events; // input event flags
// short revents; // output event flags
// } SOCPollFD;
//
// int SOC_Poll(SOCPollFD fds[], unsigned nfds, OSTick timeout);
pfds[0].fd = soc;
// pfds[0].events = SOC_POLLRDNORM | SOC_POLLWRNORM;
pfds[0].events = SOC_POLLRDNORM;
if( SOC_Poll( pfds, 1, OS_MilliSecondsToTicks( TIMEOUT * 1000 ) ) < 0 ) {
OS_TPrintf("Error: recv error\n");
mprintf("Error: recv error\n");
ret_flag = FALSE;
goto exit_label1;
}
switch( pfds[0].revents ) {
case SOC_POLLERR: // ソケットにエラーが発生しました。
OS_TPrintf("Error: SOC_POLLERR %s %d\n",__FUNCTION__,__LINE__);
mprintf("Error: SOC_POLLERR %s %d\n",__FUNCTION__,__LINE__);
ret_flag = FALSE;
goto exit_label1;
break;
case SOC_POLLHUP: // ストリーム・ソケットが未接続です。
mprintf("Error: SOC_POLLHUP %s %d\n",__FUNCTION__,__LINE__);
ret_flag = FALSE;
goto exit_label1;
break;
case SOC_POLLNVAL: // 不正なソケット記述子です。
mprintf("Error: SOC_POLLNVAL %s %d\n",__FUNCTION__,__LINE__);
ret_flag = FALSE;
goto exit_label1;
break;
default:
break;
}
/* サーバから時刻情報を受信する処理 */
/* サーバを指定して受信を行う */
// int SOC_RecvFrom(int s, void* buf, int len, int flags, void* sockFrom);
sockaddr_Size = sizeof(serversockaddr);
if( SOC_RecvFrom(soc, (char *)&NTP_Recv, sizeof(NTP_Recv), SOC_MSG_DONTWAIT ,(void *)&serversockaddr) < 0 ){
OS_TPrintf("Error: SOC_RecvFrom\n");
mprintf("Error: SOC_RecvFrom\n");
ret_flag = FALSE;
goto exit_label1;
}
/* NTPサーバから取得した時刻を現地時間に変換する */
ntp_time = SOC_NtoHl(NTP_Recv.transmit_timestamp_seconds) - 2208988800; /* 1970/01/01 からの秒数に変換 */
OS_TPrintf("ntp_time = %d\n",ntp_time);
OS_TPrintf("TimeZone %d\n", GetTimeZone());
mprintf(" TimeZone : %d:%02d\n", (GetTimeZone()/60), (GetTimeZone()%60));
ntp_time += (60*GetTimeZone());
rtc_time_to_tm(ntp_time, &tm);
OS_TPrintf("Year %d\n", tm.tm_year+1900);
OS_TPrintf("Mon %d\n", tm.tm_mon + 1); /* 0 -> 1月 */
OS_TPrintf("Day %d\n", tm.tm_mday);
OS_TPrintf("Week %d\n", tm.tm_wday);
OS_TPrintf("Hour %d\n", tm.tm_hour);
OS_TPrintf("Min %d\n", tm.tm_min);
OS_TPrintf("Sec %d\n", tm.tm_sec);
// tm.tm_yday;
// tm.tm_isdst;
exit_label1:
/* ソケットを破棄する処理 */
(void)SOC_Close(soc);
return ret_flag;
}