打印
[活动专区]

手机验证码功能3----移植过程与代码讲解--SNTP协议收发与解析

[复制链接]
462|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
candao2|  楼主 | 2023-4-13 10:24 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 candao2 于 2023-4-13 10:24 编辑

#申请原创#

概述
         本篇讲述SNTPSimpleNetwork Time Protocol)简单网络时间协议的通信过程和解析,会访问10ip地址服务器,他们都支持SNTP协议,如果访问第一个服务器,可能因为服务器本身原因或网络信号弱的原因,在超时时间内没有数据返回,就继续访问下一个ip地址,直到最后一个服务器地址,这期间,只要任何一个IP地址有数据返回,就算通信成功,解析收到的数据,再关闭网络通信。可以参看本篇末尾的《运行日志.txt》,此日志记录了在访问第9ip之后,收到了来自第二个ip的返回信息。本节所讲代码都在sntp目录下的文件中。

         1  创建UDP 传输协议的socket id
         代码如下图向NB模组发送指令:
         AT+NSOCR="DGRAM",17,8080,1\r\n
         模组返回:\r\n 0\r\n\r\nOK\r\n
         OK表示创建成功,0表示创建成功的socketid,后面当我们进行发送和接收数据的时候都要用到这个socket id,如果创建失败,原因有21是之前创建的socket id在使用后没有关闭,2 NB模组最多支持0-67socket id,已经超出了最大个数。
         上图中的SendCmd函数定义,先发送,再接收,return后面的那个函数在接收的同时还会进行数据的分析,下面第2节详细讲述。


         2  针对网络返回数据慢的分析
         SendCmd函数中return后面的那个函数声明如下:
         ATBack_t  asiacom_analyze_recv_from_nb_module_asynchronous_sntp(u32 timeout,  u32 *len,  asiacom_pfun_bool pfun_analyze_recv);
         此函数实现了上一篇提到的针对NB模组需要网络通信而导致返回数据慢的分析方法。由于在长达几十秒的串口等待接收中,NB模组可能会返回各种数据(包括错误信息,状态信息等其他未知信息),这是不可预知的。同时要保证如果在串口接收超时之前已经接收到了想要的数据,就立即结束接收,而接收到其他数据或者没有接收到数据,就继续等待直到超时结束。这与上一篇讲的接收数据分析方法不同。参看《运行日志.txt》,在接收到不是想要的数据(+NPSMR:0不是想要接收的数据,此数据表示模组已退出低功耗模式,开始和基站通信)后依然继续接收直到超时
         此函数有3个参数,超时时间,接收字节长度和一个函数指针。函数指针的类型定义如下,
         typedef bool (* asiacom_pfun_bool)(const char *string_src);

         因为NB模组返回数据的特性:以\r\n开始,以\r\n结束。所以此函数只有在每一次接收到此特性的数据,才开始进行检测,如果是需要的数据,就结束接收,否则继续等待接收。同时无论收到什么数据,都会输出到RTT日志,这样工程师或者测试人员能看到,了解NB模组的实时工作状态,便于问题与bug的分析和解决。
         而如果函数指针pfun_analyze_recvNULL,此函数就只会判断接收到OK或者ERROR等普通标志的数据,主要用再NB模组很快(毫秒级)就会返回数据的指令,这里跟上一篇的类似。上面的socket id创建指令,接收时此参数就传NULL。下图是此指令执行结果截图。
         而如果函数指针pfun_analyze_recv不为NULL,此函数就只会判断接收的数据是否满足
pfun_analyze_recv指定的条件,所以想要检测某种数据,只需要传入检测这种数据的函数名称即可,用在NB模组很慢(几十秒级)返回数据的指令,一般都是网络接收指令。


         3 发送获取网络时间的请求信息
         代码如下,发送指令给模组以后,会收到模组把此指令通过网络发送出去的报告。
         执行结果如下,参数顺序依次是socket id=0 ,第二个参数是ip地址,端口号123,发送的字节个数48,最后是48字节的内容,因为是转成十六进制,例如1b就是一个字节,后面的每20也是表示一个字节。
