#include "EC801E.h"
#include "stdio.h"
#include "usart.h"
#include "string.h"
#include "cJSON.h"
#include "uart_dev.h"
#include "anemometer_dev.h"

#define USE_UTC 1

// ID
uint8_t g_devic_id[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
// 客户端名字
char g_cilent_name[] = "Test_cilent";
// 连接用户名
char g_cilent_user_name[] = "12345";
// 连接密码
char g_cilent_paaword[] = "12345";
// 服务器IP
char g_server_ip[] = "199.7.140.10,1883";
// 订阅主题名
char g_topic_name[] = "Test_Topic_1";

// 时间戳
uint32_t g_time_stamp;
// 最新一条信息发送时的时间戳
uint32_t trans_time_stamp;

// 打开客户端网络标志
int flag_open_net = 0;
// 连接服务器标志
int flag_connect = 0;
// 订阅成功网络标志
int flag_sub = 0;
// 发布信息标志
int flag_pubex = 0;

void parse_json(uint8_t *json_buff);


//控制上电并开机
void EC801E_Power_ON()
{
    // PWR_KEY_4G_Pin低电平,上电自动开机
    HAL_GPIO_WritePin(GPIO_4G_PWR_KEY_GPIO_Port, GPIO_4G_PWR_KEY_Pin, GPIO_PIN_SET);
    //上电
    HAL_GPIO_WritePin(GPIO_4G_PWR_CTRL_GPIO_Port, GPIO_4G_PWR_CTRL_Pin, GPIO_PIN_RESET);
    HAL_Delay(1000);
    HAL_GPIO_WritePin(GPIO_4G_PWR_CTRL_GPIO_Port, GPIO_4G_PWR_CTRL_Pin, GPIO_PIN_SET);
}

//开机状态检测
//HAL_OK:正常开机
uint8_t Read_Status()
{
    uint8_t temp_status = HAL_ERROR;
    temp_status = HAL_GPIO_ReadPin(GPIO_4G_STATUS_GPIO_Port, GPIO_4G_STATUS_Pin) == GPIO_PIN_SET ? HAL_OK : HAL_ERROR;
    return temp_status;
}

//串口重定向打印
size_t __write(int handle, const unsigned char * buffer, size_t size)
{
  if(HAL_OK == HAL_UART_Transmit(&huart1,(uint8_t *)buffer,size,100000))
  {
    return size;
  }
  else
  {
    return -1;
  }
}

// MQTT打开客户端网络.连接MQTT服务器.订阅
// ip,端口,客户端ID(0-5),客户端名称,用户名,密码,订阅主题名
void MQTT_Config()
{
    // 确保4G模块完全开机
    osDelay(5000);
    
    // 打开客户端网络
    while(!flag_open_net)
    {
//    uart_sendstr(g_ec801_uart_handle, "AT+QMTOPEN=0,199.7.140.10,1883\r\n");
    uart_sendstr(g_ec801_uart_handle, "AT+QMTOPEN=0,");
    uart_sendstr(g_ec801_uart_handle, g_server_ip);
    uart_sendstr(g_ec801_uart_handle, "\r\n");
    osDelay(5000);
    }flag_open_net = 0;
    
    // 连接服务器
    while(!flag_connect)
    {
    uart_sendstr(g_ec801_uart_handle, "AT+QMTCONN=0,");
    uart_sendstr(g_ec801_uart_handle, g_cilent_name);
    uart_sendstr(g_ec801_uart_handle, ",");
    uart_sendstr(g_ec801_uart_handle, g_cilent_user_name);
    uart_sendstr(g_ec801_uart_handle, ",");
    uart_sendstr(g_ec801_uart_handle, g_cilent_paaword);
    uart_sendstr(g_ec801_uart_handle, "\r\n");
    osDelay(5000);
    }flag_connect = 0;
    
    // 订阅主题
    while(!flag_sub)
    {
    uart_sendstr(g_ec801_uart_handle, "AT+QMTSUB=0,0,");
    uart_sendstr(g_ec801_uart_handle, g_topic_name);
    uart_sendstr(g_ec801_uart_handle, ",0\r\n");
    osDelay(5000);
    }flag_sub = 0;
}

void EC801_start()
{
    EC801E_Power_ON();
    osDelay(5000);
    while(!EC801_GET_Time());
    MQTT_Config();
}

// MQTT发送数据
void MQTT_Trans_Data()
{
      //字符串长度
    uint8_t str_len = 0;
    char str_len_str[32];
  //创建获取数据指针
    float32_t *ptr = (float32_t *)&g_stMcs_Para;
    // 创建JSON数组及对象
    char *cjson_str = NULL;
    cJSON * JsonRoot =  cJSON_CreateObject();
    cJSON * DataArray = cJSON_CreateArray();
  
    //将uint8的ID存到字符串内
    char deviId_str[15];
    snprintf(deviId_str, sizeof(deviId_str), "%X%X%X%X%X%X%X", g_devic_id[0], \
                                                                g_devic_id[1], \
                                                                g_devic_id[2], \
                                                                g_devic_id[3], \
                                                                g_devic_id[4], \
                                                                g_devic_id[5], \
                                                                g_devic_id[6]);
    
    trans_time_stamp = g_time_stamp;// 将发送时时间戳存入最新发送时间时间戳
    
    cJSON_AddStringToObject(JsonRoot, "deviId", deviId_str);
    cJSON_AddStringToObject(JsonRoot, "frameType", "item_type");
    cJSON_AddNumberToObject(JsonRoot, "timeStamp", g_time_stamp);
    cJSON_AddNumberToObject(JsonRoot, "version", 10);

    cJSON_AddItemToObject(JsonRoot, "data", DataArray);//添加data数组
    
    for(int i = 0; i < sizeof(mcs_para)/sizeof(float32_t) - 2; i++)// 雨量光辐射还是空气
    {
        cJSON_AddItemToArray(DataArray, cJSON_CreateNumber(((float)((int )(ptr[i] * 100 + 0.5)))/100.0));// 四舍五入两位小数
    }
    
//   对象转字符串
    cjson_str = cJSON_Print(JsonRoot);
    
    str_len = strlen(cjson_str) + 2 + 4;
    sprintf(str_len_str, "%d", str_len);
    
    while(!flag_pubex)
    {
        // 发送发数据包命令
        uart_sendstr(g_ec801_uart_handle, "AT+QMTPUBEX=0,0,0,0,");
        uart_sendstr(g_ec801_uart_handle, g_topic_name);
        uart_sendstr(g_ec801_uart_handle, ",");
        uart_sendstr(g_ec801_uart_handle, str_len_str);
        uart_sendstr(g_ec801_uart_handle, "\r\n");
    
        //发送数据包
        osDelay(2000);
        uart_sendstr(g_ec801_uart_handle, cjson_str);
        HAL_Delay(3000);
    }flag_pubex = 0;
    
    //释放
    vPortFree(cjson_str);
    cJSON_Delete(JsonRoot);
}

// 判断闰年,1闰0平
uint16_t fml_leap_year(uint16_t year)
{
    return (((year % 4 == 0)&&(year % 100 != 0)) || (year % 400 == 0));
}

//日期转时间戳
uint32_t fml_time_to_stamp(int year, int month, int day, int hour, int minute, int second)
{
    static  uint32_t dax = 0;
    static  uint32_t day_count = 0;
    uint16_t leap_year_count = 0;
    uint16_t i;
 
    // 计算闰年数
    for (i = 1970; i < year; i++)
    {
        if (fml_leap_year(i))
        {
            leap_year_count++;
        }
    }
 
    // 计算年的总天数
    day_count = leap_year_count * 366 + (year - 1970 - leap_year_count) * 365;

    uint8_t mouthday[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    // 计算当年到当前月的所有天数

    for (i = 1; i < month; i++)
    {
        day_count += mouthday[i];
    }
    if(fml_leap_year(year))
    {
        day_count += 1;
    }

    // 累加计算当月的天数
    day_count += (day - 1);
 
    dax = (uint32_t)(day_count * 86400) + (uint32_t)((uint32_t)hour * 3600) + (uint32_t)((uint32_t)minute * 60) + (uint32_t)second;
 
    return dax;
}


//时间获取完成变量,用于控制是否开始MQTT信息接收
uint8_t time_get_ok = 0;
// 生成时间戳
int EC801_GET_Time()
{
    int year, month, day, hour, minute, second;
    if(USE_UTC)
    {
        uart_sendstr(g_ec801_uart_handle, "AT+QLTS=0\r\n");
    }else
    {
        uart_sendstr(g_ec801_uart_handle, "AT+QLTS=2\r\n");
    }
    osDelay(1000);
    char time[100] = {0};int index = 0;
    
    //        第一个“后是时间,前面不要
    do{
        time[index] = uart_dev_in_char(g_ec801_uart_handle);
    }while(time[index++] != '"' && uart_dev_char_present(g_ec801_uart_handle));
    // 丢掉前面的    
    memcpy(time, time + index - 1, index);
    index = 1;
    
    //        "前面是时间
    do{
        time[index] = uart_dev_in_char(g_ec801_uart_handle);
    }while(time[index++] != '"' && uart_dev_char_present(g_ec801_uart_handle));
    
    // 字符提取成int
    sscanf(time, "\"%d/%d/%d,%d:%d:%d\"", &year, &month, &day, &hour, &minute, &second);
    
    if(year)
    {
        time_get_ok = 1;
    }
    // 生成时间戳
    g_time_stamp = fml_time_to_stamp(year, month, day, hour, minute, second);
    return year;
}



#define JSON_BUFFER_SIZE 200
// 解析收到的4g模块数据
void parse_4g_receive_data()
{   
    if(uart_dev_char_present(g_ec801_uart_handle)){
        int temp_5_index = 0;
        char temp_5_char[5] = {0};
        
        int AT_Command_flag = 0;
        int Command_index = 0;
        char AT_Command[10] = {0};
        
        int AT_Command_ok_flag = 0;
        
        int AT_data_ok_flag = 0;
        uint8_t temp_buff[JSON_BUFFER_SIZE];
        int temp_buff_index = 0; // 索引
        
        char c = 0;
        int inJson = 0;
        
        
        memset(temp_buff, '\0', sizeof(temp_buff));//每次接受前清空一下BUFF
        for(; uart_dev_char_present(g_ec801_uart_handle);)
        {
            // 思路:挨个解析,每次解析3个字符存入BUFFER,依次后移,检测到+后看前面两个
            // 如果前面两个是AT,则继续解析
            // 如果前面两个不是AT,则将从+开始到:的内容都存入命令BUFF
            // 根据 命令BUFF 处理后面的数据
            c = uart_dev_in_char(g_ec801_uart_handle);
            temp_5_char[temp_5_index] = c;
            if(c == '+')
            {
                if(temp_5_char[(temp_5_index + 4)%5] == 'T' && temp_5_char[(temp_5_index + 3)%5] == 'A')// 判断 + 前是不是AT
                {
                }
                else
                {
                    AT_Command_flag = 1;
                }
            }
            temp_5_index = (temp_5_index + 1)%5;//更新索引
            
            // 读命令
            if(AT_Command_flag){
                AT_Command[Command_index] = c;// 存入命令Buff
                if(AT_Command[Command_index] == ':')// :后面是状态
                {
                    AT_Command_flag = 0;// 命令读完
                    AT_Command_ok_flag = 1;
                }
                Command_index ++;
            }
            
            // 命令读完,根据命令匹配反馈数据
            if(AT_Command_ok_flag)
            {
//                term_printf(AT_Command);
                // 打开QMTT客户端反馈
                if(strstr(AT_Command, "QMTOPEN"))
                {
                    temp_buff[temp_buff_index] = c;
                    if(temp_buff[temp_buff_index] == '\r'||temp_buff[temp_buff_index] == '\n')
                    {
                        // 处理完归零
                        AT_Command_ok_flag = 0;
                        memset(AT_Command, 0, 10);
                        
                        // 处理读完之后的数据
                        int client_idx, result;
                        sscanf(temp_buff, ": %d,%d", &client_idx, &result);
                        // 打开完成
                        if(result == 0)
                        {
                            flag_open_net = 1;
                        }
                        return;
                    }
                    temp_buff_index ++;                    
                }
                
                // 连接服务器反馈
                if(strstr(AT_Command, "QMTCONN"))
                {
                    temp_buff[temp_buff_index] = c;
                    if(temp_buff[temp_buff_index] == '\r'||temp_buff[temp_buff_index] == '\n')
                    {
                        // 处理完归零
                        AT_Command_ok_flag = 0;
                        memset(AT_Command, 0, 10);
                        
                        // 处理读完之后的数据
                        int client_idx, result, ret_code;
                        sscanf(temp_buff, ": %d,%d,%d", &client_idx, &result, &ret_code);
                        // 连接完成
                        if(result == 0 && ret_code == 0)
                        {
                            flag_connect = 1;
                        }
                        return;
                    }
                    temp_buff_index ++;
                }
                
                // 订阅主题反馈
                if(strstr(AT_Command, "QMTSUB"))
                {
                    temp_buff[temp_buff_index] = c;
                    if(temp_buff[temp_buff_index] == '\r'||temp_buff[temp_buff_index] == '\n')
                    {
                        // 处理完归零
                        AT_Command_ok_flag = 0;
                        memset(AT_Command, 0, 10);
                        
                        // 处理读完之后的数据
                        int client_idx, msgID, result, value;
                        sscanf(temp_buff, ": %d,%d,%d,%d", &client_idx, &msgID, &result, &value);
                        // 连接完成
                        if(result == 0)
                        {
                            flag_sub = 1;
                        }
                        return;
                    }
                    temp_buff_index ++;
                }
                
                // 发布消息反馈
                if(strstr(AT_Command, "QMTPUBEX"))
                {
                    temp_buff[temp_buff_index] = c;
                    if(temp_buff[temp_buff_index] == '\r'||temp_buff[temp_buff_index] == '\n')
                    {
                        // 处理完归零
                        AT_Command_ok_flag = 0;
                        memset(AT_Command, 0, 10);
                        
                        // 处理读完之后的数据
                        int client_idx, msgID, result, value;
                        sscanf(temp_buff, ": %d,%d,%d,%d", &client_idx, &msgID, &result, &value);
                        // 连接完成
                        if(result == 0 || result == 1)
                        {
                            flag_pubex = 1;
                        }
                        return;
                    }
                    temp_buff_index ++;
                }
                
//                收到消息反馈+++++收到json
                if(strstr(AT_Command, "QMTRECV"))
                {
                    if (c == '{')
                    {
                        AT_data_ok_flag = 1;
                    }
                    if (AT_data_ok_flag == 1) 
                    {
                        temp_buff[temp_buff_index] = c;
                        if (temp_buff[temp_buff_index] == '}')
                        {
                            // 处理完归零
                            AT_data_ok_flag = 0;
                            memset(AT_Command, 0, 10);
                            
                            // 接收完了
                            if(temp_buff[0] != '\0')
                            {
                                parse_json(temp_buff);
                            }
//                            term_printf(temp_buff);
                            return;
                        }
                        temp_buff_index ++;
                    }
                }
            }
        }
    }
}

extern int trans_4g_flag;
// 收到json数据处理
void parse_json(uint8_t *json_buff)
{
    cJSON* cjson_root = cJSON_Parse(json_buff);
    
    if(cjson_root == NULL)
    {
        term_printf("parse fail.\n");
        return;
    }
    
    cJSON* cjson_id          = cJSON_GetObjectItem(cjson_root, "deviId");
    cJSON* cjson_type        = cJSON_GetObjectItem(cjson_root, "frameType");
    cJSON* cjson_version     = cJSON_GetObjectItem(cjson_root, "version");
    cJSON* cjson_response    = cJSON_GetObjectItem(cjson_root, "response");
    cJSON* cjson_time        = cJSON_GetObjectItem(cjson_root, "timeStamp");
    
    cJSON* cjson_cmd        = cJSON_GetObjectItem(cjson_root, "cmd");
    
//    取出数据
    char *temp_id = cjson_id -> valuestring;
    char *temp_type = cjson_type -> valuestring;
    int temp_version = cjson_version -> valueint;
    int temp_response = cjson_response -> valueint;
    int temp_time = cjson_time -> valueint;
    int temp_cmd = cjson_cmd -> valueint;
    
    term_printf("deviId=%s\n frameType=%s\n version=%d\n response=%d\n timeStamp=%d\n cmd=%d", temp_id, temp_type, temp_version, temp_response, temp_time, temp_cmd);
    
    cJSON_Delete(cjson_root);
    
    // 与发送时间不一样才处理
    if(temp_time != trans_time_stamp)
    {
        term_printf("1111");
        if(temp_cmd == 1)
        {
            trans_4g_flag = 1;
        }
    }
    
//    数据处理
//    if(abs(temp_time - g_time_stamp) >= 120)
//    {
//        g_time_stamp = temp_time;
//    }
}