目前,相对主流的NB方案主要有华为海思和MTK两种。
本文讨论的是MTK方案,相应模组型号为移远BC26,固件版本BC26NBR01A03(可通过ATI指令查询得到)。
BC26使用的CoAP接入方式为LwM2M,其中关于CoAP协议栈和LwM2M协议栈的部分,已经封装在了模组AT指令集里,如下图(完整LwM2M相关指令集见Quectel_BC26_LwM2M_AT_Commands_Manual_V1.0.pdf)
下面附上拨号流程(仅主要部分流程,根据实际应用手工整理,可能会有错误,模组默认串口参数115200/8/1/None):
AT // 检测AT接口(具有波特率协商功能)
AT
OK
AT+QCGDEFCONT: "IP","psm0.eDRX0.ctnb" // 先设置APN
OK
AT+QRST=1 // 设置完APN以后需要软复位模组(APN参数掉电不丢失)
OK
F1: 0000 0000
V0: 0000 0000 [0001]
00: 0006 000C
01: 0000 0000
U0: 0000 0001 [0000]
T0: 0000 00B4
Leaving the BROM // 开机报文, 说明模组开机完成
ATE0 // 关闭回显
ATE0
OK
AT+CFUN?
+CFUN: 1 // 全功能开启
OK
AT+CPIN? // 检测SIM卡
+CPIN: READY
OK
AT+QCGDEFCONT? // 检验APN是否正确【可省略跳过】
+QCGDEFCONT: "IP","psm0.eDRX0.ctnb"
OK
AT+CESQ // 查询信号强度(CESQ值范围0~63)
+CESQ: 42,0,255,255,2,54 // 42为CESQ值, 近似于CSQ值21, 信号较好
OK
AT+CGATT? // 查询附着状态
+CGATT: 1 // 1: 已附着
OK
AT+CEREG? // 查询网络注册状态
+CEREG: 0,1 // 第二位数字 1: 已注册
OK
AT+CSCON? // 查询信号连接状态
+CSCON: 0,1 // 第二位数字 1: 已连接
OK
———————————————————————————————————————
入网过程结束,后面是LwM2M接入IoT平台的流程
———————————————————————————————————————
AT+QLWSERV="117.60.157.137",5683 // 设置目标服务器的IP和Port
OK
/*如果需要重新连接其他的IoT平台,即修改目标IP和Port,或者在后续的完善链路的过程中出现错误,则需要发送 [ AT+QLWDEL ] 指令来删除现有信息。*/
AT+QLWCONF="866971030537000" // 设置需要接入IoT平台的设备IMEI(可以通过AT+CGSN获得), 该设备需要提前在IoT平台上注册(平台会在设备在接入时检测IMEI是否在已注册列表内)
OK
AT+QLWADDOBJ=19,0,1,"0" // 添加LwM2M Object 19/0/0 ( <ObjectID>=19, <InstanceID>=0, <ResourceID>=0 )
OK
AT+QLWADDOBJ=19,1,1,"0" // 添加LwM2M Object 19/1/0 ( <ObjectID>=19, <InstanceID>=1, <ResourceID>=0 )
OK
//上述两个Object仅对电信OceanConnect平台有效, 原因见下文
AT+QLWOPEN=1 // 向IoT平台发起注册请求, 并设置数据接收模式为[Buffer access mode]
OK
CONNECT OK // 注册成功, 若失败则会收到"CONNECT FAIL"
+QLWOBSERVE: 0,19,0,0 // Object(19/0/0) 和IoT平台已经匹配
AT+QLWCFG="dataformat",1,1 // 规定收发数据的模式为 [Hex String Mode], 即在AT指令交互时看到的数据格式为HEX文本
OK
// 通过Object(19/0/0)向IoT平台发送数据76字节数据(数据内容0x01, 0xF0, 0x00,...,0xEC, 0x16, 0x77), 发送模式为0x1000(即CON模式, 发送成功后会收到""SEND OK字符串)
AT+QLWDATASEND=19,0,0,76,01F00048000100FFFFFFA638363639373130333035333739313934363031313330303434393837393700000168182D0470010017010014683200320068C90840452300027000000100EC1677,0x0100
OK
SEND OK // 发送成功
+QLWDATARECV: 19,1,0,9 // 通过Object(19/1/0)收到来自IoT平台的9字节数据
AT+QLWRD=9 // 读9字节数据
+QLWRD: 9,0 // 9: 本次读9字节; 0: 剩余未读数据0字节
01F1000500000101F9 // 收到的数据为 ( 0x01, 0xF1, 0x10,...,0x01, 0x01, 0xF9 )
OK
关于AT+QLWADDOBJ
指令添加的对象ID为19/0/0和19/1/0,移远回复对应的Object ID是由电信规定在其资源列表中的,因此在接入平台时必须要添加这两个对象(推测:19/0/0和19/1/0构成一组Object,分别支持写和读,即发送至平台的数据全部通过 19/0/0,而 平台返回的数据全部通过 19/1/0)。
接入其他IoT平台时则需要遵循对应资源列表锁规定的内容。
AT+QLWDATASEND
和AT+QLWRD
内得到的数据是电信平台所规定的“CoAP协议帧”(该描述见电信EasyIoT官网,EasyIoT建立在电信OceanConnect平台之上,终端数据先发往OceanConnect,然后再由该平台分发至EasyIoT,如果终端帧格式不符合平台相应插件的要求,即不符合“CoAP协议帧”格式,则会直接被平台丢弃,数据将不再分发至EasyIoT)因此在接入电信平台时,终端上送的数据帧都需要按照平台的要求再封装一层,所以我们才会看到01F0...
,01F1...
此类的帧格式。
不过根据LwM2M协议栈所规定的层次结构,LwM2M在CoAP之上,即LwM2M嵌入在CoAP的payload之中,那么UDP->CoAP->LwM2M->"CoAP"的层次结构就会与下图中的标准层次结构形成冲突。
对此,整理与EasyIoT开发团队的咨询邮件,可以归纳为
电信平台所描述的“CoAP协议Payload部分的报文约定”实际上是电信参考CoAP协议下的TLV结构自定义的帧格式,并不属于CoAP协议栈。
用户数据 |
---|
电信自定义TLV |
LwM2M |
CoAP |
UDP |
上表可以简单理解为: