/***
阿里云相关
**/
#include "aLiYun.h"
#include "utils_hmac.h"
#include "DBG.h"
#include "PC_DeviceTest_Fun.h"
#include "flash.h"

#if MQTT_EN


/*******************************************************************************
* Function Name  : ALiYun_Default_Parameter_Get      2022-09-03
* Description    : 初始化默认参数
* Input          : aliyun_info
* Output         : None
* Return         : None
*******************************************************************************/
void ALiYun_Default_Parameter_Get(ALIYUN_INFO* aliyun_info)
{
	UINT8 mactostr[12];     //mac地址字符数组
	uint8_t j=0;
	for(uint8_t i=0;i<6;i++)
	{
		mactostr[j]=(MACAddr[i]>>4)&0x0F;
		mactostr[j+1]=MACAddr[i]&0x0F;
		
		if(mactostr[j] <= 9)
    {
        mactostr[j] += 0x30;
    }
    else if((mactostr[j] >= 10) && (mactostr[j] <= 15))
    {
        mactostr[j] += 0x37;
    }
 
    if(mactostr[j+1] <= 9)
    {
        mactostr[j+1] += 0x30;
    }
    else if((mactostr[j+1] >= 10) && (mactostr[j+1] <= 15))
    {
        mactostr[j+1] += 0x37;
    }
		
		j+=2;
	}

	memcpy(aliyun_info->productKey,DEF_PRODUCTKEY,12);
	memcpy(aliyun_info->publish,DEF_ALIY_PUBLISH,12);
	memcpy(aliyun_info->sublish,DEF_ALIY_SUBLISH,9);
	aliyun_info->mqtt_data.keepAliveInterval=120;
	memcpy(aliyun_info->deviceName,mactostr,12);   
	Flash_Read((UINT8*)aliyun_info->deviceSecret ,33, FLASH_MCU_MQTT_START_ADDRESS+FLASH_MQTTINFO_DeviceSecret_OFFSET);

}


/*******************************************************************************
* Function Name  : ALiYun_Machine_Init
* Description    : 一机一密方式初始化阿里云
* Input          : ProductKey：ProductKey
*                	 deviceName: 设备名
*									 DeviceSecret: 设备秘钥
									 sublish: 订阅地址
									 keepAliveInterval：保持在线时间
* Output         : None
* Return         : 成功启动返回0，此处成功不代表阿里云成功初始化，只代表函数启动初始化成功
*******************************************************************************/
UINT8 ALiYun_Machine_Init(MQTT_INFO* Mqtt_info, char* ProductKey, char* deviceName, char* DeviceSecret, char* sublish, int keepAliveInterval)
{
	if(Mqtt_info == NULL || ProductKey == NULL || deviceName == NULL || sublish == NULL || DeviceSecret == NULL)  return 1;   				//参数错误
	
	UINT8 domain_name_len = strlen(ALIYUN_DOMAIN) + strlen(ProductKey) +1;
	UINT8 clientID_len 		= strlen(ALIYUN_CLIENT_ID) + strlen(deviceName) +1;
	UINT8 userName_len	  = strlen(ProductKey) + strlen(deviceName) + 2;
	UINT8 passWord_len    = 40+1;
	UINT8 sublish_len     = strlen(sublish) + strlen(ProductKey) + strlen(deviceName) + 5;
	int msg_len 					= strlen(CLIENT_ID_KEY) + strlen(deviceName) + strlen(DEVICE_NAME_KEY)  \
																	+ strlen(deviceName) + strlen(PRODUCTKEY_KEY) + strlen(ProductKey) + 1;
	
	char* domain_name = malloc(domain_name_len);      				//存放域名（ProductKey + 固定后缀）
	if(domain_name == NULL)     return 4;   //内存不足错误
	
	char* clientID 		= malloc(clientID_len);   							//存放clientID （对应设备名 + 固定后缀）
	if(clientID == NULL)
	{
		free(domain_name);
		return 4;   //内存不足错误
	}
	
	char* userName 		= malloc(userName_len);   								//存放userName （对应设备名 + & + ProductKey）
	if(userName == NULL)
	{
		free(domain_name);
		free(clientID);
		return 4;   //内存不足错误
	}
	
	char* passWord    = malloc(passWord_len);                             //存放 hmacsha1 password
	if(passWord == NULL)
	{
		free(domain_name);
		free(clientID);
		free(userName);
		return 4;   //内存不足错误
	}
	
	char* msg 				= malloc(msg_len);        												//存放 hmacsha1 参数键值对的值
	if(msg == NULL)
	{
		free(domain_name);
		free(clientID);
		free(userName);
		free(passWord);
		return 4;   //内存不足错误
	}
	
	char* sublish_str = malloc(sublish_len);        										//存放 订阅地址
	if(sublish_str == NULL)
	{
		free(domain_name);
		free(clientID);
		free(userName);
		free(passWord);
		free(msg);
		return 4;   //内存不足错误
	}
	
	memset(domain_name, 0, domain_name_len);
	memset(clientID, 0, clientID_len);
	memset(userName, 0, userName_len);
	memset(passWord, 0, passWord_len);
	memset(msg, 0, msg_len);
	memset(sublish_str, 0, sublish_len);
	
	sprintf(domain_name, "%s%s", ProductKey, ALIYUN_DOMAIN);     //拼接域名
	sprintf(clientID, "%s%s", deviceName, ALIYUN_CLIENT_ID);     //拼接clientID
	sprintf(userName, "%s&%s", deviceName, ProductKey);     			//拼接userName
	sprintf(msg, "%s%s%s%s%s%s", CLIENT_ID_KEY, deviceName, DEVICE_NAME_KEY, deviceName, PRODUCTKEY_KEY, ProductKey);    //拼接hmacsha1 参数键值对的值
	sprintf(sublish_str, "/%s/%s/%s", ProductKey, deviceName, sublish);     //拼接订阅地址
	
	PRINT("domain_name:%s\n", domain_name);
	PRINT("clientID:%s\n", clientID);
	PRINT("userName:%s\n", userName);
	
	PRINT("msg:%s\n", msg);
	
	utils_hmac_sha1(msg, strlen(msg), passWord, DeviceSecret, strlen(DeviceSecret));      //计算password
	
	PRINT("passWord:%s\n", passWord);
	
	free(msg);
	
	return MQTT_Init(Mqtt_info, domain_name, NULL, clientID, userName, passWord, sublish_str, keepAliveInterval);
}

