1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
/*
* SNTP support driver
*
* Masami Komiya <mkomiya@sonare.it> 2005
*
*/
#include <common.h>
#include <command.h>
#include <dm.h>
#include <log.h>
#include <net.h>
#include <rtc.h>
#include <net/sntp.h>
#define SNTP_TIMEOUT 10000UL
static int sntp_our_port;
/* NTP server IP address */
struct in_addr net_ntp_server;
/* offset time from UTC */
int net_ntp_time_offset;
static void sntp_send(void)
{
struct sntp_pkt_t pkt;
int pktlen = SNTP_PACKET_LEN;
int sport;
debug("%s\n", __func__);
memset(&pkt, 0, sizeof(pkt));
pkt.li = NTP_LI_NOLEAP;
pkt.vn = NTP_VERSION;
pkt.mode = NTP_MODE_CLIENT;
memcpy((char *)net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE,
(char *)&pkt, pktlen);
sntp_our_port = 10000 + (get_timer(0) % 4096);
sport = NTP_SERVICE_PORT;
net_send_udp_packet(net_server_ethaddr, net_ntp_server, sport,
sntp_our_port, pktlen);
}
static void sntp_timeout_handler(void)
{
puts("Timeout\n");
net_set_state(NETLOOP_FAIL);
return;
}
static void sntp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
unsigned src, unsigned len)
{
#ifdef CONFIG_TIMESTAMP
struct sntp_pkt_t *rpktp = (struct sntp_pkt_t *)pkt;
struct rtc_time tm;
ulong seconds;
#endif
debug("%s\n", __func__);
if (dest != sntp_our_port)
return;
#ifdef CONFIG_TIMESTAMP
/*
* As the RTC's used in U-Boot support second resolution only
* we simply ignore the sub-second field.
*/
memcpy(&seconds, &rpktp->transmit_timestamp, sizeof(ulong));
rtc_to_tm(ntohl(seconds) - 2208988800UL + net_ntp_time_offset, &tm);
#if defined(CONFIG_CMD_DATE)
# ifdef CONFIG_DM_RTC
struct udevice *dev;
int ret;
ret = uclass_get_device(UCLASS_RTC, 0, &dev);
if (ret)
printf("SNTP: cannot find RTC: err=%d\n", ret);
else
dm_rtc_set(dev, &tm);
# else
rtc_set(&tm);
# endif
#endif
printf("Date: %4d-%02d-%02d Time: %2d:%02d:%02d\n",
tm.tm_year, tm.tm_mon, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec);
#endif
net_set_state(NETLOOP_SUCCESS);
}
/*
* SNTP:
*
* Prerequisites: - own ethernet address
* - own IP address
* We want: - network time
* Next step: none
*/
int sntp_prereq(void *data)
{
if (net_ntp_server.s_addr == 0) {
puts("*** ERROR: NTP server address not given\n");
return 1;
}
return 0;
}
int sntp_start(void *data)
{
debug("%s\n", __func__);
net_set_timeout_handler(SNTP_TIMEOUT, sntp_timeout_handler);
net_set_udp_handler(sntp_handler);
memset(net_server_ethaddr, 0, sizeof(net_server_ethaddr));
sntp_send();
return 0;
}
|