This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Zigbee cli how to automatically deal with, discover, bind and other work, how to automatically bind multiple devices, is this way suitable for low power?I wrote a piece of code that handled it automatically, but it was very unstable.Ieee request not succes

/**
 * Copyright (c) 2018 - 2019, Nordic Semiconductor ASA
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form, except as embedded into a Nordic
 *    Semiconductor ASA integrated circuit in a product or a software update for
 *    such product, must reproduce the above copyright notice, this list of
 *    conditions and the following disclaimer in the documentation and/or other
 *    materials provided with the distribution.
 *
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * 4. This software, with or without modification, must only be used with a
 *    Nordic Semiconductor ASA integrated circuit.
 *
 * 5. Any software provided in binary form under this license must not be reverse
 *    engineered, decompiled, modified and/or disassembled.
 *
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
/** @file
 *
 * @defgroup zigbee_examples_cli_agent_router main.c
 * @{
 * @ingroup zigbee_examples
 * @brief CLI agent for probing the Zigbee network.
 */
#include "zb_error_handler.h"
#include "sdk_config.h"
#include "zboss_api.h"

#ifdef ZIGBEE_MEM_CONFIG_MODEL
#if (ZIGBEE_MEM_CONFIG_MODEL == 0)
/* None of the files zb_mem_config_*.h included, use default memory settings */
#elif (ZIGBEE_MEM_CONFIG_MODEL == 1)
#include "zb_mem_config_min.h"
#elif (ZIGBEE_MEM_CONFIG_MODEL == 2)
#include "zb_mem_config_med.h"
#elif (ZIGBEE_MEM_CONFIG_MODEL == 3)
#include "zb_mem_config_max.h"
#else
#error ZIGBEE_MEM_CONFIG_MODEL unsupported value, please check sdk_config.h
#endif
#endif

#include "zb_ha_configuration_tool.h"
#include "zigbee_helpers.h"
#include "zigbee_cli.h"

#include "nrf_drv_clock.h"
#include "boards.h"
#include "app_timer.h"

#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#include "bsp.h"


#include "nrf_drv_swI2c.h"
#include "oledfont.h"
#include "nrf_delay.h"

#include "zboss_api_zdo.h"


#define MAX_CHILDREN                      10    
#define IEEE_CHANNEL_MASK                   (1l << ZIGBEE_CHANNEL)              /**< Scan only one, predefined channel to find the coordinator. */
#define ERASE_PERSISTENT_CONFIG             ZB_FALSE                              /**< Do not erase NVRAM to save the network parameters after device reboot or power-off. NOTE: If this option is set to ZB_TRUE then do full device erase for all network devices before running other samples. */
#define ZIGBEE_NETWORK_STATE_LED            BSP_BOARD_LED_2                     /**< LED indicating that light switch successfully joind ZigBee network. */
zb_ieee_addr_t        ieee_addr_req;



//my


#define ZIGBEE_CONFIGURE_REPORT_TSN                  3




// Defines how long to wait, in seconds, for Configure Reporting Response.
#define ZIGBEE_CLI_CONFIGURE_REPORT_RESP_TIMEOUT         5

// Defines default value for minimum interval inside configure reporting request.
#define ZIGBEE_CLI_CONFIGURE_REPORT_DEFAULT_MIN_INTERVAL 1
// Defines default value for maximum interval inside configure reporting request.
#define ZIGBEE_CLI_CONFIGURE_REPORT_DEFAULT_MAX_INTERVAL 60

// Defines default value for minimum value change inside configure reporting request.
#define ZIGBEE_CLI_CONFIGURE_REPORT_DEFAULT_VALUE_CHANGE NULL
#define NRF_LOG_SUBMODULE_NAME report



 zb_ieee_addr_t iees;
zb_uint16_t short_addr;
char ieee_addr_buf[17] = {0};
zb_ieee_addr_t dst_ieee_addr;

zb_ieee_addr_t ieee_addr;
zb_uint8_t param_sb;


#define BMS_TEMP_ENDPOINT                 10
#define ZIGBEE_CLI_BIND_RESP_TIMEOUT       5
#define MATCH_DESC_REQ_ROLE                 ZB_NWK_BROADCAST_ALL_DEVICES   
#define ZIGBEE_MANUAL_STEERING            ZB_FALSE   
#define MATCH_DESC_REQ_START_DELAY          (2 * ZB_TIME_ONE_SECOND)            //< Delay between the light switch startup and light bulb finding procedure.
#define MATCH_DESC_REQ_TIMEOUT              (5 * ZB_TIME_ONE_SECOND)  

#define BIND_DESC_REQ_START_DELAY          (4 * ZB_TIME_ONE_SECOND)            //< Delay between the light switch startup and light bulb finding procedure.
#define BIND_DESC_REQ_TIMEOUT              (7 * ZB_TIME_ONE_SECOND)  



static uint16_t iter = 0;

static zb_void_t find_timeout(zb_uint8_t param);
static zb_void_t bint_sensor_timeout(zb_uint8_t param);
static zb_void_t zb_subscribe_timeout(zb_uint8_t param);
typedef struct {
    zb_uint16_t profile_id;
    zb_uint16_t cluster_id;
    zb_uint16_t attr_id;
    zb_uint8_t  attr_type;
    zb_uint16_t interval_min;
    zb_uint16_t interval_max;
    zb_addr_u   remote_node;
    addr_type_t remote_addr_mode;
    zb_uint8_t  remote_ep;
} configure_reporting_req_t;

typedef struct sensor_params_s
{
	zb_uint8_t  bind_ret_ok;
  zb_uint8_t  endpoint;
  zb_uint16_t short_addr;
  zb_uint16_t mac_addr;
  zb_ieee_addr_t scr_ieee_addr;
  uint8_t           tsn;
} sensor_params_t;

typedef struct sensor_button_s
{
  zb_bool_t in_progress;
  zb_time_t timestamp;
} sensor_button_t;

typedef struct sensor_ctx_s
{
  sensor_params_t sensor_params;
  sensor_button_t      button;
} sensor_ctx_t;

static sensor_ctx_t m_device_ctx;



typedef struct {
    //nrf_cli_t const * p_cli;
    uint8_t           tsn;
    bool              taken;
    bool              is_broadcast;
} tsn_ctx_t_my;










uint16_t devList[500] = {0};

//my

zb_uint8_t zb_param;

static zb_void_t bind_sensor(zb_uint8_t param);
static zb_void_t zcl_device_cb(zb_uint8_t param);
static tsn_ctx_t_my m_tsn_ctx[ZIGBEE_CONFIGURE_REPORT_TSN];
static void sensor_subscribe(zb_uint8_t param);









#if !defined ZB_ROUTER_ROLE
#error Define ZB_ROUTER_ROLE to compile CLI agent (Router) source code.
#endif

static zb_uint8_t         m_attr_zcl_version   = ZB_ZCL_VERSION;
static zb_uint8_t         m_attr_power_source  = ZB_ZCL_BASIC_POWER_SOURCE_UNKNOWN;
static zb_uint16_t        m_attr_identify_time = 0;

/* Declare attribute list for Basic cluster. */
ZB_ZCL_DECLARE_BASIC_ATTRIB_LIST(basic_attr_list, &m_attr_zcl_version, &m_attr_power_source);

/* Declare attribute list for Identify cluster. */
ZB_ZCL_DECLARE_IDENTIFY_ATTRIB_LIST(identify_attr_list, &m_attr_identify_time);

/* Declare cluster list for CLI Agent device. */
/* Only clusters Identify and Basic have attributes. */
ZB_HA_DECLARE_CONFIGURATION_TOOL_CLUSTER_LIST(cli_agent_clusters,
                                              basic_attr_list,
                                              identify_attr_list);

/* Declare endpoint for CLI Agent device. */
ZB_HA_DECLARE_CONFIGURATION_TOOL_EP(cli_agent_ep,
                                    ZIGBEE_CLI_ENDPOINT,
                                    cli_agent_clusters);

/* Declare application's device context (list of registered endpoints) for CLI Agent device. */
ZB_HA_DECLARE_CONFIGURATION_TOOL_CTX(cli_agent_ctx, cli_agent_ep);






static void log_init(void)
{
    ret_code_t err_code = NRF_LOG_INIT(NULL);
    APP_ERROR_CHECK(err_code);

    NRF_LOG_DEFAULT_BACKENDS_INIT();
}



//my

//�ϱ�

//oled

#define OLED_CMD  0	//���
#define OLED_DATA 1	//���
#define Max_Column	128



