zigbee rssi value is always 127

I am using the zigbee examples and want to see the RSSI value in any received packet.

I am calling zb_zdo_get_diag_data(short_addr, &lqi, &rssi) in zboss_signal_handler() but values are always 127.

-------------

How can I print correct rssi values?

Using nrf connect 1.9.1, nordic nrf52840 dongle

Parents Reply Children
  • Thank you for the response.

    I realized the short address is changing on boot and I was calling outside of switch statement.(first snippet) May be that's why it was returning the 127. 

    void zboss_signal_handler(zb_bufid_t bufid)
    {
    	/* Read signal description out of memory buffer. */
    	zb_zdo_app_signal_hdr_t *sg_p;
    	zb_zdo_app_signal_type_t sig = zb_get_app_signal(bufid, &sg_p);
    	zb_ret_t status = ZB_GET_APP_SIGNAL_STATUS(bufid);
    	zb_ret_t zb_err_code;
    	zb_bool_t comm_status;
    	zb_time_t timeout_bi;
    	// Get RSSI
    	zb_uint8_t lqi = 0;
    	zb_int8_t rssi = 0;
    	zb_uint16_t short_address = 0xa31b;
    	zb_zdo_get_diag_data(short_address, &lqi, &rssi);
    	LOG_INF("(short: 0x%04hx) RSSI {%d}",
    			dev_annce_params->device_short_addr, rssi);
    
    	switch (sig) {
    	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) {
    			if (ZIGBEE_MANUAL_STEERING == ZB_FALSE) {
    				LOG_INF("Start network steering");
    				comm_status = bdb_start_top_level_commissioning(
    					ZB_BDB_NETWORK_STEERING);
    				ZB_COMM_STATUS_CHECK(comm_status);
    			} else {
    				LOG_INF("Coordinator restarted successfully");
    			}
    		} else {
    			LOG_ERR("Failed to initialize Zigbee stack using NVRAM data (status: %d)",
    				status);
    		}
    		break;
    
    	case ZB_BDB_SIGNAL_STEERING:
    		if (status == RET_OK) {
    			if (ZIGBEE_PERMIT_LEGACY_DEVICES == ZB_TRUE) {
    				LOG_INF("Allow pre-Zigbee 3.0 devices to join the network");
    				zb_bdb_set_legacy_device_support(1);
    			}
    
    			/* Schedule an alarm to notify about the end of steering period.
    			 */
    			LOG_INF("Network steering started");
    			zb_err_code = ZB_SCHEDULE_APP_ALARM(
    				steering_finished, 0,
    				ZB_TIME_ONE_SECOND *
    					ZB_ZGP_DEFAULT_COMMISSIONING_WINDOW);
    			ZB_ERROR_CHECK(zb_err_code);
    		}
    		break;
    
    	case ZB_ZDO_SIGNAL_DEVICE_ANNCE: {
    		zb_zdo_signal_device_annce_params_t *dev_annce_params =
    			ZB_ZDO_SIGNAL_GET_PARAMS(
    				sg_p, zb_zdo_signal_device_annce_params_t);
    		LOG_INF("New device commissioned or rejoined (short: 0x%04hx) RSSI {%d}",
    			dev_annce_params->device_short_addr, rssi);
    
    		zb_err_code = ZB_SCHEDULE_APP_ALARM_CANCEL(steering_finished, ZB_ALARM_ANY_PARAM);
    		if (zb_err_code == RET_OK) {
    			LOG_INF("Joining period extended.");
    			zb_err_code = ZB_SCHEDULE_APP_ALARM(
    				steering_finished, 0,
    				ZB_TIME_ONE_SECOND *
    					ZB_ZGP_DEFAULT_COMMISSIONING_WINDOW);
    			ZB_ERROR_CHECK(zb_err_code);
    		}
    	} break;
    
    	default:
    		/* Call default signal handler. */
    		ZB_ERROR_CHECK(zigbee_default_signal_handler(bufid));
    		break;
    	}
    
    	/* Update network status LED. */
    	if (ZB_JOINED() &&
    	    (ZB_SCHEDULE_GET_ALARM_TIME(steering_finished, ZB_ALARM_ANY_PARAM,
    					&timeout_bi) == RET_OK)) {
    		dk_set_led_on(ZIGBEE_NETWORK_STATE_LED);
    	} else {
    		dk_set_led_off(ZIGBEE_NETWORK_STATE_LED);
    	}
    
    	/*
    	 * All callbacks should either reuse or free passed buffers.
    	 * If bufid == 0, the buffer is invalid (not passed).
    	 */
    	if (bufid) {
    		zb_buf_free(bufid);
    	}
    }

    Below version is working but for 1 of the event. Different signal has different structure to return the short address.

    - Is there any common struct to get short address, lqi and rssi for all the events?

    void zboss_signal_handler(zb_bufid_t bufid)
    {
    	/* Read signal description out of memory buffer. */
    	zb_zdo_app_signal_hdr_t *sg_p;
    	zb_zdo_app_signal_type_t sig = zb_get_app_signal(bufid, &sg_p);
    	zb_ret_t status = ZB_GET_APP_SIGNAL_STATUS(bufid);
    	zb_ret_t zb_err_code;
    	zb_bool_t comm_status;
    	zb_time_t timeout_bi;
    
    	switch (sig) {
    	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) {
    			if (ZIGBEE_MANUAL_STEERING == ZB_FALSE) {
    				LOG_INF("Start network steering");
    				comm_status = bdb_start_top_level_commissioning(
    					ZB_BDB_NETWORK_STEERING);
    				ZB_COMM_STATUS_CHECK(comm_status);
    			} else {
    				LOG_INF("Coordinator restarted successfully");
    			}
    		} else {
    			LOG_ERR("Failed to initialize Zigbee stack using NVRAM data (status: %d)",
    				status);
    		}
    		break;
    
    	case ZB_BDB_SIGNAL_STEERING:
    		if (status == RET_OK) {
    			if (ZIGBEE_PERMIT_LEGACY_DEVICES == ZB_TRUE) {
    				LOG_INF("Allow pre-Zigbee 3.0 devices to join the network");
    				zb_bdb_set_legacy_device_support(1);
    			}
    
    			/* Schedule an alarm to notify about the end of steering period.
    			 */
    			LOG_INF("Network steering started");
    			zb_err_code = ZB_SCHEDULE_APP_ALARM(
    				steering_finished, 0,
    				ZB_TIME_ONE_SECOND *
    					ZB_ZGP_DEFAULT_COMMISSIONING_WINDOW);
    			ZB_ERROR_CHECK(zb_err_code);
    		}
    		break;
    
    	case ZB_ZDO_SIGNAL_DEVICE_ANNCE: {
    		zb_zdo_signal_device_annce_params_t *dev_annce_params =
    			ZB_ZDO_SIGNAL_GET_PARAMS(
    				sg_p, zb_zdo_signal_device_annce_params_t);
    		zb_uint8_t lqi = 0;
    		zb_int8_t rssi = 0;
    		zb_zdo_get_diag_data(dev_annce_params->device_short_addr, &lqi, &rssi);
    		LOG_INF("New device commissioned or rejoined (short: 0x%04hx) RSSI {%d}",
    			dev_annce_params->device_short_addr, rssi);
    
    		zb_err_code = ZB_SCHEDULE_APP_ALARM_CANCEL(steering_finished, ZB_ALARM_ANY_PARAM);
    		if (zb_err_code == RET_OK) {
    			LOG_INF("Joining period extended.");
    			zb_err_code = ZB_SCHEDULE_APP_ALARM(
    				steering_finished, 0,
    				ZB_TIME_ONE_SECOND *
    					ZB_ZGP_DEFAULT_COMMISSIONING_WINDOW);
    			ZB_ERROR_CHECK(zb_err_code);
    		}
    	} break;
    
    	default:
    		/* Call default signal handler. */
    		ZB_ERROR_CHECK(zigbee_default_signal_handler(bufid));
    		break;
    	}
    
    	/* Update network status LED. */
    	if (ZB_JOINED() &&
    	    (ZB_SCHEDULE_GET_ALARM_TIME(steering_finished, ZB_ALARM_ANY_PARAM,
    					&timeout_bi) == RET_OK)) {
    		dk_set_led_on(ZIGBEE_NETWORK_STATE_LED);
    	} else {
    		dk_set_led_off(ZIGBEE_NETWORK_STATE_LED);
    	}
    
    	/*
    	 * All callbacks should either reuse or free passed buffers.
    	 * If bufid == 0, the buffer is invalid (not passed).
    	 */
    	if (bufid) {
    		zb_buf_free(bufid);
    	}
    }

  • Hi,

    Yes, that is very likely the reason. In Zigbee, short addresses are not static, so a device will get a new address when it joins a network for the first time, or it might also get a new address under different circumstances, such as an end device rejoining under a different parent in some cases.

    One option is to store the short address of a device somewhere when it joins the network and/or updates it's address, and then use the stored value when calling zb_zdo_get_diag_data(). However, this is partly done for you already if the device is a neighbor device, as the address will be stored in the neighbor table. If the device is a neighbor anyway, then it might be easier to just use the neighbor table entry directly instead of using zb_zdo_get_diag_data(), as the neighbor table entry contains information about RSSI. This will be RSSI for the device and not for specific packets though.

    Another option is to use the Diagnostics cluster, which is intended to provide information about network performance, especially for testing purposes. In this cluster you have the LastMessageRSSI attribute (ZB_ZCL_ATTR_DIAGNOSTICS_LAST_RSSI_ID), which is RSSI for the last message received. So if you use this on your device you will get RSSI of the last message without needing to know the address of the device that sent the message.

    Best regards,

    Marte

Related