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

Zigbee: Giving end device permission to join network

Hi,

I'm working with the nrf52840-DK and using the nRF5 SDK v15.2.0 Stack version.

I´ve got a working program for my coordinator (C) and my end device (ED). The C establishes the network successfully, the ED is able to join and they are both able to send messages to each other, by pressing one of the buttons on the nrf52840 DK. It also works to find out the short address and other information about the new joined device.
NOTE: I attached my coordinators main, buttons_handler_function, and zboss_signal_handler below.

As soon as the ED is switched on, it starts searching for a network, if it is in range of my C, it instantly joins the network. Now I want my C not to respond to the joining requests of the the ED unless one of the C buttons is pressed.

So far I couldn´t find a way to control the commissioning/joining procedure. Feels like Zigbee is managing all of this stuff by it self and is giving me just an interrupt in the zboss_signal_handler. It jumps correctly into the case ZB_ZDO_SIGNAL_DEVICE_ANNCE, which gives me the chance to get all the informations about the new device (as mentioned above) and call other functions. But at the time I get the interrupt in the zboss_signal_handler, the joining procedure is already done!

I already figured out that I could change -> ZB_DEFAULT_PRMIT_JOINING_DURATION   0xff  (in zb_config_common.h ). But I don´t know on which value I have to set ZB_DEFAULT_PRMIT_JOINING_DURATION in order to lower the permit time to a few seconds. But this still won´t enable me to control the commissioning/joining procedure.


So my two issues that I´m struggling with are:

1. How to control the commissioning/joining procedure?

2. Do I have to reduce the joining duration and how do I do that?

Thanks
Greetings Luke

#include "zboss_api.h"
#include "zboss_api_aps.h"
#include "zb_mem_config_med.h"
#include "zb_error_handler.h"

#include "zb_zcl_commands.h"
#include "zb_zcl_basic.h"
#include "bsp.h"
#include "boards.h"


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


#define MAX_CHILDREN                      2                                    /**< The maximum amount of connected devices. Setting this value to 0 disables association to this device.  */
#define IEEE_CHANNEL_MASK                 (1l << ZIGBEE_CHANNEL)                /**< Scan only one, predefined channel to find the coordinator. */
#define COORDINATOR_ENDPOINT              10                                    /**< Device endpoint, used to receive light controlling commands. */
#define ERASE_NVRAM_AT_REBOOT             ZB_FALSE                              /**< Do not erase NVRAM to save the network parameters after device reboot or power-off. */
#define ZB_ON_STATUS                      BSP_BOARD_LED_0                       //LED indicating that device boot was successful
#define ZB_MESSAGE_RECEIVED               BSP_BOARD_LED_3                       //LED indicating that message was receive
#define ZB_NWK_ROLE_LED                   BSP_BOARD_LED_1                       //LED indicating which NWK role device has
#define ZB_FOUND_DEVICE_LED_2             BSP_BOARD_LED_2 

#ifndef ZB_COORDINATOR_ROLE
#error Define ZB_COORDINATROR_ROLE to compile coordinator source code.
#endif 

/*
.....SOME DECALRATIONS AND DEFINTIONS OF VARIABLES AND FUNCTIONS....

*/