void Write_IIC_Command(unsigned char IIC_Command)
{
   nrf_drv_swI2c_start();
   nrf_drv_swI2c_writeByte(0x78);            //Slave address,SA0=0
	nrf_drv_swI2c_wait_ack();	
   nrf_drv_swI2c_writeByte(0x00);			//write command
	nrf_drv_swI2c_wait_ack();	
   nrf_drv_swI2c_writeByte(IIC_Command); 
	nrf_drv_swI2c_wait_ack();	
   nrf_drv_swI2c_stop();
}
/**********************************************
// IIC Write Data
**********************************************/
void Write_IIC_Data(unsigned char IIC_Data)
{
   nrf_drv_swI2c_start();
   nrf_drv_swI2c_writeByte(0x78);			//D/C#=0; R/W#=0
	nrf_drv_swI2c_wait_ack();	
   nrf_drv_swI2c_writeByte(0x40);			//write data
	nrf_drv_swI2c_wait_ack();	
   nrf_drv_swI2c_writeByte(IIC_Data);
	nrf_drv_swI2c_wait_ack();	
   nrf_drv_swI2c_stop();
}
void OLED_WR_Byte(unsigned dat,unsigned cmd)
{
	if(cmd)
			{

		Write_IIC_Data(dat);
   
		}
	else {
   Write_IIC_Command(dat);
		
	}


}

void OLED_Init(void)
{
	OLED_WR_Byte(0xAE,OLED_CMD);//--display off
	OLED_WR_Byte(0x02,OLED_CMD);//---set low column address
	OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
	OLED_WR_Byte(0x40,OLED_CMD);//--set start line address  
	OLED_WR_Byte(0xB0,OLED_CMD);//--set page address
	OLED_WR_Byte(0x81,OLED_CMD); // contract control
	OLED_WR_Byte(0xFF,OLED_CMD);//--128   
	OLED_WR_Byte(0xA1,OLED_CMD);//set segment remap 
	OLED_WR_Byte(0xA6,OLED_CMD);//--normal / reverse
	OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
	OLED_WR_Byte(0x3F,OLED_CMD);//--1/32 duty
	OLED_WR_Byte(0xC8,OLED_CMD);//Com scan direction
	OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset
	OLED_WR_Byte(0x00,OLED_CMD);//
	
	OLED_WR_Byte(0xD5,OLED_CMD);//set osc division
	OLED_WR_Byte(0x80,OLED_CMD);//
	
	OLED_WR_Byte(0xD8,OLED_CMD);//set area color mode off
	OLED_WR_Byte(0x05,OLED_CMD);//
	
	OLED_WR_Byte(0xD9,OLED_CMD);//Set Pre-Charge Period
	OLED_WR_Byte(0xF1,OLED_CMD);//
	
	OLED_WR_Byte(0xDA,OLED_CMD);//set com pin configuartion
	OLED_WR_Byte(0x12,OLED_CMD);//
	
	OLED_WR_Byte(0xDB,OLED_CMD);//set Vcomh
	OLED_WR_Byte(0x30,OLED_CMD);//
	
	OLED_WR_Byte(0x8D,OLED_CMD);//set charge pump enable
	OLED_WR_Byte(0x14,OLED_CMD);//
	
	OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panel
}

//��������

	void OLED_Set_Pos(unsigned char x, unsigned char y) 
{ 
	OLED_WR_Byte(0xb0+y,OLED_CMD);
	OLED_WR_Byte((((x+2)&0xf0)>>4)|0x10,OLED_CMD);
	OLED_WR_Byte(((x+2)&0x0f),OLED_CMD); 
}   	  
//����OLED��ʾ    
void OLED_Display_On(void)
{
	OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC����
	OLED_WR_Byte(0X14,OLED_CMD);  //DCDC ON
	OLED_WR_Byte(0XAF,OLED_CMD);  //DISPLAY ON
}
//�ر�OLED��ʾ     
void OLED_Display_Off(void)
{
	OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC����
	OLED_WR_Byte(0X10,OLED_CMD);  //DCDC OFF
	OLED_WR_Byte(0XAE,OLED_CMD);  //DISPLAY OFF
}		   			 
//��������,������,������Ļ�Ǻ�ɫ��!��û����һ��!!!
void OLED_Clear(void)  
{  
	uint8_t i,n;		    
	for(i=0;i<8;i++)  
	{  
		OLED_WR_Byte (0xb0+i,OLED_CMD);    //����ҳ��ַ��0~7��
		OLED_WR_Byte (0x02,OLED_CMD);      //������ʾλ�á��е͵�ַ
		OLED_WR_Byte (0x10,OLED_CMD);      //������ʾλ�á��иߵ�ַ   
		for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA); 
	} //������ʾ
}
void OLED_On(void)  
{  
	uint8_t i,n;		    
	for(i=0;i<8;i++)  
	{  
		OLED_WR_Byte (0xb0+i,OLED_CMD);    //����ҳ��ַ��0~7��
		OLED_WR_Byte (0x02,OLED_CMD);      //������ʾλ�á��е͵�ַ
		OLED_WR_Byte (0x10,OLED_CMD);      //������ʾλ�á��иߵ�ַ   
		for(n=0;n<128;n++)OLED_WR_Byte(1,OLED_DATA); 
	} //������ʾ
}


void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size)
{      	
	unsigned char c=0,i=0;	
		c=chr-' ';//�õ�ƫ�ƺ��ֵ			
		if(x>Max_Column-1){x=0;y=y+2;}
		if(Char_Size ==16)
			{
			OLED_Set_Pos(x,y);	
			for(i=0;i<8;i++)
			OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);
			OLED_Set_Pos(x,y+1);
			for(i=0;i<8;i++)
			OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
			}
			else {	
				OLED_Set_Pos(x,y);
				for(i=0;i<6;i++)
				OLED_WR_Byte(F6x8[c][i],OLED_DATA);
				
			}
}
void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t Char_Size)
{
	unsigned char j=0;
	while (chr[j]!='\0')
	{		OLED_ShowChar(x,y,chr[j],Char_Size);
			x+=8;
		if(x>120){x=0;y+=2;}
			j++;
	}
}

uint32_t oled_pow(uint8_t m,uint8_t n)
{
	uint32_t result=1;	 
	while(n--)result*=m;    
	return result;
}				  
//��ʾ2������
//x,y :�������	 
//len :���ֵ�λ��
//size:�����С
//mode:ģʽ	0,���ģʽ;1,����ģʽ
//num:��ֵ(0~4294967295);	 		  
void OLED_ShowNum(uint8_t x,uint8_t y,uint32_t num,uint8_t len,uint8_t size2)
{         	
	uint8_t t,temp;
	uint8_t enshow=0;						   
	for(t=0;t<len;t++)
	{
		temp=(num/oled_pow(10,len-t-1))%10;
		if(enshow==0&&t<(len-1))
		{
			if(temp==0)
			{
				OLED_ShowChar(x+(size2/2)*t,y,' ',size2);
				continue;
			}else enshow=1; 
		 	 
		}
	 	OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2); 
	}
} 
//��ʾһ���ַ��Ŵ�

