KW41Z板卡-openthread的udp通讯
[复制链接]
本帖最后由 wakojosin 于 2024-3-24 11:54 编辑
测试环境
使用的硬件是KW41Z开发板和nrf52840开发板,两者都跑openthread协议栈进行下面的实验。
固件方面两者烧写的是各自的ftd-cli工程。
下面测试过程用NRF代表NRF52840,NXP代表KW41Z。
测试过程
启动接口。
NRF:
> ifconfig up
Done
> thread start
Done
>
> state
leader
Done
>
NXP:
> eui64
1bf3040000000000
Done
> ifconfig up
Done
>
入网,此时使用NRF作为leader设备,NXP作为节点(会自动升级为rooter)。
NRF:
> commissioner start
Commissioner: petitioning
Done
> Commissioner: active
commissioner joiner add 1bf3040000000000 PPSSKK
Done
> ~ Discovery Request from 12954efa1b74f63f: version=4,joiner=1
Commissioner: Joiner start 5795cc01d9ef484e
Commissioner: Joiner connect 5795cc01d9ef484e
=========[[THCI] direction=recv | type=JOIN_FIN.req | len=048]==========
| 10 01 01 21 0A 4F 50 45 | 4E 54 48 52 45 41 44 22 | ...!.OPENTHREAD"
| 05 4B 57 34 31 5A 23 10 | 74 68 72 65 61 64 2D 72 | .KW41Z#.thread-r
| 65 66 65 72 65 6E 63 65 | 25 06 18 B4 30 00 00 10 | eference%..40...
------------------------------------------------------------------------
=========[[THCI] direction=send | type=JOIN_FIN.rsp | len=003]==========
| 10 01 01 .. .. .. .. .. | .. .. .. .. .. .. .. .. | ................
------------------------------------------------------------------------
Commissioner: Joiner finalize 5795cc01d9ef484e
-MESH-CP-: [THCI] direction=send | type=JOIN_ENT.ntf
-MESH-CP-: [THCI] direction=recv | type=JOIN_ENT.rsp
Commissioner: Joiner end 5795cc01d9ef484e
Commissioner: Joiner remove 5795cc01d9ef484e
>
> ipaddr
fd9f:129:4246:a051:0:ff:fe00:fc31
fd9f:129:4246:a051:0:ff:fe00:fc00
fd9f:129:4246:a051:0:ff:fe00:2400
fd9f:129:4246:a051:b860:2a7f:75dd:e101
fe80:0:0:0:28f0:3f23:5560:65b0
Done
NXP:
> joiner start PPSSKK
Done
> Join success
>
> thread start
Done
>
> state
child
Done
>
> ipaddr
fd9f:129:4246:a051:0:ff:fe00:2401
fd9f:129:4246:a051:104e:6c93:d338:7114
fe80:0:0:0:4c86:1466:c96e:a32c
Done
UDP测试
NRF:
> udp open
Done
> udp bind :: 1234
Done
> udp send fd9f:129:4246:a051:104e:6c93:d338:7114 2345 hello41z
Done
> 10 bytes from fd9f:129:4246:a051:104e:6c93:d338:7114 2345 hello52840
NXP:
> udp open
Done
> udp bind :: 2345
Done
> 8 bytes from fd9f:129:4246:a051:b860:2a7f:75dd:e101 1234 hello41z
> udp send fd9f:129:4246:a051:b860:2a7f:75dd:e101 1234 hello52840
Done
>
UDP命令分析
路径位于:ot-kw41z/openthread/src/cli/cli_udp.cpp
udp open
//这个命令主要是调用otUdpOpen,HandleUdpReceive函数用来处理接收到的数据
otUdpOpen(GetInstancePtr(), &mSocket, HandleUdpReceive, this);
udp bind
//这个命令主要是调用otUdpBind来开启端口监听
otUdpBind(GetInstancePtr(), &mSocket, &sockaddr, netif);
udp send
//这个命令主要是构建一个message,将数据写进message中,然后通过otUdpSend发送
message = otUdpNewMessage(GetInstancePtr(), &messageSettings);
otMessageAppend(message, aArgs[0].GetCString(), aArgs[0].GetLength());
otUdpSend(GetInstancePtr(), &mSocket, message, &messageInfo);
udp connect:调用otUdpConnect来与指定主机建立连接。
udp close:调用otUdpClose来关闭UDP客户端。
写自己的demo
在ot-kw41z/openthread/examples/apps路径下,复制cli,重命名为demo,然后修改此目录下的CMakeLists.txt,前后内容如下
修改前:
if(OT_APP_CLI)
add_subdirectory(cli)
endif()
add_subdirectory(ncp)
修改后:
if(OT_APP_CLI)
add_subdirectory(cli)
add_subdirectory(demo)
endif()
add_subdirectory(ncp)
增加demo.c,主要代码如下:
static otMessage *mMessage = NULL;
static otMessageInfo mMessageInfo;
static otUdpSocket mSocket;
void DemoProcess(otInstance *instance)
{
if(NULL == instance)
{
return;
}
if(!otUdpIsOpen(instance, &mSocket))
{
return;
}
otMessage *message = mMessage;
if(message != NULL)
{
mMessage = NULL;
if(OT_ERROR_NONE != otUdpSend(instance, &mSocket, message, &(mMessageInfo)))
{
DBG_INFO_OUT("send message failed!\n");
otMessageFree(message);
}
}
}
bool DemoMessageSet(otMessage *message, const otMessageInfo *info)
{
if(mMessage == NULL)
{
mMessage = message;
memcpy(&mMessageInfo.mPeerAddr, &(info->mPeerAddr), sizeof(mMessageInfo.mPeerAddr));
mMessageInfo.mPeerPort = info->mPeerPort;
return true;
}
else
{
return false;
}
}
static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
{
char buf[1500];
int length;
bool isSecurity = otMessageIsLinkSecurityEnabled(aMessage);
DBG_INFO_OUT("%d bytes from ", otMessageGetLength(aMessage) - otMessageGetOffset(aMessage));
otIp6AddressToString(&aMessageInfo->mPeerAddr, buf, sizeof(buf));
DBG_INFO_OUT("%s:%d (%d) ", buf, aMessageInfo->mPeerPort, isSecurity);
length = otMessageRead(aMessage, otMessageGetOffset(aMessage), buf, sizeof(buf) - 1);
buf[length] = '\0';
DBG_INFO_OUT("%s\n", buf);
// create message
otInstance *instance = (otInstance *)aContext;
if(instance)
{
otMessage *message = otUdpNewMessage(instance, NULL);
if(message)
{
if(OT_ERROR_NONE == otMessageAppend(message, buf, length))
{
if(DemoMessageSet(message, aMessageInfo))
{
message = NULL;
}
}
if(message)
{
otMessageFree(message);
}
}
}
}
void DemoInit(otInstance *instance)
{
otSockAddr sockaddr;
if(instance== NULL)
{
return ;
}
if(otUdpIsOpen(instance, &mSocket))
{
return ;
}
memset(&mSocket, 0, sizeof(mSocket));
if(OT_ERROR_NONE != otUdpOpen(instance, &mSocket, HandleUdpReceive, instance))
{
return ;
}
memset(&sockaddr, 0, sizeof(sockaddr));
otIp6AddressFromString("::", &sockaddr.mAddress);
sockaddr.mPort = 12345;
if(OT_ERROR_NONE != otUdpBind(instance, &mSocket, &sockaddr, OT_NETIF_THREAD))
{
return ;
}
}
代码实现的是echo功能。
|