This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2530: zigbee 协调器发送组播信息,为什么终端节点收不到?

Part Number: CC2530
Other Parts Discussed in Thread: Z-STACK

z-stack 2.5.1 a   zigbee 协调器发送组播信息,为什么路由节点可以收到,但终端节点收不到?

协调器发送组播信息 :

    void SampleApp_SendGroupMessage(void);
               {
                 if ( AF_DataRequest( &SampleApp_Flash_DstAddr, &SampleApp_epDesc,
                       SAMPLEAPP_FLASH_CLUSTERID,
                       1,
                       data,
                       &SampleApp_TransID,
                       AF_DISCV_ROUTE,
                       AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
                    {
                     }
                 else
                    {
                    // Error occurred in request to send.
                     }

判断接收到消息,作出反应

void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
{
  uint16 flashTime;

  switch ( pkt->clusterId )    /*判断输入/输出簇ID*/
  {

    case SAMPLEAPP_FLASH_CLUSTERID:   /*如果输入/输出簇ID为SAMPLEAPP_FLASH_CLUSTERID*/
      flashTime = BUILD_UINT16(pkt->cmd.Data[1], pkt->cmd.Data[2] );
      HalLedBlink( HAL_LED_4, 4, 50, (flashTime / 4) );    /*接收到数据,并将收到的数据设定为LED闪烁时间*/
      HalUARTWrite(0,"haha",4);  判断接收到消息,作出反应
      break;

  • 终端设备会定期休眠,所以收不到组播消息
    要收到组播消息终端要一直处于开启状态,修改配置文件f8config.cfg中ALWAYS_ON=TRUE


  • 已经把  -DRFD_RCVC_ALWAYS_ON=TURE   设置好,但终端节点还是收不到消息,是哪里的问题?

  • 你有把終端設備加入這個组嗎?

  • 把终端加入组里需要什么特殊的操作吗?

  • 要怎样检查终端在没在组里呢?

  • 協調器可以透過zclGeneral_SendAddGroupRequest送加入组的命令給终端,终端收到後會在zclGeneral_ProcessInGroupsServer去處理

  • 这个是必须的吗? 我用另一个组播程序把终端的 -DRFD_RCVC_ALWAYS_ON=TURE   设置好,也没有发送加入组的命令,就可以收到消息,也没有发送加入组的命令。我现在在我的程序基础上加了一个组播,就收不到了。

  • 也可以用來aps_AddGroup在設備端把設備加入到Group

  • 加上还是不行,以下为我的代码、

    uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events )
    {
    uint8 Display_Buf[6] = {0};
    uint16 shortAddr = 0;
    uint16 shortAddrNew = 0;
    uint16 PANID=0;
    uint16 parentshortAddr = 0;
    uint16 parentshortAddrNew = 0;

    afIncomingMSGPacket_t *MSGpkt;

    (void)task_id; // Intentionally unreferenced parameter


    if ( events & SYS_EVENT_MSG ) /*系统消息事件*/
    {

    MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID );
    while ( MSGpkt ) /*调用数据接收函数接收数据.2*/
    {

    switch ( MSGpkt->hdr.event ) /*判断具体事件*/
    {
    // Received when a key is pressed

    case KEY_CHANGE:
    SampleApp_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
    break; /*如果为按键事件,调用案件处理函数.3*/


    // Received when a messages is received (OTA) for this endpoint
    case AF_INCOMING_MSG_CMD:
    HAL_TOGGLE_LED1(); /*?*/
    SampleApp_MessageMSGCB( MSGpkt );

    n=n+1;
    m=n;

    num_to_str(m,Display_Buf, 4 , 16);
    Gui_DrawFont_GBK16(48,96,BLACK,YELLOW,Display_Buf);

    if (m>10)
    {


    uint8 data[1]={'9'};
    void SampleApp_SendGroupMessage(void);
    {
    if ( AF_DataRequest( &SampleApp_Flash_DstAddr, &SampleApp_epDesc,
    SAMPLEAPP_FLASH_CLUSTERID,
    1,
    data,
    &SampleApp_TransID,
    AF_DISCV_ROUTE,
    AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
    {
    }
    else
    {
    // Error occurred in request to send.
    }

    }
    }


    break; /*如果为数据接收事件,调用数据接收函数.3*/



    // Received whenever the device changes state in the network
    case ZDO_STATE_CHANGE:

    if(SampleApp_NwkState == DEV_NWK_ORPHAN)
    {
    void leaveNetBySelf(void);
    {

    //主动离开参考
    NLME_LeaveReq_t leaveReq;
    osal_memset((uint8 *)&leaveReq,0,sizeof(NLME_LeaveReq_t));
    osal_memcpy(leaveReq.extAddr,NLME_GetExtAddr(),Z_EXTADDR_LEN);
    // zgWriteStartupOptions(ZG_STARTUP_SET, ZCD_STARTOPT_DEFAULT_NETWORK_STATE);
    // SystemReset();
    leaveReq.removeChildren = 1;
    leaveReq.rejoin = 0;
    leaveReq.silent = 0;
    SystemReset();
    }

    }

    SampleApp_NwkState = (devStates_t)(MSGpkt->hdr.status);

    if ( (SampleApp_NwkState == DEV_ZB_COORD)
    ||(SampleApp_NwkState == DEV_ROUTER)
    || (SampleApp_NwkState == DEV_END_DEVICE) ) /*如果为网络状态改变事件,则判断网络类型.5*/
    {
    // osal_start_timerEx(SampleApp_TaskID,CLEAR_EVT,15000);

    if(SampleApp_NwkState == DEV_END_DEVICE)
    {
    aps_AddGroup( SAMPLEAPP_ENDPOINT,&SampleApp_Group );
    Gui_DrawFont_GBK16(0,16,RED,CYAN," EndDevice ");
    Gui_DrawFont_GBK16(0,48,BLACK,YELLOW,"ShortAddr: ");
    Gui_DrawFont_GBK16(0,64,BLACK,YELLOW, "Temp:");
    Gui_DrawFont_GBK16(0,80,BLACK,YELLOW, "parentSA:");


    }
    else if(SampleApp_NwkState == DEV_ZB_COORD)
    {
    Gui_DrawFont_GBK16(0,16,RED,CYAN," CooDevice ");
    }
    else
    {
    Gui_DrawFont_GBK16(0,16,RED,CYAN," RouterDevice ");
    Gui_DrawFont_GBK16(0,48,BLACK,YELLOW,"ShortAddr: ");
    Gui_DrawFont_GBK16(0,64,BLACK,YELLOW, "parentSA:");
    }


    if ( (SampleApp_NwkState == DEV_ROUTER)
    || (SampleApp_NwkState == DEV_END_DEVICE) )
    {

    //显示设备地址shortAddr
    zb_GetDeviceInfo(ZB_INFO_SHORT_ADDR, &shortAddr);
    shortAddrNew = LO_UINT16(shortAddr) << 8;
    shortAddrNew = HI_UINT16(shortAddr) |shortAddrNew;
    num_to_str(shortAddrNew, Display_Buf, 4 , 16);
    Gui_DrawFont_GBK16(94,48,BLACK,YELLOW,Display_Buf);



    // Start sending the periodic message in a regular interval.
    osal_start_timerEx( SampleApp_TaskID,
    SAMPLEAPP_SEND_PERIODIC_MSG_EVT,
    SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT ); /*调用定时函数,进行定时事件处理.3*/

    }
    //显示PANID
    zb_GetDeviceInfo(ZB_INFO_PAN_ID, &PANID);
    num_to_str(PANID, Display_Buf, 4 , 16);
    Gui_DrawFont_GBK16(94,32,BLACK,YELLOW,Display_Buf);


    }
    else
    {
    // Device is no longer in the network
    }

    break;

    default:
    break;
    }

    // Release the memory
    osal_msg_deallocate( (uint8 *)MSGpkt ); /*释放空间*/

    // Next - if one is available
    MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID ); /*调用数据接收函数接收数据*/


    }

    // return unprocessed events返回未处理的事件
    return (events ^ SYS_EVENT_MSG);
    }

    if ( events & CLEAR_EVT ) //处理使 n 定时清零事件
    { n=0;
    osal_start_timerEx(SampleApp_TaskID,CLEAR_EVT,CLEAR_EVENT_TIMEOUT);
    return (events ^ CLEAR_EVT);
    }

    if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT ) /*如果为定时事件,进行定时事件处理*/
    {

    if(SampleApp_NwkState == DEV_ROUTER)
    {

    //sendDummyReport();
    sendReport();
    osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT,
    (SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT + (osal_rand() & 0x00FF)) ); /*循环调用定时函数.2*/
    }
    else{
    DHT11_TEST();
    sendReport();

    num_to_str(ucharT_data_H, Display_Buf, 4 , 10 );
    Gui_DrawFont_GBK16(94,64,BLACK,YELLOW, Display_Buf);
    // Setup to send message again in normal period (+ a little jitter)
    osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT,
    (SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT + (osal_rand() & 0x00FF)) ); /*循环调用定时函数.2*/

    }
    // return unprocessed events
    return (events ^ SAMPLEAPP_SEND_PERIODIC_MSG_EVT);
    }

    // Discard unknown events
    return 0;
    }

    void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
    {
    uint16 flashTime;

    uint8 rssi_buf[4];
    uint8 Display_Buf[6] = {0};
    uint16 a;
    uint8 b;


    switch ( pkt->clusterId ) /*判断输入/输出簇ID*/
    {
    uint8 pFrame[ZB_RECV_LENGTH];

    case SAMPLEAPP_PERIODIC_CLUSTERID:
    // Start of Frame Delimiter
    pFrame[FRAME_SOF_OFFSET] = CPT_SOP; // Start of Frame Delimiter

    // Length
    pFrame[FRAME_LENGTH_OFFSET] = 10;

    // Command type
    pFrame[FRAME_CMD0_OFFSET] = LO_UINT16(ZB_RECEIVE_DATA_INDICATION);
    pFrame[FRAME_CMD1_OFFSET] = HI_UINT16(ZB_RECEIVE_DATA_INDICATION);

    // Source address
    pFrame[FRAME_DATA_OFFSET+ ZB_RECV_SRC_OFFSET] = (pkt->cmd.Data[4]);
    pFrame[FRAME_DATA_OFFSET+ ZB_RECV_SRC_OFFSET+ 1] = (pkt->cmd.Data[5]);

    // Command ID
    pFrame[FRAME_DATA_OFFSET+ ZB_RECV_CMD_OFFSET] = LO_UINT16(SENSOR_REPORT_CMD_ID);
    pFrame[FRAME_DATA_OFFSET+ ZB_RECV_CMD_OFFSET+ 1] = HI_UINT16(SENSOR_REPORT_CMD_ID);

    // Length
    pFrame[FRAME_DATA_OFFSET+ ZB_RECV_LEN_OFFSET] = LO_UINT16(4);
    pFrame[FRAME_DATA_OFFSET+ ZB_RECV_LEN_OFFSET+ 1] = HI_UINT16(4);

    // Data
    pFrame[FRAME_DATA_OFFSET+ ZB_RECV_DATA_OFFSET] = (pkt->cmd.Data[0]);
    pFrame[FRAME_DATA_OFFSET+ ZB_RECV_DATA_OFFSET+ 1] =(pkt->cmd.Data[1]);
    pFrame[FRAME_DATA_OFFSET+ ZB_RECV_DATA_OFFSET+ 2] = (pkt->cmd.Data[2]);
    pFrame[FRAME_DATA_OFFSET+ ZB_RECV_DATA_OFFSET+ 3] = (pkt->cmd.Data[3]);

    // Frame Check Sequence
    pFrame[ZB_RECV_LENGTH - 1] = calcFCS(&pFrame[FRAME_LENGTH_OFFSET], (ZB_RECV_LENGTH - 2) );

    //串口打印温度
    uint8 T[8];
    DHT11_TEST();
    T[0]=wendu_shi+48;
    T[1]=wendu_ge+48;
    HalUARTWrite(0,"temp=",5);
    HalUARTWrite(0,T,2);
    HalUARTWrite(0,"℃",2);
    HalUARTWrite(0,"\n",1);

    // Gui_DrawFont_GBK16(94,48,BLACK,YELLOW,Display_Buf);
    HalUARTWrite(HAL_UART_PORT_0,pFrame, ZB_RECV_LENGTH);

    break;

    case SAMPLEAPP_FLASH_CLUSTERID: /*如果输入/输出簇ID为SAMPLEAPP_FLASH_CLUSTERID*/
    flashTime = BUILD_UINT16(pkt->cmd.Data[1], pkt->cmd.Data[2] );
    HalLedBlink( HAL_LED_4, 4, 50, (flashTime / 4) ); /*接收到数据,并将收到的数据设定为LED闪烁时间*/
    HalUARTWrite(0,"haha",4);
    break;

    }

    }

  • SampleApp_Group裡面填什麼?

  • aps_Group_t SampleApp_Group; /*组信息定义*/

    afAddrType_t SampleApp_Flash_DstAddr;

    SampleApp_Flash_DstAddr.addrMode = (afAddrMode_t)afAddrGroup;
    SampleApp_Flash_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
    SampleApp_Flash_DstAddr.addr.shortAddr = SAMPLEAPP_FLASH_GROUP;

    #define SAMPLEAPP_FLASH_GROUP                  0x0001   /*组ID定义*/

    SampleApp_Group.ID = SAMPLEAPP_FLASH_GROUP;
    osal_memcpy( SampleApp_Group.name, "Group 1", 7 ); /*组名设置为group 1*/
    aps_AddGroup( SAMPLEAPP_ENDPOINT, &SampleApp_Group ); /*将组信息添加至aps层*/ /*组信息初始化.3*/

    #define SAMPLEAPP_MAX_CLUSTERS 2 /*最大输入/输出簇个数*/
    #define SAMPLEAPP_PERIODIC_CLUSTERID 1 /*输入/输出簇ID*/
    #define SAMPLEAPP_FLASH_CLUSTERID 2

  • 1. aps_AddGroup完先用aps_FindGroup或是aps_FindGroupForEndpoint先去檢查group有沒有加成功

    2.如果group有加成功,用sniffer抓包看看groupcast有沒有送出

  • 检查到已经加成功了, 路由节点可以收到组播消息就能证明协调器发送的组播消息送出了吧? 终端节点就是收不到

  • 路由节点可以收到组播消息是可以证明协调器发送的组播消息送出,建議你設置斷點在终端节的afIncomingData理頭調試看看afIncomingData有沒有收到组播消息

  • 没有收到组播消息

  • 那就還是要建議你搭配抓包調試终端节的afIncomingData

  • 我发现,我这个协调器发消息的地址是0XFFFF  这是广播不是组播,我明明发送的是组播消息,问题是出在这吗

  • 只用截圖無法判斷,可以附上完整的抓包檔嗎?

  • 請問你afIncomingData內的斷點設在那?

  • 设在 SampleApp_ProcessEvent( uint8 task_id, uint16 events ) 里的各种事件和SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )里的各种情况,

  • 所以你根本沒有照建議在afIncomingData內設置斷點調试?

  • 您说的afIncomingData具体在什么地方? 是AF.c中的吗

  • 断点设置到那,显示有错误,不会执行到那

  • 把optimize level降低后重新compile再设置断点到那試試

  • 我把等级降到最低了,还是有错误,执行不到这里

  • 你截圖給我看看执行不到哪里?

  • 先取消所有断点,再设置一個断点再afIncomingData裡試試

  • 终端节点可以运行到这里的断点了,但只是开头运行到这里一次,以后就回不来了

  • 你終端要有收到封包才會运行到afIncomingData、所以你要送個Group cast出來看一下終端會不會运行到afIncomingData

  • 我发现一个问题,如果在协调器的SampleApp_Init里加一个循环发送组播消息,终端节点是可以收到消息的,但是终端节点的原本读取温度并上传信息的功能就会失效。如果把组播语句放在协调器的判断语句里(如下代码中),终端节点又会收不到组播消息。这是因为接收消息和读取温度并上传信息冲突了吗?

    case AF_INCOMING_MSG_CMD:
    HAL_TOGGLE_LED1(); /*?*/
    SampleApp_MessageMSGCB( MSGpkt );

    n=n+1;
    m=n;

    num_to_str(m,Display_Buf, 4 , 16);
    Gui_DrawFont_GBK16(48,96,BLACK,YELLOW,Display_Buf);

    if (m>10)
    {

    uint8 data[1]={'9'};
    void SampleApp_SendGroupMessage(void);
    {
    if ( AF_DataRequest( &SampleApp_Flash_DstAddr, &SampleApp_epDesc,
    SAMPLEAPP_FLASH_CLUSTERID,
    1,
    data,
    &SampleApp_TransID,
    AF_DISCV_ROUTE,
    AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
    {
    }
    else
    {
    // Error occurred in request to send.
    }

  • 你有沒有抓包確認组播放在协调器的判断语句里的時候,组播有沒有送出?

  • 应该是送出的,因为路由节点接收到了协调器发送的组播消息

  • 這種情況下有抓包看看终端节点的读取温度并上传信息的封包送出嗎?

  • 组播放在协调器的判断语句中时,是可以收到终端节点发送的信息的,通过协调器的串口助手可以看到终端发来的温度,rssi等信息

  • 我沒辦法從你的描述判斷問題,你還是抓包看一下是什麼狀況吧