int zcl_attr_tostr(char * p_str_buf, uint16_t buf_len, zb_uint16_t attr_type, zb_uint8_t * p_attr)
{
    int bytes_written = 0;
    int string_len;
    int i;

    if ((p_str_buf == NULL) || (p_attr == NULL))
    {
        return -1;
    }

    switch (attr_type)
    {
        /* Boolean */
        case ZB_ZCL_ATTR_TYPE_BOOL:
            bytes_written = snprintf(p_str_buf, buf_len, "%s", *((zb_bool_t *)p_attr) ? "True" : "False");
            break;

        /* 1 byte */
        case ZB_ZCL_ATTR_TYPE_8BIT:
        case ZB_ZCL_ATTR_TYPE_8BITMAP:
        case ZB_ZCL_ATTR_TYPE_U8:
        case ZB_ZCL_ATTR_TYPE_8BIT_ENUM:
            bytes_written = snprintf(p_str_buf, buf_len, "%hu", *((zb_uint8_t*)p_attr));
            break;

        case ZB_ZCL_ATTR_TYPE_S8:
            bytes_written = snprintf(p_str_buf, buf_len, "%hd", *((zb_int8_t*)p_attr));
            break;

        /* 2 bytes */
        case ZB_ZCL_ATTR_TYPE_16BIT:
        case ZB_ZCL_ATTR_TYPE_16BITMAP:
        case ZB_ZCL_ATTR_TYPE_U16:
        case ZB_ZCL_ATTR_TYPE_16BIT_ENUM:
            bytes_written = snprintf(p_str_buf, buf_len, "%hu", *((zb_uint16_t*)p_attr));
            break;

        case ZB_ZCL_ATTR_TYPE_S16:
            bytes_written = snprintf(p_str_buf, buf_len, "%hd", *((zb_int16_t*)p_attr));
            break;

        /* 4 bytes */
        case ZB_ZCL_ATTR_TYPE_32BIT:
        case ZB_ZCL_ATTR_TYPE_32BITMAP:
        case ZB_ZCL_ATTR_TYPE_U32:
            bytes_written = snprintf(p_str_buf, buf_len, "%u", *((zb_uint32_t*)p_attr));
            break;

        case ZB_ZCL_ATTR_TYPE_S32:
            bytes_written = snprintf(p_str_buf, buf_len, "%d", *((zb_int32_t*)p_attr));
            break;

        /* String */
        case ZB_ZCL_ATTR_TYPE_CHAR_STRING:
            string_len = p_attr[0];
            p_attr++;

            if ((buf_len - bytes_written) < (string_len + 1))
            {
                return -1;
            }

            for (i = 0; i < string_len; i++)
            {
                /*lint -save -e661 */
                p_str_buf[bytes_written + i] = ((char *)p_attr)[i];
                /*lint -restore */
            }
            p_str_buf[bytes_written + i] = '\0';
            bytes_written += string_len + 1;
            break;

        case ZB_ZCL_ATTR_TYPE_IEEE_ADDR:
            /*lint -e661 -e662 -save */
            bytes_written = to_hex_str(p_str_buf, buf_len, (const uint8_t *)p_attr, sizeof(zb_64bit_addr_t), true);
            /*lint -restore */
            break;

        default:
            bytes_written = snprintf(p_str_buf, buf_len, "Value type 0x%x unsupported", attr_type);
            break;
    }

    return bytes_written;
}

static void print_attr(zb_zcl_parsed_hdr_t * p_zcl_hdr, zb_uint8_t param)
{
      zb_buf_t                 * p_buf         = ZB_BUF_FROM_REF(param);
    zb_zcl_report_attr_req_t * p_attr_resp   = NULL;
    int                        bytes_written = 0;
    char                       print_buf[255];

    if (p_zcl_hdr->addr_data.common_data.source.addr_type == ZB_ZCL_ADDR_TYPE_SHORT)
    {
        NRF_LOG_INFO( "Received value  node 0x%04x",
                         p_zcl_hdr->addr_data.common_data.source.u.short_addr);
    }
    else
    {
        bytes_written = ieee_addr_to_str(print_buf, sizeof(print_buf), p_zcl_hdr->addr_data.common_data.source.u.ieee_addr);
        if (bytes_written < 0)
        {
           NRF_LOG_INFO( "Received value updates from the remote node (unknown address)");
        }
        else
        {
            NRF_LOG_INFO( "Received value updates from node 0x%s", nrf_log_push(print_buf));
        }
    }

//
    ZB_ZCL_GENERAL_GET_NEXT_REPORT_ATTR_REQ(p_buf, p_attr_resp);


    NRF_LOG_INFO("Profile: 0x%04x Cluster: 0x%04x Attribute: 0x%04x Type: %hu Valuesss: %s",
                p_zcl_hdr->profile_id, p_zcl_hdr->cluster_id, p_attr_resp->attr_id,
               p_attr_resp->attr_type, nrf_log_push(print_buf));
    bytes_written = 0;
    while (p_attr_resp != NULL)
    {
        bytes_written = zcl_attr_tostr(&print_buf[bytes_written],
                                        sizeof(print_buf) - bytes_written,
                                        p_attr_resp->attr_type,
                                        p_attr_resp->attr_value);

        if (bytes_written < 0)
        {
            NRF_LOG_ERROR("Unable to print updated attribute value");
        }
        else
        {    //NRF_LOG_INFO
            NRF_LOG_INFO("Profile: 0x%04x Cluster: 0x%04x Attribute: 0x%04x Type: %hu Value: %s",
                p_zcl_hdr->profile_id, p_zcl_hdr->cluster_id, p_attr_resp->attr_id,
               p_attr_resp->attr_type, nrf_log_push(print_buf));
        }

        ZB_ZCL_GENERAL_GET_NEXT_REPORT_ATTR_REQ(p_buf, p_attr_resp);
    }
    




}



















static void zb_subscribe_unsubscribe_cb(zb_uint8_t param)
{
    zb_ret_t                           zb_err_code;
    zb_buf_t                         * p_buf  = ZB_BUF_FROM_REF(param);
    zb_zcl_configure_reporting_res_t * p_resp = NULL;
    zb_bool_t                          failed = ZB_FALSE;
   


     NRF_LOG_INFO("  reporting  callback ");
    zb_err_code = ZB_SCHEDULE_ALARM_CANCEL(zb_subscribe_timeout, ZB_ALARM_ANY_PARAM);
    if (zb_err_code != RET_OK)
    {
    //    print_error(p_tsn_ctx->p_cli, "Unable to cancel timeout timer");
      //  goto free_tsn_ctx;

       NRF_LOG_INFO("Unable to cancel timeout timer");

    }

    // Check if response contains only status code.
    if (sizeof(zb_zcl_configure_reporting_res_t) > ZB_BUF_LEN(p_buf))
    {
        p_resp = (zb_zcl_configure_reporting_res_t*)ZB_BUF_BEGIN(p_buf);
        if (p_resp->status == ZB_ZCL_STATUS_SUCCESS)
        {
          

          NRF_LOG_INFO("  reporting   is ok ");
           

        }
        else
        {
           NRF_LOG_INFO( "Error: Unable to configure reporting. Status: %d", p_resp->status);
        }
     
    }


    // Received a full Configure Reporting Response frame.
    ZB_ZCL_GENERAL_GET_NEXT_CONFIGURE_REPORTING_RES(p_buf, p_resp);
    if (p_resp == NULL)
    {
       

      NRF_LOG_INFO("Unable to parse configure reporting response");

    }


    while (p_resp != NULL)
    {
        if (p_resp->status == ZB_ZCL_STATUS_SUCCESS)
        {
            switch (p_resp->direction)
            {
                case ZB_ZCL_CONFIGURE_REPORTING_SEND_REPORT:
                 NRF_LOG_INFO("Local subscription to attribute ID %hx updated\r\n",p_resp->attr_id);
                    break;

                case ZB_ZCL_CONFIGURE_REPORTING_RECV_REPORT:
              NRF_LOG_INFO( "Remote node subscription to receive attribute ID %hx updated\r\n",   p_resp->attr_id);
                    break;

                default:
                    NRF_LOG_INFO( "Unknown reporting configuration direction for attribute %hx",p_resp->attr_id);
                    failed = ZB_TRUE;
                    break;
            }
        }
        else
        {
            NRF_LOG_INFO( "Unable to configure attribute %hx reporting. Status: %hd\r\n",  p_resp->attr_id, p_resp->status);


            failed = ZB_TRUE;
        }
        ZB_ZCL_GENERAL_GET_NEXT_CONFIGURE_REPORTING_RES(p_buf, p_resp);
    }

    if (failed == ZB_TRUE)
    {
       

        NRF_LOG_INFO("One or more attributes reporting were not configured successfully");

    }
    else
    {
        //print_done(p_tsn_ctx->p_cli, ZB_FALSE);
    }

//free_tsn_ctx:
  //  invalidate_ctx(p_tsn_ctx);
    ZB_FREE_BUF_BY_REF(param);





}

static void zb_ieee_addr_req(zb_uint8_t param);

static void zb_ieee_addr_timeout(zb_uint8_t param)
{
    zb_ret_t                  zb_err_code;


if(param)
{
  
  
         NRF_LOG_INFO("ieee addrss req timeout ");
  
        zb_err_code = ZB_SCHEDULE_ALARM(zb_ieee_addr_req, param, MATCH_DESC_REQ_START_DELAY);
        ZB_ERROR_CHECK(zb_err_code);
        zb_err_code = ZB_SCHEDULE_ALARM(zb_ieee_addr_timeout, 0, MATCH_DESC_REQ_TIMEOUT);
        ZB_ERROR_CHECK(zb_err_code);



}
else
{

       zb_err_code = ZB_GET_OUT_BUF_DELAYED(zb_ieee_addr_timeout);
        ZB_ERROR_CHECK(zb_err_code);



}






}