asiacom_analyze_recv_from_nb_module_asynchronous_sntp函数接收到NB模组返回的信息:模组成功收到了mcu发来的指令信息,即在0这个socket id上要发送48个字节。


         4  等待接收信息
         接收的代码也在上面截图中的atUdpSend函数中,atUdpSend函数在发送请求AT命令后,会立即收到模组接收到此AT命令的回复,接着mcu要继续等待接收模组从服务获取的时间数据,当NB模组接收到服务器返回的数据,会先串口发送一个通知信息告诉mcu我收到数据,mcu此时就应该发送一条接收AT指令来接收模组的数据。
         如下代码是mcu接收和解析模组的这个通知消息,可以看到第3个参数传入了一个函数is_recv_flag_of_NSONMI,用来检测是否是这个通知消息(+_NSONMI:打头的消息)

         检测到此通知消息后,MCU发送接收指令给模组,代码如下,SendCmd函数会完成此指令的发送并接收到包含时间信息的数据。
SendCmd函数执行成功后,对接收的数据再次检测是否是+NSORF:打头,然后提取出表示网络时间的字段,代码也是在atUdpRecv函数中,如下图。

         5  解析出时间
         这里要说明下,获取的网络时间是UTC时间,就是0时区的时间,而北京时间是8时区的时间,所以二者相差8个小时。当读取或者更新本地RTC时间是用的北京时间,而下一篇计算验证码用的是UTC时间。
         如下代码,atUdpRecv函数上面已经讲过,把atUdpRecv函数获取字符串格式的时间buff转换成SNTP数据包结构体变量SNTPData。通过公式减掉网络通信的延时时间,得到以秒为单位的时间值tv.tv_secctimeC语言标准头文件<time.h>中的函数,可以把以秒为单位的时间值tv.tv_sec转换成具体的年月日和时分秒。
         最后调用refresh_rtc_time_sntp来更新本地RTC时间,定义如下,此函数定义在rtc.c中。
         4,5两步的执行日志如下图:
         注意看解析得到的UTC时间UTC:Fri  Feb  308:00:44 2023  更新到本地的RTC时间sntp:2023-02-03,16:00:44
         二者相差8小时,也注意看日志中的时间戳变化,之前都是2023-01-12,更新本地RTC时间成功之后就变成2023-02-03


         6  关闭scoket id
执行结果如下,注意每次通信完成后都要关闭scoket id,有时候我们在创建scoket id的时候总是返回失败,就需要先关闭上一次创建的scoket id

       附录《运行日志》
[2023-01-12T04:22:30] main 114  "wait for nbiot booting......"
[2023-01-12T04:22:30] send_AT_CMD 212  "AT
"
[2023-01-12T04:22:30] asiacom_recv_data_from_nb_module 66  "
ERROR
"
[2023-01-12T04:22:30] send_AT_CMD 212  "AT
"
[2023-01-12T04:22:30] asiacom_recv_data_from_nb_module 66  "
OK
"
[2023-01-12T04:22:30] check_nb_online 254  "1 "
[2023-01-12T04:22:30] send_data_to_nb_module 83  "AT+CGATT?
"
[2023-01-12T04:22:30] asiacom_recv_data_from_nb_module 66  "
+CGATT:1

OK
"
[2023-01-12T04:22:30] send_data_to_nb_module 83  "AT+CSQ
"
[2023-01-12T04:22:30] asiacom_recv_data_from_nb_module 66  "
+CSQ:24,99

OK
"
[2023-01-12T04:22:30] send_data_to_nb_module 83  "AT+NPSMR=1
"
[2023-01-12T04:22:30] asiacom_recv_data_from_nb_module 66  "
OK
"
[2023-01-12T04:22:30] sntp_get_time 191  "isocketflag=-1 "
[2023-01-12T04:22:30] atCreateUdpSockets 87  "AT+NSOCR="DGRAM",17,8080,1
"
[2023-01-12T04:22:30] asiacom_analyze_recv_from_nb_module_asynchronous_sntp 192  "
0

OK
"
[2023-01-12T04:22:30] sntp_get_time 195  "ERROR -1 socketnumber 0 !!!!"
[2023-01-12T04:22:30] atUdpSend 169  ": AT+NSOST=0,120.24.166.46,123,48,1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
"
[2023-01-12T04:22:31] asiacom_analyze_recv_from_nb_module_asynchronous_sntp 192  "
0,48

OK
"
[2023-01-12T04:22:32] asiacom_analyze_recv_from_nb_module_asynchronous_sntp 174  "
+NPSMR:0
"
[2023-01-12T04:22:46] atUdpSend 169  ": AT+NSOST=0,120.25.115.20,123,48,1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
"
[2023-01-12T04:22:46] asiacom_analyze_recv_from_nb_module_asynchronous_sntp 192  "
0,48

OK
"
[2023-01-12T04:23:01] atUdpSend 169  ": AT+NSOST=0,203.107.6.88,123,48,1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
"
[2023-01-12T04:23:01] asiacom_analyze_recv_from_nb_module_asynchronous_sntp 192  "
0,48

