/**
* 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());
}
}
/**
* @}
*/