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

adding an "array" attribute

Hello!
I add an attribute array (0x48) for the user cluster.
Having problems using the "array" attribute:


1. If you select the data type of 16 or 32 bits, then an alignment is added in the transmission, since the frame structure is: 8 bits for the type of array variables, then 16 bits for the length. Alignment is added after the 8 bit field for the variable type.
I use an array of 8-bit variables in the declaration, then a pointer to the desired structure and this is not a problem.


2. For some reason, 32 bytes are always transferred, regardless of the size of the specified array. Is this hardcoded or is it possible to specify the size?

#ifndef ZB_ZCL_ANALOG_SIGNAL_H__
#define ZB_ZCL_ANALOG_SIGNAL_H__

#include "zcl/zb_zcl_common.h"

/* Cluster ZB_ZCL_CLUSTER_ID_ANALOG_VALUE */

#define   ANALOG_NUMBER_OF_ARRAY_ELEMENTS     18
#define   ANALOG_DATA_TYPE                    ZB_ZCL_ATTR_TYPE_U8

typedef struct  struct_analog_data
{   
    zb_uint8_t  Element_Type;    
    zb_uint8_t  Number_Of_Elements1;
    zb_uint8_t  Number_Of_Elements2;  
    zb_uint8_t  allign;
    zb_int16_t  Analog_Signal_Array[ANALOG_NUMBER_OF_ARRAY_ELEMENTS];
} analog_data_t;

enum analog_array_element_t
{
   ANALOG_T1 = 0,
   ANALOG_T2,
   ANALOG_T3,
   ANALOG_T4,
   ANALOG_T5,
   ANALOG_T6,
   ANALOG_T7,
   ANALOG_T8,
   ANALOG_T9,
   ANALOG_T10,
   ANALOG_T11,
   ANALOG_T12,
   ANALOG_T13,
   ANALOG_T14,
   ANALOG_T15,
   ANALOG_T16,
   ANALOG_DI,
   ANALOG_DO,
};

typedef struct
{
    zb_bool_t       OutOfService;
    float           PresentValue;
    zb_uint8_t      StatusFlags;  
    analog_data_t   AnalogData;
} zb_zcl_analog_attrs_t;


enum zb_zcl_analog_measurement_attr_e
{
    ZB_ZCL_ATTR_ANALOG_SERVICE_ID = 0x0051,
    ZB_ZCL_ATTR_ANALOG_VALUE_ID   = 0x0055,
    ZB_ZCL_ATTR_ANALOG_STATUS_ID  = 0x006F,
    ZB_ZCL_ATTR_ANALOG_ARRAY_ID   = 0x0080,
};

/**@brief MeasuredValue attribute unknown value. */
#define ZB_ZCL_ATTR_ANALOG_VALUE_UNKNOWN                  ((zb_int16_t)0x8000)

/**@brief MinMeasuredValue attribute minimum value. */
#define ZB_ZCL_ATTR_ANALOG_MIN_VALUE_MIN_VALUE            ((zb_int16_t)0x8001)

/**@brief MinMeasuredValue attribute maximum value. */
#define ZB_ZCL_ATTR_ANALOG_MIN_VALUE_MAX_VALUE            0x7FFE

/**@brief MinMeasuredValue attribute invalid value. */
#define ZB_ZCL_ATTR_ANALOG_MIN_VALUE_INVALID              ((zb_int16_t)0x8000)

/**@brief MaxMeasuredValue attribute minimum value. */
#define ZB_ZCL_ATTR_ANALOG_MAX_VALUE_MIN_VALUE            ((zb_int16_t)0x8002)

/**@brief MaxMeasuredValue attribute maximum value. */
#define ZB_ZCL_ATTR_ANALOG_MAX_VALUE_MAX_VALUE            0x7FFF

/**@brief MaxMeasuredValue attribute invalid value. */
#define ZB_ZCL_ATTR_ANALOG_MAX_VALUE_INVALID              ((zb_int16_t)0x8000)

