Setup: Segger Embedded Studio v3.52, nRF5_SDK_for_Thread_and_Zigbee_v4, nRF52840 Custom Board
Hello,
I based my code off of your Zigbee cli_agent_router example. In the routine cli_agent_ep_handler_ping(zb_bufid_t bufid), the buffer "bufid" is released at certain points, but not everywhere I think it should be released. I've attached the routine below.
/**@brief The Handler to 'intercept' every frame coming to the endpoint * * @param bufid Reference to a ZBOSS buffer */ static zb_uint8_t cli_agent_ep_handler_ping(zb_bufid_t bufid) { zb_zcl_parsed_hdr_t * p_cmd_info = ZB_BUF_GET_PARAM(bufid, zb_zcl_parsed_hdr_t); zb_uint32_t time_diff; if (p_cmd_info->cluster_id != PING_CUSTOM_CLUSTER || p_cmd_info->profile_id != ZB_AF_HA_PROFILE_ID) { return ZB_FALSE; } NRF_LOG_INST_DEBUG(m_log.p_log, "New ping frame received, bufid: %d", bufid); ping_req_indicate(bufid); if (p_cmd_info->cmd_id == PING_ECHO_REPLY) { zb_uint16_t remote_short_addr = 0x0000; /* We have our ping reply */ ping_request_t * p_request = find_request_by_sn(p_cmd_info->seq_number); if (p_request == NULL) { return ZB_FALSE; } if (p_request->remote_addr_mode == ZB_APS_ADDR_MODE_16_ENDP_PRESENT) { remote_short_addr = p_request->remote_addr.addr_short; } else { remote_short_addr = zb_address_short_by_ieee(p_request->remote_addr.addr_long); } if (p_cmd_info->addr_data.common_data.source.addr_type == ZB_ZCL_ADDR_TYPE_SHORT) { if (remote_short_addr != p_cmd_info->addr_data.common_data.source.u.short_addr) { return ZB_FALSE; } } else { return ZB_FALSE; } /* Catch the timers value */ time_diff = get_request_duration(p_request); /* Cancel the ongoing alarm which was to erase the row... */ zb_ret_t zb_err_code = ZB_SCHEDULE_APP_ALARM_CANCEL(invalidate_row_cb, get_request_row(p_request)); ZB_ERROR_CHECK(zb_err_code); /* Call callback function in order to indicate echo response reception. */ if (p_request->p_cb) { p_request->p_cb(PING_EVT_ECHO_RECEIVED, time_diff, p_request); } /* ...and erase it manually */ if (zb_err_code == RET_OK) { zb_ping_release_request(p_request); } } else if ((p_cmd_info->cmd_id == PING_ECHO_REQUEST) || (p_cmd_info->cmd_id == PING_ECHO_NO_ACK_REQUEST)) { zb_uint8_t len = zb_buf_len(bufid); ping_reply_t * p_reply = ping_aquire_reply(); if (p_reply == NULL) { NRF_LOG_INST_WARNING(m_log.p_log, "Cannot obtain new row for incoming ping request"); return ZB_FALSE; } /* Save the Ping Reply information in the table and schedule a sending function */ p_reply->count = len; p_reply->ping_seq = p_cmd_info->seq_number; if (p_cmd_info->cmd_id == PING_ECHO_REQUEST) { NRF_LOG_INST_DEBUG(m_log.p_log, "PING echo request with APS ACK received"); p_reply->send_ack = 1; } else { NRF_LOG_INST_DEBUG(m_log.p_log, "PING echo request without APS ACK received"); p_reply->send_ack = 0; } if (p_cmd_info->addr_data.common_data.source.addr_type == ZB_ZCL_ADDR_TYPE_SHORT) { p_reply->remote_short_addr = p_cmd_info->addr_data.common_data.source.u.short_addr; } else { NRF_LOG_INST_WARNING(m_log.p_log, "Drop ping request due to incorrect address type"); ping_release_reply(p_reply); zb_buf_free(bufid); return ZB_TRUE; } /* Send the Ping Reply, if not possible then invalidate the row */ ping_reply_send(p_reply); } else if (p_cmd_info->cmd_id == PING_NO_ECHO_REQUEST) { NRF_LOG_INST_DEBUG(m_log.p_log, "PING request without ECHO received"); } else { NRF_LOG_INST_WARNING(m_log.p_log, "Unsupported Ping message received, cmd_id %d\r\n", p_cmd_info->cmd_id); } zb_buf_free(bufid); return ZB_TRUE; }
Can you explain why zb_buf_free(bufid) is not called after:
ping_request_t * p_request = find_request_by_sn(p_cmd_info->seq_number); if (p_request == NULL) { // I think zb_buf_free(bufid) should be called here return ZB_FALSE; } if (p_request->remote_addr_mode == ZB_APS_ADDR_MODE_16_ENDP_PRESENT) { remote_short_addr = p_request->remote_addr.addr_short; } else { remote_short_addr = zb_address_short_by_ieee(p_request->remote_addr.addr_long); } if (p_cmd_info->addr_data.common_data.source.addr_type == ZB_ZCL_ADDR_TYPE_SHORT) { if (remote_short_addr != p_cmd_info->addr_data.common_data.source.u.short_addr) { // I think zb_buf_free(bufid) should be called here return ZB_FALSE; } } else { // I think zb_buf_free(bufid) should be called here return ZB_FALSE; }
Thanks!
John