/******************************************************************
** Copyright (c) 2009  Wuhan xiyun Technology Co., Ltd .
** FileName:	handle.request.c
** Author:	 	chw
** Mail:		
** Editor:		chw
** Date:		2020-12-03 13:34
** Version: 	2020-12-03
** File Description:  处理mqtt的设备配置请求
** Param explain: char* mac : 网关MAC地址
   char* subMac             ：子节点MAC地址
  MQTTAsync_message *pubmsg : 消息结构体
  MYSQL *_db                ：数据库连接
  char *topicName           : 消息主题
******************************************************************/


//备份服务器配置请求
int  do_SCR_BKS(char *topicName, MQTTAsync_message *pubmsg, MYSQL *_db)
{
    //debug("topicName=%s payloadlen=%d\n", topicName, pubmsg->payloadlen);

    //校验长度
    if(CheckMsgLength(topicName, pubmsg,12))
        return 1;

    unsigned char* data = pubmsg->payload;

    char mac[25] = {0};     //网关mac
    Hex2Str((const char*)data,mac,12);
    log("↑ 收到备份服务器配置请求,网关:%s  \n",mac);

    SendBakIP(mac , _db);

    return 0;
}

//节点信息表配置请求
int  do_SCR_NAT(char *topicName, MQTTAsync_message *pubmsg, MYSQL *_db)
{
    //debug("topicName=%s payloadlen=%d\n", topicName, pubmsg->payloadlen);

    //校验长度
    if(CheckMsgLength(topicName, pubmsg,12))
        return 1;

    unsigned char* data = pubmsg->payload;

    char mac[25] = {0};     //网关mac
    Hex2Str((const char*)data,mac,12);
    log("↑ 收到节点信息表配置请求,网关:%s \n",mac);

    SendSubInfo(mac , _db);

    return 0;
}

//额定电压配置请求
int  do_SCR_SRV(char *topicName, MQTTAsync_message *pubmsg, MYSQL *_db)
{
    //debug("topicName=%s payloadlen=%d\n", topicName, pubmsg->payloadlen);

    //校验长度
    if(CheckMsgLength(topicName, pubmsg,18))
        return 1;

    unsigned char* data = pubmsg->payload;

    char mac[25] = {0};     //网关mac
    char subMac[13] = {0};     //子节点
    Hex2Str((const char*)data,mac,12);
    Hex2Str((const char*)(data+12),subMac,6);
    if(strcmp(subMac,"0F0000000001") == 0)
    {
        log("↑ 收到额定电压配置请求,网关:%s \n",mac);
        SendRatedVoltage(mac,"",_db);
    }
    else
    {
        log("↑ 收到额定电压配置请求,网关:%s,节点:%s \n",mac,subMac);
        SendRatedVoltage(mac,subMac,_db);
    }
    
    return 0;
}

//额定电流配置请求
int  do_SCR_SRC(char *topicName, MQTTAsync_message *pubmsg, MYSQL *_db)
{
    //debug("topicName=%s payloadlen=%d\n", topicName, pubmsg->payloadlen);

    //校验长度
    if(CheckMsgLength(topicName, pubmsg,18))
        return 1;

    unsigned char* data = pubmsg->payload;

    char mac[25] = {0};     //网关mac
    char subMac[13] = {0};     //子节点
    Hex2Str((const char*)data,mac,12);
    Hex2Str((const char*)(data+12),subMac,6);
    if(strcmp(subMac,"0F0000000001") == 0)
    {
        log("↑ 收到额定电流配置请求,网关:%s \n",mac);
        SendRatedCurrent(mac,"",_db);
    }
    else
    {
        log("↑ 收到额定电流配置请求,网关:%s,节点:%s \n",mac,subMac);
        SendRatedCurrent(mac,subMac,_db);
    }
    
    return 0;
}

//开关时间段配置请求
int  do_SCR_STS(char *topicName, MQTTAsync_message *pubmsg, MYSQL *_db)
{
    //debug("topicName=%s payloadlen=%d\n", topicName, pubmsg->payloadlen);

    //校验长度
    if(CheckMsgLength(topicName, pubmsg,18))
        return 1;

    unsigned char* data = pubmsg->payload;

    char mac[25] = {0};     //网关mac
    char subMac[13] = {0};     //子节点
    Hex2Str((const char*)data,mac,12);
    Hex2Str((const char*)(data+12),subMac,6);
    if(strcmp(subMac,"0F0000000001") == 0)
    {
        log("↑ 收到开关时间段配置请求,网关:%s \n",mac);
        SendOnOffTimeMuilt(mac,"",_db);
    }
    else
    {
        log("↑ 收到开关时间段配置请求,网关:%s,节点:%s \n",mac,subMac);
        SendOnOffTimeMuilt(mac,subMac,_db);
    }
    
    return 0;
}

