
#define REPORT_DEFAULT_TIMEOUT_TIME		        3000 // Unit: ms

typedef struct {
    UINT16_T u16DelayTime;
    ZG_DELIVERY_MODE_E eRecvMsgMode;
    TAL_SEND_QOS_E eSendMsgMode;
} LIGHT_REPORT_CTRL_PARAM_T;


typedef struct {
    UINT8_T *data;
    UINT8_T u8epId;
    UINT8_T u8zclId;
    UINT8_T u8CmdId;
    UINT8_T u8AttrNum;
    UINT8_T u8SendMode;
    UINT16_T u16GroupId;
    UINT16_T u16ClusterId;
    UINT16_T u16AttrId[4];
	ZG_ATTR_TYPE_E eAttrType[4];
    ZG_ZCL_FRAME_TYPE_E eFrameType;
    LIGHT_REPORT_CTRL_PARAM_T tCtrl;
    TAL_SEND_RESULT_CB pCallback;
} LIGHT_REPORT_PARAM_T;

static void light_report_data(LIGHT_REPORT_PARAM_T *tRptParam)
{
	TAL_ZG_SEND_DATA_T send_data;
	UINT8_T i = 0;
	UINT16_T u16DataOffset = 0;

	memset(&send_data, 0x00, SIZEOF(TAL_ZG_SEND_DATA_T));

	send_data.qos = tRptParam->tCtrl.eSendMsgMode;
	send_data.delay_time = tRptParam->tCtrl.u16DelayTime;
	send_data.random_time = 0;
	send_data.zcl_id = tRptParam->u8zclId;
	send_data.frame_type = tRptParam->eFrameType;
	send_data.command_id = tRptParam->u8CmdId;

	send_data.addr.mode = tRptParam->u8SendMode;

	send_data.direction = ZG_ZCL_DATA_SERVER_TO_CLIENT;

	send_data.addr.type.dev.src_ep = tRptParam->u8epId;
	send_data.addr.type.dev.dst_ep = 0x01;
	send_data.addr.type.dev.dst_addr = 0x0000;
	send_data.addr.type.dev.cluster_id = tRptParam->u16ClusterId;

	if(NULL != tRptParam->data) {
		if(send_data.frame_type == ZG_ZCL_FRAME_TYPE_GLOBAL) {
			send_data.data.zg.attr_sum = tRptParam->u8AttrNum;
			for(i = 0; i < tRptParam->u8AttrNum; i++) {
				send_data.data.zg.attr[i].attr_id = tRptParam->u16AttrId[i];
				send_data.data.zg.attr[i].type = tRptParam->eAttrType[i];
				if(ATTR_ARRAY_ATTRIBUTE_TYPE == tRptParam->eAttrType[i]) {
					send_data.data.zg.attr[i].size = tRptParam->data[u16DataOffset] + 1;
					memcpy(&send_data.data.zg.attr[i].value[0], &(tRptParam->data[u16DataOffset]), (tRptParam->data[u16DataOffset] + 1) );
				} else {
					send_data.data.zg.attr[i].size = tRptParam->data[u16DataOffset];
					memcpy(&send_data.data.zg.attr[i].value[0], &tRptParam->data[u16DataOffset+1], tRptParam->data[u16DataOffset]);
				}
				u16DataOffset += send_data.data.zg.attr[i].size + 1;
			}
		} else {
			send_data.data.private.len = tRptParam->data[0];
			memcpy(send_data.data.private.data, &tRptParam->data[1], tRptParam->data[0]);
		}
	}

    TAL_PR_DEBUG("----> Clear zcl_id: %d", send_data.zcl_id);
	tal_zg_clear_send_data(ZG_CLEAR_ALL_ZCL_ID, &send_data.zcl_id);
	tal_zg_send_data(&send_data, tRptParam->pCallback, REPORT_DEFAULT_TIMEOUT_TIME);
}


static void light_report_ctrl_param_get(LIGHT_REPORT_CTRL_PARAM_T *tReportCtrlParam)
{
	UINT8_T u8TempMsgMode = QOS_VIP_0;

	if(ZG_UNICAST_MODE == tReportCtrlParam->eRecvMsgMode) {
		// u8TempMsgMode = QOS_1;
		tReportCtrlParam->u16DelayTime = 100 + tal_system_get_random(128);
	} else {
		// u8TempMsgMode = QOS_1;
		tReportCtrlParam->u16DelayTime = 6000 + tal_system_get_random(10000);
	}

	if((QOS_VIP_1 + 1) == tReportCtrlParam->eSendMsgMode) {
		tReportCtrlParam->eSendMsgMode = u8TempMsgMode;
	}
}

static void light_report_data_attr_param_get(LIGHT_REPORT_PARAM_T *tRptParam,\
	UINT8_T u8zclId, UINT16_T u16ClusterId, UINT16_T u16AttrId, ZG_ATTR_TYPE_E eAttrType)
{
	tRptParam->u8epId = 0x01;
	tRptParam->u8zclId = u8zclId;
	tRptParam->u8CmdId = CMD_REPORT_ATTRIBUTES_COMMAND_ID;
	tRptParam->u8AttrNum = 1;
	tRptParam->u8SendMode = SEND_MODE_DEV;
	tRptParam->u16GroupId = 0x0000;
	tRptParam->u16ClusterId = u16ClusterId;
	tRptParam->u16AttrId[0] = u16AttrId;
	tRptParam->eAttrType[0] = eAttrType;
	tRptParam->eFrameType = ZG_ZCL_FRAME_TYPE_GLOBAL;
	tRptParam->pCallback = NULL;
}

VOID_T light_report_onoff_state_send_ret_callback(TAL_SEND_ST_E eSendState, TAL_ZG_SEND_DATA_T *tSendData)
{
	TAL_PR_DEBUG("--> Send result: %d, zclID: %d, Time: %d", eSendState, tSendData->zcl_id, tSendData->delay_time);
}


VOID_T light_report_onoff_state(BOOL_T bSwitchStatus, UINT16_T u16DelayTime)
{
	UINT8_T u8TempBuffer[2] = {0x00};
	LIGHT_REPORT_PARAM_T tRptParam = {0x00};

	// 说明：eRecvMsgMode == 接受消息回调参数TAL_ZCL_MSG_T *msg -> msg->mode
	tRptParam.tCtrl.eRecvMsgMode = eRecvMsgMode;
	tRptParam.tCtrl.eSendMsgMode = (QOS_VIP_1 + 1);
	light_report_ctrl_param_get( &(tRptParam.tCtrl) );
	if(u16DelayTime) {
		tRptParam.tCtrl.u16DelayTime = u16DelayTime;
	}

	u8TempBuffer[0] = 1;
	u8TempBuffer[1] = bSwitchStatus;

	TAL_PR_DEBUG("Report on/off %d", bSwitchStatus);

	tRptParam.data = u8TempBuffer;
    light_report_data_attr_param_get(&tRptParam,\
		ZCL_ID_LIGHT_ONOFF, CLUSTER_ON_OFF_CLUSTER_ID,\
		ATTR_ON_OFF_ATTRIBUTE_ID, ATTR_BOOLEAN_ATTRIBUTE_TYPE);
	tRptParam.pCallback = light_report_onoff_state_send_ret_callback;

	light_report_data(&tRptParam);

	tal_zg_write_attribute(0x01, CLUSTER_ON_OFF_CLUSTER_ID,
		ATTR_ON_OFF_ATTRIBUTE_ID, &bSwitchStatus, ATTR_BOOLEAN_ATTRIBUTE_TYPE);

}