OK
"
[2023-01-12T04:23:16] atUdpSend 169  ": AT+NSOST=0,37.187.100.18,123,48,1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
"
[2023-01-12T04:23:16] asiacom_analyze_recv_from_nb_module_asynchronous_sntp 192  "
0,48

OK
"
[2023-01-12T04:23:31] atUdpSend 169  ": AT+NSOST=0,202.112.7.13,123,48,1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
"
[2023-01-12T04:23:32] asiacom_analyze_recv_from_nb_module_asynchronous_sntp 192  "
0,48

OK
"
[2023-01-12T04:23:47] atUdpSend 169  ": AT+NSOST=0,202.120.2.101,123,48,1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
"
[2023-01-12T04:23:47] asiacom_analyze_recv_from_nb_module_asynchronous_sntp 192  "
0,48

OK
"
[2023-01-12T04:24:02] atUdpSend 169  ": AT+NSOST=0,210.72.145.44,123,48,1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
"
[2023-01-12T04:24:02] asiacom_analyze_recv_from_nb_module_asynchronous_sntp 192  "
0,48

OK
"
[2023-01-12T04:24:17] atUdpSend 169  ": AT+NSOST=0,182.92.12.11,123,48,1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
"
[2023-01-12T04:24:18] asiacom_analyze_recv_from_nb_module_asynchronous_sntp 192  "
0,48

OK
"
[2023-01-12T04:24:33] atUdpSend 169  ": AT+NSOST=0,223.113.97.99,123,48,1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
"
[2023-01-12T04:24:33] asiacom_analyze_recv_from_nb_module_asynchronous_sntp 192  "
0,48

OK
"
[2023-01-12T04:24:39] asiacom_analyze_recv_from_nb_module_asynchronous_sntp 174  "
+NSONMI:0,48
"
[2023-01-12T04:24:39] is_recv_flag_of_NSONMI 42  "RECV_NSONMI"
[2023-01-12T04:24:39] atUdpRecv 241  ": AT+NSORF=0,1024
"
[2023-01-12T04:24:39] asiacom_analyze_recv_from_nb_module_asynchronous_sntp 192  "
+NSORF:0,120.25.115.20,123,48,1C0200E7000000080000004B0A893507E78C77CDA314A32D0000000000000000E78C7808CCF3BB69E78C7808CECFFFD6,0

OK
"
[2023-01-12T04:24:39] rev_handle 143  "t1:3884742664 UTC:Tue Feb  7 07:11:09 2023
"
[2023-02-07T15:11:09] refresh_rtc_time_by_sntp 610  "sntp:2023-02-07,15:11:09"
[2023-02-07T15:11:09] atCloseSockets 131  ": AT+NSOCL=0
"
[2023-02-07T15:11:09] asiacom_analyze_recv_from_nb_module_asynchronous_sntp 192  "
+NSONMI:0,48

OK
"
[2023-02-07T15:11:09] get_utc_time_from_rtc 590  "current time:2023-02-07T15:11:09"
[2023-02-07T15:11:09] main 128  "device_id:35519330 pwd:948184"




使用特权

评论回复
沙发
tpgf| | 2023-5-6 14:23 | 只看该作者
SNTP协议采用客户端/服务器的工作方式,可以采用单播(点对点)或者广播(一点对多点)模式操作

使用特权

评论回复
板凳
nawu| | 2023-5-6 15:09 | 只看该作者
网络中一般存在很多台SNTP服务器,客户端会通过一定的算法选择最好的几台服务器使用

使用特权

评论回复
地板
aoyi| | 2023-5-6 15:41 | 只看该作者
在实际应用中,SNTP协议主要被用来同步因特网上计算机的时间。

使用特权

评论回复
5
zljiu| | 2023-5-8 10:09 | 只看该作者
网络时间协议是一种在网络计算机上同步计算机时间的协议,它具有高度的精确性(能精确到几十毫秒),但是算法非常复杂

使用特权

评论回复
6
gwsan| | 2023-5-8 10:17 | 只看该作者
SNTP协议采用客户端/服务器的工作方式,可以采用单播(点对点)或者广播(一点对多点)模式操作。SNTP服务器通过接收GPS信号或自带的原子钟作为系统的时间基准。

使用特权

评论回复
7
tfqi| | 2023-5-8 13:24 | 只看该作者
SNTP的消息格式与RFC-1305中所描述的NTP格式是一致的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

5

帖子

0

粉丝