zb_void_t ieee_addr_callback(zb_uint8_t param)
{




    NRF_LOG_INFO("ieee addrss callback  ");
    zb_buf_t                * p_buf  = ZB_BUF_FROM_REF(param);
    zb_zdo_ieee_addr_resp_t * p_resp = (zb_zdo_ieee_addr_resp_t *)ZB_BUF_BEGIN(p_buf);
    zb_ret_t                  zb_err_code;
    if (p_resp->status == ZB_ZDP_STATUS_SUCCESS)
    {
        zb_address_ieee_ref_t addr_ref_req;
        
        zb_uint16_t           nwk_addr_req;
        zb_ret_t              ret;

        ZB_LETOH64(ieee_addr_req, p_resp->ieee_addr_remote_dev);

        
        ZB_LETOH16(&nwk_addr_req, &(p_resp->nwk_addr_remote_dev));
        NRF_LOG_INFO("ieee req :%d",(const uint8_t *)ieee_addr_req);
			

			
        ret = zb_address_update(ieee_addr_req, nwk_addr_req, ZB_TRUE, &addr_ref_req);
        if (ret == RET_OK)
        {
					
	 NRF_LOG_INFO("ieee req is ok");
					
          NRF_LOG_INFO("ieee req :%d",(const uint8_t *)ieee_addr_req);
          zb_err_code = ZB_SCHEDULE_ALARM_CANCEL(zb_ieee_addr_timeout, ZB_ALARM_ANY_PARAM);         
        
        }else{

          NRF_LOG_INFO("ieee req :%d", p_resp->status);


        }
        




     }
   

   ZB_FREE_BUF_BY_REF(param);
		 
		 //sensor_subscribe
		 
		//zb_subscribe_timeout




		 
      if(m_device_ctx.sensor_params.short_addr != 0x0000)
								 {
									 
	    NRF_LOG_INFO("bind    .........");
					
        zb_err_code = ZB_SCHEDULE_ALARM(bind_sensor, param, MATCH_DESC_REQ_START_DELAY);
        ZB_ERROR_CHECK(zb_err_code);
        zb_err_code = ZB_SCHEDULE_ALARM(bint_sensor_timeout, 0, MATCH_DESC_REQ_TIMEOUT);
        ZB_ERROR_CHECK(zb_err_code);
      			 
								 }
		 
		 
		 
		 
		 
		 
		 
		 
		 
   


}


static void zb_ieee_addr_req(zb_uint8_t param)
{

       zb_buf_t   * p_buf=NULL;
       p_buf=ZB_GET_OUT_BUF();
       if(p_buf==NULL)
       {

         NRF_LOG_INFO("not bind command ");
       
       }
	   
	
   zb_zdo_ieee_addr_req_t *req_t=ZB_GET_BUF_PARAM(p_buf, zb_zdo_ieee_addr_req_t);



   NRF_LOG_INFO("ieee addrss req");

  // zb_buf_t * buf=ZB_GET_OUT_BUF();
   //zb_zdo_ieee_addr_req_t *req_t=NULL;
   //ZB_BUF_INITIAL_ALLOC(buf,sizeof(zb_zdo_ieee_addr_req_t),req_t);
   
  
   req_t->start_index=0;
   req_t->request_type=0;
   req_t->nwk_addr=m_device_ctx.sensor_params.short_addr;
    
   m_device_ctx.sensor_params.tsn=zb_zdo_ieee_addr_req(ZB_REF_FROM_BUF(p_buf), ieee_addr_callback);
	
    NRF_LOG_INFO("ieee command req start  ");
  if(m_device_ctx.sensor_params.tsn==ZB_ZDO_INVALID_TSN)
  {
      NRF_LOG_INFO("ieee command   ZB_ZDO_INVALID_TSN");
  }
	
	

    ZB_FREE_BUF(p_buf);

}














static zb_uint8_t ep_report(zb_uint8_t param)
{
    zb_buf_t            * p_zcl_cmd_buf = (zb_buf_t *)ZB_BUF_FROM_REF(param);
    zb_zcl_parsed_hdr_t * p_cmd_info    = ZB_GET_BUF_PARAM(p_zcl_cmd_buf, zb_zcl_parsed_hdr_t);
    zb_uint8_t          p_tsn_ctx;

    if (p_cmd_info->cmd_id == ZB_ZCL_CMD_REPORT_ATTRIB)
    {
        print_attr(p_cmd_info, param);
        ZB_FREE_BUF_BY_REF(param);
        return ZB_TRUE;
    }
    else if (p_cmd_info->cmd_id == ZB_ZCL_CMD_CONFIG_REPORT_RESP)
    {
        // Find command context by ZCL sequence number.
        p_tsn_ctx = p_cmd_info->seq_number;
        if (p_tsn_ctx != NULL)
        {
            zb_subscribe_unsubscribe_cb(param);
            return ZB_TRUE;
        }
    }

    return ZB_FALSE;
}













static void sensor_subscribe(zb_uint8_t param)
{

    configure_reporting_req_t   req;
    zb_buf_t                  * p_buf;
    zb_uint8_t                * p_cmd_ptr;
    zb_ret_t                    zb_err_code;
    zb_bool_t                   subscribe;

    NRF_LOG_INFO("sensor_subscribe");
   // OLED_ShowString(35,0,"sensor_subscribe  in!",16);nrf_delay_ms(1);


   
     OLED_Clear();nrf_delay_us(100) ;
	    OLED_ShowString(35,0,"sensor_subscribe",26);nrf_delay_ms(1);


    req.remote_addr_mode = parse_address(ieee_addr_buf, &req.remote_node, ADDR_ANY);
     if (req.remote_addr_mode == ADDR_INVALID)
    {
       //"Invalid remote address"


       NRF_LOG_INFO("Invalid remote address");
        return;
    }


    //type for subscribe  
    
    req.remote_ep=10;
    req.cluster_id=ZB_ZCL_CLUSTER_ID_PRESSURE_MEASUREMENT;
    req.profile_id=ZB_AF_HA_PROFILE_ID;
    req.attr_id=0;
    req.attr_type=41;

    //

    req.interval_min = ZIGBEE_CLI_CONFIGURE_REPORT_DEFAULT_MIN_INTERVAL;
    req.interval_max = ZIGBEE_CLI_CONFIGURE_REPORT_DEFAULT_MAX_INTERVAL;
    //��������

    p_buf = ZB_GET_OUT_BUF();
    if(p_buf==NULL)
    {

     NRF_LOG_INFO("not sensor subscribe command *****");
   
    }




    ZB_ZCL_GENERAL_INIT_CONFIGURE_REPORTING_SRV_REQ(p_buf,
                                                    p_cmd_ptr,
                                                    ZB_ZCL_ENABLE_DEFAULT_RESPONSE);
    ZB_ZCL_GENERAL_ADD_SEND_REPORT_CONFIGURE_REPORTING_REQ(p_cmd_ptr,
        req.attr_id, req.attr_type, req.interval_min, req.interval_max,
        ZIGBEE_CLI_CONFIGURE_REPORT_DEFAULT_VALUE_CHANGE);
    ZB_ZCL_GENERAL_SEND_CONFIGURE_REPORTING_REQ(p_buf, p_cmd_ptr,
        req.remote_node, req.remote_addr_mode, req.remote_ep, 64,
        req.profile_id, req.cluster_id, NULL);
    //
   zb_err_code = ZB_SCHEDULE_ALARM(zb_subscribe_timeout, 0,ZIGBEE_CLI_CONFIGURE_REPORT_RESP_TIMEOUT * ZB_TIME_ONE_SECOND);

    if (zb_err_code != RET_OK)
    {
       NRF_LOG_INFO("Unable to schedule timeout timer");
        
    }
     



   
}

 















