#include "ntp.h" #include #include #include "net.h" ntp::ntp() { } ntp::~ntp() { } bool ntp::get_from(const std::string& ip, struct tm* t) { net::Conn* conn = net::Dial("udp", ip + ":123", 1000); if (conn == NULL) { LOGE("Dial failed"); return false; } typedef struct { uint8_t li_vn_mode; // Eight bits. li, vn, and mode. // li. Two bits. Leap indicator. // vn. Three bits. Version number of the protocol. // mode. Three bits. Client will pick mode 3 for client. uint8_t stratum; // Eight bits. Stratum level of the local clock. uint8_t poll; // Eight bits. Maximum interval between successive messages. uint8_t precision; // Eight bits. Precision of the local clock. uint32_t rootDelay; // 32 bits. Total round trip delay time. uint32_t rootDispersion; // 32 bits. Max error aloud from primary clock source. uint32_t refId; // 32 bits. Reference clock identifier. uint32_t refTm_s; // 32 bits. Reference time-stamp seconds. uint32_t refTm_f; // 32 bits. Reference time-stamp fraction of a second. uint32_t origTm_s; // 32 bits. Originate time-stamp seconds. uint32_t origTm_f; // 32 bits. Originate time-stamp fraction of a second. uint32_t rxTm_s; // 32 bits. Received time-stamp seconds. uint32_t rxTm_f; // 32 bits. Received time-stamp fraction of a second. uint32_t txTm_s; // 32 bits and the most important field the client cares about. Transmit time-stamp seconds. uint32_t txTm_f; // 32 bits. Transmit time-stamp fraction of a second. } ntp_packet; // Total: 384 bits or 48 bytes. // Create and zero out the packet. All 48 bytes worth. ntp_packet packet = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; memset(&packet, 0, sizeof(ntp_packet)); // Set the first byte's bits to 00,011,011 for li = 0, vn = 3, and mode = 3. The rest will be left set to zero. *((char *) &packet + 0) = 0x1b; // Represents 27 in base 10 or 00011011 in base 2. int n = conn->Write((byte*) &packet, (int)sizeof(ntp_packet)); if (n < 0) { // LOGE("ERROR writing to socket\n"); delete conn; return false; } // Wait and receive the packet back from the server. If n == -1, it failed. LOGD("synctime read start...\n"); //n = recv(sockfd, (char*) &packet, sizeof(ntp_packet), MSG_DONTWAIT); n = conn->Read((byte*) &packet, (int)sizeof(ntp_packet), 3000); LOGE("read return %d", n); if (n < 0) { LOGE("ERROR reading from socket\n"); delete conn; return false; } // These two fields contain the time-stamp seconds as the packet left the NTP server. // The number of seconds correspond to the seconds passed since 1900. // ntohl() converts the bit/byte order from the network's to host's "endianness". packet.txTm_s = ntohl(packet.txTm_s); // Time-stamp seconds. packet.txTm_f = ntohl(packet.txTm_f); // Time-stamp fraction of a second. // Extract the 32 bits that represent the time-stamp seconds (since NTP epoch) from when the packet left the server. // Subtract 70 years worth of seconds from the seconds since 1900. // This leaves the seconds since the UNIX epoch of 1970. // (1900)------------------(1970)**************************************(Time Packet Left the Server) const int64_t NTP_TIMESTAMP_DELTA = 2208988800ull; time_t txTm = (time_t) (packet.txTm_s - NTP_TIMESTAMP_DELTA); // Print the time we got from the server, accounting for local timezone and conversion from UTC time. // LOGD("Time: %s", ctime((const time_t*) &txTm)); setenv("TZ", "GMT-8", 1); tzset(); struct tm *o = localtime(&txTm); *t = *o; LOGD("ret: %d %d %d %d\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour); // updateAmPmText(t->tm_hour <12); delete conn; return true; } bool ntp::get(struct tm* out) { const char* host_name[] = { "120.25.115.20", "203.107.6.88", "182.92.12.11", "120.25.115.20", "103.11.143.248", "202.73.57.107", "158.69.48.97", "216.218.254.202", }; for(unsigned int i =0;i< (sizeof(host_name)/sizeof(host_name[0]));i++){ if (get_from(host_name[i], out)) { return true; } } return false; } NtpThread* NtpThread::getInstance(void) { static NtpThread NTP; return &NTP; } bool NtpThread::readyToRun() { LOGD("--%d-- --%s--\n 启动线程同步时间!!", __LINE__, __FILE__); return true; } bool NtpThread::threadLoop() { LOGD("--%d-- --%s--\n 同步时间!!", __LINE__, __FILE__); for(int level1 = 0; level1 <= reTry; ++level1) { ntp n; tm t; setenv("TZ", "GMT-8", 1); tzset(); if (n.get(&t)) { if (TimeHelper::setDateTime(&t)) { LOGD("--%d-- --%s-- 成功设置时间!!", __LINE__, __FILE__); return false; } LOGD("--%d-- --%s-- 时间设置失败!!", __LINE__, __FILE__); continue; } } LOGD("--%d-- --%s-- 时间获取失败!!", __LINE__, __FILE__); return false; }