VOID_T air_data_report(UINT8_T ep, 
                       UINT8_T *data, 
                       UINT16_T data_lens, 
                       UINT8_T dpid, 
                       UINT8_T type, 
                       TAL_SEND_QOS_E qos)
{
    if(data_lens > 0 && data == NULL) {
        return;
    }
    TAL_ZG_SEND_DATA_T send_data;
    tal_system_memset(&send_data, 0, SIZEOF(TAL_ZG_SEND_DATA_T));

    send_data.qos = qos;
    send_data.delay_time = 0;
    send_data.zcl_id = 0x68;  //6*16 + 8 = 104
    // send_data.zcl_id = 108; //ZCL_ID_TEMPERATURE_MIN;

    send_data.direction = ZG_ZCL_DATA_SERVER_TO_CLIENT;
    send_data.frame_type = ZG_ZCL_FRAME_TYPE_SPEC_TO_CLUSTER;
    send_data.command_id = 0x06; /*report cmd*/

    send_data.addr.mode = SEND_MODE_DEV;
    send_data.addr.type.dev.cluster_id = CLUSTER_PRIVATE_TUYA_CLUSTER_ID;
    send_data.addr.type.dev.dst_ep = 0x01;

    send_data.addr.type.dev.dst_addr = TUYA_GATEWAY_ADDRESS;
    send_data.addr.type.dev.src_ep = TUYA_PRIMARY_ENDPOINT;

    if(data_lens > (SIZEOF(send_data.data.private.data) - 6)) {
        return;
    }
    send_data.data.private.len = data_lens + 6;
    send_data.data.private.data[2] = dpid; /* DP id*/
    send_data.data.private.data[3] = type; /*DP type*/
    send_data.data.private.data[4] = (data_lens >> 8) & 0xFF;
    send_data.data.private.data[5] = data_lens & 0xFF; /*DP len*/
    tal_system_memcpy(&send_data.data.private.data[6], data, data_lens); /*DP data*/
    // USER_PR_DEBUG("------ data[6789]: %d, %d, %d, %d\r\n", 
    //     send_data.data.private.data[6], 
    //     send_data.data.private.data[7],
    //     send_data.data.private.data[8], 
    //     send_data.data.private.data[9]);

    tal_zg_clear_send_data(ZG_CLEAR_ALL_ZCL_ID, &send_data.zcl_id);
    // tal_zg_send_data(&send_data, send_data_result_callback, 1000); //1000 -> 3000
    tal_zg_send_data(&send_data, NULL, 1000); //1000 -> 3000

    USER_PR_DEBUG("[D]: [%s], clu[0x%x], dpid[%d], zcl_id[%d]\r\n", __FUNCTION__, CLUSTER_PRIVATE_TUYA_CLUSTER_ID, dpid, send_data.zcl_id);
}


VOID_T report_private_defined_attribute(VOID_T)
{
    INT16_T temp_int16;
    INT32_T temp_int32;
    UINT8_T temp_data_lens; //4 or 1
    UINT8_T temp_data[4];
    UINT8_T temp_data2[4];
    // UINT32_T temp_uint32;

    // temp_data_lens = 4;
    // temp_int32 = -15 * 100; //min temperature
    // tal_system_memcpy(&temp_data[0], &temp_int32, sizeof(INT32_T));
    // air_data_report(0x01, temp_data, temp_data_lens, 102, DPID_VALUE_TYPE_UINT32, QOS_1);

    tal_zg_read_attribute(0x01, CLUSTER_PRIVATE_TUYA_CLUSTER_ID, 0xE000, (UINT8_T *)&temp_int16, sizeof(INT16_T));
    USER_PR_DEBUG("report_private_defined_attribute read back temp_int16 min: %d\r\n", temp_int16);
    temp_data_lens = 4;
    temp_int32 = temp_int16;
    tal_system_memcpy(&temp_data[0], &temp_int32, sizeof(INT32_T));
    temp_data2[0] = temp_data[3];
    temp_data2[1] = temp_data[2];
    temp_data2[2] = temp_data[1];
    temp_data2[3] = temp_data[0];
    USER_PR_DEBUG("------ temp[0123]: %d, %d, %d, %d\r\n", temp_data[0], temp_data[1], temp_data[2], temp_data[3]);
    air_data_report(0x01, temp_data2, temp_data_lens, 102, DPID_VALUE_TYPE_UINT32, QOS_1);

    // temp_data_lens = 2;
    // tal_system_memcpy(&temp_data[0], &temp_int16, sizeof(INT16_T));
    // air_data_report(0x01, temp_data, temp_data_lens, 102, ATTR_INT16S_ATTRIBUTE_TYPE, QOS_1);
}

VOID_T tbl_report_humidity(VOID_T) {
    report_humidity_attribute(ATTR_RELATIVE_HUMIDITY_MEASURED_VALUE_ATTRIBUTE_ID, ATTR_INT16U_ATTRIBUTE_TYPE, 100, ZCL_ID_HUMIDITY);

    extern VOID_T report_private_defined_attribute(VOID_T);
    report_private_defined_attribute();

}