/**@brief MeasuredValue attribute unknown value. */
#define ZB_ZCL_ATTR_ANALOG_DEFAULT_STATUS_FLAG            ((zb_uint8_t)0x00)

/**@brief Default value for Value attribute. */
#define ZB_ZCL_ANALOG_VALUE_DEFAULT_VALUE ((zb_int16_t)0x0)

#define ZB_SET_ATTR_DESCR_WITH_ZB_ZCL_ATTR_ANALOG_VALUE_ID(data_ptr)              \
{                                                                                 \
    ZB_ZCL_ATTR_ANALOG_VALUE_ID,                                                  \
    ZB_ZCL_ATTR_TYPE_SINGLE,                                                      \
    ZB_ZCL_ATTR_ACCESS_READ_ONLY | ZB_ZCL_ATTR_ACCESS_WRITE_OPTIONAL,             \
    (zb_voidp_t) data_ptr                                                         \
}

#define ZB_SET_ATTR_DESCR_WITH_ZB_ZCL_ATTR_ANALOG_SERVICE_ID(data_ptr)             \
{                                                                                  \
    ZB_ZCL_ATTR_ANALOG_SERVICE_ID,                                                 \
    ZB_ZCL_ATTR_TYPE_BOOL,                                                         \
    ZB_ZCL_ATTR_ACCESS_READ_ONLY | ZB_ZCL_ATTR_ACCESS_WRITE_OPTIONAL,              \
    (zb_voidp_t) data_ptr                                                          \
}

#define ZB_SET_ATTR_DESCR_WITH_ZB_ZCL_ATTR_ANALOG_STATUS_ID(data_ptr)              \
{                                                                                  \
    ZB_ZCL_ATTR_ANALOG_STATUS_ID,                                                  \
    ZB_ZCL_ATTR_TYPE_8BITMAP,                                                      \
    ZB_ZCL_ATTR_ACCESS_READ_ONLY,                                                  \
    (zb_voidp_t) data_ptr                                                          \
}

#define ZB_SET_ATTR_DESCR_WITH_ZB_ZCL_ATTR_ANALOG_ARRAY_ID(data_ptr)               \
{                                                                                  \
    ZB_ZCL_ATTR_ANALOG_ARRAY_ID,                                                   \
    ZB_ZCL_ATTR_TYPE_ARRAY,                                                        \
    ZB_ZCL_ATTR_ACCESS_READ_ONLY,                                                  \
    (zb_voidp_t) data_ptr                                                          \
}


/**@brief Declares attribute list for the cluster on the server side.

 */
#define ZB_ZCL_DECLARE_ANALOG_ATTRIB_LIST(attr_list,                   \
    service, value, status, array)                                     \
  ZB_ZCL_START_DECLARE_ATTRIB_LIST(attr_list)                          \
  ZB_ZCL_SET_ATTR_DESC(ZB_ZCL_ATTR_ANALOG_SERVICE_ID, (service))       \
  ZB_ZCL_SET_ATTR_DESC(ZB_ZCL_ATTR_ANALOG_VALUE_ID, (value))           \
  ZB_ZCL_SET_ATTR_DESC(ZB_ZCL_ATTR_ANALOG_STATUS_ID, (status))         \
  ZB_ZCL_SET_ATTR_DESC(ZB_ZCL_ATTR_ANALOG_ARRAY_ID, (array))           \
  ZB_ZCL_FINISH_DECLARE_ATTRIB_LIST

/**@brief Function initialising the server side of Cluster. */
zb_void_t zb_zcl_analog_init_server(void);
/**@brief Function initialising the client side of Cluster. */
zb_void_t zb_zcl_analog_init_client(void);

/**@brief Defines needed for the stack to initialise the cluster correctly. */
#define ZB_ZCL_CLUSTER_ID_CUSTOM_ATTR_SERVER_ROLE_INIT zb_zcl_analog_init_server
#define ZB_ZCL_CLUSTER_ID_CUSTOM_ATTR_CLIENT_ROLE_INIT zb_zcl_analog_init_client