//开关控制模式请求
int  do_SCR_SCM(char *topicName, MQTTAsync_message *pubmsg, MYSQL *_db)
{
    //debug("topicName=%s payloadlen=%d\n", topicName, pubmsg->payloadlen);

    //校验长度
    if(CheckMsgLength(topicName, pubmsg,18))
        return 1;

    unsigned char* data = pubmsg->payload;

    char mac[25] = {0};     //网关mac
    char subMac[13] = {0};     //子节点
    Hex2Str((const char*)data,mac,12);
    Hex2Str((const char*)(data+12),subMac,6);
    if(strcmp(subMac,"0F0000000001") == 0)
    {
        log("↑ 收到开关控制模式请求,网关:%s \n",mac);
        SendSwitchModeFromDB(mac,"",_db);
    }
    else
    {
        log("↑ 收到开关控制模式请求,网关:%s,节点:%s \n",mac,subMac);
        SendSwitchModeFromDB(mac,subMac,_db);
    }
    
    return 0;
}

//传感器阈值配置请求
int  do_SCR_SAT(char *topicName, MQTTAsync_message *pubmsg, MYSQL *_db)
{
    //debug("topicName=%s payloadlen=%d\n", topicName, pubmsg->payloadlen);

    //校验长度
    if(CheckMsgLength(topicName, pubmsg,12))
        return 1;

    unsigned char* data = pubmsg->payload;

    char mac[25] = {0};     //网关mac
    Hex2Str((const char*)data,mac,12);
    log("↑ 收到传感器阈值配置请求,网关:%s \n",mac);

    SendSensorThreshold(mac , _db);

    return 0;
}

//服务器时间同步请求
int  do_SCR_NTP(char *topicName, MQTTAsync_message *pubmsg, MYSQL *_db)
{
    //debug("topicName=%s payloadlen=%d\n", topicName, pubmsg->payloadlen);
    UNUSED(_db);
    //校验长度
    if(CheckMsgLength(topicName, pubmsg,12))
        return 1;

    unsigned char* data = pubmsg->payload;

    char mac[25] = {0};     //网关mac
    Hex2Str((const char*)data,mac,12);
    log("↑ 收到服务器时间同步请求,网关:%s \n",mac);

    //发送时间同步
    usleep(1000);
    SendNTP(mac);

    return 0;
}