/*******************************************************************************
* Function Name  : ALIYUN_Flash_Parameter_Init
* Description    : 从flash获取参数初始化阿里云
* Input          : Mqtt_info
* Output         : None
* Return         : None
*******************************************************************************/
UINT8 ALIYUN_Flash_Parameter_Init(MQTT_INFO* Mqtt_info)
{
	if(Mqtt_info == NULL)  return 1;
	char* publish = NULL;
	ALIYUN_INFO aliyun_info;
	ALIYUN_INFO aliyun_temp;
	UINT8 ret = 0; 
	UINT16 keepAlive = 0;
	
	memset(&aliyun_info, 0x00, sizeof(ALIYUN_INFO)); 
	Flash_Read((UINT8*)&aliyun_temp ,sizeof(ALIYUN_INFO)-4, FLASH_MCU_MQTT_START_ADDRESS);
	
//	Dbg_Println(DBG_BIT_NET_STATUS_bit,"temp_keepAliveInterval:%d", aliyun_temp.mqtt_data.keepAliveInterval);
//	Dbg_Println(DBG_BIT_NET_STATUS_bit,"temp_sublish:%s", aliyun_temp.sublish);
//	Dbg_Println(DBG_BIT_NET_STATUS_bit,"temp_temp_temp_temp_publish:%s", aliyun_temp.publish);
//	Dbg_Println(DBG_BIT_NET_STATUS_bit,"temp_temp_productKey:%s", aliyun_temp.productKey);
//	Dbg_Println(DBG_BIT_NET_STATUS_bit,"temp_temp_deviceName:%s", aliyun_temp.deviceName);
//	Dbg_Println(DBG_BIT_NET_STATUS_bit,"temp_deviceSecret:%s\n", aliyun_temp.deviceSecret);
	
	if(memcmp(aliyun_info.deviceName,aliyun_temp.deviceName,sizeof(aliyun_info.deviceName))!=0
		||memcmp(aliyun_info.productKey,aliyun_temp.productKey,sizeof(aliyun_info.productKey))!=0
		||memcmp(aliyun_info.publish,aliyun_temp.publish,sizeof(aliyun_info.publish))!=0
		||memcmp(aliyun_info.sublish,aliyun_temp.sublish,sizeof(aliyun_info.sublish))!=0
		||memcmp(&aliyun_info.mqtt_data.keepAliveInterval,&aliyun_temp.mqtt_data.keepAliveInterval,sizeof(aliyun_info.mqtt_data.keepAliveInterval))!=0
		)
	{
		memcpy(&aliyun_info,&aliyun_temp,sizeof(ALIYUN_INFO));     //flash中参数不为零，则使用flash中的参数初始化阿里云。否则，使用默认参数初始化。
	}
	else
	{
		ALiYun_Default_Parameter_Get(&aliyun_info);
	}
	
	Dbg_Println(DBG_BIT_NET_STATUS_bit,"keepAliveInterval:%d", aliyun_info.mqtt_data.keepAliveInterval);
	Dbg_Println(DBG_BIT_NET_STATUS_bit,"sublish:%s", aliyun_info.sublish);
	Dbg_Println(DBG_BIT_NET_STATUS_bit,"publish:%s", aliyun_info.publish);
	Dbg_Println(DBG_BIT_NET_STATUS_bit,"productKey:%s", aliyun_info.productKey);
	Dbg_Println(DBG_BIT_NET_STATUS_bit,"deviceName:%s", aliyun_info.deviceName);
	Dbg_Println(DBG_BIT_NET_STATUS_bit,"deviceSecret:%s", aliyun_info.deviceSecret);
	
	if(aliyun_info.mqtt_data.keepAliveInterval < 0xFFFF)
	{
		keepAlive = aliyun_info.mqtt_data.keepAliveInterval;
	}
	else     //参数不合法，使用默认值
	{
		keepAlive = 120;
	}
	
	if(aliyun_info.sublish[0] != 0xFF && aliyun_info.sublish[0] != 0x00)
	{

	}
	else     //参数不合法，返回
	{
		ret = 3;
		goto reault;
	}
	
	if(aliyun_info.productKey[0] != 0xFF && aliyun_info.productKey[0] != 0x00)
	{
		
	}
	else     //参数不合法，返回
	{
		ret = 3;
		goto reault;
	}
	
	if((aliyun_info.deviceName[0] != 0xFF) && (aliyun_info.deviceName[0] != 0x00) && (0x0C == strlen((char *)aliyun_info.deviceName)))  
	{
		
	}
	else     //参数不合法，返回
	{
		ret = 3;
		goto reault;
	}
	
	if(aliyun_info.deviceSecret[0] != 0xFF && aliyun_info.deviceSecret[0] != 0x00)
	{
		
	}
	else     //参数不合法，返回
	{
		ret = 3;
		goto reault;
	}
	
	if(aliyun_info.publish[0] != 0xFF && aliyun_info.publish[0] != 0x00)
	{
		UINT8 len = strlen((char*)aliyun_info.publish) + strlen((char*)aliyun_info.productKey) + strlen((char*)aliyun_info.deviceName) + 5;
		publish = malloc(len);
		if(publish == NULL)
		{
			ret = 4;
			goto reault;
		}
		memset(publish, 0, len);
		sprintf(publish, "/%s/%s/%s", (char*)aliyun_info.productKey, (char*)aliyun_info.deviceName, (char*)aliyun_info.publish);   //拼接发布地址
		
		if(Mqtt_info->pub_topic)
		{
			free(Mqtt_info->pub_topic);
		}
		Mqtt_info->pub_topic = publish;
	}
	
	reault:
		switch(ret)
		{
			case 0:     //无错误
			case 4:     //publish错误不影响初始化
				return ALiYun_Machine_Init(Mqtt_info, (char*)aliyun_info.productKey, (char*)aliyun_info.deviceName, (char*)aliyun_info.deviceSecret, 
					(char*)aliyun_info.sublish, keepAlive);   //初始化阿里云
			
			default:    //有错误
				Dbg_Println(DBG_BIT_NET_STATUS_bit,"ALIYUN_Flash_Parameter err, Clear ALIYUN_Flash");
				memset(&aliyun_info, 0x00, sizeof(ALIYUN_INFO));      //清0
				Flash_Write((uint8_t *)&aliyun_info,sizeof(ALIYUN_INFO) ,FLASH_MCU_MQTT_START_ADDRESS);   //清空			
				if(publish)   free(publish);
				return ret;
			
		}
}
#endif

