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

How to leave a zigbee network and erase all network data, then join another

Hi, I have been studying a lot of issues reported here about leaving network and joining another.

The most common answer is to use zb_bdb_reset_via_local_action(0);
But when I try that the device is stuck and also consuming a lot of current (5mA increase, and it is stuck)


Instead I have tried another way which leaves the network, but it will rejoin the same network again even after the 3 minutes of bdb permit (running against the cli example) it does not seem to have cleared all data neccesary.

Can you help me get this sorted?

The project is based on the multiprotocol zigbee/ble doorlock example, it is build using 16.0.0 and zigbee 4.1.0 the latter with some adjustments, see diff below.


A current measurement with an erased chip that is scanning for network, and after a few tries the coordinator is started (bdb start) and the device joins.

A current measuement where the joined device is instructed (locally) to leave the network, but it rejoins directly:

current measurement when using  zb_bdb_reset_via_local_action(0), it is stuck with an increased current consumption of about 5mA:


This is my main file:

/**
 * 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_multiprotocol_nus_door_lock main.c
 * @{
 * @ingroup  zigbee_examples
 * @brief    UART over BLE application with Zigbee HA Door Lock profile.
 *
 * This file contains the source code for a sample application that uses the Nordic UART service
 * and a door lock operating a Zigbee network.
 * This application uses the @ref srvlib_conn_params module.
 */

#include "zboss_api.h"
#include "zboss_api_addons.h"
#include "zb_mem_config_min.h"
#include "zb_error_handler.h"
#include "zb_zcl_identify.h"
#include "zb_zcl_power_config.h"
#include "zigbee_helpers.h"
#include "zboss_api_zcl.h"
#include "nus.h"

#include "app_timer.h"
#include "boards.h"
#include "bsp_btn_ble.h"
#include "fds.h"

#include "nrf_drv_clock.h"

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

#include "radio_iic.h"

#define POLL_INTERVAL_MS                    10000
#define APP_BLE_OBSERVER_PRIO               1                                       /**< Application's BLE observer priority. You shouldn't need to modify this value. */
#define IEEE_CHANNEL_MASK                   (1l << ZIGBEE_CHANNEL)                  /**< Scan only one, predefined channel to find the coordinator. */
#define DOOR_LOCK_ENDPOINT                  8                                       /**< First source endpoint used to control Door Lock. */
#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 Door Lock successfully joind Zigbee network. */
#define DOOR_LOCK_STATE_LED                 BSP_BOARD_LED_3                         /**< LED indicating that the state of the door (closed - ON, open - OFF). */
#define DOOR_LOCK_CONFIG_FILE               0xBEEF                                  /**< ID of the file with the Door Lock configuration. */
#define DOOR_LOCK_CONFIG_STATE_KEY          0x1337                                  /**< ID of the key with Door Lock state inside the configuration. */

#define DOOR_LOCK_BASIC_APP_VERSION         01                                      /**< Version of the application software (1 byte). */
#define DOOR_LOCK_BASIC_STACK_VERSION       10                                      /**< Version of the implementation of the Zigbee stack (1 byte). */
#define DOOR_LOCK_BASIC_HW_VERSION          11                                      /**< Version of the hardware of the device (1 byte). */
#define DOOR_LOCK_BASIC_MANUF_NAME          "unitware"                              /**< Manufacturer name (32 bytes). */
#define DOOR_LOCK_BASIC_MODEL_ID            "uwlock"                                /**< Model number assigned by manufacturer (32-bytes long string). */
#define DOOR_LOCK_BASIC_DATE_CODE           "20200420"                              /**< First 8 bytes specify the date of manufacturer of the device in ISO 8601 format (YYYYMMDD). Th rest (8 bytes) are manufacturer specific. */
#define DOOR_LOCK_BASIC_POWER_SOURCE        ZB_ZCL_BASIC_POWER_SOURCE_BATTERY       /**< Type of power sources available for the device. For possible values see section 3.2.2.2.8 of ZCL specification. */
#define DOOR_LOCK_BASIC_PH_ENV              ZB_ZCL_BASIC_ENV_UNSPECIFIED            /**< Describes the type of physical environment. For possible values see section 3.2.2.2.10 of ZCL specification. */
#define DOOR_LOCK_BASIC_LOCATION_DESC       ""                                      /**< Describes the physical location of the device (16 bytes). May be modified during commisioning process. */

#define NUS_COMMAND_UNLOCK                 "unlock"                                 /**< NUS command that will unlock the door. */
#define NUS_COMMAND_LOCK                   "lock"                                   /**< NUS command that will lock the door. */
#define NUS_COMMAND_OPEN                   "open"                                   /**< NUS command that will open the door. */
#define NUS_COMMAND_CLOSE                  "close"                                  /**< NUS command that will close the door. */
#define NUS_COMMAND_LEAVE                  "leave"                                  /**< NUS command that will cause lock to leave zigbee network and try to find a new one. */


#if !defined ZB_ED_ROLE
#error Define ZB_ED_ROLE to compile Door Lock (End Device) source code.
#endif

static volatile bool m_fds_initialized;                                             /**< Flag which signals the FDS subsystem being initialised. */
static volatile bool m_garbage_flag;                                                /**< Flag which signals the need for garbage collector to clean up the flash. */

#define NWK_SEARCH_ATTEMPTS       3
#define NWK_SEARCH_INTERVAL       (      3 * ZB_TIME_ONE_SECOND)
#define NWK_SEARCH_INTERVAL_LONG  0 //(60 * 60 * ZB_TIME_ONE_SECOND)
static int m_nwk_searches_to_go = NWK_SEARCH_ATTEMPTS;

/* Protocol-agnostic configuration of Door Lock. */
typedef struct
{
    uint32_t is_locked;
} door_lock_configuration_t;

typedef struct
{
    zb_uint8_t lock_state;
    zb_uint8_t lock_type;
    zb_bool_t  actuator_enabled;
    zb_uint8_t door_state;
} zb_zcl_door_lock_attrs_extended_t;

typedef struct
{
    uint8_t percentage_remaining_x2;
    uint32_t alarm_state;
} power_config_state_t;

/** @brief Declare attribute list for DoorLock cluster
    @param attr_list - attribute list name
    @param lock_state
    @param lock_type
    @param actuator_enabled
*/
#define ZB_ZCL_DECLARE_DOOR_LOCK_ATTRIB_LIST_EXTENDED(attr_list,                      \
                                                      lock_state,                     \
                                                      lock_type,                      \
                                                      actuator_enabled,               \
                                                      door_state)                     \
  ZB_ZCL_START_DECLARE_ATTRIB_LIST(attr_list)                                         \
  ZB_ZCL_SET_ATTR_DESC(ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_ID,       (lock_state))       \
  ZB_ZCL_SET_ATTR_DESC(ZB_ZCL_ATTR_DOOR_LOCK_LOCK_TYPE_ID,        (lock_type))        \
  ZB_ZCL_SET_ATTR_DESC(ZB_ZCL_ATTR_DOOR_LOCK_ACTUATOR_ENABLED_ID, (actuator_enabled)) \
  ZB_ZCL_SET_ATTR_DESC(ZB_ZCL_ATTR_DOOR_LOCK_DOOR_STATE_ID,       (door_state))       \
  ZB_ZCL_FINISH_DECLARE_ATTRIB_LIST


/* Main application customizable context. Stores all settings and static values. */
typedef struct door_lock_ctx_s
{
    door_lock_configuration_t         configuration;  // Configuration has to be word-aligned, because of FDS, hence it's first in the structure.

    zb_zcl_basic_attrs_ext_t          basic_attr;
    zb_zcl_identify_attrs_t           identify_attr;
    zb_zcl_scenes_attrs_t             scenes_attr;
    zb_zcl_groups_attrs_t             groups_attr;
    zb_zcl_door_lock_attrs_extended_t door_lock_attr;
    power_config_state_t              battery;
} door_lock_ctx_t;

static door_lock_ctx_t m_dev_ctx;

/* Configuration record for the FDS subsystem. */
static fds_record_t const m_configuration_record =
{
    .file_id           = DOOR_LOCK_CONFIG_FILE,
    .key               = DOOR_LOCK_CONFIG_STATE_KEY,
    .data.p_data       = &m_dev_ctx.configuration,
    /* The length of a record is always expressed in 4-byte units (words). */
    .data.length_words = (sizeof(m_dev_ctx.configuration) + 3) / sizeof(uint32_t),
};

ZB_ZCL_DECLARE_BASIC_ATTRIB_LIST_EXT(basic_attr_list,
                                     &m_dev_ctx.basic_attr.zcl_version,
                                     &m_dev_ctx.basic_attr.app_version,
                                     &m_dev_ctx.basic_attr.stack_version,
                                     &m_dev_ctx.basic_attr.hw_version,
                                     m_dev_ctx.basic_attr.mf_name,
                                     m_dev_ctx.basic_attr.model_id,
                                     m_dev_ctx.basic_attr.date_code,
                                     &m_dev_ctx.basic_attr.power_source,
                                     m_dev_ctx.basic_attr.location_id,
                                     &m_dev_ctx.basic_attr.ph_env,
                                     m_dev_ctx.basic_attr.sw_ver);

