2021-08-24 06:24 AM
Hi,
I am working with the STM32WB55 Nucleo board to create a Zigbee device being able to connect to a Philips Hue Bridge v2.1. Using a 2.4GHz sniffer with wireshark I am able to follow the communication which goes through the following steps with no problems:
Where it fails is the coordinator (hue bridge) sends a Read attributes on the Basic cluster (0x0000) to the STM32. It responds with a ZCL Default response where status says "unsupported cluster (0xc3)".
And the trace output from the STM32WB55 reports that it sends this default response, but I would expect it to be responding with the Basic attributes configured.
The code is based on the Zigbee_OnOff_Client_Router example modified to be a ZCL_DEVICE_COLOR_DIMMABLE_LIGHT server.
static void APP_ZIGBEE_StackLayersInit(void)
{
APP_DBG("APP_ZIGBEE_StackLayersInit");
zigbee_app_info.zb = ZbInit(0U, NULL, NULL);
assert(zigbee_app_info.zb != NULL);
/* Basic cluster */
/*char * mfr_str = "E TestPlus";
memcpy(& zb_mfr_str[1], mfr_str, strlen(mfr_str));
zb_mfr_str[0] = strlen(mfr_str);
ZbZclBasicWriteDirect(zigbee_app_info.zb, ENDPOINT_ON_OFF, ZCL_BASIC_ATTR_MFR_NAME, zb_mfr_str, 12);*/
struct ZbZclBasicServerDefaults defaultCustom;
defaultCustom.app_version = 0x00;
defaultCustom.hw_version = 0x01;
defaultCustom.stack_version = 10; // TODO: IS this right?
defaultCustom.power_source = ZCL_BASIC_POWER_SINGLE_PHASE;
uint8_t zb_mfr_str[6] = {5, 'H', 'E', 'L', 'L', 'O'};
memcpy(defaultCustom.mfr_name, zb_mfr_str, 6);
memcpy(defaultCustom.model_name, zb_mfr_str, 6);
uint8_t zb_ver_str[6] = {5, '1', '.', '0', '.', '7'};
memcpy(defaultCustom.sw_build_id, zb_ver_str, 6);
ZbZclBasicServerConfigDefaults(zigbee_app_info.zb, &defaultCustom);
/* Create the endpoint and cluster(s) */
APP_ZIGBEE_ConfigEndpoints();
Is there any explanation for why the Zigbee stack does not respond to the basic cluster read attributes request?
Kind regards,
Jakob
2021-10-19 05:39 AM
Hello,
I'm reusing this thread, as I encounter similar problems.
It seems there are some bad memory copies, but the structure used is the same in both 2) or 3) cases.
Any idea ?
Thanks,
Pascal
---
I'm using IDE 1.7, WB 1.12.1, with FreeRtos.
The function for initialization of the Basic cluster. The copyNToPascalString has been verified (similar as strncpy, but including the length in the first byte). Whatever, the test string does not work too.
static void APP_ZIGBEE_ConfigBasicServer(bool endpoints_already_created) {
struct ZbZclBasicServerDefaults basic_zb_id;
char teststring[6] = { 5,'T','E','S','T','1' };
basic_zb_id.app_version = 0;
basic_zb_id.stack_version = 0;
copyNToPascalString((char*)basic_zb_id.mfr_name, MANUFACTURER_NAME, ZCL_BASIC_MANUFACTURER_NAME_LENGTH);
//copyNToPascalString((char*)basic_zb_id.model_name, PRODUCT_NAME, ZCL_BASIC_MODEL_IDENTIFIER_LENGTH);
memcpy(basic_zb_id.model_name, teststring, 6);
copyNToPascalString((char*)basic_zb_id.date_code, "", ZCL_BASIC_DATE_CODE_LENGTH);
basic_zb_id.power_source = ZCL_BASIC_POWER_DC;
basic_zb_id.hw_version = (uint8_t)BOARD_REVISION;
copyNToPascalString((char*)basic_zb_id.sw_build_id, VERSION_STRING, ZCL_BASIC_SW_BUILD_ID_LENGTH);
if (endpoints_already_created) {
// La fonction ZbZclBasicServerConfigDefaults ne peut pas être appelée si les endpoints sont déjà créés
enum ZclStatusCodeT status;
status = ZbZclBasicWriteDirect(zigbee_app_info.zb, APP_ZIGBEE_MEAS_ENDPOINT, ZCL_BASIC_ATTR_APP_VERSION, &basic_zb_id.app_version, sizeof(basic_zb_id.app_version));
status = ZbZclBasicWriteDirect(zigbee_app_info.zb, APP_ZIGBEE_MEAS_ENDPOINT, ZCL_BASIC_ATTR_STACK_VERSION, &basic_zb_id.stack_version, sizeof(basic_zb_id.stack_version));
status = ZbZclBasicWriteDirect(zigbee_app_info.zb, APP_ZIGBEE_MEAS_ENDPOINT, ZCL_BASIC_ATTR_MFR_NAME, basic_zb_id.mfr_name, 1+basic_zb_id.mfr_name[0]);
status = ZbZclBasicWriteDirect(zigbee_app_info.zb, APP_ZIGBEE_MEAS_ENDPOINT, ZCL_BASIC_ATTR_MODEL_NAME, basic_zb_id.model_name, 1+basic_zb_id.model_name[0]);
status = ZbZclBasicWriteDirect(zigbee_app_info.zb, APP_ZIGBEE_MEAS_ENDPOINT, ZCL_BASIC_ATTR_DATE_CODE, basic_zb_id.date_code, 1+basic_zb_id.date_code[0]);
status = ZbZclBasicWriteDirect(zigbee_app_info.zb, APP_ZIGBEE_MEAS_ENDPOINT, ZCL_BASIC_ATTR_POWER_SOURCE, &basic_zb_id.power_source, sizeof(basic_zb_id.power_source));
status = ZbZclBasicWriteDirect(zigbee_app_info.zb, APP_ZIGBEE_MEAS_ENDPOINT, ZCL_BASIC_ATTR_HARDWARE_VERSION, &basic_zb_id.hw_version, sizeof(basic_zb_id.hw_version));
status = ZbZclBasicWriteDirect(zigbee_app_info.zb, APP_ZIGBEE_MEAS_ENDPOINT, ZCL_BASIC_ATTR_SW_BUILD_ID, basic_zb_id.sw_build_id, 1+basic_zb_id.sw_build_id[0]);
UNUSED(status);
}
else
ZbZclBasicServerConfigDefaults(zigbee_app_info.zb, &basic_zb_id); // FIXME Do not work
}
The initialization, before or after the ZbInit call :
/**
* @brief Initialize Zigbee stack layers
* @param None
* @retval None
*/
static void APP_ZIGBEE_StackLayersInit(void)
{
APP_DBG("APP_ZIGBEE_StackLayersInit");
zigbee_app_info.zb = ZbInit(0U, NULL, NULL);
assert(zigbee_app_info.zb != NULL);
APP_ZIGBEE_ConfigBasicServer(false); // <<<<<< FIXME does not work here !!!
/* Create the endpoint and cluster(s) */
APP_ZIGBEE_ConfigEndpoints();
// APP_ZIGBEE_ConfigBasicServer(true); // <<<<<< works here
/* USER CODE BEGIN APP_ZIGBEE_StackLayersInit */
BSP_LED_set(false);
/* USER CODE END APP_ZIGBEE_StackLayersInit */
/* Configure the joining parameters */
zigbee_app_info.join_status = (enum ZbStatusCodeT) 0x01; /* init to error status */
zigbee_app_info.join_delay = HAL_GetTick(); /* now */
zigbee_app_info.startupControl = ZbStartTypeJoin;
/* Initialization Complete */
zigbee_app_info.has_init = true;
/* run the task */
osThreadFlagsSet(OsTaskNwkFormId,1);
} /* APP_ZIGBEE_StackLayersInit */
2021-11-12 07:34 AM
The basic cluster is mapped by default on each endpoint.
It would be interesting to know what are the active endpoints on the STM32WB.
If the Read Attribute is sent to an endpoint that does not exists or reserved (Green power), this behavior may happen.
void
ZbZclAddEndpointNoBasic(struct ZigBeeT *zb, struct ZbApsmeAddEndpointReqT *addReqPtr, struct ZbApsmeAddEndpointConfT *addConfPtr)
{
/* Create the endpoint as usual */
ZbApsmeAddEndpoint(zb, addReqPtr, addConfPtr);
if (addConfPtr->status != ZB_STATUS_SUCCESS) {
return;
}
/* ZSDK-2256: Add a filter rule that if a cluster command arrives on
* this endpoint, but there are no handlers for it, return a
* Default Response error (ZCL_STATUS_UNSUPPORTED_CLUSTER). */
if (!ZbApsmeEndpointConfigNoMatchCallback(zb, addReqPtr->endpoint, zcl_no_match_callback, zb)) {
2021-11-12 08:16 AM
Bonjour,
I use 2 different endpoints (one for sensors, the second for a relay). The Basic cluster is embedded twice, that's the default as you written..
Please note : The ZbZclAddEndpointNoBasic function appears in the zcl.h file, but is not defined. (last official stack and API)
I'd like to remove the basic cluster redundancy.
Whatever, the ZbZclBasicServerConfigDefaults stills not working yet, but I'd like to remove my workaround one day.
Best regards,
Pascal
2021-11-12 09:03 AM
Indeed ZbZclAddEndpointNoBasic is only declared in zcl.h file but not defined anywhere else.in the WB FW v1.12.
Note that this fonction is totally removed in the next to come very soon WB FW v1.13.