//OTA数据请求
int  do_SCR_OTA(char *topicName, MQTTAsync_message *pubmsg, MYSQL *_db)
{
    //debug("topicName=%s payloadlen=%d\n", topicName, pubmsg->payloadlen);
    UNUSED(topicName);
    MQTTAsync_message sendData = MQTTAsync_message_initializer;
    char updateSql[1024] = {0};
    char buf[2048] = {0};
    char topicName2[256];
    char filename[256] = {0}; //升级文件
    unsigned int number = 0; //请求的包序号
    int offset = 0;//偏移数
    float rate_progress = 0.0;
    int upgrade_status = 0;//当前升级状态0：未开始  1：正在升级 2：完成 3：出现错误

    char2short sequence_number;
    unsigned char* data = pubmsg->payload;

    char mac[25] = {0};     //网关mac
    Hex2Str((const char*)data,mac,12);
    //log("↑ 收到ota升级请求,网关:%s \n",mac);
    sprintf(topicName2,"PP/%s/DS/OTA",mac);

    //查询升级文件名
    GetUpgradeFileFromDB(mac,_db,filename);
    if(strlen(filename)<=0)
    {
        log("↑ 收到ota升级请求,网关:%s,升级文件名为空! \n",mac);
        return 1;
    }

    //确认加载了升级文件
    //UpgradeFileAddFromDB(file_list,filename,);

    //取升级文件ota_info
    ota_info* info = GetOtaInfoByFileName(file_list,filename);
    if(info == NULL)
    {
        log("↑ 收到ota升级请求,网关:%s,升级文件名:%s,ota_info为空! \n",mac,filename);
        return 1;
    }
    //请求ota_info数据
    if(data[12] == 0x00 && data[13] == 0x80)
    {
        buf[2] = info->ota_mode;
        memcpy(buf+3,info->old_file_name,48);//旧文件名
        buf[51] = ((char*)&info->old_file_len)[0];//旧文件长度
        buf[52] = ((char*)&info->old_file_len)[1];
        buf[53] = ((char*)&info->old_file_len)[2];
        buf[54] = ((char*)&info->old_file_len)[3];
        buf[55] = ((char*)&info->old_file_crc)[0];//旧文件crc32校验值
        buf[56] = ((char*)&info->old_file_crc)[1];
        buf[57] = ((char*)&info->old_file_crc)[2];
        buf[58] = ((char*)&info->old_file_crc)[3];
        memcpy(buf+59,info->new_file_name,48);//新文件名
        buf[107] = ((char*)&info->new_file_len)[0];//新文件长度
        buf[108] = ((char*)&info->new_file_len)[1];
        buf[109] = ((char*)&info->new_file_len)[2];
        buf[110] = ((char*)&info->new_file_len)[3];
        buf[111] = ((char*)&info->new_file_crc)[0];//新文件crc32校验值
        buf[112] = ((char*)&info->new_file_crc)[1];
        buf[113] = ((char*)&info->new_file_crc)[2];
        buf[114] = ((char*)&info->new_file_crc)[3];
        buf[115] = info->ota_state;
        buf[116] = ((char*)&info->ota_file_len)[0];//ota 文件的长度
        buf[117] = ((char*)&info->ota_file_len)[1];
        buf[118] = ((char*)&info->ota_file_len)[2];
        buf[119] = ((char*)&info->ota_file_len)[3];
        buf[120] = ((char*)&info->ota_file_crc)[0];//ota文件 crc32校验值
        buf[121] = ((char*)&info->ota_file_crc)[1];
        buf[122] = ((char*)&info->ota_file_crc)[2];
        buf[123] = ((char*)&info->ota_file_crc)[3];
        buf[124] = ((char*)&info->ota_file_total_packets)[0];//ota文件的总的包数
        buf[125] = ((char*)&info->ota_file_total_packets)[1];
        buf[126] = ((char*)&info->ota_file_packet_len)[0];//ota文件每包的数据长度
        buf[127] = ((char*)&info->ota_file_packet_len)[1];
        sendData.payloadlen = 128;
        log(" 请求ota升级包信息头,文件名:%s,网关:%s,payloadlen:%d,请求包序号:0x0080 \n",filename,mac,sendData.payloadlen);
    }
    //请求ota升级包
    else
    {
        memcpy(sequence_number.c_char,data+12,2);
        number = sequence_number.i_short;
        sequence_number.i_short +=1;

        EndianSwap((unsigned char*)sequence_number.c_char,0,2);

        //序号
        memcpy(buf,sequence_number.c_char,2);
        log("请求的升级包序号:%02x %02x -->:%d\n",data[12],data[13],number);
        if((number+1)>info->ota_file_total_packets)
        {
            log("请求的升级包序号太大:%02x %02x ,-->:%d\n",data[12],data[13],number);
            return -1;
        }
        //升级包
        offset = number*info->ota_file_packet_len;
        //非最后一包
        if((number+1) != info->ota_file_total_packets)
        {
            memcpy(buf+2,info->buf+offset,info->ota_file_packet_len);
            sendData.payloadlen = info->ota_file_packet_len+2;
        }
        //最后一包
        else
        {
            int len = info->ota_file_len % info->ota_file_packet_len;
            memcpy(buf+2,info->buf+offset,len);
            sendData.payloadlen = len+2;
        }
        log(" 请求ota包序号:%d,文件名:%s,网关:%s,发送包序号:%d,payloadlen:%d \n",number,filename,mac,number+1,sendData.payloadlen);
    }

    //填充报文
    sendData.payload = buf;
    sendData.qos = 0;
    sendData.retained = 0;

    //发送
    int ret = my_mqqta_sendmsg(topicName2, &sendData);
    //SendSensorThreshold(mac , _db);

    //更新数据库
    upgrade_status = 1;
    rate_progress = ((float)(number+1)/(float)info->ota_file_total_packets)*100.0;
    sprintf(updateSql,"update dev_status_upgrade set status = %d,rate_progress = %.2f,current_request_number = %d,update_time = now() where "
                    " gateway_mac = '%s'",upgrade_status,rate_progress,number,mac);
    excuteSql(_db,updateSql);

    return 0;
}