static zb_void_t find_sensor_cb(zb_uint8_t param)
{

  //eui64
  /*
    zb_uint16_t short_addr;
    zb_ieee_addr_t addr;
    char ieee_addr_buf[17] = {0};
    zb_get_long_address(addr);
    ieee_addr_to_str(ieee_addr_buf, sizeof(ieee_addr_buf), addr);
    NRF_LOG_INFO("eui64 out addr: %s ",NRF_LOG_PUSH(ieee_addr_buf) );

    short_addr = zb_address_short_by_ieee(addr);
     
    NRF_LOG_INFO("short out addr: %04x ", short_addr);*/
 
 //end eui64


    
    
    zb_buf_t                   * p_buf  = ZB_BUF_FROM_REF(param);                              // Resolve buffer number to buffer address
    zb_zdo_match_desc_resp_t   * p_resp = (zb_zdo_match_desc_resp_t *) ZB_BUF_BEGIN(p_buf);    // Get the begining of the response
    zb_apsde_data_indication_t * p_ind  = ZB_GET_BUF_PARAM(p_buf, zb_apsde_data_indication_t); // Get the pointer to the parameters buffer, which stores APS layer response
    zb_uint8_t                 * p_match_ep;
    zb_ret_t                     zb_err_code;
     if ((p_resp->status == ZB_ZDP_STATUS_SUCCESS) && (p_resp->match_len > 0) && (!m_device_ctx.sensor_params.short_addr))
    {
        /* Match EP list follows right after response header */
        p_match_ep = (zb_uint8_t *)(p_resp + 1);

        /* We are searching for exact cluster, so only 1 EP may be found */
        m_device_ctx.sensor_params.endpoint   = *p_match_ep;
        m_device_ctx.sensor_params.short_addr = p_ind->src_addr;
        m_device_ctx.sensor_params.mac_addr = p_ind->mac_src_addr;


        NRF_LOG_INFO("Found sensor short_addr: %04x", m_device_ctx.sensor_params.short_addr);

       

        ZB_SCHEDULE_ALARM_CANCEL(find_timeout, ZB_ALARM_ANY_PARAM);


        if(m_device_ctx.sensor_params.short_addr != 0x0000){
         NRF_LOG_INFO("IEEE  REQ sensor1 ");
					
        zb_err_code = ZB_SCHEDULE_ALARM(zb_ieee_addr_req, param, MATCH_DESC_REQ_START_DELAY);
        ZB_ERROR_CHECK(zb_err_code);
        zb_err_code = ZB_SCHEDULE_ALARM(zb_ieee_addr_timeout, 0, MATCH_DESC_REQ_TIMEOUT);
        ZB_ERROR_CHECK(zb_err_code);



        }
       // ZB_ERROR_CHECK(zb_err_code);

      //  bsp_board_led_on(BULB_FOUND_LED);
    }

    if (param)
    {
        ZB_FREE_BUF_BY_REF(param);
    }
    






      if(m_device_ctx.sensor_params.short_addr != 0x0000)
								 {
									 
	  NRF_LOG_INFO("IEEE.......... ");
					
        zb_err_code = ZB_SCHEDULE_ALARM(zb_ieee_addr_req, param, MATCH_DESC_REQ_START_DELAY);
        ZB_ERROR_CHECK(zb_err_code);
        zb_err_code = ZB_SCHEDULE_ALARM(zb_ieee_addr_timeout, 0, MATCH_DESC_REQ_TIMEOUT);
        ZB_ERROR_CHECK(zb_err_code);
									 
								 }






}




static zb_void_t bind_sensor_cb(zb_uint8_t param)
{


    zb_buf_t           * p_buf  = ZB_BUF_FROM_REF(param);
    zb_zdo_bind_resp_t * p_resp = (zb_zdo_bind_resp_t *)ZB_BUF_BEGIN(p_buf);
    zb_ret_t             zb_err_code;
   

    


		    m_device_ctx.sensor_params.bind_ret_ok =p_resp->status; 
		
    if (p_resp->status == ZB_ZDP_STATUS_SUCCESS)
    {
			
       ZB_FREE_BUF_BY_REF(param);	
			sensor_subscribe(param);
       
      NRF_LOG_INFO("bind_sensor is ok");
      zb_err_code = ZB_SCHEDULE_ALARM_CANCEL(bint_sensor_timeout, ZB_ALARM_ANY_PARAM);
		  
      }
    else
    {
       
     NRF_LOG_INFO("bind status %d",p_resp->status);

    }

   ZB_FREE_BUF_BY_REF(param);


}





static zb_void_t bind_sensor(zb_uint8_t param)
{ 
       //zb_buf_t                  * p_buf = ZB_BUF_FROM_REF(param); // Resolve buffer number to buffer address
    //zb_zdo_match_desc_param_t * p_req;

    /* Initialize pointers inside buffer and reserve space for zb_zdo_match_desc_param_t request */
    //UNUSED_RETURN_VALUE(ZB_BUF_INITIAL_ALLOC(p_buf, sizeof(zb_zdo_match_desc_param_t) + (1) * sizeof(zb_uint16_t), p_req));
      zb_buf_t                * p_buf=NULL;
       p_buf=ZB_GET_OUT_BUF();
       if(p_buf==NULL)
       {

         NRF_LOG_INFO("not bind command ");
       
       }
	   
	
    zb_zdo_bind_req_param_t * p_req=ZB_GET_BUF_PARAM(p_buf, zb_zdo_bind_req_param_t);
	 //UNUSED_RETURN_VALUE(ZB_BUF_INITIAL_ALLOC(p_buf, sizeof(zb_zdo_bind_req_param_t) + (1) * sizeof(zb_uint16_t), p_req));
	
	
	//=ZB_GET_BUF_PARAM(p_buf, zb_zdo_bind_req_param_t);
     zb_ret_t                  zb_err_code;
    //bind req type 
    //ZIGBEE_CLI_ENDPOINT
    // zb_apsme_binding_req_t req;
    // req = ZB_GET_BUF_PARAM(p_buf, zb_apsme_binding_req_t);

    p_req->dst_addr_mode=ZB_BIND_DST_ADDR_MODE_64_BIT_EXTENDED;//
    // p_req->dst_addr_mode= ZB_APS_ADDR_MODE_64_ENDP_PRESENT;
    //req->addr_mode = ZB_APS_ADDR_MODE_64_ENDP_PRESENT;
   NRF_LOG_INFO("bind sensor addr: %04x", m_device_ctx.sensor_params.short_addr);
   p_req->src_endp=m_device_ctx.sensor_params.endpoint;
  // p_req->src_address = parse_long_address(m_device_ctx.sensor_params.mac_addr, p_req->src_address);
 
   p_req->dst_endp=ZIGBEE_CLI_ENDPOINT;
   
   p_req->cluster_id=ZB_ZCL_CLUSTER_ID_PRESSURE_MEASUREMENT;
	 
	 
	
  
  
  

 
    ZB_MEMCPY(p_req->src_address, &ieee_addr_req, sizeof(zb_ieee_addr_t));
  
   ZB_MEMCPY(p_req->dst_address.addr_long, &ieee_addr, sizeof(zb_ieee_addr_t));
         p_req->req_dst_addr= zb_address_short_by_ieee(ieee_addr_req);

   
   
   m_device_ctx.sensor_params.tsn=zb_zdo_bind_req(ZB_REF_FROM_BUF(p_buf), bind_sensor_cb);

    NRF_LOG_INFO("bind sensor main ");
  if(m_device_ctx.sensor_params.tsn==ZB_ZDO_INVALID_TSN)
  {
    NRF_LOG_INFO("bind sensor ZB_ZDO_INVALID_TSN");
   }



   //zb_err_code = ZB_SCHEDULE_ALARM(bint_sensor_timeout,m_device_ctx.sensor_params.tsn,ZIGBEE_CLI_BIND_RESP_TIMEOUT * ZB_TIME_ONE_SECOND);
   //ZB_ERROR_CHECK(zb_err_code);
	//NRF_LOG_INFO("bind_sensor. 2");
	
	

}
static zb_void_t bint_sensor_timeout(zb_uint8_t param)

{

   zb_ret_t                  zb_err_code;
   
	
	  
	
	
	

    if(param)
    {
    
    
        NRF_LOG_INFO("bind sensor timeout ");
        zb_err_code = ZB_SCHEDULE_ALARM(bind_sensor, param, MATCH_DESC_REQ_START_DELAY );
        ZB_ERROR_CHECK(zb_err_code);
        zb_err_code = ZB_SCHEDULE_ALARM(bint_sensor_timeout, 0, MATCH_DESC_REQ_TIMEOUT );
        ZB_ERROR_CHECK(zb_err_code);
       
    
    }
    else
    {
     zb_err_code = ZB_GET_OUT_BUF_DELAYED(bint_sensor_timeout);
     ZB_ERROR_CHECK(zb_err_code);


    }



}




