Thread 使用 UDP 上的单播和多播传输提供应用程序框架实现所需的基本服务。
线程规范仅关注网络层;由于它与应用层无关,因此可以设计许多应用层无问题运行。
在该实验室中,用户将使用该应用层的约束应用协议 (CoAP),因为 Thread 堆栈使用 CoAP 进行大多数多跳网络管理和调试消息。
受限应用协议 (CoAP) 是一种专门用于物联网中受限节点和受限网络的 Web 传输协议。它使用具有四种方法的二进制 RESTful 协议
CoAP 还使用 ACK 响应;可确认(请求 ACK)和不可确认的消息。
Thread 堆栈使用 CoAP 来处理大多数多跳网络管理和调试消息
通过本实验用户将修改固件以实现以下列表:
实验室期望的流程行为如图 1 所示。
图 1 实验室期望行为示意图
设置
在下面的列表中,带有破折号(—)的组件将用于创建此实验室。
—牧师一个
— Thread Router 合格设备项目
— TeraTerm
图2 FRDM-KW41Z
将在 router_eligible_device_app.c 文件 中进行以下更改 。
1.定义在 shell 中用于访问资源的 URI 路径名。
#定义APP_RESOURCE1_URI_PATH“/resource1”
#定义 APP_RESOURCE2_URI_PATH“/resource2”
2. 使用 coapUriPath_t 声明 URI 资源。使用此结构时,用户必须输入 URI 路径的长度和上一步创建的路径。
const coapUriPath_t gAPP_RESOURCE1_URI_PATH = {SizeOfString(APP_RESOURCE1_URI_PATH), APP_RESOURCE1_URI_PATH};
const coapUriPath_t gAPP_RESOURCE2_URI_PATH = {SizeOfString(APP_RESOURCE2_URI_PATH), APP_RESOURCE2_URI_PATH};
3.创建资源的回调。此回调将处理接收到的数据包并根据接收到的 COAP 方法类型执行所需的操作。
static void APP_CoapResource1Cb(coapSessionStatus_t sessionStatus, void *pData, coapSession_t *pSession, uint32_t dataLen);
static void APP_CoapResource2Cb(coapSessionStatus_t sessionStatus, void *pData, coapSession_t *pSession, uint32_t dataLen);
4. 为接收到的数据包添加回调处理程序,在此函数中将定义根据接收到的 COAP 方法类型执行哪些操作。
静态无效APP_CoapResource1Cb ( coapSessionStatus_t 会话状态, 无效* pData, coapSession_t *pSession, uint32_t 数据长度 ) { 静态 uint8_t pMySessionPayload[3]={0x31,0x32,0x33}; 静态uint32_t pMyPayloadSize = 3; coapSession_t *pMySession = NULL; pMySession = COAP_OpenSession(mAppCoapInstId); COAP_AddOptionToList(pMySession,COAP_URI_PATH_OPTION,APP_RESOURCE2_URI_PATH,SizeOfString(APP_RESOURCE2_URI_PATH)); 如果(gCoapConfirmable_c == pSession->msgType) { 如果(gCoapGET_c == pSession->代码) { shell_write("'CON' 数据包已接收 'GET',有效载荷为:"); } 如果(gCoapPOST_c == pSession->代码) { shell_write("'CON' 数据包已接收带有有效载荷的 'POST':"); } 如果(gCoapPUT_c == pSession->代码) { shell_write("'CON' 数据包已接收 'PUT',有效载荷为:"); } 如果(gCoapFailure_c!=sessionStatus) { COAP_Send(pSession,gCoapMsgTypeAckSuccessChanged_c,pMySessionPayload,pMyPayloadSize); } } 否则,如果(gCoapNonConfirmable_c == pSession->msgType) { 如果(gCoapGET_c == pSession->代码) { shell_write("'NON' 数据包已接收 'GET',有效载荷为:"); } 如果(gCoapPOST_c == pSession->代码) { shell_write("'NON' 数据包接收到了带有有效载荷的 'POST': "); } 如果(gCoapPUT_c == pSession->代码) { shell_write("'NON' 数据包已接收 'PUT',有效载荷为:"); } } shell_writeN(pData,dataLen); shell_write("\r\n"); pMySession->msgType=gCoapNonConfirmable_c; pMySession->代码=gCoapPOST_c; pMySession->pCallback =NULL; FLib_MemCpy(&pMySession->remoteAddr,&gCoapDestAddress,sizeof(ipAddr_t)); COAP_SendMsg(pMySession,pMySessionPayload,pMyPayloadSize); shell_write("'NON' 数据包以 'POST' 形式发送,有效载荷为:"); shell_writeN((char*)pMySessionPayload,pMyPayloadSize); shell_write("\r\n"); } |
每个 UDP 端口可以有一个 COAP 实例,如果应用程序只使用一个端口,则一个实例就足够了。
每个实例可以有多个 COAP 会话,每个数据包/事务都有一个 COAP 会话。在这种情况下,由于期望的结果是获得不同的 ACK 响应,因此需要使用新资源创建新的会话。
静态无效APP_CoapResource2Cb ( coapSessionStatus_t 会话状态, 无效* pData, coapSession_t *pSession, uint32_t 数据长度 ) { 如果(gCoapNonConfirmable_c == pSession->msgType) { shell_write("'NON' 数据包接收到了带有有效载荷的 'POST': "); shell_writeN(pData,dataLen); shell_write("\r\n"); } } |
5. 创建回调后,必须在函数APP_InitCoapDemo(void)中将其注册到 CoAP 回调数组中。
{APP_CoapResource1Cb, (coapUriPath_t*)&gAPP_RESOURCE1_URI_PATH},
{APP_CoapResource2Cb,(coapUriPath_t*)&gAPP_RESOURCE2_URI_PATH},
关于 CoAP 库的使用,有一些事情需要提及,这些事情在本实验室中没有使用,但可能对其他类型的应用程序有用。
当使用COAP_SendMsg()时,会话将默认自动关闭,除非使用pSession->autoClose进行指示。
发送消息时有两个选项:
可确认( CON ) :等待 ACK 回复,直到收到消息后才会关闭会话,或者在重传次数耗尽时关闭会话。
不可确认( NON ) :对于 NON,在发送消息后立即生效。
如果发送了一条消息但没有得到响应,则会在每个 COAP_ACK_TIMEOUT (以毫秒为单位)后发送一次重新传输,重新传输将以指数方式发送:首先在随机(2,3)秒后,接下来将超时时间加倍,依此类推,直到 达到 COAP_MAX_RETRANSMIT 。
重传停止后,会话将自动关闭并通知应用程序失败,应用程序回调将以状态 gCoapFailure_c 调用 。
当调用回调时当前会话仍然有效,但退出函数后CoAP会话将关闭它。有两种不同的解决方法:
必须创建一个新会话
设置pSession->autoClose = FALSE 。如果 autoClose 设置为 FALSE,请不要忘记使用COAP_CloseSession()从应用程序关闭会话。
1.下载修改后的固件到开发板
2. 为每块板子打开一个串口终端,波特率为115200
图3 串行终端及其配置
3. 在其中一个板子的终端输入“ thr create ” ,该板子将成为领导者。
图 4 带有命令“thr create”的板 1
图 5 执行“thr create”命令后的 Board 1
4. 网络创建完成后, 在第二块板的终端中 输入“thr join” 。
图 6 使用命令“thr join”的板 2
图 7 执行“thr join”命令后的板 2
5. 在两个串行终端中输入命令“ifconfig” 。此命令将显示板的所有地址。
图 8 使用“ifconfig”命令后,板 1
图 9 执行“ifconfig”命令后的板 2
6. 为了测试创建的回调,必须发送 CoAP 消息。必须输入以下命令;
coap
|
coap CON POST fe80::5df0:2bf0:d69b:1b3c /resource1 hello
|
图10 CoAP命令发送
7. 发送的结果必须是这样的:
—董事会 1
董事会 1 将向董事会 2 请求资源 1
图 11 发送 CoAP 命令之前的 Board 1
由于它已被编码,另一块板将发送 ACK 并打印消息。
图 12 发送 CoAP 命令后的 Board 1
—董事会 2
图13 收到CoAP命令后的Board 2
如果使用CON消息,请求板将收到响应,而如果消息是NON类型,则不会收到响应。
当使用这种类型的消息时,无论包类型如何,发送消息时都会打开一个新会话,并且它将发送非类型的消息。