ZB_ZCL_DECLARE_IDENTIFY_ATTRIB_LIST(identify_attr_list, &m_dev_ctx.identify_attr.identify_time);

ZB_ZCL_DECLARE_GROUPS_ATTRIB_LIST(groups_attr_list, &m_dev_ctx.groups_attr.name_support);

ZB_ZCL_DECLARE_SCENES_ATTRIB_LIST(scenes_attr_list,
                                  &m_dev_ctx.scenes_attr.scene_count,
                                  &m_dev_ctx.scenes_attr.current_scene,
                                  &m_dev_ctx.scenes_attr.current_group,
                                  &m_dev_ctx.scenes_attr.scene_valid,
                                  &m_dev_ctx.scenes_attr.name_support);

ZB_ZCL_DECLARE_DOOR_LOCK_ATTRIB_LIST_EXTENDED(door_lock_attr_list,
                                              &m_dev_ctx.door_lock_attr.lock_state,
                                              &m_dev_ctx.door_lock_attr.lock_type,
                                              &m_dev_ctx.door_lock_attr.actuator_enabled,
                                              &m_dev_ctx.door_lock_attr.door_state);

ZB_ZCL_DECLARE_POWER_CONFIG_BATTERY_ATTRIB_LIST_MIN(power_config_attr_list,
                                              &m_dev_ctx.battery.percentage_remaining_x2,
                                              &m_dev_ctx.battery.alarm_state);

ZB_HA_DECLARE_DOOR_LOCK_CLUSTER_LIST(door_lock_clusters,
                                     door_lock_attr_list,
                                     power_config_attr_list,
                                     basic_attr_list,
                                     identify_attr_list,
                                     groups_attr_list,
                                     scenes_attr_list);

ZB_HA_DECLARE_DOOR_LOCK_EP(door_lock_ep, DOOR_LOCK_ENDPOINT, door_lock_clusters);

ZB_HA_DECLARE_DOOR_LOCK_CTX(door_lock_ctx, door_lock_ep);



static void cmd_lock(int count);
static void cmd_unlock(int count);
static void door_lock_try_to_join_network(void);

/**@brief Function for handling BLE events.
 *
 * @param[in]   p_ble_evt   Bluetooth stack event.
 * @param[in]   p_context   Unused.
 */
static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{
    uint32_t err_code;

    UNUSED_PARAMETER(p_context);

    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_CONNECTED:
            NRF_LOG_INFO("Connected");
            err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
            APP_ERROR_CHECK(err_code);
            break;

        case BLE_GAP_EVT_DISCONNECTED:
            NRF_LOG_INFO("Disconnected");
            bsp_board_led_off(BSP_BOARD_LED_0);
            bsp_board_led_off(BSP_BOARD_LED_1);
            break;

        case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
        {
            NRF_LOG_DEBUG("PHY update request.");
            ble_gap_phys_t const phys =
            {
                .rx_phys = BLE_GAP_PHY_AUTO,
                .tx_phys = BLE_GAP_PHY_AUTO,
            };
            err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys);
            APP_ERROR_CHECK(err_code);
        } break;

        case BLE_GATTC_EVT_TIMEOUT:
            // Disconnect on GATT Client timeout event.
            err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
                                             BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            APP_ERROR_CHECK(err_code);
            break;

        case BLE_GATTS_EVT_TIMEOUT:
            // Disconnect on GATT Server timeout event.
            err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
                                             BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            APP_ERROR_CHECK(err_code);
            break;

        default:
            // No implementation needed.
            break;
    }
}


/***************************************************************************************************
 * @section Initialization
 **************************************************************************************************/

/**@brief Function for the SoftDevice initialization.
 *
 * @details This function initializes the SoftDevice and the BLE event interrupt.
 */
static void ble_stack_init(void)
{
    ret_code_t err_code;

    err_code = nrf_sdh_enable_request();
    APP_ERROR_CHECK(err_code);

    // Configure the BLE stack using the default settings.
    // Fetch the start address of the application RAM.
    uint32_t ram_start = 0;
    err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
    APP_ERROR_CHECK(err_code);

    // Enable BLE stack.
    err_code = nrf_sdh_ble_enable(&ram_start);
    APP_ERROR_CHECK(err_code);

    // Register a handler for BLE events.
    NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
}


/**@brief Function for initializing the nrf log module.
 */
static void log_init(void)
{
    ret_code_t err_code = NRF_LOG_INIT(NULL);
    APP_ERROR_CHECK(err_code);

    NRF_LOG_DEFAULT_BACKENDS_INIT();
}

/**@brief Function for initializing the application timer.
 */
static void timer_init(void)
{
    uint32_t error_code;
    error_code          = app_timer_init();
    APP_ERROR_CHECK(error_code);
}


/**@brief Functiom which essentially sets the door state.
 *
 * @param[in] value ZB_ZCL_ATTR_DOOR_LOCK_DOOR_STATE_OPEN to open,
 *                  ZB_ZCL_ATTR_DOOR_LOCK_DOOR_STATE_CLOSED to close.
 */
static zb_void_t set_door_state(zb_uint8_t value)
{
    switch (value)
    {
    case ZB_ZCL_ATTR_DOOR_LOCK_DOOR_STATE_CLOSED:
    case ZB_ZCL_ATTR_DOOR_LOCK_DOOR_STATE_OPEN:
        NRF_LOG_INFO("new door state: %d", value);
        UNUSED_RETURN_VALUE(zb_zcl_set_attr_val(DOOR_LOCK_ENDPOINT,
                                                ZB_ZCL_CLUSTER_ID_DOOR_LOCK,
                                                ZB_ZCL_CLUSTER_SERVER_ROLE,
                                                ZB_ZCL_ATTR_DOOR_LOCK_DOOR_STATE_ID,
                                                &value,
                                                ZB_FALSE));
        break;

    default:
        NRF_LOG_WARNING("Wrong value of door state - omitting");
    }

    zb_zdo_pim_set_long_poll_interval(POLL_INTERVAL_MS);
    door_lock_try_to_join_network();
}


/**@brief Functiom which essentially sets the lock state via i2c and stores the value in flash.
 *
 * @param[in] value ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_LOCKED to lock,
 *                  ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_UNLOCKED to unlock.
 */
static zb_void_t set_lock_state(zb_uint8_t value)
{
    NRF_LOG_INFO("new lock state: %d", value);
    if (value == ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_LOCKED)
    {
        m_dev_ctx.configuration.is_locked = (uint32_t) true;
        bsp_board_led_on(DOOR_LOCK_STATE_LED);
        UNUSED_RETURN_VALUE(zb_zcl_set_attr_val(DOOR_LOCK_ENDPOINT,
                                                ZB_ZCL_CLUSTER_ID_DOOR_LOCK,
                                                ZB_ZCL_CLUSTER_SERVER_ROLE,
                                                ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_ID,
                                                &value,
                                                ZB_FALSE));
    }
    else if (value == ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_UNLOCKED)
    {
        m_dev_ctx.configuration.is_locked = (uint32_t) false;
        bsp_board_led_off(DOOR_LOCK_STATE_LED);
        UNUSED_RETURN_VALUE(zb_zcl_set_attr_val(DOOR_LOCK_ENDPOINT,
                                                ZB_ZCL_CLUSTER_ID_DOOR_LOCK,
                                                ZB_ZCL_CLUSTER_SERVER_ROLE,
                                                ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_ID,
                                                &value,
                                                ZB_FALSE));
    }
    else
    {
        NRF_LOG_WARNING("Wrong value of lock state - omitting");
        return;
    }

    ret_code_t        err_code;
    fds_record_desc_t desc = {0};
    fds_find_token_t  tok  = {0};

    err_code = fds_record_find(DOOR_LOCK_CONFIG_FILE, DOOR_LOCK_CONFIG_STATE_KEY, &desc, &tok);
    APP_ERROR_CHECK(err_code);

    err_code = fds_record_update(&desc, &m_configuration_record);
    APP_ERROR_CHECK(err_code);
    /* Set the garbage flag to dispatch the garbage collector. */
    m_garbage_flag = true;

    zb_zdo_pim_set_long_poll_interval(POLL_INTERVAL_MS);
    door_lock_try_to_join_network();
}

/**@brief Function for initializing all clusters attributes.
 */
