解决方案:Z-Stack协议栈学习笔记6---单播

三龙创业 阅读:414 2024-01-26 16:05:20 评论:0

基于上一章的代码改为与之间使用单播模式通讯。单播故名思议就是点对点通讯,一个节点通过一个网络地址唯一的找到另一个节点。协议中可使用16位短地址或64位IEEE地址这两个地址类型。

64位IEEE地址:

全球唯一标识,一般在芯片出厂时烧录进芯片,在工作时从芯片中读出。全球唯一,理论上没有两个IEEE地址相同的节点;

16位短地址:

在某个网络中唯一存在。协调器的短地址总是为1,其余节点短地址向他们的父节点获取。当一个设备接入网络后其父节点会产生一个随机数作为他的短地址,然后这个节点会使用这条短地址在网络内广播一条数据“声明自己的存在”。如果这时网络中有另一个设备具有相同的短地址也会广播一条数据表示”地址冲突“,这时这两台地址冲突的节点都会重新获取新的短地址。重复这个操作直到网络中没有重复的短地址存在。

本实验基于16位短地址寻址,当网络形成后按下按键s1发送一条单播数据给,收到的数据后记录他的16位短地址。当按下的按键s1时,以之前记录的16位短地址发送一条单播数据。可以再这两台设备的串口上看到他们收到的数据内容。

知识点:

从实验需求可以看出我们必须在代码中区别当前设备的类型,即当前设备是、还是,不同的模式处理方式是不一样的。在协议栈中我们可以使用宏的值来判断当前模式,这个宏可能出现的值有以下三种,即三种工作模式:

开发中可以通过一个简单的if--else语句判断当前处于哪种模式,例如如果当前是模式就打印”“的代码如下:

if ( ZSTACK_DEVICE_BUILD == DEVICE_BUILD_ENDDEVICE ) {
    HalUARTStr(0, "helloworld!\r\n");
}

是在预编译阶段被定义的,在.h中定义

短址生成赚钱_短址赚钱网_https短网址生成

代码分析:

初始化部分:

与广播和组播不同,单播初始化时需要将目的地址初始化为单播模式,位置在.c的()中:

模式为16位短地址的单播模式,是具体的单播地址,这个在发送时会填写具体地址:

接收部分:

与广播与组播相同,同样是在函数()中处理接收到的数据,接收到后打印数据内容,如果是则记录对方短地址:

void TestApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
{
  switch ( pkt->clusterId )
  {
    case TESTAPP_CLUSTERID:
        HalUARTStr(0, "rcvd:");
        HalUARTStr(0, (uint8 *)pkt->cmd.Data);
        HalUARTStr(0, "\r\n");
        //coordinator模式下记录源地址,用于返回数据
        if ( ZSTACK_DEVICE_BUILD == DEVICE_BUILD_COORDINATOR ) {
            if ( otherAddr == 0 && pkt->srcAddr.addrMode == afAddr16Bit ) {
                otherAddr = pkt->srcAddr.addr.shortAddr;
            }
        }
    break;
  }
}

发送部分:

发送部分依然是在按键处理中,每当按下一次按键后就发送一条数据。与的发送流程是不一样的,主要区别在于短地址的获取。的发送目的地址就是的目的地址即总是,而的发送目的地址是的短地址,这个需要在接收数据包中获取。因此第一条数据必须是从发送到,因为一开始是不知道的短地址的,这时按键不发送数据。

void TestApp_HandleKeys( byte shift, byte keys )
{    
    static int count = 0;
    char str[20] = "send data ---> ";          
    
    //stone:add********************/
    if( keys & HAL_KEY_SW_6 ) {
        if ( networkState == 0 ) {
            return;      //组网不成功时不发送数据
        }
        if ( ZSTACK_DEVICE_BUILD == DEVICE_BUILD_COORDINATOR ) {
            if ( otherAddr == 0 ) {
                return;  //coordinator在还没有获取到endDevice地址的情况下不发送
            } else {
                TestApp_DstAddr.addr.shortAddr = otherAddr; // 将获取到的endDevice的短地址作为发送地址
            }
        }
        if ( ZSTACK_DEVICE_BUILD == DEVICE_BUILD_ENDDEVICE ) {
            TestApp_DstAddr.addr.shortAddr = 0; //coordinator 的地址总是为0
        }
        str[15] = count / 100 % 10 + '0';
        str[16] = count / 10 % 10 + '0';
        str[17] = count % 10 + '0';
        str[18] = '\0';
        if( ++count >= 1000 ) count = 0;
        //发送数据
        if ( AF_DataRequest( &TestApp_DstAddr, &TestApp_epDesc,
                   TESTAPP_CLUSTERID,
                   (byte)osal_strlen( str ) + 1,
                   (byte *)&str,
                   &TestApp_TransID,
                   AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
        {
        // Successfully requested to be sent.
            HalUARTStr(0, "send success!\r\n");
        }
        else
        {
        // Error occurred in request to send.
            HalUARTStr(0, "send fail!\r\n");
        }          
    }
    //************end***************/
}

实验:

在组网成功后,先按下的按键s1,发送一条单播数据到。当收到的数据包后也就同时获取到了的短地址,这时双方都可以通过按键s1互发数据了。

声明

版权声明 1、本站文章为原创请勿转载盗用 本站少部分学习教程、软件等仅限用于学习体验和研究目的;如果您认为侵犯了您的合法权益,请联系我们删除。联系QQ 5959693 马上删除

排行榜
关注我们

扫一扫关注我们,了解最新精彩内容