1*4882a593Smuzhiyun #include "datetimewidget.h"
2*4882a593Smuzhiyun #include "ui_datetimewidget.h"
3*4882a593Smuzhiyun #include <QTimer>
4*4882a593Smuzhiyun #include <QDebug>
5*4882a593Smuzhiyun #include "terminal.h"
6*4882a593Smuzhiyun #include <QTimeZone>
7*4882a593Smuzhiyun #include "terminal.h"
8*4882a593Smuzhiyun #include <QDateTime>
9*4882a593Smuzhiyun #include "messagebox.h"
10*4882a593Smuzhiyun #include "systemmanager.h"
11*4882a593Smuzhiyun #include <QLocale>
12*4882a593Smuzhiyun #include <QTimeZone>
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun Q_LOGGING_CATEGORY(flapp, "app.rtc")
DateTimeWidget(QWidget * parent)15*4882a593Smuzhiyun DateTimeWidget::DateTimeWidget( QWidget *parent) :
16*4882a593Smuzhiyun IWidget(parent),
17*4882a593Smuzhiyun ui(new Ui::DateTimeWidget),
18*4882a593Smuzhiyun m_checker(Q_NULLPTR)
19*4882a593Smuzhiyun {
20*4882a593Smuzhiyun ui->setupUi(this);
21*4882a593Smuzhiyun }
22*4882a593Smuzhiyun
~DateTimeWidget()23*4882a593Smuzhiyun DateTimeWidget::~DateTimeWidget()
24*4882a593Smuzhiyun {
25*4882a593Smuzhiyun delete ui;
26*4882a593Smuzhiyun }
27*4882a593Smuzhiyun
id()28*4882a593Smuzhiyun QString DateTimeWidget::id()
29*4882a593Smuzhiyun {
30*4882a593Smuzhiyun return "rtc";
31*4882a593Smuzhiyun }
32*4882a593Smuzhiyun
initUi()33*4882a593Smuzhiyun void DateTimeWidget::initUi()
34*4882a593Smuzhiyun {
35*4882a593Smuzhiyun ui->zoneLbl->setText(QTimeZone::systemTimeZoneId());
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun auto addDateTime= [=]( QComboBox *pComBox, int start, int end, const QString &unit=""){
38*4882a593Smuzhiyun for(int n=start; n<=end; n++){
39*4882a593Smuzhiyun QString s = QString::number(n);
40*4882a593Smuzhiyun if(n<10)
41*4882a593Smuzhiyun {
42*4882a593Smuzhiyun s ="0" +s;
43*4882a593Smuzhiyun }
44*4882a593Smuzhiyun pComBox->addItem(tr((s +" " + unit).toLocal8Bit().data()) , n);
45*4882a593Smuzhiyun }
46*4882a593Smuzhiyun };
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun auto changDay= [=]( ){
49*4882a593Smuzhiyun ui->dayComBox->clear();
50*4882a593Smuzhiyun QDate d(currentvalue(ui->yearCombox),
51*4882a593Smuzhiyun currentvalue(ui->monthComBox),
52*4882a593Smuzhiyun 1);
53*4882a593Smuzhiyun int maxDays = d.daysInMonth();
54*4882a593Smuzhiyun addDateTime(ui->dayComBox, 1, maxDays, "Day");
55*4882a593Smuzhiyun };
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun addDateTime(ui->yearCombox, 2020, 2050, "Year");
58*4882a593Smuzhiyun addDateTime(ui->monthComBox, 1, 12, "Month");
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun connect(ui->yearCombox, &QComboBox::currentTextChanged, this, [=](){
61*4882a593Smuzhiyun changDay();
62*4882a593Smuzhiyun });
63*4882a593Smuzhiyun connect(ui->monthComBox, &QComboBox::currentTextChanged, this, [=](){
64*4882a593Smuzhiyun changDay();
65*4882a593Smuzhiyun });
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun addDateTime(ui->hourComBox, 0, 24, "Houre");
68*4882a593Smuzhiyun addDateTime(ui->minutuComBo, 0, 59,"Minute");
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun ui->yearCombox->setCurrentIndex(2);
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun auto setEnable= [=](bool checked ){
73*4882a593Smuzhiyun ui->yearCombox->setEnabled(checked);
74*4882a593Smuzhiyun ui->monthComBox->setEnabled(checked);
75*4882a593Smuzhiyun ui->dayComBox->setEnabled(checked);
76*4882a593Smuzhiyun ui->hourComBox->setEnabled(checked);
77*4882a593Smuzhiyun ui->minutuComBo->setEnabled(checked);
78*4882a593Smuzhiyun };
79*4882a593Smuzhiyun
80*4882a593Smuzhiyun connect(ui->manualRaidoBtn, &QRadioButton::clicked, this, [=](bool checked){
81*4882a593Smuzhiyun setEnable(checked);
82*4882a593Smuzhiyun });
83*4882a593Smuzhiyun connect(ui->ntpRadioBtn, &QRadioButton::clicked, this, [=](bool checked){
84*4882a593Smuzhiyun setEnable(!checked);
85*4882a593Smuzhiyun });
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun ui->manualRaidoBtn->click();
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun QTimer *timer = new QTimer(this);
90*4882a593Smuzhiyun connect(timer, &QTimer::timeout, this, [=](){
91*4882a593Smuzhiyun ui->systimeDataeLbl->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
92*4882a593Smuzhiyun QString result = Terminal::execCmd("hwclock -r");
93*4882a593Smuzhiyun if(SystemManager::instance()->getMatch(result, "[0-9]+").isEmpty())
94*4882a593Smuzhiyun {
95*4882a593Smuzhiyun ui->rtctimeLbl->setText("ERROR");
96*4882a593Smuzhiyun }else{
97*4882a593Smuzhiyun ui->rtctimeLbl->setText(result);
98*4882a593Smuzhiyun }
99*4882a593Smuzhiyun });
100*4882a593Smuzhiyun timer->start(1000);
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun m_checker = new NetworkChecker(this);
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun
currentvalue(QComboBox * d)106*4882a593Smuzhiyun int DateTimeWidget::currentvalue(QComboBox *d)
107*4882a593Smuzhiyun {
108*4882a593Smuzhiyun return d->itemData(d->currentIndex()).toInt();
109*4882a593Smuzhiyun }
110*4882a593Smuzhiyun
on_applyBtn_clicked()111*4882a593Smuzhiyun void DateTimeWidget::on_applyBtn_clicked()
112*4882a593Smuzhiyun {
113*4882a593Smuzhiyun QDateTime datetime;
114*4882a593Smuzhiyun if(ui->manualRaidoBtn->isChecked())
115*4882a593Smuzhiyun {
116*4882a593Smuzhiyun QDate d(currentvalue(ui->yearCombox),
117*4882a593Smuzhiyun currentvalue(ui->monthComBox),
118*4882a593Smuzhiyun currentvalue(ui->dayComBox));
119*4882a593Smuzhiyun QTime t(currentvalue(ui->hourComBox),
120*4882a593Smuzhiyun currentvalue(ui->minutuComBo));
121*4882a593Smuzhiyun datetime.setDate(d);
122*4882a593Smuzhiyun datetime.setTime(t);
123*4882a593Smuzhiyun }else{
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun if(!m_checker->networkIsOk())
126*4882a593Smuzhiyun {
127*4882a593Smuzhiyun MessageBox::showMessage(this, "Unable to access the network by DNS name,");
128*4882a593Smuzhiyun return;
129*4882a593Smuzhiyun }
130*4882a593Smuzhiyun long long mSeconds =NTPGetTimeBeijingMSeconds() ;
131*4882a593Smuzhiyun datetime = QDateTime::fromMSecsSinceEpoch(mSeconds);
132*4882a593Smuzhiyun ui->applyBtn->setEnabled(false);
133*4882a593Smuzhiyun QTimer::singleShot(2000, this, [=](){
134*4882a593Smuzhiyun ui->applyBtn->setEnabled(true);
135*4882a593Smuzhiyun });
136*4882a593Smuzhiyun }
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun QString cmd = QString("date -s %1 %2").
139*4882a593Smuzhiyun arg("\"" + datetime.toString("yyyy-MM-dd hh:mm:ss") + "\"").
140*4882a593Smuzhiyun arg("\"+%Y-%m-%d %H:%M:%S\"");
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun qCDebug(flapp)<< cmd;
143*4882a593Smuzhiyun system(cmd.toLocal8Bit().constData());
144*4882a593Smuzhiyun system("hwclock -w");
145*4882a593Smuzhiyun }
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun #include <sys/types.h>
149*4882a593Smuzhiyun #include <sys/socket.h>
150*4882a593Smuzhiyun #include <netdb.h>
151*4882a593Smuzhiyun #include <unistd.h>
152*4882a593Smuzhiyun #include <QDateTime>
153*4882a593Smuzhiyun #include <QDebug>
154*4882a593Smuzhiyun //NTP 标度与 Unix 标度只相差一个常数 2208988800,这是 1900/1/1 (NTP 标度起点)与 1970/1/1 (Unix 标度起点)之间的秒数差别
NTPGetTimeBeijingMSeconds()155*4882a593Smuzhiyun long long DateTimeWidget::NTPGetTimeBeijingMSeconds()
156*4882a593Smuzhiyun {
157*4882a593Smuzhiyun
158*4882a593Smuzhiyun #define NTP_TIMESTAMP_DELTA 2208988800
159*4882a593Smuzhiyun int sockfd, n; // Socket file descriptor and the n return result from writing/reading from the socket.
160*4882a593Smuzhiyun int portno = 123; // NTP UDP port number.
161*4882a593Smuzhiyun const char* host_name = "ntp.aliyun.com"; // NTP server host-name.
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun typedef struct
164*4882a593Smuzhiyun {
165*4882a593Smuzhiyun uint8_t li_vn_mode; // Eight bits. li, vn, and mode.
166*4882a593Smuzhiyun // li. Two bits. Leap indicator.
167*4882a593Smuzhiyun // vn. Three bits. Version number of the protocol.
168*4882a593Smuzhiyun // mode. Three bits. Client will pick mode 3 for client.
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun uint8_t stratum; // Eight bits. Stratum level of the local clock.
171*4882a593Smuzhiyun uint8_t poll; // Eight bits. Maximum interval between successive messages.
172*4882a593Smuzhiyun uint8_t precision; // Eight bits. Precision of the local clock.
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun uint32_t rootDelay; // 32 bits. Total round trip delay time.
175*4882a593Smuzhiyun uint32_t rootDispersion; // 32 bits. Max error aloud from primary clock source.
176*4882a593Smuzhiyun uint32_t refId; // 32 bits. Reference clock identifier.
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun uint32_t refTm_s; // 32 bits. Reference time-stamp seconds.
179*4882a593Smuzhiyun uint32_t refTm_f; // 32 bits. Reference time-stamp fraction of a second.
180*4882a593Smuzhiyun
181*4882a593Smuzhiyun uint32_t origTm_s; // 32 bits. Originate time-stamp seconds.
182*4882a593Smuzhiyun uint32_t origTm_f; // 32 bits. Originate time-stamp fraction of a second.
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun uint32_t rxTm_s; // 32 bits. Received time-stamp seconds.
185*4882a593Smuzhiyun uint32_t rxTm_f; // 32 bits. Received time-stamp fraction of a second.
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun uint32_t txTm_s; // 32 bits and the most important field the client cares about. Transmit time-stamp seconds.
188*4882a593Smuzhiyun uint32_t txTm_f; // 32 bits. Transmit time-stamp fraction of a second.
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun } ntp_packet; // Total: 384 bits or 48 bytes.
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun // Create and zero out the packet. All 48 bytes worth.
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun ntp_packet packet = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun memset( &packet, 0, sizeof( ntp_packet ) );
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun // 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.
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun *( ( char * ) &packet + 0 ) = 0x1b; // Represents 27 in base 10 or 00011011 in base 2.
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun struct sockaddr_in serv_addr; // Server address data structure.
203*4882a593Smuzhiyun struct hostent *server; // Server data structure.
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun sockfd = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); // Create a UDP socket.
206*4882a593Smuzhiyun
207*4882a593Smuzhiyun if ( sockfd < 0 )
208*4882a593Smuzhiyun printf("ERROR opening socket\n");
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun server = gethostbyname( host_name ); // Convert URL to IP.
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun if ( server == NULL )
213*4882a593Smuzhiyun printf("ERROR, no such host\n");
214*4882a593Smuzhiyun
215*4882a593Smuzhiyun // Zero out the server address structure.
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun bzero( ( char* ) &serv_addr, sizeof( serv_addr ) );
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun serv_addr.sin_family = AF_INET;
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun // Copy the server’s IP address to the server address structure.
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun bcopy( ( char* )server->h_addr, ( char* ) &serv_addr.sin_addr.s_addr, server->h_length );
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun serv_addr.sin_port = htons( portno );
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun // Call up the server using its IP address and port number.
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun if ( ::connect( sockfd, ( struct sockaddr * ) &serv_addr, sizeof( serv_addr) ) < 0 )
230*4882a593Smuzhiyun printf("ERROR connecting\n");
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun n = write( sockfd, ( char* ) &packet, sizeof( ntp_packet ) );
233*4882a593Smuzhiyun
234*4882a593Smuzhiyun if ( n < 0 )
235*4882a593Smuzhiyun printf("ERROR writing to socket\n");
236*4882a593Smuzhiyun
237*4882a593Smuzhiyun // Wait and receive the packet back from the server. If n == -1, it failed.
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun n = read( sockfd, ( char* ) &packet, sizeof( ntp_packet ) );
240*4882a593Smuzhiyun
241*4882a593Smuzhiyun if ( n < 0 )
242*4882a593Smuzhiyun printf( "ERROR reading from socket\n");
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun packet.txTm_s = ntohl( packet.txTm_s ); // Time-stamp seconds.
245*4882a593Smuzhiyun packet.txTm_f = ntohl( packet.txTm_f ); // Time-stamp fraction of a second.
246*4882a593Smuzhiyun long long mSecond =(packet.txTm_s- NTP_TIMESTAMP_DELTA)*1000+ packet.txTm_f*232/1000/1000/1000;
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun qDebug()<<QDateTime::fromMSecsSinceEpoch(mSecond);
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun return mSecond;
251*4882a593Smuzhiyun }
252*4882a593Smuzhiyun
NetworkChecker(QObject * parent)253*4882a593Smuzhiyun NetworkChecker::NetworkChecker(QObject *parent):QObject(parent)
254*4882a593Smuzhiyun {
255*4882a593Smuzhiyun this->start("ping www.forlinx.com");
256*4882a593Smuzhiyun }
257*4882a593Smuzhiyun
processMessage(const QString & info)258*4882a593Smuzhiyun void NetworkChecker::processMessage(const QString &info)
259*4882a593Smuzhiyun {
260*4882a593Smuzhiyun m_info +=info;
261*4882a593Smuzhiyun }
262*4882a593Smuzhiyun
networkIsOk()263*4882a593Smuzhiyun bool NetworkChecker::networkIsOk()
264*4882a593Smuzhiyun {
265*4882a593Smuzhiyun bool bOk =m_info.contains("ttl=");
266*4882a593Smuzhiyun m_info.clear();
267*4882a593Smuzhiyun return bOk;
268*4882a593Smuzhiyun }
269