static void door_lock_clusters_attr_init(void)
{
    /* Basic cluster attributes data */
    m_dev_ctx.basic_attr.zcl_version   = ZB_ZCL_VERSION;
    m_dev_ctx.basic_attr.app_version   = DOOR_LOCK_BASIC_APP_VERSION;
    m_dev_ctx.basic_attr.stack_version = DOOR_LOCK_BASIC_STACK_VERSION;
    m_dev_ctx.basic_attr.hw_version    = DOOR_LOCK_BASIC_HW_VERSION;

    /* Use ZB_ZCL_SET_STRING_VAL to set strings, because the first byte should
     * contain string length without trailing zero.
     *
     * For example "test" string wil be encoded as:
     *   [(0x4), 't', 'e', 's', 't']
     */
    ZB_ZCL_SET_STRING_VAL(m_dev_ctx.basic_attr.mf_name,
                          DOOR_LOCK_BASIC_MANUF_NAME,
                          ZB_ZCL_STRING_CONST_SIZE(DOOR_LOCK_BASIC_MANUF_NAME));

    ZB_ZCL_SET_STRING_VAL(m_dev_ctx.basic_attr.model_id,
                          DOOR_LOCK_BASIC_MODEL_ID,
                          ZB_ZCL_STRING_CONST_SIZE(DOOR_LOCK_BASIC_MODEL_ID));

    ZB_ZCL_SET_STRING_VAL(m_dev_ctx.basic_attr.date_code,
                          DOOR_LOCK_BASIC_DATE_CODE,
                          ZB_ZCL_STRING_CONST_SIZE(DOOR_LOCK_BASIC_DATE_CODE));

    m_dev_ctx.basic_attr.power_source = DOOR_LOCK_BASIC_POWER_SOURCE;

    ZB_ZCL_SET_STRING_VAL(m_dev_ctx.basic_attr.location_id,
                          DOOR_LOCK_BASIC_LOCATION_DESC,
                          ZB_ZCL_STRING_CONST_SIZE(DOOR_LOCK_BASIC_LOCATION_DESC));


    m_dev_ctx.basic_attr.ph_env = DOOR_LOCK_BASIC_PH_ENV;

    /* Identify cluster attributes data */
    m_dev_ctx.identify_attr.identify_time = ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE;

    /* Door Lock cluster attributes data */
    m_dev_ctx.door_lock_attr.lock_type        = ZB_ZCL_ATTR_DOOR_LOCK_LOCK_TYPE_OTHER;
    m_dev_ctx.door_lock_attr.lock_state       = m_dev_ctx.configuration.is_locked ? ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_LOCKED : ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_UNLOCKED;
    m_dev_ctx.door_lock_attr.actuator_enabled = ZB_TRUE;

    //todo get input or something
    m_dev_ctx.door_lock_attr.door_state       = ZB_ZCL_ATTR_DOOR_LOCK_DOOR_STATE_CLOSED;

    if ((bool)m_dev_ctx.configuration.is_locked == false)
    {
        set_lock_state(ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_UNLOCKED);
    }
    else
    {
        set_lock_state(ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_LOCKED);
    }

    set_door_state(m_dev_ctx.door_lock_attr.door_state);

    m_dev_ctx.battery.percentage_remaining_x2 = 0xff;
    m_dev_ctx.battery.alarm_state = 0;
}

/**@brief Perform local operation - leave network.
 *
 * @param[in]   bufid   Reference to Zigbee stack buffer that will be used to construct leave request.
 */
static void door_lock_leave_nwk(zb_bufid_t bufid)
{
    zb_ret_t zb_err_code;

    // We are going to leave
    if (bufid)
    {
        zb_zdo_mgmt_leave_param_t * p_req_param;

        p_req_param = ZB_BUF_GET_PARAM(bufid, zb_zdo_mgmt_leave_param_t);
        UNUSED_RETURN_VALUE(ZB_BZERO(p_req_param, sizeof(zb_zdo_mgmt_leave_param_t)));

        // Set dst_addr == local address for local leave
        p_req_param->dst_addr = ZB_PIBCACHE_NETWORK_ADDRESS();
        p_req_param->rejoin   = ZB_FALSE;
        UNUSED_RETURN_VALUE(zdo_mgmt_leave_req(bufid, NULL));
    }
    else
    {
        zb_err_code = zb_buf_get_out_delayed(door_lock_leave_nwk);
        ZB_ERROR_CHECK(zb_err_code);
    }
}



/**@brief Function for starting join/rejoin procedure.
 *
 * param[in]   leave_type   Type of leave request (with or without rejoin).
 */
static zb_void_t door_lock_retry_join(zb_uint8_t leave_type)
{
    zb_bool_t comm_status;

    if (leave_type == ZB_NWK_LEAVE_TYPE_RESET)
    {
        comm_status = bdb_start_top_level_commissioning(ZB_BDB_NETWORK_STEERING);
        ZB_COMM_STATUS_CHECK(comm_status);
    }
}

/**@brief Function for leaving current network and starting join procedure afterwards.
 *
 * @param[in]   bufid   Optional reference to Zigbee stack buffer to be reused by leave and join procedure.
 */
static zb_void_t door_lock_leave_and_join(zb_bufid_t bufid)
{
//TODO: funktionen att lämna et nätverk fungerar men den söker inte nytt och kopplar upp som den skall efter det. då krävs en powercykle.
//      jag har labbat mig fram till hur det ser ut här, de referenser jag hittade på infocenter fungerade sämre. 
    if (ZB_JOINED())
    {
        // Leave network. Joining procedure will be initiated inisde Zigbee stack signal handler.
//        zb_bdb_reset_via_local_action(0);
        door_lock_leave_nwk(bufid);
    }
    else
    {
        // Already left network. Start joining procedure.
        door_lock_retry_join(ZB_NWK_LEAVE_TYPE_RESET);

        if (bufid)
        {
            zb_buf_free(bufid);
        }
    }
}


static void set_data_req(zb_bufid_t bufid)
{
    NRF_LOG_INFO(__FUNCTION__);

    if (bufid)
    {
        zb_buf_free(bufid);
    }

    zb_zdo_pim_set_long_poll_interval(POLL_INTERVAL_MS);
}


void door_lock_try_to_join_network(void)
{
    if (ZB_JOINED()) return;

    if (m_nwk_searches_to_go) return;  //already in progress

    m_nwk_searches_to_go = NWK_SEARCH_ATTEMPTS;
    door_lock_retry_join(ZB_NWK_LEAVE_TYPE_RESET);
}

/**@brief Handler of the FDS events.
 *
 * @param[in] p_evt Pointer to the FDS context.
 */
static void fds_evt_handler(fds_evt_t const * p_evt)
{
    switch (p_evt->id)
    {
        case FDS_EVT_INIT:
            if (p_evt->result == NRF_SUCCESS)
            {
                m_fds_initialized = true;
            }
            break;

        default:
            break;
    }
}

/**@brief Function to initialise FDS storage and read the initial lock state out of it.
 */
static void storage_init(void)
{
    ret_code_t err_code;

    /* Register the handler. */
    UNUSED_RETURN_VALUE(fds_register(fds_evt_handler));

    err_code = fds_init();
    APP_ERROR_CHECK(err_code);

    /* Wait until we're initialised. */
    while (!m_fds_initialized)
    {
    }

    /* Get the record data out. */
    fds_record_desc_t desc = {0};
    fds_find_token_t  tok  = {0};

    err_code = fds_record_find(DOOR_LOCK_CONFIG_FILE, DOOR_LOCK_CONFIG_STATE_KEY, &desc, &tok);
    if (err_code == NRF_SUCCESS)
    {
        NRF_LOG_INFO("Previous configuration found");

        /* A config file is in flash. Let's update the RAM value. */
        fds_flash_record_t config = {0};

        /* Open the record and read its contents. */
        err_code = fds_record_open(&desc, &config);
        APP_ERROR_CHECK(err_code);

        /* Copy the configuration from flash into the configuration in the RAM. */
        memcpy(&m_dev_ctx.configuration, config.p_data, sizeof(door_lock_configuration_t));

        NRF_LOG_INFO("Loaded configuration: door is %s", m_dev_ctx.configuration.is_locked ? "locked" : "unlocked");

        /* Close the record when done reading. */
        err_code = fds_record_close(&desc);
        APP_ERROR_CHECK(err_code);
    }
    else
    {
        NRF_LOG_INFO("Previous configuration not found, creating one");

        err_code = fds_record_write(&desc, &m_configuration_record);
        APP_ERROR_CHECK(err_code);
    }
}

/**@brief initializing LEDs.
 */
static void leds_init(void)
{
    ret_code_t       error_code;

    /* Initialize LEDs - use BSP to control them. */
    error_code = bsp_init(BSP_INIT_LEDS, NULL);
    APP_ERROR_CHECK(error_code);
    bsp_board_leds_off();
}

/**@brief Callback function for handling ZCL commands.
 *
 * @param[in]   bufid   Reference to Zigbee stack buffer used to pass received data.
 */
