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