ntp.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. #include "ntp.h"
  2. #include <memory.h>
  3. #include <utils/TimeHelper.h>
  4. #include "net.h"
  5. ntp::ntp() {
  6. }
  7. ntp::~ntp() {
  8. }
  9. bool ntp::get_from(const std::string& ip, struct tm* t) {
  10. net::Conn* conn = net::Dial("udp", ip + ":123", 1000);
  11. if (conn == NULL) {
  12. LOGE("Dial failed");
  13. return false;
  14. }
  15. typedef struct {
  16. uint8_t li_vn_mode; // Eight bits. li, vn, and mode.
  17. // li. Two bits. Leap indicator.
  18. // vn. Three bits. Version number of the protocol.
  19. // mode. Three bits. Client will pick mode 3 for client.
  20. uint8_t stratum; // Eight bits. Stratum level of the local clock.
  21. uint8_t poll; // Eight bits. Maximum interval between successive messages.
  22. uint8_t precision; // Eight bits. Precision of the local clock.
  23. uint32_t rootDelay; // 32 bits. Total round trip delay time.
  24. uint32_t rootDispersion; // 32 bits. Max error aloud from primary clock source.
  25. uint32_t refId; // 32 bits. Reference clock identifier.
  26. uint32_t refTm_s; // 32 bits. Reference time-stamp seconds.
  27. uint32_t refTm_f; // 32 bits. Reference time-stamp fraction of a second.
  28. uint32_t origTm_s; // 32 bits. Originate time-stamp seconds.
  29. uint32_t origTm_f; // 32 bits. Originate time-stamp fraction of a second.
  30. uint32_t rxTm_s; // 32 bits. Received time-stamp seconds.
  31. uint32_t rxTm_f; // 32 bits. Received time-stamp fraction of a second.
  32. uint32_t txTm_s; // 32 bits and the most important field the client cares about. Transmit time-stamp seconds.
  33. uint32_t txTm_f; // 32 bits. Transmit time-stamp fraction of a second.
  34. } ntp_packet; // Total: 384 bits or 48 bytes.
  35. // Create and zero out the packet. All 48 bytes worth.
  36. ntp_packet packet = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  37. memset(&packet, 0, sizeof(ntp_packet));
  38. // 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.
  39. *((char *) &packet + 0) = 0x1b; // Represents 27 in base 10 or 00011011 in base 2.
  40. int n = conn->Write((byte*) &packet, (int)sizeof(ntp_packet));
  41. if (n < 0) {
  42. // LOGE("ERROR writing to socket\n");
  43. delete conn;
  44. return false;
  45. }
  46. // Wait and receive the packet back from the server. If n == -1, it failed.
  47. LOGD("synctime read start...\n");
  48. //n = recv(sockfd, (char*) &packet, sizeof(ntp_packet), MSG_DONTWAIT);
  49. n = conn->Read((byte*) &packet, (int)sizeof(ntp_packet), 3000);
  50. LOGE("read return %d", n);
  51. if (n < 0) {
  52. LOGE("ERROR reading from socket\n");
  53. delete conn;
  54. return false;
  55. }
  56. // These two fields contain the time-stamp seconds as the packet left the NTP server.
  57. // The number of seconds correspond to the seconds passed since 1900.
  58. // ntohl() converts the bit/byte order from the network's to host's "endianness".
  59. packet.txTm_s = ntohl(packet.txTm_s); // Time-stamp seconds.
  60. packet.txTm_f = ntohl(packet.txTm_f); // Time-stamp fraction of a second.
  61. // Extract the 32 bits that represent the time-stamp seconds (since NTP epoch) from when the packet left the server.
  62. // Subtract 70 years worth of seconds from the seconds since 1900.
  63. // This leaves the seconds since the UNIX epoch of 1970.
  64. // (1900)------------------(1970)**************************************(Time Packet Left the Server)
  65. const int64_t NTP_TIMESTAMP_DELTA = 2208988800ull;
  66. time_t txTm = (time_t) (packet.txTm_s - NTP_TIMESTAMP_DELTA);
  67. // Print the time we got from the server, accounting for local timezone and conversion from UTC time.
  68. // LOGD("Time: %s", ctime((const time_t*) &txTm));
  69. setenv("TZ", "GMT-8", 1);
  70. tzset();
  71. struct tm *o = localtime(&txTm);
  72. *t = *o;
  73. LOGD("ret: %d %d %d %d\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour);
  74. // updateAmPmText(t->tm_hour <12);
  75. delete conn;
  76. return true;
  77. }
  78. bool ntp::get(struct tm* out) {
  79. const char* host_name[] = {
  80. "120.25.115.20",
  81. "203.107.6.88",
  82. "182.92.12.11",
  83. "120.25.115.20",
  84. "103.11.143.248",
  85. "202.73.57.107",
  86. "158.69.48.97",
  87. "216.218.254.202",
  88. };
  89. for(unsigned int i =0;i< (sizeof(host_name)/sizeof(host_name[0]));i++){
  90. if (get_from(host_name[i], out)) {
  91. return true;
  92. }
  93. }
  94. return false;
  95. }
  96. NtpThread* NtpThread::getInstance(void)
  97. {
  98. static NtpThread NTP;
  99. return &NTP;
  100. }
  101. bool NtpThread::readyToRun() {
  102. LOGD("--%d-- --%s--\n 启动线程同步时间!!", __LINE__, __FILE__);
  103. return true;
  104. }
  105. bool NtpThread::threadLoop()
  106. {
  107. LOGD("--%d-- --%s--\n 同步时间!!", __LINE__, __FILE__);
  108. for(int level1 = 0; level1 <= reTry; ++level1)
  109. {
  110. ntp n;
  111. tm t;
  112. setenv("TZ", "GMT-8", 1);
  113. tzset();
  114. if (n.get(&t)) {
  115. if (TimeHelper::setDateTime(&t)) {
  116. LOGD("--%d-- --%s-- 成功设置时间!!", __LINE__, __FILE__);
  117. return false;
  118. }
  119. LOGD("--%d-- --%s-- 时间设置失败!!", __LINE__, __FILE__);
  120. continue;
  121. }
  122. }
  123. LOGD("--%d-- --%s-- 时间获取失败!!", __LINE__, __FILE__);
  124. return false;
  125. }