static zb_void_t zcl_device_cb(zb_bufid_t bufid)
{
    zb_zcl_device_callback_param_t * p_device_cb_param = ZB_BUF_GET_PARAM(bufid, zb_zcl_device_callback_param_t);

    NRF_LOG_INFO("zcl_device_cb");

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

    switch (p_device_cb_param->device_cb_id)
    {
        case ZB_ZCL_DOOR_LOCK_UNLOCK_DOOR_CB_ID:
            cmd_lock(0);
            break;

        case ZB_ZCL_DOOR_LOCK_LOCK_DOOR_CB_ID:
            cmd_unlock(0);
            set_lock_state(ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_LOCKED);
            break;

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

/**@brief Function for initializing the Zigbee Stack.
 */
static void zigbee_init(void)
{
    zb_ieee_addr_t ieee_addr;

    m_nwk_searches_to_go = NWK_SEARCH_ATTEMPTS;

    /* 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("door_lock_nus");

    /* Set device address to the value read from FICR registers. */
    zb_osif_get_ieee_eui64(ieee_addr);
    zb_set_long_address(ieee_addr);

    /* Set up Zigbee protocol main parameters. */
    zb_set_network_ed_role(IEEE_CHANNEL_MASK);
    zigbee_erase_persistent_storage(ERASE_PERSISTENT_CONFIG);

    zb_set_ed_timeout(ED_AGING_TIMEOUT_64MIN);
    zb_set_keepalive_timeout(ZB_MILLISECONDS_TO_BEACON_INTERVAL(300));
    zb_set_rx_on_when_idle(ZB_FALSE);

    if (ZB_PIBCACHE_RX_ON_WHEN_IDLE() == ZB_FALSE)
    {
        zigbee_power_down_unused_ram();
    }

    /* Register callback for handling ZCL commands. */
    ZB_ZCL_REGISTER_DEVICE_CB(zcl_device_cb);

    /* Register Door Lock device context (endpoints). */
    ZB_AF_REGISTER_DEVICE_CTX(&door_lock_ctx);

    /* Initialize clusters' attributes. */
    door_lock_clusters_attr_init();
    zb_zcl_power_config_init_server();
}

/**@brief Lock the Lock via the BLE connection.
 *
 * @param[in] count Unused parameter, inherited from NUS command template.
 */
static void cmd_lock(int count)
{
    UNUSED_PARAMETER(count);
    NRF_LOG_INFO("LOCK");

    radio_iic_do_lock();
    nus_start_advertising();
}

/**@brief Unlock the Lock via the BLE connection.
 *
 * @param[in] count Unused parameter, inherited from NUS command template.
 */
static void cmd_unlock(int count)
{
    UNUSED_PARAMETER(count);
    NRF_LOG_INFO("UNLOCK");

    //say unlocked now for safety
    set_lock_state(ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_UNLOCKED);

    radio_iic_do_unlock();
}

/**@brief Simulate opening the door via the BLE connection.
 *
 * @param[in] count Unused parameter, inherited from NUS command template.
 */
static void cmd_open(int count)
{
    UNUSED_PARAMETER(count);
    NRF_LOG_INFO("OPEN");
    set_door_state(ZB_ZCL_ATTR_DOOR_LOCK_DOOR_STATE_OPEN);
}

/**@brief Simulate closing the door via the BLE connection.
 *
 * @param[in] count Unused parameter, inherited from NUS command template.
 */
static void cmd_close(int count)
{
    UNUSED_PARAMETER(count);
    NRF_LOG_INFO("CLOSE");
    set_door_state(ZB_ZCL_ATTR_DOOR_LOCK_DOOR_STATE_CLOSED);
}


static void cmd_leave(int count)
{
    UNUSED_PARAMETER(count);
    NRF_LOG_INFO("LEAVE");

    door_lock_leave_nwk(0);
//  zb_bdb_reset_via_local_action(0);
}


/**@brief Function which adds the commands to the NUS commander.
 */
static void add_nus_commands(void)
{
    UNUSED_RETURN_VALUE(NUS_ADD_COMMAND(NUS_COMMAND_UNLOCK, cmd_unlock));
    UNUSED_RETURN_VALUE(NUS_ADD_COMMAND(NUS_COMMAND_LOCK,   cmd_lock));
    UNUSED_RETURN_VALUE(NUS_ADD_COMMAND(NUS_COMMAND_OPEN,   cmd_open));
    UNUSED_RETURN_VALUE(NUS_ADD_COMMAND(NUS_COMMAND_CLOSE,  cmd_close));
    UNUSED_RETURN_VALUE(NUS_ADD_COMMAND(NUS_COMMAND_LEAVE,  cmd_leave));
}

/**@brief Zigbee stack event handler.
 *
 * @param[in]   bufid   Reference to the Zigbee stack buffer used to pass signal.
 */
void zboss_signal_handler(zb_bufid_t bufid)
{
    zb_zdo_app_signal_hdr_t  * p_sg_p = NULL;
    zb_zdo_app_signal_type_t   sig    = zb_get_app_signal(bufid, &p_sg_p);
    zb_ret_t                   status = ZB_GET_APP_SIGNAL_STATUS(bufid);
    zb_ret_t                   zb_err_code;

    /* Update network status LED */
    zigbee_led_status_update(bufid, ZIGBEE_NETWORK_STATE_LED);

    switch(sig)
    {
        case ZB_BDB_SIGNAL_DEVICE_REBOOT:
            /* fall-through */
        case ZB_BDB_SIGNAL_STEERING:
            if (status == RET_OK)
            {
                zb_ext_pan_id_t extended_pan_id;
                char ieee_addr_buf[17] = {0};
                int  addr_len;

                zb_get_extended_pan_id(extended_pan_id);
                addr_len = ieee_addr_to_str(ieee_addr_buf, sizeof(ieee_addr_buf), extended_pan_id);
                if (addr_len < 0)
                {
                    strcpy(ieee_addr_buf, "unknown");
                }

                NRF_LOG_INFO("Joined network successfully (Extended PAN ID: %s, PAN ID: 0x%04hx)", NRF_LOG_PUSH(ieee_addr_buf), ZB_PIBCACHE_PAN_ID());

                zb_err_code = ZB_SCHEDULE_APP_ALARM(set_data_req, 0, ZB_TIME_ONE_SECOND);
                ZB_ERROR_CHECK(zb_err_code);
            }
            else
            {
                NRF_LOG_ERROR("Failed to join network (status: %d)", status);
                bsp_board_led_off(ZIGBEE_NETWORK_STATE_LED);
                if (m_nwk_searches_to_go)
                {
                    m_nwk_searches_to_go--;

                    zb_err_code = ZB_SCHEDULE_APP_ALARM(door_lock_leave_and_join, 0, NWK_SEARCH_INTERVAL);
                    ZB_ERROR_CHECK(zb_err_code);
                }
                else if (NWK_SEARCH_INTERVAL_LONG)
                {
                    //retry after a while
                    m_nwk_searches_to_go = NWK_SEARCH_ATTEMPTS;
                    zb_err_code = ZB_SCHEDULE_APP_ALARM(door_lock_leave_and_join, 0, NWK_SEARCH_INTERVAL_LONG);
                    ZB_ERROR_CHECK(zb_err_code);
                }
            }
            break;

        case ZB_ZDO_SIGNAL_LEAVE:
            if (status == RET_OK)
            {
                zb_zdo_signal_leave_params_t * 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);
                m_nwk_searches_to_go = NWK_SEARCH_ATTEMPTS;
                door_lock_retry_join(p_leave_params->leave_type);
            }
            else
            {
                NRF_LOG_ERROR("Unable to leave network (status: %d)", status);
            }
            break;

        case ZB_COMMON_SIGNAL_CAN_SLEEP:
            {
                zb_sleep_now();
            }
            break;

        default:
            /* Call default signal handler. */
            ZB_ERROR_CHECK(zigbee_default_signal_handler(bufid));
            break;
    }

    if (bufid)
    {
        zb_buf_free(bufid);
    }
}

void configure_attribute_reporting()
{
    zb_ret_t   zb_err_code;

    zb_zcl_reporting_info_t report_door_state_info;
    zb_zcl_reporting_info_t report_lock_state_info;
    zb_zcl_reporting_info_t report_battery_remaining_info;
    zb_zcl_reporting_info_t report_battery_alarm_state;

    memset(&report_door_state_info, 0, sizeof(report_door_state_info));
    memset(&report_lock_state_info, 0, sizeof(report_lock_state_info));
    memset(&report_battery_remaining_info, 0, sizeof(report_battery_remaining_info));
    memset(&report_battery_alarm_state, 0, sizeof(report_battery_alarm_state));

//TODO:  this is another issue. I want the reports to be sent at network join/power up and then on change
//       for now I did try to get them to be sent repeatedly but that does not work either. sending on
//       update works for all but the battery_alarm
    report_door_state_info.direction = ZB_ZCL_CONFIGURE_REPORTING_SEND_REPORT;
    report_door_state_info.ep = DOOR_LOCK_ENDPOINT;
    report_door_state_info.cluster_id = ZB_ZCL_CLUSTER_ID_DOOR_LOCK;
    report_door_state_info.cluster_role = ZB_ZCL_CLUSTER_SERVER_ROLE;
    report_door_state_info.attr_id = ZB_ZCL_ATTR_DOOR_LOCK_DOOR_STATE_ID;
    report_door_state_info.dst.profile_id = ZB_AF_HA_PROFILE_ID;
    //report_door_state_info.u.send_info.min_interval = 0;      // on change
    report_door_state_info.u.send_info.min_interval = 5;
    // report_door_state_info.u.send_info.max_interval = 30;     // 30 seconds
    report_door_state_info.u.send_info.max_interval = 10;     // 30 seconds
    report_door_state_info.u.send_info.delta.u8 = 1;


    report_lock_state_info.direction = ZB_ZCL_CONFIGURE_REPORTING_SEND_REPORT;
    report_lock_state_info.ep = DOOR_LOCK_ENDPOINT;
    report_lock_state_info.cluster_id = ZB_ZCL_CLUSTER_ID_DOOR_LOCK;
    report_lock_state_info.cluster_role = ZB_ZCL_CLUSTER_SERVER_ROLE;
    report_door_state_info.attr_id = ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_ID;
    report_lock_state_info.dst.profile_id = ZB_AF_HA_PROFILE_ID;
    //report_lock_state_info.u.send_info.min_interval = 0;      // on change
    report_lock_state_info.u.send_info.min_interval = 5;
    // report_lock_state_info.u.send_info.max_interval = 30;     // 30 seconds
    report_lock_state_info.u.send_info.max_interval = 10;     // 30 seconds
    report_lock_state_info.u.send_info.delta.u8 = 1;


    report_battery_remaining_info.direction = ZB_ZCL_CONFIGURE_REPORTING_SEND_REPORT;
    report_battery_remaining_info.ep = DOOR_LOCK_ENDPOINT;
    report_battery_remaining_info.cluster_id = ZB_ZCL_CLUSTER_ID_POWER_CONFIG;
    report_battery_remaining_info.cluster_role = ZB_ZCL_CLUSTER_SERVER_ROLE;
    report_battery_remaining_info.attr_id = ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_PERCENTAGE_REMAINING_ID;
    report_battery_remaining_info.dst.profile_id = ZB_AF_HA_PROFILE_ID;
    //report_battery_remaining_info.u.send_info.min_interval = 0;      // on change
    report_battery_remaining_info.u.send_info.min_interval = 5;
    // report_battery_remaining_info.u.send_info.max_interval = 30;     // 30 seconds
    report_battery_remaining_info.u.send_info.max_interval = 10;     // 30 seconds
    report_battery_remaining_info.u.send_info.delta.u8 = 1;

    report_battery_alarm_state.direction = ZB_ZCL_CONFIGURE_REPORTING_SEND_REPORT;
    report_battery_alarm_state.ep = DOOR_LOCK_ENDPOINT;
    report_battery_alarm_state.cluster_id = ZB_ZCL_CLUSTER_ID_POWER_CONFIG;
    report_battery_alarm_state.cluster_role = ZB_ZCL_CLUSTER_SERVER_ROLE;
    report_battery_alarm_state.attr_id = ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_ALARM_STATE_ID;
    report_battery_alarm_state.dst.profile_id = ZB_AF_HA_PROFILE_ID;
    //report_battery_alarm_state.u.send_info.min_interval = 0;      // on change
    report_battery_alarm_state.u.send_info.min_interval = 5;
    // report_battery_alarm_state.u.send_info.max_interval = 30;     // 30 seconds
    report_battery_alarm_state.u.send_info.max_interval = 10;     // 30 seconds
    report_battery_alarm_state.u.send_info.delta.u8 = 1;



    zb_err_code = zb_zcl_put_reporting_info(&report_door_state_info, ZB_TRUE);    // Assume the override parameter here is to override the default configuration.
    ZB_ERROR_CHECK(zb_err_code);

    zb_err_code = zb_zcl_put_reporting_info(&report_lock_state_info, ZB_TRUE);    // Assume the override parameter here is to override the default configuration.
    ZB_ERROR_CHECK(zb_err_code);

    zb_err_code = zb_zcl_put_reporting_info(&report_battery_remaining_info, ZB_TRUE);    // Assume the override parameter here is to override the default configuration.
    ZB_ERROR_CHECK(zb_err_code);

    zb_err_code = zb_zcl_put_reporting_info(&report_battery_alarm_state, ZB_TRUE);    // Assume the override parameter here is to override the default configuration.
    ZB_ERROR_CHECK(zb_err_code);


    zb_err_code = zb_zcl_start_attr_reporting(DOOR_LOCK_ENDPOINT, ZB_ZCL_CLUSTER_ID_DOOR_LOCK, ZB_ZCL_CLUSTER_SERVER_ROLE, ZB_ZCL_ATTR_DOOR_LOCK_DOOR_STATE_ID);
    ZB_ERROR_CHECK(zb_err_code);

    zb_err_code = zb_zcl_start_attr_reporting(DOOR_LOCK_ENDPOINT, ZB_ZCL_CLUSTER_ID_DOOR_LOCK, ZB_ZCL_CLUSTER_SERVER_ROLE, ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_ID);
    ZB_ERROR_CHECK(zb_err_code);

    zb_err_code = zb_zcl_start_attr_reporting(DOOR_LOCK_ENDPOINT, ZB_ZCL_CLUSTER_ID_POWER_CONFIG, ZB_ZCL_CLUSTER_SERVER_ROLE, ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_PERCENTAGE_REMAINING_ID);
    ZB_ERROR_CHECK(zb_err_code);

    zb_err_code = zb_zcl_start_attr_reporting(DOOR_LOCK_ENDPOINT, ZB_ZCL_CLUSTER_ID_POWER_CONFIG, ZB_ZCL_CLUSTER_SERVER_ROLE, ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_ALARM_STATE_ID);
    ZB_ERROR_CHECK(zb_err_code);
}


void radio_iic_cb_lockstate_is_locked(void)
{
    NRF_LOG_INFO("main got lockstate from radio_iic LOCKED");
    set_lock_state(ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_LOCKED);
}

void radio_iic_cb_lockstate_is_unlocked(void)
{
    NRF_LOG_INFO("main got lockstate from radio_iic UNLOCKED");
    set_lock_state(ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_UNLOCKED);
    nus_start_advertising();
}

void radio_iic_cb_doorstate_is_closed(void)
{
    NRF_LOG_INFO("main got doorstate from radio_iic CLOSED");
    set_door_state(ZB_ZCL_ATTR_DOOR_LOCK_DOOR_STATE_CLOSED);
}

void radio_iic_cb_doorstate_is_open(void)
{
    NRF_LOG_INFO("main got doorstate from radio_iic OPEN");
    set_door_state(ZB_ZCL_ATTR_DOOR_LOCK_DOOR_STATE_OPEN);
}

void radio_iic_cb_cmd_leave_and_join_network(void)
{
    cmd_leave(0);
}

void radio_iic_cb_battery_status(radio_iic_percentage_t percent, bool battery_is_low)
{
    NRF_LOG_INFO("main got battery status from radio_iic %d%%, %s", percent, battery_is_low ? "LOW":"ok");

    m_dev_ctx.battery.percentage_remaining_x2 = percent * 2;
    m_dev_ctx.battery.alarm_state = battery_is_low ? ZB_ZCL_POWER_CONFIG_BATTERY_ALARM_STATE_SOURCE1_MIN_THRESHOLD : 0;

    UNUSED_RETURN_VALUE(zb_zcl_set_attr_val(DOOR_LOCK_ENDPOINT,
                                            ZB_ZCL_CLUSTER_ID_POWER_CONFIG,
                                            ZB_ZCL_CLUSTER_SERVER_ROLE,
                                            ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_PERCENTAGE_REMAINING_ID,
                                            &m_dev_ctx.battery.percentage_remaining_x2,
                                            ZB_FALSE));

    UNUSED_RETURN_VALUE(zb_zcl_set_attr_val(DOOR_LOCK_ENDPOINT,
                                            ZB_ZCL_CLUSTER_ID_POWER_CONFIG,
                                            ZB_ZCL_CLUSTER_SERVER_ROLE,
                                            ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_ALARM_STATE_ID,
                                            &m_dev_ctx.battery.alarm_state,
                                            ZB_FALSE));

    zb_zdo_pim_set_long_poll_interval(POLL_INTERVAL_MS);
    door_lock_try_to_join_network();
}

/**@brief Function for application main entry.
 */
int main(void)
{
    zb_ret_t   zb_err_code;

    /* Initialize loging system and timers. */
    log_init();
    timer_init();

    /* Intitialise the FDS storage subsystem. */
    storage_init();

    /* Initialise the LEDs and to steer the lock. */
    leds_init();

    /* Bluetooth initialization. */
    ble_stack_init();

    /* NUS Commander initialization. */
    nus_init(NULL);

    /* Add commands to NUS */
    add_nus_commands();

    /* Initialize Zigbee stack. */
    zigbee_init();

    radio_iic_init();

    /* Start execution. */
    NRF_LOG_INFO("BLE Zigbee dynamic door lock example started.");

    /** Start Zigbee Stack. */
    zb_err_code = zboss_start_no_autostart();
    ZB_ERROR_CHECK(zb_err_code);

    configure_attribute_reporting();

    while(1)
    {
        radio_iic_exe();

        zboss_main_loop_iteration();

        UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());

        if (m_garbage_flag)
        {
            m_garbage_flag = false;
            UNUSED_RETURN_VALUE(fds_gc());
        }
    }
}