static zb_void_t find_sensor(zb_uint8_t param)
{


    zb_buf_t                  * p_buf = ZB_BUF_FROM_REF(param); // Resolve buffer number to buffer address
    zb_zdo_match_desc_param_t * p_req;

    /* Initialize pointers inside buffer and reserve space for zb_zdo_match_desc_param_t request */
    UNUSED_RETURN_VALUE(ZB_BUF_INITIAL_ALLOC(p_buf, sizeof(zb_zdo_match_desc_param_t) + (1) * sizeof(zb_uint16_t), p_req));

    p_req->nwk_addr         = MATCH_DESC_REQ_ROLE;              // Send to devices specified by MATCH_DESC_REQ_ROLE
    p_req->addr_of_interest = MATCH_DESC_REQ_ROLE;              // Get responses from devices specified by MATCH_DESC_REQ_ROLE
    p_req->profile_id       = ZB_AF_HA_PROFILE_ID;              // Look for Home Automation profile clusters
    // Ҫ��
    /* We are searching for 2 clusters: On/Off and Level Control Server */
    p_req->num_in_clusters  = 1;
    p_req->num_out_clusters = 0;
    /*lint -save -e415 // Suppress warning 415 "likely access of out-of-bounds pointer" */
   // p_req->cluster_list[0]  = ZB_ZCL_CLUSTER_ID_DOOR_LOCK;
    p_req->cluster_list[1]  = ZB_ZCL_CLUSTER_ID_PRESSURE_MEASUREMENT;
    /*lint -restore */
     
    NRF_LOG_INFO(" sensor short addr  %04x",m_device_ctx.sensor_params.short_addr);
    //NRF_LOG_INFO(" sensor  nwk_addr  %s",p_req->nwk_addr);

   // m_device_ctx.sensor_params.short_addr = 0x00; // Reset short address in order to parse only one response.
    UNUSED_RETURN_VALUE(zb_zdo_match_desc_req(param, find_sensor_cb));


  


}


static zb_void_t zb_subscribe_timeout(zb_uint8_t param)
{

   
    if(param)
    {
     
     NRF_LOG_INFO("zb_subscribe_timeout   time out");


    
    }
    else
    {

     
    }




}


static zb_void_t find_timeout(zb_uint8_t param)
{


 zb_ret_t zb_err_code;

    if (param)
    {  

        NRF_LOG_INFO("Found sensor addr: %04x", m_device_ctx.sensor_params.short_addr);
        NRF_LOG_INFO("sensor not found, try again");
        zb_err_code = ZB_SCHEDULE_ALARM(find_sensor, param, MATCH_DESC_REQ_START_DELAY);
        ZB_ERROR_CHECK(zb_err_code);
        zb_err_code = ZB_SCHEDULE_ALARM(find_timeout, 0, MATCH_DESC_REQ_TIMEOUT);
        ZB_ERROR_CHECK(zb_err_code);
    }
    else
    {
        zb_err_code = ZB_GET_OUT_BUF_DELAYED(find_timeout);
        ZB_ERROR_CHECK(zb_err_code);
    }





}







/**@brief Callback used in order to visualise network steering period.
 *
 * @param[in]   param   Not used. Required by callback type definition.
 */
static zb_void_t steering_finished(zb_uint8_t param)
{
    UNUSED_PARAMETER(param);
    NRF_LOG_INFO("Network steering finished");
   // bsp_board_led_off(ZIGBEE_NETWORK_STATE_LED);
}




/**@brief Retry to form a Zigbee network. */
static zb_void_t bdb_restart_top_level_commissioning(zb_uint8_t param)
{
    UNUSED_RETURN_VALUE(bdb_start_top_level_commissioning(ZB_BDB_NETWORK_STEERING));
}

//ez mode callback























/*
static zb_void_t zcl_device_cb(zb_uint8_t param)
{
    NRF_LOG_INFO("zcl_device_cb");
   
    zb_uint8_t                       cluster_id;
    zb_uint8_t                       attr_id;
    zb_buf_t                       * p_buffer = ZB_BUF_FROM_REF(param);
    zb_zcl_device_callback_param_t * p_device_cb_param = ZB_GET_BUF_PARAM(p_buffer, zb_zcl_device_callback_param_t);

    NRF_LOG_INFO("zcl_device_cb id %hd", p_device_cb_param->device_cb_id);

   
    p_device_cb_param->status = RET_OK;
    NRF_LOG_INFO("device_cb_id: %d", p_device_cb_param->device_cb_id);

    switch (p_device_cb_param->device_cb_id)
    {
        case ZB_ZCL_SHADE_GET_VALUE_CB_ID:
            cluster_id = p_device_cb_param->cb_param.set_attr_value_param.cluster_id;
            attr_id    = p_device_cb_param->cb_param.set_attr_value_param.attr_id;
            NRF_LOG_INFO("cluster_id: %d", cluster_id);
            NRF_LOG_INFO("attr_id: %d", attr_id);
            switch (attr_id)
            {
              case ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID:
                NRF_LOG_INFO("Get temp value: %d", attr_id);
              break;
              case ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_VOLTAGE_ID:
                NRF_LOG_INFO("Get bat volt value: %d", attr_id);
              break;
              default:
                NRF_LOG_INFO("Unhandled cluster attribute id: %d", cluster_id);
              break;
            }
        break;
        case ZB_ZCL_SET_ATTR_VALUE_CB_ID:
            cluster_id = p_device_cb_param->cb_param.set_attr_value_param.cluster_id;
            attr_id    = p_device_cb_param->cb_param.set_attr_value_param.attr_id;

            if (cluster_id == ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT)
            {
                uint8_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data8;

                NRF_LOG_INFO("attribute id %d", attr_id);
                if (attr_id == ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID)
                {
                    NRF_LOG_INFO("Get temp value: %d", value);
                }
            }
        default:
            p_device_cb_param->status = RET_ERROR;
            break;
    }

    NRF_LOG_INFO("zcl_device_cb status: %hd", p_device_cb_param->status);
}
*/
/*
static void buttons_handler(bsp_event_t evt)
{
    zb_ret_t   zb_err_code;
    zb_int32_t button;

    switch(evt)
    {
        case BSP_EVENT_KEY_0:
            //button = LIGHT_SWITCH_BUTTON_ON;
            break;

        case BSP_EVENT_KEY_1:
            //button = LIGHT_SWITCH_BUTTON_OFF;
            break;

        case BSP_EVENT_KEY_2:
                NRF_LOG_INFO("go to find sensor ");
                zb_err_code = ZB_SCHEDULE_ALARM(find_sensor, param_sb, MATCH_DESC_REQ_START_DELAY);
                ZB_ERROR_CHECK(zb_err_code);
                zb_err_code = ZB_SCHEDULE_ALARM(find_timeout, 0, MATCH_DESC_REQ_TIMEOUT);
                ZB_ERROR_CHECK(zb_err_code);
            return;

        case BSP_EVENT_KEY_3:
             

       
               NRF_LOG_INFO("go to report attr");
               zb_err_code = ZB_SCHEDULE_ALARM(sensor_subscribe, param_sb, MATCH_DESC_REQ_START_DELAY);
               ZB_ERROR_CHECK(zb_err_code);
               zb_err_code = ZB_SCHEDULE_ALARM(zb_subscribe_timeout, 0, MATCH_DESC_REQ_TIMEOUT);
               ZB_ERROR_CHECK(zb_err_code);
				
				
				
				
            return;


        case BSP_EVENT_KEY_4:
            //cycle_endpoint(ZB_FALSE);
            return;

        default:
            NRF_LOG_INFO("Unhandled BSP Event received: %d", evt);
            return;
    }

   
}


*/













//my

  static zb_void_t zcl_device_cb(zb_uint8_t param)
{
    zb_uint8_t                       cluster_id;
    zb_uint8_t                       attr_id;
    zb_buf_t                       * p_buffer = ZB_BUF_FROM_REF(param);
    zb_zcl_device_callback_param_t * p_device_cb_param =
                     ZB_GET_BUF_PARAM(p_buffer, zb_zcl_device_callback_param_t);

    NRF_LOG_INFO("zcl_device_cb id %hd", p_device_cb_param->device_cb_id);

    /* Set default response value. */
    p_device_cb_param->status = RET_OK;

    switch (p_device_cb_param->device_cb_id)
    {  


        
        case ZB_ZCL_LEVEL_CONTROL_SET_VALUE_CB_ID:
            NRF_LOG_INFO("Level control setting to %d", p_device_cb_param->cb_param.level_control_set_value_param.new_value);
          
            break;

        case ZB_ZCL_SET_ATTR_VALUE_CB_ID:
            cluster_id = p_device_cb_param->cb_param.set_attr_value_param.cluster_id;
            attr_id    = p_device_cb_param->cb_param.set_attr_value_param.attr_id;

            if (cluster_id == ZB_ZCL_CLUSTER_ID_ON_OFF)
            {
                uint8_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data8;

                NRF_LOG_INFO("on/off attribute setting to %hd", value);
                if (attr_id == ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID)
                {
                   
                }
            }
            else if (cluster_id == ZB_ZCL_CLUSTER_ID_LEVEL_CONTROL)
            {
                uint16_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data16;

                NRF_LOG_INFO("level control attribute setting to %hd", value);
                if (attr_id == ZB_ZCL_ATTR_LEVEL_CONTROL_CURRENT_LEVEL_ID)
                {
                    
                }
            }
            else
            {
                /* Other clusters can be processed here */
                NRF_LOG_INFO("Unhandled cluster attribute id: %d", cluster_id);
            }
            break;

        default:
            p_device_cb_param->status = RET_ERROR;
            break;
    }

    NRF_LOG_INFO("zcl_device_cb status: %hd", p_device_cb_param->status);
}