#endif /* ZB_ZCL_ANALOG_SIGNAL_H__ */

Parents
  • Hi,

    Are you implementing a custom cluster or are you trying to implement the "Analog Value" cluster from the ZCL specification?

    According to the ZCL specification the lenght (in octets) for the Array attribute type (0x48) shoud be 2 octets + the sum of lengths of contents.

     From the specification "The zeroth element is readable, always has type 16 bit unsigned integer, and holds the number of elements contained in the array".

    2. For some reason, 32 bytes are always transferred, regardless of the size of the specified array. Is this hardcoded or is it possible to specify the size?

    It looks like you are sending your own data type, since you have the struct 'analog_data_t' for attribute 0x0080, and I guess this is why you are having trouble. This is not encouraged by the Zigbee specification, see section 2.6.2 Data types in the ZCL specification.

    Best regards,

    Marjeris

  • pay attention "helloz" is in the next attribute "string", but it is passed along with the array, as if the length of the array is being ignored (last picture)

    m_dev_ctx.custom_attr.ArrayAttrData.Data_Array[0]=0x1122;
    m_dev_ctx.custom_attr.ArrayAttrData.Data_Array[1]=0x3344;
    m_dev_ctx.custom_attr.ArrayAttrData.Data_Array[2]=0x5566;
    m_dev_ctx.custom_attr.ArrayAttrData.Data_Array[3]=0x7788;
    m_dev_ctx.custom_attr.ArrayAttrData.Element_Type=CUSTOM_ARRAY_DATA_TYPE;
    m_dev_ctx.custom_attr.ArrayAttrData.Number_Of_Elements_1=CUSTOM_NUMBER_OF_ARRAY_ELEMENTS*2+1;
    m_dev_ctx.custom_attr.StringAttrData[0]=5;
    m_dev_ctx.custom_attr.StringAttrData[1]='h';
    m_dev_ctx.custom_attr.StringAttrData[2]='e';
    m_dev_ctx.custom_attr.StringAttrData[3]='l';
    m_dev_ctx.custom_attr.StringAttrData[4]='l';
    m_dev_ctx.custom_attr.StringAttrData[5]='o';
    m_dev_ctx.custom_attr.StringAttrData[6]='z';

  • Hi,

    I am sorry for the late reply. I was not able to reproduce your issue. Are you still struggling with this? Could you send your whole project folder so I can test this at my end?

    Best regards,

    Marjeris

  • hi and thanks.

    No more, now I am packing data into an array and transmitting it as a string. An array also works, but the entire array that was defined during initialization (CUSTOM_NUMBER_OF_ARRAY_ELEMENTS) is transmitted. And the value specified in the request (it may be less) is ignored and is still transmitted more as it was specified during initialization. The data still comes through, of course. It seems like the "sum of lengths of content" field is not used by the stack, the whole array is sent all the time.

  • Hi,

    Nice to hear you found a workaround and have not been stucked without a reply. Again I am sorry I didn't came back to you earlier.

    Litvinus said:
    It seems like the "sum of lengths of content" field is not used by the stack, the whole array is sent all the time.

    If you have project files you can share to reproduce this it would be helpful for us as we can then verify if this is a bug or not more easily and then report it to our SDK team internally.

    BTW which nRF5 SDK version are you using?

Reply
  • Hi,

    Nice to hear you found a workaround and have not been stucked without a reply. Again I am sorry I didn't came back to you earlier.

    Litvinus said:
    It seems like the "sum of lengths of content" field is not used by the stack, the whole array is sent all the time.

    If you have project files you can share to reproduce this it would be helpful for us as we can then verify if this is a bug or not more easily and then report it to our SDK team internally.

    BTW which nRF5 SDK version are you using?

Children
Related