/**
 * @}
 */

The diff relative 4.1.0

--- a/components/boards/boards.h
+++ b/components/boards/boards.h
@@ -103,6 +103,7 @@ extern "C" {
 #define BSP_INIT_BUTTONS (1 << 1) /**< Enable buttons during initialization (@ref bsp_board_init).*/
 /**@} */
 
 /**
  * Function for returning the state of an LED.
  *
@@ -112,6 +113,15 @@ extern "C" {
  */
 bool bsp_board_led_state_get(uint32_t led_idx);
 
+#if !LEDS_NUMBER
+
+#define bsp_board_led_on(led_idx)      ;
+#define bsp_board_led_off(led_idx)     ;
+#define bsp_board_led_invert(led_idx)  ;
+#define bsp_board_leds_off()           ;
+#define bsp_board_leds_on()            ;
+
+#else
 /**
  * Function for turning on an LED.
  *
@@ -141,6 +151,7 @@ void bsp_board_leds_off(void);
  * Function for turning on all LEDs.
  */
 void bsp_board_leds_on(void);
+#endif
 
 /**
  * Function for initializing the BSP handling for the board.
diff --git a/components/boards/pca10059.h b/components/boards/pca10059.h
index 64f77c7..9e19bcd 100644
--- a/components/boards/pca10059.h
+++ b/components/boards/pca10059.h
@@ -88,6 +88,10 @@ extern "C" {
 
 #define HWFC           true
 
+#define ARDUINO_13_PIN              22
+#define ARDUINO_SCL_PIN             17    // SCL signal pin
+#define ARDUINO_SDA_PIN             15    // SDA signal pin
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/components/toolchain/gcc/Makefile.posix b/components/toolchain/gcc/Makefile.posix
index 2616bb0..4803a9f 100644
--- a/components/toolchain/gcc/Makefile.posix
+++ b/components/toolchain/gcc/Makefile.posix
@@ -1,3 +1,3 @@
-GNU_INSTALL_ROOT ?= /usr/local/gcc-arm-none-eabi-7-2018-q2-update/bin/
-GNU_VERSION ?= 7.3.1
+GNU_INSTALL_ROOT ?= /usr/local/gcc-arm-none-eabi-9-2019-q4-major/bin/
+GNU_VERSION ?= 9.2.1
 GNU_PREFIX ?= arm-none-eabi
diff --git a/components/zigbee/cli/zigbee_cli_cmd_attr_report.c b/components/zigbee/cli/zigbee_cli_cmd_attr_report.c
index 85a3554..42cdb0c 100644
--- a/components/zigbee/cli/zigbee_cli_cmd_attr_report.c
+++ b/components/zigbee/cli/zigbee_cli_cmd_attr_report.c
@@ -317,9 +317,9 @@ static void print_attr_update(zb_zcl_parsed_hdr_t * p_zcl_hdr, zb_bufid_t bufid)
 
     /* Get the contents of Read Attribute Response frame */
     ZB_ZCL_GENERAL_GET_NEXT_REPORT_ATTR_REQ(bufid, p_attr_resp);
-    bytes_written = 0;
     while (p_attr_resp != NULL)
     {
+        bytes_written = 0;
         bytes_written = zcl_attr_to_str(&print_buf[bytes_written],
                                         sizeof(print_buf) - bytes_written,
                                         p_attr_resp->attr_type,
diff --git a/components/zigbee/cli/zigbee_cli_cmd_bdb.c b/components/zigbee/cli/zigbee_cli_cmd_bdb.c
index ea8de8a..8aec3f8 100644
--- a/components/zigbee/cli/zigbee_cli_cmd_bdb.c
+++ b/components/zigbee/cli/zigbee_cli_cmd_bdb.c
@@ -50,7 +50,7 @@
  * @{
  */
 
-static zb_nwk_device_type_t m_default_role      = ZB_NWK_DEVICE_TYPE_ROUTER;
+static zb_nwk_device_type_t m_default_role      = ZB_NWK_DEVICE_TYPE_COORDINATOR;
 static zb_bool_t            m_stack_is_started  = ZB_FALSE;
 static zb_bool_t            m_legacy_mode       = ZB_FALSE;
 
diff --git a/examples/multiprotocol/app_utils/nus.c b/examples/multiprotocol/app_utils/nus.c
index 369c57f..ab3b45b 100644
--- a/examples/multiprotocol/app_utils/nus.c
+++ b/examples/multiprotocol/app_utils/nus.c
@@ -238,8 +238,6 @@ static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
             break;
 
         case BLE_ADV_EVT_IDLE:
-            err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
-            APP_ERROR_CHECK(err_code);
             break;
 
         default:
@@ -370,6 +368,7 @@ static void advertising_init(void)
 
     memset(&init, 0, sizeof(init));
 
+
     init.advdata.name_type          = BLE_ADVDATA_FULL_NAME;
     init.advdata.include_appearance = false;
     init.advdata.flags              = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
@@ -389,6 +388,15 @@ static void advertising_init(void)
     ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
 }
 
+
+void nus_start_advertising(void)
+{
+    uint32_t       err_code;
+    err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
+    APP_ERROR_CHECK(err_code);
+}
+
+
 /**@brief Function for initializing NUS service.
  *
  * @param[in] handler Default Handler to use. If NULL,
@@ -432,9 +440,7 @@ void nus_init(nus_handler_t handler)
     nus_service_init(handler);
     advertising_init();
     conn_params_init();
-
-    err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
-    APP_ERROR_CHECK(err_code);
+    nus_start_advertising();
 }
 
 /**@brief Function to set the NUS default handler. */
diff --git a/examples/multiprotocol/app_utils/nus.h b/examples/multiprotocol/app_utils/nus.h
index f55ef0d..8b9747d 100644
--- a/examples/multiprotocol/app_utils/nus.h
+++ b/examples/multiprotocol/app_utils/nus.h
@@ -57,8 +57,8 @@
 #define APP_NUS_OBSERVER_PRIO               1                                   /**< Application's BLE observer priority. You shouldn't need to modify this value. */
 #define APP_BLE_CONN_CFG_TAG                1                                   /**< A tag identifying the SoftDevice BLE configuration. */
 #define NUS_SERVICE_UUID_TYPE               BLE_UUID_TYPE_VENDOR_BEGIN          /**< UUID type for the Nordic UART Service (vendor specific). */
-#define APP_ADV_DURATION                    18000                               /**< The advertising duration (180 seconds) in units of 10 milliseconds. */
-#define APP_ADV_INTERVAL                    320                                 /**< The advertising interval (in units of 0.625 ms. This value corresponds to 200 ms). */
+#define APP_ADV_DURATION                    3000                                /**< The advertising duration (30 seconds) in units of 10 milliseconds. */
+#define APP_ADV_INTERVAL                    3200/2                              /**< The advertising interval (in units of 0.625 ms. This value corresponds to 1000 ms). */
 #define MIN_CONN_INTERVAL                   MSEC_TO_UNITS(200, UNIT_1_25_MS)    /**< Minimum acceptable connection interval (200 ms), Connection interval uses 1.25 ms units. */
 #define MAX_CONN_INTERVAL                   MSEC_TO_UNITS(300, UNIT_1_25_MS)    /**< Maximum acceptable connection interval (300 ms), Connection interval uses 1.25 ms units. */
 #define SLAVE_LATENCY                       0                                   /**< Slave latency. */
@@ -139,5 +139,6 @@ bool nus_remove_command(char * cmd);
  */
 void nus_set_default_handler(nus_handler_t handler);
 
+void nus_start_advertising(void);
 
 #endif /* NUS_H__ */
diff --git a/examples/multiprotocol/ble_zigbee/ble_zigbee_dynamic_door_lock_nus/pca10059/s140/armgcc/Makefile b/examples/multiprotocol/ble_zigbee/ble_zigbee_dynamic_door_lock_nus/pca10059/s140/armgcc/Makefile
index 57c437b..33df8b3 100644
--- a/examples/multiprotocol/ble_zigbee/ble_zigbee_dynamic_door_lock_nus/pca10059/s140/armgcc/Makefile
+++ b/examples/multiprotocol/ble_zigbee/ble_zigbee_dynamic_door_lock_nus/pca10059/s140/armgcc/Makefile
@@ -54,10 +54,10 @@ SRC_FILES += \
   $(SDK_ROOT)/external/zboss/addons/zcl/zb_zcl_common_addons.c \
   $(SDK_ROOT)/external/zboss/addons/zcl/zb_zcl_ota_upgrade_addons.c \
   $(SDK_ROOT)/components/boards/boards.c \
-  $(SDK_ROOT)/integration/nrfx/legacy/nrf_drv_clock.c \
-  $(SDK_ROOT)/integration/nrfx/legacy/nrf_drv_ppi.c \
-  $(SDK_ROOT)/integration/nrfx/legacy/nrf_drv_rng.c \
-  $(SDK_ROOT)/integration/nrfx/legacy/nrf_drv_uart.c \
+  $(SDK_ROOT)/../nrf5_sdk/integration/nrfx/legacy/nrf_drv_clock.c \
+  $(SDK_ROOT)/../nrf5_sdk/integration/nrfx/legacy/nrf_drv_ppi.c \
+  $(SDK_ROOT)/../nrf5_sdk/integration/nrfx/legacy/nrf_drv_rng.c \
+  $(SDK_ROOT)/../nrf5_sdk/integration/nrfx/legacy/nrf_drv_uart.c \
   $(SDK_ROOT)/modules/nrfx/hal/nrf_ecb.c \
   $(SDK_ROOT)/modules/nrfx/soc/nrfx_atomic.c \
   $(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_clock.c \
@@ -96,7 +96,7 @@ INC_FOLDERS += \
   $(SDK_ROOT)/components/libraries/experimental_task_manager \
   $(SDK_ROOT)/components/libraries/gpiote \
   $(SDK_ROOT)/components/ble/ble_services/ble_lbs_c \
-  $(SDK_ROOT)/integration/nrfx/legacy \
+  $(SDK_ROOT)/../nrf5_sdk/integration/nrfx/legacy \
   $(SDK_ROOT)/components/libraries/usbd \
   $(SDK_ROOT)/components/ble/ble_services/ble_lbs \
   $(SDK_ROOT)/components/ble/ble_services/ble_cts_c \
@@ -213,7 +213,7 @@ INC_FOLDERS += \
   $(SDK_ROOT)/modules/nrfx/mdk \
   $(SDK_ROOT)/components/ble/ble_racp \
   $(SDK_ROOT)/components/ble/ble_services/ble_hts \
-  $(SDK_ROOT)/integration/nrfx \
+  $(SDK_ROOT)/../nrf5_sdk/integration/nrfx \
   $(SDK_ROOT)/components/ble/ble_services/ble_lls \
   $(SDK_ROOT)/components/nfc/t2t_parser \
   $(SDK_ROOT)/components/libraries/ringbuf \
@@ -262,7 +262,7 @@ CFLAGS += -DZB_TRACE_LEVEL=0
 CFLAGS += -DZB_TRACE_MASK=0
 CFLAGS += -mcpu=cortex-m4
 CFLAGS += -mthumb -mabi=aapcs
-CFLAGS += -Wall -Werror
+CFLAGS += -Wall # -Werror
 CFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16
 # keep every function in a separate section, this allows linker to discard unused ones
 CFLAGS += -ffunction-sections -fdata-sections -fno-strict-aliasing
diff --git a/examples/zigbee/experimental/cli/cli_agent_router/pca10056/blank/armgcc/Makefile b/examples/zigbee/experimental/cli/cli_agent_router/pca10056/blank/armgcc/Makefile
index 4c93dd8..54a81f5 100644
--- a/examples/zigbee/experimental/cli/cli_agent_router/pca10056/blank/armgcc/Makefile
+++ b/examples/zigbee/experimental/cli/cli_agent_router/pca10056/blank/armgcc/Makefile
@@ -59,10 +59,10 @@ SRC_FILES += \
   $(SDK_ROOT)/components/libraries/experimental_section_vars/nrf_section_iter.c \
   $(SDK_ROOT)/components/libraries/sortlist/nrf_sortlist.c \
   $(SDK_ROOT)/components/libraries/strerror/nrf_strerror.c \
-  $(SDK_ROOT)/integration/nrfx/legacy/nrf_drv_clock.c \
-  $(SDK_ROOT)/integration/nrfx/legacy/nrf_drv_power.c \
-  $(SDK_ROOT)/integration/nrfx/legacy/nrf_drv_rng.c \
-  $(SDK_ROOT)/integration/nrfx/legacy/nrf_drv_uart.c \
+  $(SDK_ROOT)/../nrf5_sdk/integration/nrfx/legacy/nrf_drv_clock.c \
+  $(SDK_ROOT)/../nrf5_sdk/integration/nrfx/legacy/nrf_drv_power.c \
+  $(SDK_ROOT)/../nrf5_sdk/integration/nrfx/legacy/nrf_drv_rng.c \
+  $(SDK_ROOT)/../nrf5_sdk/integration/nrfx/legacy/nrf_drv_uart.c \
   $(SDK_ROOT)/modules/nrfx/hal/nrf_ecb.c \
   $(SDK_ROOT)/components/drivers_nrf/nrf_soc_nosd/nrf_nvic.c \
   $(SDK_ROOT)/modules/nrfx/hal/nrf_nvmc.c \
@@ -105,7 +105,7 @@ INC_FOLDERS += \
   $(SDK_ROOT)/external/utf_converter \
   $(SDK_ROOT)/external/zboss/addons \
   $(SDK_ROOT)/components/libraries/usbd/class/cdc/acm \
-  $(SDK_ROOT)/integration/nrfx \
+  $(SDK_ROOT)/../nrf5_sdk/integration/nrfx \
   $(PROJ_DIR) \
   $(SDK_ROOT)/components/libraries/cli/uart \
   $(SDK_ROOT)/external/zboss/zb_error \
@@ -125,7 +125,7 @@ INC_FOLDERS += \
   $(SDK_ROOT)/components/libraries/cli \
   $(SDK_ROOT)/components/drivers_nrf/nrf_soc_nosd \
   $(SDK_ROOT)/components/libraries/usbd/class/cdc \
-  $(SDK_ROOT)/integration/nrfx/legacy \
+  $(SDK_ROOT)/../nrf5_sdk/integration/nrfx/legacy \
   $(SDK_ROOT)/components/libraries/button \
   $(SDK_ROOT)/components/libraries/log \
   $(SDK_ROOT)/modules/nrfx/hal \
@@ -180,7 +180,7 @@ CFLAGS += -DZB_TRACE_LEVEL=0
 CFLAGS += -DZB_TRACE_MASK=0
 CFLAGS += -mcpu=cortex-m4
 CFLAGS += -mthumb -mabi=aapcs
-CFLAGS += -Wall -Werror
+CFLAGS += -Wall #-Werror
 CFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16
 # keep every function in a separate section, this allows linker to discard unused ones
 CFLAGS += -ffunction-sections -fdata-sections -fno-strict-aliasing
diff --git a/examples/zigbee/experimental/cli/cli_agent_router/pca10059/mbr/armgcc/Makefile b/examples/zigbee/experimental/cli/cli_agent_router/pca10059/mbr/armgcc/Makefile
index a276acf..a29f420 100644
--- a/examples/zigbee/experimental/cli/cli_agent_router/pca10059/mbr/armgcc/Makefile
+++ b/examples/zigbee/experimental/cli/cli_agent_router/pca10059/mbr/armgcc/Makefile
@@ -59,10 +59,10 @@ SRC_FILES += \
   $(SDK_ROOT)/components/libraries/experimental_section_vars/nrf_section_iter.c \
   $(SDK_ROOT)/components/libraries/sortlist/nrf_sortlist.c \
   $(SDK_ROOT)/components/libraries/strerror/nrf_strerror.c \
-  $(SDK_ROOT)/integration/nrfx/legacy/nrf_drv_clock.c \
-  $(SDK_ROOT)/integration/nrfx/legacy/nrf_drv_power.c \
-  $(SDK_ROOT)/integration/nrfx/legacy/nrf_drv_rng.c \
-  $(SDK_ROOT)/integration/nrfx/legacy/nrf_drv_uart.c \
+  $(SDK_ROOT)/../nrf5_sdk/integration/nrfx/legacy/nrf_drv_clock.c \
+  $(SDK_ROOT)/../nrf5_sdk/integration/nrfx/legacy/nrf_drv_power.c \
+  $(SDK_ROOT)/../nrf5_sdk/integration/nrfx/legacy/nrf_drv_rng.c \
+  $(SDK_ROOT)/../nrf5_sdk/integration/nrfx/legacy/nrf_drv_uart.c \
   $(SDK_ROOT)/modules/nrfx/hal/nrf_ecb.c \
   $(SDK_ROOT)/components/drivers_nrf/nrf_soc_nosd/nrf_nvic.c \
   $(SDK_ROOT)/modules/nrfx/hal/nrf_nvmc.c \
@@ -105,7 +105,7 @@ INC_FOLDERS += \
   $(SDK_ROOT)/external/utf_converter \
   $(SDK_ROOT)/external/zboss/addons \
   $(SDK_ROOT)/components/libraries/usbd/class/cdc/acm \
-  $(SDK_ROOT)/integration/nrfx \
+  $(SDK_ROOT)/../nrf5_sdk/integration/nrfx \
   $(PROJ_DIR) \
   $(SDK_ROOT)/components/libraries/cli/uart \
   $(SDK_ROOT)/external/zboss/zb_error \
@@ -126,7 +126,7 @@ INC_FOLDERS += \
   $(SDK_ROOT)/components/libraries/cli \
   $(SDK_ROOT)/components/drivers_nrf/nrf_soc_nosd \
   $(SDK_ROOT)/components/libraries/usbd/class/cdc \
-  $(SDK_ROOT)/integration/nrfx/legacy \
+  $(SDK_ROOT)/../nrf5_sdk/integration/nrfx/legacy \
   $(SDK_ROOT)/components/libraries/button \
   $(SDK_ROOT)/components/libraries/log \
   $(SDK_ROOT)/modules/nrfx/hal \
@@ -182,7 +182,7 @@ CFLAGS += -DZB_TRACE_LEVEL=0
 CFLAGS += -DZB_TRACE_MASK=0
 CFLAGS += -mcpu=cortex-m4
 CFLAGS += -mthumb -mabi=aapcs
-CFLAGS += -Wall -Werror
+CFLAGS += -Wall #-Werror
 CFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16
 # keep every function in a separate section, this allows linker to discard unused ones
 CFLAGS += -ffunction-sections -fdata-sections -fno-strict-aliasing
diff --git a/external/zboss/include/ha/zb_ha_door_lock.h b/external/zboss/include/ha/zb_ha_door_lock.h
index fdf8555..7b7bab8 100644
--- a/external/zboss/include/ha/zb_ha_door_lock.h
+++ b/external/zboss/include/ha/zb_ha_door_lock.h
@@ -78,7 +78,7 @@ PURPOSE: Door lock device definition
 
 /** @cond internal */
 
-#define ZB_HA_DOOR_LOCK_IN_CLUSTER_NUM  5   /*!< @internal Door Lock IN clusters number */
+#define ZB_HA_DOOR_LOCK_IN_CLUSTER_NUM  6   /*!< @internal Door Lock IN clusters number */
 #define ZB_HA_DOOR_LOCK_OUT_CLUSTER_NUM 0   /*!< @internal Door Lock OUT clusters number */
 
 /** @internal @brief Number of clusters for DoorLock HA device. */
@@ -102,6 +102,7 @@ PURPOSE: Door lock device definition
 #define ZB_HA_DECLARE_DOOR_LOCK_CLUSTER_LIST(                    \
       cluster_list_name,                                         \
       door_lock_attr_list,                                       \
+      power_config_attr_list,                                    \
       basic_attr_list,                                           \
       identify_attr_list,                                        \
       groups_attr_list,                                          \
@@ -129,6 +130,13 @@ PURPOSE: Door lock device definition
           ZB_ZCL_CLUSTER_SERVER_ROLE,                            \
           ZB_ZCL_MANUF_CODE_INVALID                              \
         ),                                                       \
+        ZB_ZCL_CLUSTER_DESC(                                     \
+          ZB_ZCL_CLUSTER_ID_POWER_CONFIG,                        \
+          ZB_ZCL_ARRAY_SIZE(power_config_attr_list, zb_zcl_attr_t), \
+          (power_config_attr_list),                              \
+          ZB_ZCL_CLUSTER_SERVER_ROLE,                            \
+          ZB_ZCL_MANUF_CODE_INVALID                              \
+        ),                                                       \
         ZB_ZCL_CLUSTER_DESC(                                     \
           ZB_ZCL_CLUSTER_ID_SCENES,                              \
           ZB_ZCL_ARRAY_SIZE(scenes_attr_list, zb_zcl_attr_t),    \
@@ -169,6 +177,7 @@ PURPOSE: Door lock device definition
           ZB_ZCL_CLUSTER_ID_BASIC,                                          \
           ZB_ZCL_CLUSTER_ID_IDENTIFY,                                       \
           ZB_ZCL_CLUSTER_ID_DOOR_LOCK,                                      \
+          ZB_ZCL_CLUSTER_ID_POWER_CONFIG,                                   \
           ZB_ZCL_CLUSTER_ID_SCENES,                                         \
           ZB_ZCL_CLUSTER_ID_GROUPS                                          \
         }                                                                   \
diff --git a/external/zboss/include/zcl/zb_zcl_door_lock.h b/external/zboss/include/zcl/zb_zcl_door_lock.h
index 8c097de..8ac837d 100644
--- a/external/zboss/include/zcl/zb_zcl_door_lock.h
+++ b/external/zboss/include/zcl/zb_zcl_door_lock.h
@@ -781,6 +781,14 @@ typedef ZB_PACKED_PRE struct zb_zcl_door_lock_read_unlock_door_res_payload_s
     (zb_voidp_t) data_ptr                                         \
   }
 
+#define ZB_SET_ATTR_DESCR_WITH_ZB_ZCL_ATTR_DOOR_LOCK_DOOR_STATE_ID(data_ptr)                 \
+  {                                                                                          \
+    ZB_ZCL_ATTR_DOOR_LOCK_DOOR_STATE_ID,                                                     \
+    ZB_ZCL_ATTR_TYPE_8BIT_ENUM,                                                              \
+    ZB_ZCL_ATTR_ACCESS_READ_ONLY | ZB_ZCL_ATTR_ACCESS_REPORTING | ZB_ZCL_ATTR_ACCESS_SCENE,  \
+    (zb_voidp_t) data_ptr                                                                    \
+  }
+
 #define ZB_SET_ATTR_DESCR_WITH_ZB_ZCL_ATTR_DOOR_LOCK_RF_OPERATION_EVENT_MASK_ID(data_ptr) \
   {                                                               \
     ZB_ZCL_ATTR_DOOR_LOCK_RF_OPERATION_EVENT_MASK_ID,             \
@@ -790,7 +798,9 @@ typedef ZB_PACKED_PRE struct zb_zcl_door_lock_read_unlock_door_res_payload_s
   }
 
 /*! @internal @brief Number of attributes mandatory for reporting in Door Lock cluster */
+#ifndef ZB_ZCL_DOOR_LOCK_REPORT_ATTR_COUNT
 #define ZB_ZCL_DOOR_LOCK_REPORT_ATTR_COUNT  1
+#endif
 
 /*! @}
     @endcond */ /* DoorLock cluster internals */
diff --git a/external/zboss/include/zcl/zb_zcl_power_config.h b/external/zboss/include/zcl/zb_zcl_power_config.h
index 7302dcd..0b00bcd 100644
--- a/external/zboss/include/zcl/zb_zcl_power_config.h
+++ b/external/zboss/include/zcl/zb_zcl_power_config.h
@@ -710,6 +710,29 @@ enum zb_zcl_power_config_battery_alarm_state_e
     percent_threshold2, percent_threshold3, alarm_state)                                    \
   ZB_ZCL_FINISH_DECLARE_ATTRIB_LIST
 
+
+/** @cond internals_doc */
+#define ZB_ZCL_POWER_CONFIG_BATTERY_ATTRIB_LIST_MIN(bat_num,   \
+    remaining, alarm_state)                                    \
+  /* ext attribute */  \
+  ZB_SET_ATTR_DESCR_WITH_ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_PERCENTAGE_REMAINING_ID(remaining, bat_num), \
+  ZB_SET_ATTR_DESCR_WITH_ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_ALARM_STATE_ID(alarm_state, bat_num), \
+
+/*! @}
+ *  @endcond */ /* internals_doc */
+
+/** @brief Declare attribute list for Power Configuration cluster - server side (Battery attribute
+    list extended)
+    @param attr_list - attribute list name
+    @param remaining - pointer to variable to store BatteryPercentageRemaining attribute
+    @param alarm_state - pointer to variable to store BatteryAlarmState attribute
+*/
+#define ZB_ZCL_DECLARE_POWER_CONFIG_BATTERY_ATTRIB_LIST_MIN(attr_list,   \
+    remaining, alarm_state)                                              \
+  ZB_ZCL_START_DECLARE_ATTRIB_LIST(attr_list)                            \
+  ZB_ZCL_POWER_CONFIG_BATTERY_ATTRIB_LIST_MIN(,                          \
+    remaining, alarm_state)                                              \
+  ZB_ZCL_FINISH_DECLARE_ATTRIB_LIST
 /*! @} */ /* Power Configuration cluster attributes */
 
 /*! @name Power Configuration cluster commands

wireshark capture of normal join, than a couple of local leaves and rejoins.

zigbee-traffic.pcap

  • I do not understand? You have the log above, the ZB_COMM_STATUS_ChECK prints out ERROR 1 in one case and does not trigger otherwise. 

    The execution does not stop.

    It seems like it is working ok when connectiong to a homey, but not to home assistant using conbee II stick. But I cannot tell why from the logs in home assistant and I guess that the error is on our side. Does the decoded logs say anything?

  • Sorry. I have sent a question to the Zigbee team to check that I decoded the logs correctly. But if I did, the log doesn't say anything more than that:

    <info> app: Network left (leave type: 0)
    <error> app: Unable to start BDB commissioning at /work/src/app/doorlock/main.c:524
    <error> app: ERROR 1 [RET_ERROR] at /work/src/app/doorlock/main.c:524
    <error> app: Failed to join network (status: -1)
    <error> app: Failed to join network (status: -1)

    I'll ping them, and get back to you when I get a reply.

  • Hello,

    Can you please try the following:

    In sdk_config.h please set (modify) the following defines:

    #define ZIGBEE_TRACE_LEVEL 4
    #define ZIGBEE_TRACE_MASK TRACE_SUBSYSTEM_ZCL | TRACE_SUBSYSTEM_ZDO | TRACE_SUBSYSTEM_NWK

    And in addition, you need to replace your zboss stack with the debug version (sorry for not mentioning this earlier).

    I don't know what IDE you are using, but either way, if you go to SDK_for_Thread_and_Zigbee_4.1.0\external\zboss\lib, you will see the folders:

    -gcc
    -iar
    -keil

    So you are already using one of the libraries from one of these folders. You will also see a folder called "debug". Replace the libzboss library in your project with the equivalent library within the "debug" folder. After you have applied these changes, please collect the trace again, and post it here.

    One more question: Is there any way for us to reproduce what you are seeing using only DKs (No external HW)? If so, can you please zip the project folder and attach it here?

    Please try to unzip it in an unmodified SDK4.1.0 to make sure that:

    1. It compiles

    2. It reproduces without changes in the common SDK files.

    If you have any custom files, move them into the project folder.

    Best regards,

    Edvin

  • Hi,

    How did you fix that issue? I've got the exact same problem here where the program gets stuck when calling zb_bdb_reset_via_local_action(0)

    Best,

  • If the person who posted this doesn't return, please create a new ticket where you explain in detail what you are doing and what you are seeing.

    Best regards,

    Edvin

Related