/**@brief ZigBee stack event handler.
 *
 * @param[in]   param   Reference to ZigBee stack buffer used to pass arguments (signal).
 */
void zboss_signal_handler(zb_uint8_t param)
{
    zb_zdo_app_signal_hdr_t                  * p_sg_p             = NULL;
    zb_zdo_app_signal_type_t                   sig                = zb_get_app_signal(param, &p_sg_p);
    zb_ret_t                                   status             = ZB_GET_APP_SIGNAL_STATUS(param);
   // zb_nwk_device_type_t                       role               = ZB_NWK_DEVICE_TYPE_COORDINATOR;
	zb_param=param;
                
    zb_ret_t                       zb_err_code;
    zb_bool_t                 comm_status;
    switch (sig)
    {



          
        case ZB_BDB_SIGNAL_STEERING:
            if (status == RET_OK)
            {



                 memset(devList, 0, sizeof(devList));
                /* Schedule an alarm to notify about the end of steering period */
                NRF_LOG_INFO("Network steering started");
                bsp_board_led_on(ZIGBEE_NETWORK_STATE_LED);
                zb_err_code = ZB_SCHEDULE_ALARM(steering_finished, 0, ZB_TIME_ONE_SECOND * ZB_ZGP_DEFAULT_COMMISSIONING_WINDOW);
                ZB_ERROR_CHECK(zb_err_code);
            }
            else
            {
                NRF_LOG_INFO("Network steering failed to start. Status: %d. Retry network formation after 1 second.", status);
                bsp_board_led_off(ZIGBEE_NETWORK_STATE_LED);
                zb_err_code = ZB_SCHEDULE_ALARM(bdb_restart_top_level_commissioning, 0, ZB_TIME_ONE_SECOND);
                ZB_ERROR_CHECK(zb_err_code);
            }
            break;









           case ZB_ZDO_SIGNAL_SKIP_STARTUP:
            if (zb_bdb_is_factory_new())
            {
                NRF_LOG_INFO("Start network steering & formation.");
                comm_status = bdb_start_top_level_commissioning(ZB_BDB_NETWORK_STEERING | ZB_BDB_NETWORK_FORMATION);
                ZB_COMM_STATUS_CHECK(comm_status);
            }
            else
            {
                comm_status = bdb_start_top_level_commissioning(ZB_BDB_INITIALIZATION);
                ZB_COMM_STATUS_CHECK(comm_status);
            }
            break;     




        case ZB_BDB_SIGNAL_DEVICE_FIRST_START:
      
         if (status == RET_OK)
            {
                if (ZIGBEE_MANUAL_STEERING == ZB_FALSE)
                {
                    NRF_LOG_INFO("Start network steering.");
                    comm_status = bdb_start_top_level_commissioning(ZB_BDB_NETWORK_STEERING);
                    ZB_COMM_STATUS_CHECK(comm_status);
                }
            }
            else
            {
                NRF_LOG_ERROR("Failed to form network.");
            }
            break;



        case ZB_BDB_SIGNAL_DEVICE_REBOOT:
            if (status == RET_OK)
            {
                         
                         
                         
                         
                         //ZB_NWK_DEVICE_TYPE_COORDINATOR

                  

                NRF_LOG_INFO("Device started OK. Start network steering. Reason: %d", sig);
                bsp_board_led_on(ZIGBEE_NETWORK_STATE_LED);
                UNUSED_RETURN_VALUE(bdb_start_top_level_commissioning(ZB_BDB_NETWORK_STEERING));

                zb_err_code = ZB_SCHEDULE_ALARM(bdb_restart_top_level_commissioning, 0, ZB_TIME_ONE_SECOND);
                ZB_ERROR_CHECK(zb_err_code);
					
							
             if (m_device_ctx.sensor_params.short_addr == 0x0000)  				  
                {
                NRF_LOG_INFO("go to find sensor ");
                zb_err_code = ZB_SCHEDULE_ALARM(find_sensor, param, MATCH_DESC_REQ_START_DELAY);
                ZB_ERROR_CHECK(zb_err_code);
                zb_err_code = ZB_SCHEDULE_ALARM(find_timeout, 0, MATCH_DESC_REQ_TIMEOUT);
                ZB_ERROR_CHECK(zb_err_code);
									
									param=0;
                  }       //bind_sensor
												 
			
                 


                         //bint_sensor_timeout

                       //sensor_subscribe
							
								
								
						
            // ZB_SCHEDULE_ALARM(req_rum(),0,MATCH_DESC_REQ_TIMEOUT);
                //agent_ep_handler_report

             //  zb_err_code = ZB_SCHEDULE_ALARM(handlerreport, param, MATCH_DESC_REQ_START_DELAY);
               //ZB_ERROR_CHECK(zb_err_code);
              



                // NRF_ZIGBEE_EP_HANDLER_REGISTER(NULL, agent_ep_handler_report);



                      




     
            }
            else
            {
              
                bsp_board_led_off(ZIGBEE_NETWORK_STATE_LED);
               
            }
            break;

        case ZB_ZDO_SIGNAL_LEAVE:
            if (status == RET_OK)
            {
                zb_zdo_signal_leave_params_t * p_leave_params;
                bsp_board_led_off(ZIGBEE_NETWORK_STATE_LED);
                p_leave_params = ZB_ZDO_SIGNAL_GET_PARAMS(p_sg_p, zb_zdo_signal_leave_params_t);
                NRF_LOG_INFO("Network left. Leave type: %d", p_leave_params->leave_type);
            }
            else
            {
                NRF_LOG_ERROR("Unable to leave network. Status: %d", status);
            }
            break;

        case ZB_ZDO_SIGNAL_PRODUCTION_CONFIG_READY:
            if (status != RET_OK)
            {
                NRF_LOG_WARNING("Production config is not present or invalid");
            }
            break;

     

        case ZB_NWK_SIGNAL_NO_ACTIVE_LINKS_LEFT:
            NRF_LOG_WARNING("Parent is unreachable");
            break;

        case ZB_ZDO_SIGNAL_DEVICE_UPDATE:
            {
                char ieee_addr_buf[17] = {0};
                zb_zdo_signal_device_update_params_t * p_update_params;
                p_update_params = ZB_ZDO_SIGNAL_GET_PARAMS(p_sg_p, zb_zdo_signal_device_update_params_t);
               
                ZB_LETOH64(iees,p_update_params->long_addr);
                UNUSED_RETURN_VALUE(ieee_addr_to_str(ieee_addr_buf, sizeof(ieee_addr_buf), p_update_params->long_addr));
        
                NRF_LOG_INFO("Device has updated its status in the network, short address: %04x, long address: %s, status: %d", 
                             p_update_params->short_addr, NRF_LOG_PUSH(ieee_addr_buf), p_update_params->status);
            }
            break;

        case ZB_ZDO_SIGNAL_DEVICE_AUTHORIZED:
            {
                char ieee_addr_buf[17] = {0};
                zb_zdo_signal_device_authorized_params_t * p_authorize_params;
                p_authorize_params = ZB_ZDO_SIGNAL_GET_PARAMS(p_sg_p, zb_zdo_signal_device_authorized_params_t);
		   ZB_LETOH64(iees,p_authorize_params->long_addr);					
                UNUSED_RETURN_VALUE(ieee_addr_to_str(ieee_addr_buf, sizeof(ieee_addr_buf), p_authorize_params->long_addr));
                
                NRF_LOG_INFO("Device authorization event happened, short address: %04x, long address: %s, authorization type: %d, authorization status: %d", 
                             p_authorize_params->short_addr, NRF_LOG_PUSH(ieee_addr_buf), p_authorize_params->authorization_type, p_authorize_params->authorization_status);
            }
            break;


   //



      case ZB_ZDO_SIGNAL_DEVICE_ANNCE:
        {
             NRF_LOG_INFO("JOIND! \r\n");
              zb_buf_t                    * p_buf = ZB_BUF_FROM_REF(param);
              zb_apsde_data_indication_t * p_ind  = ZB_GET_BUF_PARAM(p_buf, zb_apsde_data_indication_t); // Get the pointer to the parameters buffer, which stores APS layer response
             devList[iter] = p_ind->src_addr;
             NRF_LOG_INFO("Addr = 0x%02x\r\n", devList[iter]);

              param = 0; 
             iter++;
         }


     break;

   case ZB_BDB_SIGNAL_FINDING_AND_BINDING_INITIATOR_FINISHED:
            {
                zb_zdo_signal_fb_initiator_finished_params_t * f_n_b_status = ZB_ZDO_SIGNAL_GET_PARAMS(p_sg_p, zb_zdo_signal_fb_initiator_finished_params_t);
                switch(f_n_b_status->status)
                {
                    case ZB_ZDO_FB_INITIATOR_STATUS_SUCCESS:
                        NRF_LOG_INFO("F&B: Remote peer has been bound.");
                        sensor_subscribe(param);
                        ep_report(param);


                        break;

                    case ZB_ZDO_FB_INITIATOR_STATUS_CANCEL:
                        NRF_LOG_INFO("F&B: Initiator process was cancelled.");
                        break;

                    case ZB_ZDO_FB_INITIATOR_STATUS_ALARM:
                        NRF_LOG_INFO("F&B: Initiator process was timed out.");
                        break;

                    case ZB_ZDO_FB_INITIATOR_STATUS_ERROR:
                        NRF_LOG_ERROR("F&B: Error.");
                        break;

                    default:
                        NRF_LOG_ERROR("F&B: Unknown error, status %d.", f_n_b_status->status);
                        break;
                }
            }
           // bsp_board_led_off(FINDING_N_BINDING_STATE_LED);
            break;


    //



        default:
            /* Unhandled signal. For more information see: zb_zdo_app_signal_type_e and zb_ret_e */
            NRF_LOG_INFO("Unhandled signal %d. Status: %d", sig, status);
    }

    if (param)
    {
        ZB_FREE_BUF_BY_REF(param);
    }
}