static void buttons_routine(bsp_event_t event)
{
  zb_ret_t        error_code;
  zb_uint8_t      transmit_mode_id;

  switch (event)
  {
    case BSP_EVENT_KEY_0:
    {
      current_pressed_button = BSP_EVENT_KEY_0-13;
      NRF_LOG_INFO("BUTTON: %d is pressed", current_pressed_button);
      break;
    }

    case BSP_EVENT_KEY_1:
    {
	current_pressed_button = BSP_EVENT_KEY_1-13;
      	NRF_LOG_INFO("BUTTON: %d is pressed", current_pressed_button);
      	break;
    }

    case BSP_EVENT_KEY_2:
    {
 	current_pressed_button = BSP_EVENT_KEY_2-13;
      	NRF_LOG_INFO("BUTTON: %d is pressed", current_pressed_button);
      	break;
    }

    case BSP_EVENT_KEY_3:
    {
 	current_pressed_button = BSP_EVENT_KEY_3-13;
      	NRF_LOG_INFO("BUTTON: %d is pressed", current_pressed_button);
      	break;

    default: 
    {
      NRF_LOG_INFO("Button without meaning -> no action");
      break;
    }
  }

  ZB_FREE_BUF_BY_REF(event);
};



void zboss_signal_handler(zb_uint8_t param)
{
  zb_zdo_app_signal_type_t  signal = zb_get_app_signal(param,NULL);
  zb_ret_t                  status = ZB_GET_APP_SIGNAL_STATUS(param);
  zb_ret_t                  zb_error_code;
  zb_bool_t                 comm_status;

  g_p_buf    = ZB_BUF_FROM_REF(param); 
  g_p_ind    = ZB_GET_BUF_PARAM(g_p_buf, zb_apsde_data_indication_t);
  // Getting information out of the received Signal.
  switch (signal)
  {
    case ZB_BDB_SIGNAL_DEVICE_FIRST_START:   //Device started and commissioned
    case ZB_BDB_SIGNAL_DEVICE_REBOOT:
    {
      if(status ==RET_OK)
      {
        NRF_LOG_INFO ("Device start: SUCCESSFUL. Network steering started. Signal: %d Status: %d",signal, status);
        comm_status=bdb_start_top_level_commissioning(ZB_BDB_NETWORK_STEERING);
        ZB_COMM_STATUS_CHECK(comm_status);
        //zb_error_code =ZB_SCHEDULE_ALARM(find_member_routine_to,param,ZB_C_SHORT_TIME_DELAY);
        //ZB_ERROR_CHECK(zb_error_code);
      }

      else
      {
        NRF_LOG_ERROR("Network steering failed, retry again. Status %d",status);
        zb_error_code=ZB_SCHEDULE_ALARM(bdb_restart_top_level_commissioning,0,ZB_TIME_ONE_SECOND);

      }
      break;
     }

     case ZB_BDB_SIGNAL_STEERING:
     {
      
      if(status ==RET_OK)
      {
        NRF_LOG_INFO("Steering in progress: %d", signal);
        zb_error_code = ZB_SCHEDULE_ALARM(steering_finished,param,ZB_TIME_ONE_SECOND);
      }
      else
      {
        NRF_LOG_ERROR("Steering failed. retry again in 1s. Status: %d", status);
        zb_error_code = ZB_SCHEDULE_ALARM(bdb_restart_top_level_commissioning,0, ZB_TIME_ONE_SECOND);
        ZB_ERROR_CHECK(zb_error_code);
      }
      break;
     }

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

     case ZB_ZDO_SIGNAL_DEVICE_ANNCE:
     {
        NRF_LOG_INFO("\n++++Signal Device Announcement: %d ->Status:%d+++",signal,status);
        UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
        zb_error_code = ZB_GET_OUT_BUF_DELAYED2(get_peer_address,param);
        ZB_ERROR_CHECK(zb_error_code);
      break;
     }

      default:
      NRF_LOG_INFO("UNKNOWN SIGNAL-> %d! Status: %d",signal,status);
      break;
    }
  //Free Buffer
  if(param)
  {
    //ZB_FREE_BUF_BY_REF(param);
  }
 }
/*END*******************************************************************ZBOSS SIGNAL HANDLER******************************************************************************/


int main(void)
 {
    zb_ret_t       zb_err_code;
    zb_ieee_addr_t ieee_addr;


    timers_init();
    log_init();
    leds_init();
    buttons_init();

    ZB_SET_TRACE_LEVEL(ZIGBEE_TRACE_LEVEL);
    ZB_SET_TRACE_MASK(ZIGBEE_TRACE_MASK);
    ZB_SET_TRAF_DUMP_OFF();

    ZB_INIT("zdo_zc");

    zb_osif_get_ieee_eui64(ieee_addr);
    zb_set_long_address(ieee_addr);

    zb_set_network_coordinator_role(IEEE_CHANNEL_MASK);
    zb_set_max_children(MAX_CHILDREN);
    //do not erase NVRAM after Reboot
    zb_set_nvram_erase_at_start(ERASE_NVRAM_AT_REBOOT);

    //ZB_ZCL_REGISTER_DEVICE_CB(zcl_device_cb);

    ZB_AF_REGISTER_DEVICE_CTX(&router_ctx);

    //Registering the zcl_device_cb in order to handle interrupt, when message is received
    ZB_AF_SET_ENDPOINT_HANDLER(COORDINATOR_ENDPOINT, zcl_device_cb);

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


    bsp_board_led_on(ZB_ON_STATUS);

    while(1)
    {
        bsp_board_led_off(ZB_MESSAGE_RECEIVED);
        zboss_main_loop_iteration();
        UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
    }
}

  • Hi,

    Have you read this section of the Zigbee SDK documentation?

    Support for Zigbee commissioning

    Best regards,
    Jørgen

  • Hi Jørgen,
    thank you, I got it working for the End-Device, but NOT for the coordinator. 
    The End-Device now joines, only if a button is pressed on the ED-Board. I tried to do it like explained in the support file, but the zboss_start_no_autostart() function won't call my zboss_signal_handler until the zboss_start() is executed, by the way, there is now zboss_start_continue() function as mentioned in the file, I had to use zboss_start().
    So for my End Device, everything seems fine the code is working, but different to the instruction.
    I've uploaded the code (includes, buttons-handler, zboss_signal_handler, main) up here:

    /*********************************************************END DEVICE*****************************************************/
    #include "zboss_api.h"
    #include "zboss_api_aps.h"
    #include "zb_mem_config_min.h"
    #include "zb_error_handler.h"
    
    #include "zb_zcl_commands.h"
    #include "zb_zcl_basic.h"
    #include "app_timer.h"
    #include "bsp.h"
    #include "boards.h"
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    #include "nrf_log_default_backends.h"
    
    #include "zb_zcl_freq_management.h"
    
    //#include "zb_nwk_nib.h"
    
    //#include "ED_tx_routines.h"
    
    #include "ED_connect_routines.c"
    #include "ED_tx_routines.c"
    #include "ED_buttons_routine.c"
    
    //#include "ED_timer.c"
    
    
    //DEFINES
    #define IEEE_CHANNEL_MASK           (1l<<ZIGBEE_CHANNEL)      //Scans predefined channel for Coordinator
    #define ENDPOINT                    1                         //Source of this Endpoint
    #define ERASE_PERSISTENT_CONFIG     ZB_TRUE                  //Do not erase NVRAM
    #define ZB_JOINED_LED               BSP_BOARD_LED_3           //LED indiciating that joining was succesful
    #define ZB_DEVICE_ON_LED            BSP_BOARD_LED_0           //LED indiciating that device is turned on
    #define ZB_SHORT_DELAY              (1*ZB_TIME_ONE_SECOND)      //One Second short delay
    #define ZB_LONG_DELAY               (5*ZB_TIME_ONE_SECOND)      //Long Delay
    
    #define SIMPLE_TIMER_ENABLED
    #define current_state               APP_STATE_SINGLE_SHOT
    
    #define BUTTON_0                    BSP_BOARD_BUTTON_0        //Board Button 0
    
    /**************************************************************************************************************/
    /*...SOME VARIABLES AND FUNCTIONS DEFINITIONS....*/
    /**************************************************************************************************************/
    
    
    static void buttons_init(void)
    {
      ret_code_t    error_code;
      error_code = bsp_init(BSP_INIT_BUTTONS, buttons_routine);
      APP_ERROR_CHECK(error_code);
    }
    
    /********************************************BUTTONS HANDLER FUNCTION -END DEVICE******************************************/
    static void buttons_routine(bsp_event_t event)
    {
      zb_ret_t        error_code;
      zb_uint8_t      transmit_mode_id;
    
      transmit_mode_id =0; //Variable to identify which sending cb is called, depending on which button was pressed
      //zb_uint32_t     button;
      NRF_LOG_INFO("\n");
      switch (event)
      {
        case BSP_EVENT_KEY_0:
        {
          joining_button = true;
          //.....
          break;
        }
    
        case BSP_EVENT_KEY_1:
        {
          //....
          break;
        }
    
        case BSP_EVENT_KEY_2:
        {
          //...
          break;
        }
    
            case BSP_EVENT_KEY_3:
        {
          //...
    
          break;
        }
    
        default: 
        {
          NRF_LOG_INFO("Button without meaning -> no action");
          break;
        }
      }
      ZB_FREE_BUF_BY_REF(event);
    };
    
    /********************************************ZBOSS_SIGNAL_HANDLER -END DEVICE******************************************/
    
    void zboss_signal_handler(zb_uint8_t signal_param)
    {
      //Variables to handle unpacking of signal buffer
      zb_zdo_app_signal_hdr_t           *p_ext_signal_info  =NULL; //pointer to extended signal information
      //zb_zdo_signal_leave_params_t      *p_leave_param      =NULL;
      zb_zdo_app_signal_type_t                signal              =zb_get_app_signal(signal_param, &p_ext_signal_info);
      zb_ret_t                                status              =ZB_GET_APP_SIGNAL_STATUS(signal_param);
      zb_ret_t                                zb_error_code;
      /*zb_buf_t*/zb_uint8_t                                buf;
      zb_zdo_mgmt_permit_joining_req_param_t *req_param;
    
      switch (signal)
      {
        case ZB_BDB_SIGNAL_DEVICE_FIRST_START:                    //First signal after Reboot
        {
          NRF_LOG_INFO("DEVICE FIRST START");
        }
    
        case ZB_BDB_SIGNAL_DEVICE_REBOOT:                         //Signal that joinging the network was succesful
        {
          if(status==RET_OK && joining_button==true)
          {
            if(ZB_JOINED()==true)
            {
              NRF_LOG_INFO("JOINED NETWORK SUCCESSFULLY -> Status: %d", status);
              bsp_board_led_on(ZB_JOINED_LED);                      //turn on LED idicating-> joing network was succesful
              NRF_LOG_INFO("Network-Role: %d", zb_get_network_role());
              joined_network=true;
            }
    
            else
            {
              NRF_LOG_INFO("JOINING NETWORK FAILED -> Status: %d, PRESS BUTTON TO TRY AGAIN", status);
              joined_network=false;
              joining_button = false; //Reset value for pressed button
            };
          }
          else
          {
            NRF_LOG_INFO("+++NOT NETWORK FOUND+++");
            retry_join(ZB_NWK_LEAVE_TYPE_RESET);
            bsp_board_led_off(ZB_JOINED_LED);
          };
          
          if (signal_param)
          {ZB_FREE_BUF_BY_REF(signal_param);};
          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_ZDO_SIGNAL_SKIP_STARTUP:
         {
            NRF_LOG_WARNING("SKIP_START_UP");
            break;
         }
    
        default: 
        break;
      };//closing: switch (signal)
    
      UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
    };
    
    /********************************************MAIN FUNCTION -END DEVICE******************************************/
    
    int main(void)
    {    
        //defining variables for error_code and adress handling 
        zb_ret_t        zb_error_code;
        zb_ieee_addr_t  ieee_addr;
        zb_uint16_t     data = 0x00FF;
        int time =0;
         
        //Initializiation of timer and log mode
        timers_init();
        led_init();
        log_init();
        buttons_init();
      
        //Set the ZigBee stack: logging level, trace mask, dump subsystem
        ZB_SET_TRACE_LEVEL (ZIGBEE_TRACE_LEVEL);
        ZB_SET_TRACE_MASK (ZIGBEE_TRACE_MASK);
        ZB_SET_TRAF_DUMP_OFF();
    
        //Initializing of the ZigBee-Stack
        ZB_INIT();
    
        //Read values from FICR Register and set device adress to them
        zb_osif_get_ieee_eui64(ieee_addr);
        zb_set_long_address(ieee_addr);
    
        zb_set_network_ed_role(IEEE_CHANNEL_MASK);
        zb_set_nvram_erase_at_start(ERASE_PERSISTENT_CONFIG);
    
        zb_set_keepalive_timeout(ZB_MILLISECONDS_TO_BEACON_INTERVAL(300));
    
        /* Register dimmer switch device context (endpoints). */
        ZB_AF_REGISTER_DEVICE_CTX(&router_ctx);
    
        //Registering the zcl_device_cb in order to handle interrupt, when message is received
        ZB_AF_SET_ENDPOINT_HANDLER(ENDPOINT, zcl_device_cb);
    
        /Start ZigBee-Stack
        zb_error_code = zboss_start_no_autostart();
        ZB_ERROR_CHECK(zb_error_code);
    
        NRF_LOG_INFO("START WHILE LOOP");
        UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
    
    
        bsp_board_led_on(ZB_DEVICE_ON_LED);
    
        zboss_start();
        while(1)
        {
          zboss_main_loop();
          bsp_board_led_off(ZB_MESSAGE_RECEIVED_LED);
          UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
        }
    }
    


    But my main problem as mentioned above is not solved yet.
    I want my Coordinator to establish a network right after switching it on. But I want my coordinator permitting other devices to join the network only when a button on the coordinators board is pressed.

    As soon as my End-Device sends a joining request, I get an interrupt in the signal handler with the signal: ZB_NWK_SIGNAL_DEVICE_ASSOCIATED: so the end device already joined the network, before I had a chance to  decide whether the coordinator should give permission or not. 

    Is there a way, to check the incoming joining request, before my Coordinator automatically gives permission?
    Here's my code for the coordinator:

    /***********************************************COORDINATOR*****************************************************/
    
    #include "zboss_api.h"
    #include "zboss_api_aps.h"
    #include "zb_mem_config_med.h"
    #include "zb_error_handler.h"
    
    #include "zb_zcl_commands.h"
    #include "zb_zcl_basic.h"
    #include "bsp.h"
    #include "boards.h"
    //#include "app_pwm.h"
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    //#include "zb_ha_dimmable_light.h"
    //#include "zb_nrf52840_internal.h"
    
    #include "zb_zcl_freq_management.h"
    
    #define MAX_CHILDREN                      2                                    /**< The maximum amount of connected devices. Setting this value to 0 disables association to this device.  */
    #define IEEE_CHANNEL_MASK                 (1l << ZIGBEE_CHANNEL)                /**< Scan only one, predefined channel to find the coordinator. */
    #define COORDINATOR_ENDPOINT              10                                    /**< Device endpoint, used to receive light controlling commands. */
    #define ERASE_NVRAM_AT_REBOOT             ZB_TRUE                              /**< Do not erase NVRAM to save the network parameters after device reboot or power-off. */
    #define ZB_ON_STATUS                      BSP_BOARD_LED_0                       //LED indicating that device boot was successful
    #define ZB_NWK_ROLE_LED                   BSP_BOARD_LED_1                       //LED indicating which NWK role device has
    #define ZB_C_LONG_TIME_DELAY              (4*ZB_TIME_ONE_SECOND)      //4 seconds long delay
    #define ZB_C_SHORT_TIME_DELAY             (2*ZB_TIME_ONE_SECOND)      //2 seconds short
    #define ZB_ULTRA_LONG_DELAY         (15*ZB_TIME_ONE_SECOND)           //15 sec Long Delay
    
    #ifndef ZB_COORDINATOR_ROLE
    #error Define ZB_COORDINATROR_ROLE to compile coordinator source code.
    #endif 
    
    
    /******************************************************************************************************************/
    /*DEFINITION OF SOME VARIALBLES AND FUNCTIONS */
    /*...........................................:*/
    /*...........................................:*/
    /******************************************************************************************************************/
    
    
    
    static void buttons_init(void)
    {
      ret_code_t    error_code;
      error_code = bsp_init(BSP_INIT_BUTTONS, buttons_routine);
      APP_ERROR_CHECK(error_code);
    }
    
    /**************************************************BUTTONS HANDLER -COORDINATOR**************************************************/
    static void buttons_routine(bsp_event_t event)
    {
      zb_ret_t        error_code;
      zb_uint8_t      transmit_mode_id;
    
      transmit_mode_id =0; //Variable to identify which sending cb is called, depending on which button was pressed
      //zb_uint32_t     button;
      NRF_LOG_INFO("\n");
      switch (event)
      {
        case BSP_EVENT_KEY_0:
        {
          current_pressed_button = BSP_EVENT_KEY_0-13;
          commissioning_button= true;
          break;
        }
    
        case BSP_EVENT_KEY_1:
        {
          current_pressed_button = BSP_EVENT_KEY_1-13;
          break;
        }
    
        case BSP_EVENT_KEY_2:
        {
          current_pressed_button = BSP_EVENT_KEY_2-13;
          break;
        }
    
        case BSP_EVENT_KEY_3:
        {
          current_pressed_button = BSP_EVENT_KEY_3-13;
          break;
        }
    
        default: 
        {
          NRF_LOG_INFO("Button without meaning -> no action");
          break;
        }
      }
      ZB_FREE_BUF_BY_REF(event);
    };
    
    
    
    
    /**************************************************ZBOSS_SIGNAL_HANDLER -COORDINATOR**************************************************/
    
    void zboss_signal_handler(zb_uint8_t param)
    {
      zb_zdo_app_signal_type_t  signal = zb_get_app_signal(param,NULL);
      zb_ret_t                  status = ZB_GET_APP_SIGNAL_STATUS(param);
      zb_ret_t                  zb_error_code;
      zb_bool_t                 comm_status;
    
      g_p_buf    = ZB_BUF_FROM_REF(param); 
      g_p_ind    = ZB_GET_BUF_PARAM(g_p_buf, zb_apsde_data_indication_t);
      switch (signal)
      {
        case ZB_BDB_SIGNAL_DEVICE_FIRST_START:   //Device started and commissioned
        {
          NRF_LOG_INFO("DEVICE FIRST START");
        }
    
        case ZB_ZDO_SIGNAL_SKIP_STARTUP:
         {
            NRF_LOG_WARNING("SKIP_START_UP");
            break;
         }
    
        case ZB_BDB_SIGNAL_DEVICE_REBOOT:
        {
          if(status ==RET_OK)
          {
            NRF_LOG_INFO ("Device start: SUCCESSFUL. Network steering started. Signal: %d Status: %d",signal, status);
            comm_status=bdb_start_top_level_commissioning(ZB_BDB_NETWORK_STEERING);
            ZB_COMM_STATUS_CHECK(comm_status);
          }
    
          else
          {
            NRF_LOG_ERROR("Network steering failed, retry again. Status %d",status);
            zb_error_code=ZB_SCHEDULE_ALARM(bdb_restart_top_level_commissioning,0,ZB_TIME_ONE_SECOND);
          }
          break;
    
         }
    
         case ZB_BDB_SIGNAL_STEERING:
         {
          
          if(status ==RET_OK)
          {
            NRF_LOG_INFO("Steering in progress: %d", signal);
            zb_error_code = ZB_SCHEDULE_ALARM(steering_finished,param,ZB_TIME_ONE_SECOND);//*ZB_ZGP_DEFAULT_COMMISSIONING_WINDOW/28);
          }
          else
          {
            NRF_LOG_ERROR("Steering failed. retry again in 1s. Status: %d", status);
            zb_error_code = ZB_SCHEDULE_ALARM(bdb_restart_top_level_commissioning,0, ZB_TIME_ONE_SECOND);
            ZB_ERROR_CHECK(zb_error_code);
          }
          break;
         }
    
         case ZB_ZDO_SIGNAL_PRODUCTION_CONFIG_READY:
         {
          if(status!=RET_OK)
          {
            NRF_LOG_WARNING("Production config is not present!");
            ZB_FREE_BUF_BY_REF(param);
          }
          break;
         }
    
         case ZB_ZDO_SIGNAL_DEVICE_ANNCE:
         {
            NRF_LOG_INFO("\n++++Signal Device Announcement: %d ->Status:%d+++",signal,status);
            UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
            zb_error_code = ZB_GET_OUT_BUF_DELAYED2(get_peer_address,param);
            ZB_ERROR_CHECK(zb_error_code);
    
          //zb_error_code= ZB_SCHEDULE_ALARM(get_peer_address,param,ZB_TIME_ONE_SECOND);
          break;
         }
    
         case ZB_NWK_SIGNAL_DEVICE_ASSOCIATED:
         {
    	NRF_LOG_INFO("NWK_SIGNAL_DEVICE_ASSOCIATED")
    
         }
    
          default:
          NRF_LOG_INFO("UNKNOWN SIGNAL-> %d! Status: %d",signal,status);
          break;
        }
      UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
      //ZB_FREE_BUF_BY_REF(param);
     }
    
    /**************************************************MAIN FUNCTION -COORDINATOR**************************************************/
    int main(void)
     {
        zb_ret_t       zb_err_code;
        zb_ieee_addr_t ieee_addr;
    
    
        /* Initialize loging system and GPIOs. */
        timers_init();
        log_init();
        leds_init();
        buttons_init();
    
        /* 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("zdo_zc");
    
        /* Set device address to the value read from FICR registers. */
        zb_osif_get_ieee_eui64(ieee_addr);
        zb_set_long_address(ieee_addr);
    
        /* Set static long IEEE address. */
        zb_set_network_coordinator_role(IEEE_CHANNEL_MASK);
        zb_set_max_children(MAX_CHILDREN);
        //do not erase NVRAM after Reboot
        zb_set_nvram_erase_at_start(ERASE_NVRAM_AT_REBOOT);
    
        /* Register callback for handling ZCL commands. */
        //ZB_ZCL_REGISTER_DEVICE_CB(zcl_device_cb);
    
        /* Register dimmer switch device context (endpoints). */
        ZB_AF_REGISTER_DEVICE_CTX(&router_ctx);
    
        //Registering the zcl_device_cb in order to handle interrupt, when message is received
        ZB_AF_SET_ENDPOINT_HANDLER(COORDINATOR_ENDPOINT, zcl_device_cb);
    
        /** Start Zigbee Stack. */
        zboss_start();
    
        bsp_board_led_on(ZB_ON_STATUS);
    
        
        while(1)
        {
          zboss_main_loop();
          bsp_board_led_off(ZB_MESSAGE_RECEIVED);
          UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
        }
    }
    
    


    Thank you

  • Hi,

    I'm sorry for the long wait for the answer to this case. I just got this feedback from the developers:

    The trick is to use zboss_start_no_autostart() and then handle commissioning manually in ZB_ZDO_SIGNAL_SKIP_STARTUP. It's somehow described in the docs although I see that DSR didn't update that part of the dev guide. Please see attached diff: 

    diff --git a/sdk/nrf5/examples/zigbee/light_control/light_coordinator/main.c b/sdk/nrf5/examples/zigbee/light_control/light_coordinator/main.c
    index 2d85e098d3..d6b57052e1 100644
    --- a/sdk/nrf5/examples/zigbee/light_control/light_coordinator/main.c
    +++ b/sdk/nrf5/examples/zigbee/light_control/light_coordinator/main.c
    @@ -131,20 +131,16 @@ void zboss_signal_handler(zb_uint8_t param)
     
         switch(sig)
         {
    -        case ZB_BDB_SIGNAL_DEVICE_FIRST_START: // Device started and commissioned first time after NVRAM erase.
    -        case ZB_BDB_SIGNAL_DEVICE_REBOOT:      // BDB initialization completed after device reboot, use NVRAM contents during initialization. Device joined/rejoined and started.
    -            if (status == RET_OK)
    +        case ZB_ZDO_SIGNAL_SKIP_STARTUP:
    +            if (zb_bdb_is_factory_new())
                 {
    -                NRF_LOG_INFO("Device started OK. Start network steering.");
    -                comm_status = bdb_start_top_level_commissioning(ZB_BDB_NETWORK_STEERING);
    +                comm_status = bdb_start_top_level_commissioning(ZB_BDB_NETWORK_STEERING | ZB_BDB_NETWORK_FORMATION);
                     ZB_COMM_STATUS_CHECK(comm_status);
                 }
                 else
                 {
    -                NRF_LOG_ERROR("Device startup failed. 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);
    +                comm_status = bdb_start_top_level_commissioning(ZB_BDB_INITIALIZATION);
    +                ZB_COMM_STATUS_CHECK(comm_status);
                 }
                 break;
     
    @@ -225,7 +221,7 @@ int main(void)
         zigbee_erase_persistent_storage(ERASE_PERSISTENT_CONFIG);
     
         /** Start Zigbee Stack. */
    -    zb_err_code = zboss_start();
    +    zb_err_code = zboss_start_no_autostart();
         ZB_ERROR_CHECK(zb_err_code);
     
         while(1)
    

    Best regards,
    Jørgen

  • Hi,

    thanks for replying! Yes it works with SKIP_START_UP but this only helps me to control the procedure to found the network.

    But as soon as my End-Device sends a joining request, I get an interrupt in the signal handler with the signal: ZB_NWK_SIGNAL_DEVICE_ASSOCIATED: so the end device already joined the network, before I had a chance to  decide whether the coordinator should give permission or not. 

    Is there a way, to check the incoming joining request, before my Coordinator automatically gives permission?

    If found out that a former ember ZigBee Stack, from 2007 already had this option: http://www.anglia.com/zigbee/pdf/principles.pdf (Turn to slide 5). There's a function that can accept or deny the joining requests. They called it emberTrustCenterJoinHandler(). 
    Is there something similar for the Nordic ZigBee Stack. Kind of a function that enables me, to accept or deny the joining request?

    Thanks
    Greeting Luke

  • Hi,

    Apologies for the long wait for my reply in this case. I just got the feedback from our developer:

    Unfortunately, there is no such functions/API in the current Zigbee stack. There are two approaches that could be used to control which devices join the network:

    1. Use Install Codes. The Install Code of a device which is joining the network must be added to the Trust Center before it can join.
    2. Handle ZB_ZDO_SIGNAL_DEVICE_ANNCE, to detect that a device has joined, and use zdo_mgmt_leave_req() to remove the device from the network. This is not bullet proof since DEVICE_ANNCE is a broadcast message and could be missed by the coordinator.

    Best regards,
    Jørgen

Related