/**@brief Function for application main entry.
 */
int main(void)
{
    ret_code_t     ret;
   
    ret_code_t     err_code;
    
    /* Intiialise the leds */

     //leds_buttons_init();

     bsp_board_init(BSP_INIT_LEDS);
     bsp_board_leds_off();
	
	    nrf_drv_swI2c_init();
	    OLED_Init();	
	    OLED_Clear();nrf_delay_us(100) ;
	    OLED_ShowString(35,0,"HELLO!",16);nrf_delay_ms(1);
	    
	
	

	
	  
    /* Initialize loging system and GPIOs. */
    log_init();



    ret = app_timer_init();
    APP_ERROR_CHECK(ret);

    /* Initialize the Zigbee CLI subsystem */
    //zb_cli_init(ZIGBEE_CLI_ENDPOINT);

    /* Set ZigBee stack logging level and traffic dump subsystem. */
    ZB_SET_TRACE_LEVEL(ZIGBEE_TRACE_LEVEL);
    ZB_SET_TRACE_MASK(ZIGBEE_TRACE_MASK);
    ZB_SET_TRAF_DUMP_OFF();

    /* Initialize ZigBee stack. */
    ZB_INIT("cli_agent_router");

    /* Set device address to the value read from FICR registers. */
    zb_osif_get_ieee_eui64(ieee_addr);
    zb_set_long_address(ieee_addr);
   
     
    ieee_addr_to_str(ieee_addr_buf, sizeof(ieee_addr_buf), ieee_addr);
    //NRF_LOG_INFO("eui64 out addr: %s ",NRF_LOG_PUSH(ieee_addr_buf) );
    short_addr = zb_address_short_by_ieee(ieee_addr);
    //NRF_LOG_INFO("short out addr: %04x ", short_addr);
     zb_set_network_coordinator_role(IEEE_CHANNEL_MASK);
    zb_set_max_children(MAX_CHILDREN);

   // zb_set_bdb_primary_channel_set(IEEE_CHANNEL_MASK);
    zigbee_erase_persistent_storage(ERASE_PERSISTENT_CONFIG);

    /* Register CLI Agent device context (endpoints). */

   /* Register callback for handling ZCL commands. */
     

    ZB_ZCL_REGISTER_DEVICE_CB(zcl_device_cb);
   
     

    //ZB_AF_REGISTER_DEVICE_CTX();
    ZB_AF_REGISTER_DEVICE_CTX(&cli_agent_ctx);

    /* Set the endpoint receive hook */
   ZB_AF_SET_ENDPOINT_HANDLER(ZIGBEE_CLI_ENDPOINT, cli_agent_ep_handler);

  

    


   

    if (ZIGBEE_MANUAL_STEERING == ZB_TRUE)
    {
        ret = zboss_start_no_autostart();
    }
    else
    {
        ret = zboss_start();
    }

   // ZB_ERROR_CHECK(ret);

    /* Start ZigBee stack. */
    while(1)
    {
        zboss_main_loop_iteration();
        UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
    }
}


/**
 * @}
 */

Parents
  • Hi.

    Could you please try to ask the question you have with more details and format/clean the code so it is easier to read?

    Best regards,

    Andreas

  • Hi.

    I still do not understand your question, unfortunately.

    If your problem is that the IEEE request is not working, have you either looked at the CLI example or zboss_api_zdo.h?

    You can find an example of how to call there;

    ** @brief IEEE_addr_req primitive.
      *
      * @param param - index of buffer with primitive parameters \ref zb_zdo_ieee_addr_req_s.
      * Parameters must be put into the buffer as data (allocated).
      * @param cb    - user's function to call when got response from the remote.
      * @return        - ZDP transaction sequence number or 0xFF if operation cannot be
      *                performed now (nor enough memory, resources, etc.)
      *
      * @b Example:
      * @code
      * {
      *   zb_zdo_ieee_addr_req_t *req = NULL;
      *   zb_uint8_t tsn;
      *
      *   ZB_BUF_INITIAL_ALLOC(buf, sizeof(zb_zdo_ieee_addr_req_t), req);
      *
      *   req->nwk_addr = ind->src_addr;
      *   req->request_type = ZB_ZDO_SINGLE_DEV_RESPONSE;
      *   req->start_index = 0;
      *   tsn = zb_zdo_ieee_addr_req(ZB_REF_FROM_BUF(buf), ieee_addr_callback);
      *
      *   if (tsn == ZB_ZDO_INVALID_TSN)
      *   {
      *     TRACE_MSG(TRACE_ZDO2, "request failed", (FMT__0));
      *   }
      * }
      *
      * void ieee_addr_callback(zb_uint8_t param)
      * {
      *   zb_buf_t *buf = ZB_BUF_FROM_REF(param);
      *   zb_zdo_nwk_addr_resp_head_t *resp;
      *   zb_ieee_addr_t ieee_addr;
      *   zb_uint16_t nwk_addr;
      *   zb_address_ieee_ref_t addr_ref;
      *
      *   TRACE_MSG(TRACE_ZDO2, "zb_get_peer_short_addr_cb param %hd", (FMT__H, param));
      *
      *   resp = (zb_zdo_nwk_addr_resp_head_t*)ZB_BUF_BEGIN(buf);
      *   TRACE_MSG(
      *       TRACE_ZDO2, "resp status %hd, nwk addr %d", (FMT__H_D, resp->status, resp->nwk_addr));
      *   ZB_DUMP_IEEE_ADDR(resp->ieee_addr);
      *   if (resp->status == ZB_ZDP_STATUS_SUCCESS)
      *   {
      *     ZB_LETOH64(ieee_addr, resp->ieee_addr);
      *     ZB_LETOH16(&nwk_addr, &resp->nwk_addr);
      *     zb_address_update(ieee_addr, nwk_addr, ZB_TRUE, &addr_ref);
      *   }
          zb_free_buf(buf);
      * }
      *
      * @endcode

    Best regards,

    Andreas

  • Request timeout, look at CIL?I don't know why, this company's products are so difficult to develop.The documentation is too sloppy.

  • Request timeout, look at CIL?I don't know why, this company's products are so difficult to develop.The documentation is too sloppy.

Reply Children
Related