//--------------------------------------------------------------------- #include #include #include "SlaveCtrl.h" #include "crc16.h" #include "filemanage.h" #include "classxml.h" #define SYSCODE 0xAAAAAAAA #define Version 12 #define ADJ_VOL 0 #define ADJ_DIS 1 #define ADJ_CHR 2 //#define EN_THREAD_WORK_DEBUG #ifdef EN_THREAD_WORK_DEBUG #define THREAD_WORK_DEBUG qDebug #else #define THREAD_WORK_DEBUG(...) #endif QList master_cmd; SlaveCtrl::SlaveCtrl(Working_Page *page) { work_page = page; IF_CLOSEServer = IF_CLOSEClient = false; connect(this,SIGNAL(SendInterface(int)),work_page->work_thread,SLOT(RecvInterface(int))); connect(this,SIGNAL(sendParam(int)),work_page,SLOT(operatorCMD_Work(int))); connect(work_page,SIGNAL(senddeleteSocket()),this,SLOT(deleteSocket())); ServerFlag = ClientFlag = 0; } SlaveCtrl::~SlaveCtrl() { quit(); wait(); } bool SlaveCtrl::CheckLen(FRAME_DATA *recv) { if(recv->Len >= 18) { return true; } return false; } bool SlaveCtrl::CheckSYNCode(FRAME_DATA *recv) { if(recv->SYNCode == SYSCODE) { return true; } return false; } bool SlaveCtrl::CheckCRC(FRAME_DATA *recv) { unsigned short Temp = recv->CRC; recv->CRC =0; recv->CRC = CRC16::CalCRC16(recv,recv->Len); if(recv->CRC == Temp) { return true; } return false; } bool SlaveCtrl::WriteFrameData(FRAME_DATA *Sent) { QByteArray arrTest; arrTest.append(reinterpret_cast(Sent),Sent->Len); //qDebug()<write(arrTest)==Sent->Len) { tcpSocket->flush(); tcpSocket->waitForBytesWritten(1000); return true; } else return false; } else if(ClientFlag) { if(tcpClient->write(arrTest)==Sent->Len) { tcpClient->flush(); tcpClient->waitForBytesWritten(1000); return true; } else return false; } else return false; } bool SlaveCtrl::ReadFrameHead(FRAME_DATA *recv, FRAME_DATA *Sent) { if(CheckSYNCode(recv) == true) { if(CheckLen(recv) == false) { Sent->RecState = LEN_ERR; } return true; } else { return false; } } bool SlaveCtrl::ReadFrameData(FRAME_DATA &recv, FRAME_DATA &Sent) { if(ReadFrameHead(&recv,&Sent) == true) { if(Sent.RecState == SUCCEED) { if(CheckCRC(&recv) == false) { Sent.RecState = CRC_ERR; } } return true; } return false; } //---------------------------------------------------------------------------------- quint16 SlaveCtrl::getMonData(quint8 *info,quint16 MonNum) { static quint8 cnt = 0; static quint8 bak_state = 0; MON_DATA mondata; memset(&mondata,0,sizeof(MON_DATA)); for(int i=0;i<4;i++) { mondata.GroupVol[i] = work_page->work_thread->fboData.SumVoltage; mondata.GroupCur[i] = work_page->work_thread->fboData.SubCurrent[i]; mondata.reserved[0] = work_page->work_thread->fboData.OnlineVol; if(work_page->work_thread->localData.SysWorkState == Discharging || work_page->work_thread->localData.SysWorkState == Paused_Dischg) { bak_state = work_page->work_thread->localData.SysWorkState; cnt = 5; } else cnt = 0; if((cnt > 0) && (work_page->work_thread->localData.SysWorkState == WorkStopped)) { cnt--; mondata.BattStatus[0] = bak_state + 0x80; mondata.GroupCur[0] = 0; } else { mondata.BattStatus[0] = work_page->work_thread->localData.SysWorkState + 0x80; bak_state = work_page->work_thread->localData.SysWorkState; if(work_page->work_thread->localData.SysWorkState == WorkStopped/* && work_page->work_thread->localData.deviceTestType != TYPE_ON_LINE*/) mondata.GroupCur[0] = 0; } } mondata.BattStatus[1] = 0x80; mondata.BattStatus[2] = 0x80; mondata.BattStatus[3] = 0x80; if(MonNum>300) MonNum = 100; memcpy(mondata.MonomerVol,work_page->work_thread->fboData.SingleVol,MonNum*2); memcpy(info,&mondata,32 + MonNum*2); return 32 + MonNum*2; } //quint16 SlaveCtrl::getAdjData(quint8 *info) //{ // ADJ_DATA adjdata; // memset(&adjdata,0,sizeof(adjdata)); // adjdata.OnlineVol = work_page->work_thread->fboData.OnlineVol; // adjdata.GroupVol = 0.1*work_page->work_thread->fboData.SumVoltage; // adjdata.dis_cur = 0.1*work_page->work_thread->fboData.SumCurrent; // adjdata.chr_cur = 0.1*work_page->work_thread->fboData.SumCurrent; // adjdata.out_cur = 0; // memcpy(info,&adjdata,sizeof(ADJ_DATA)); // return sizeof(ADJ_DATA); //} quint16 SlaveCtrl::getTestData(quint8 *info) { TEST_DATA testdata; memset(&testdata,0,sizeof(testdata)); testdata.OnlineVol = work_page->work_thread->fboData.OnlineVol; testdata.GroupVol = work_page->work_thread->fboData.SumVoltage; testdata.CurrTime = work_page->work_thread->getTestFileTime(); testdata.testtime = work_page->work_thread->fboData.m_TestTime; if(work_page->work_thread->localData.SysWorkState == Paused_Dischg || work_page->work_thread->localData.SysWorkState == Paused_charge) { testdata.KeyState = 1; } else if(work_page->work_thread->localData.SysWorkState == Charging || work_page->work_thread->localData.SysWorkState == WaitForCharging) { testdata.KeyState = work_page->work_thread->localData.SysWorkState-1; } else { testdata.KeyState = work_page->work_thread->localData.SysWorkState; } if(work_page->work_thread->localData.SysWorkState == Discharging) testdata.monomerCount = work_page->work_thread->localData.monomerLowCount; // else if(work_page->work_thread->localData.SysWorkState == Charging) // testdata.monomerCount = work_page->work_thread->localData.monomerHighCount; testdata.curr_cur = work_page->work_thread->fboData.SumCurrent;//*0.1 testdata.AllCap = work_page->work_thread->fboData.AllCap; testdata.SMaxIndex = work_page->work_thread->localData.SMaxIndex[0]; testdata.SMaxVol = work_page->work_thread->localData.SMaxVol[0]; testdata.SMinIndex = work_page->work_thread->localData.SMinIndex[0]; testdata.SMinVol = work_page->work_thread->localData.SMinVol[0]; testdata.dischgTimes = work_page->work_thread->localData.dischgTimes; //testdata.HighTemp = work_page->work_thread->GetBYDInfo()->temp_hight; //testdata.LowTTemp = work_page->work_thread->GetBYDInfo()->temp_low; if(work_page->work_thread->localData.SysWorkState == WorkStopped/* && work_page->work_thread->localData.deviceTestType != TYPE_ON_LINE*/) testdata.curr_cur = 0; if(work_page->work_thread->fboData.SumVoltagework_thread->localData.RLY_OK&(~IGBT_VALUE); } else testdata.reserved[0] = work_page->work_thread->localData.RLY_OK&(IGBT_VALUE_X); memcpy(info,&testdata,sizeof(TEST_DATA)); return sizeof(TEST_DATA); } quint8 *SlaveCtrl::getFileDataHead(FILE_LIST_DATA &data,TEST_DATA_INFO &test_info,quint8 total,quint8 Index) { data.TotalFileNum = total; data.CurrFileIndex = Index; data.TestStartTime = test_info.fbo_data_head_start.TestStartTime; data.TestTimeLong = test_info.fbo_data_head_stop.TestTimeLong; data.DataType = test_info.fbo_data_head_start.DataType; data.TestCur = test_info.fbo_data_head_start.TestCur; data.TestCap = test_info.fbo_data_head_stop.TestCap; data.STDCap = test_info.fbo_data_head_start.STDCap; data.MVLLimit = test_info.fbo_data_head_start.MVLLimit; data.SumVLLimit = test_info.fbo_data_head_start.SumVLLimit; data.BattSum = test_info.fbo_data_head_start.BattSum; data.BattGroup = test_info.fbo_data_head_start.BattGroup; data.StopType = test_info.fbo_data_head_stop.StopType; data.MonomerVol = test_info.fbo_data_head_start.MonomerVol; return (quint8 *)&data; } quint16 SlaveCtrl::getPageFileData(FRAME_DATA &recv, FRAME_DATA &Sent) { quint8 i; quint8 page = recv.Db1; quint16 j=0; FileManage fileManage; QStringList nameList = fileManage.getFiles(work_page->batteryName+"/",".FBO"); TEST_DATA_INFO test_info; FILE_LIST_DATA file_data; if(page*8 > nameList.count()) { Sent.RecState = FILE_DATA_ERR; return 0; } for(i=0;i<8 && i+page*8batteryName+"/"+nameList.at(i+page*8),test_info)) { getFileDataHead(file_data,test_info,nameList.count(),i+page*8); memcpy(Sent.info+j,&file_data,sizeof(FILE_LIST_DATA)); j += sizeof(FILE_LIST_DATA); } } return j; } quint16 SlaveCtrl::getFileSmallBlock(FRAME_DATA &recv, FRAME_DATA &Sent) { quint16 Cnt_len=0; quint16 total_block=0; quint16 file_index = recv.RecState*256+recv.type; quint16 smallBlock = recv.workState*256+recv.Alarm; FileManage fileManage; QStringList nameList = fileManage.getFiles(work_page->batteryName+"/",".FBO"); if(file_index >= nameList.count()) { Sent.RecState = FILE_DATA_ERR; return 0; } if(ClassXML::ReadsmallBlockDataFBO(dataDir+work_page->batteryName+"/"+nameList.at(file_index), Sent.info,Cnt_len,total_block,smallBlock)) { Sent.Db1 = (total_block>>8)&0xFF; Sent.Db2 = (total_block)&0xFF; Sent.Db3 = (smallBlock>>8)&0xFF; Sent.Db4 = (smallBlock)&0xFF; return Cnt_len; } return 0; } quint16 SlaveCtrl::getBattName(FRAME_DATA &recv, FRAME_DATA &Sent) { quint16 batt_index = recv.RecState*256+recv.type; QStringList batt_list = FileManage::getDirs(); quint16 batt_total = batt_list.count(); if(batt_index >= batt_total) { Sent.RecState = FILE_DATA_ERR; return 0; } Sent.Db1 = (batt_total>>8)&0xFF; Sent.Db2 = batt_total&0xFF; Sent.Db3 = recv.RecState; Sent.Db4 = recv.type; QString battname = batt_list.at(batt_index); memcpy(Sent.info,battname.toUtf8().data(),battname.toUtf8().length()); return battname.toUtf8().length(); } quint16 SlaveCtrl::getfileName(FRAME_DATA &recv, FRAME_DATA &Sent) { quint16 batt_index = recv.RecState*256+recv.type;//FF quint16 file_index = recv.workState*256+recv.Alarm;//0 QStringList batt_list = FileManage::getDirs(); quint16 batt_total = batt_list.count(); if(batt_index >= batt_total) { Sent.RecState = FILE_DATA_ERR; return 0; } QStringList file_List = FileManage::getFiles(batt_list.at(batt_index)+"/",".FBO"); quint16 file_total = file_List.count(); if(file_index >= file_total) { Sent.RecState = FILE_DATA_ERR; return 0; } Sent.Db1 = (file_total>>8)&0xFF; Sent.Db2 = file_total&0xFF; Sent.Db3 = recv.workState; Sent.Db4 = recv.Alarm; QString filename = file_List.at(file_index); memcpy(Sent.info,filename.toUtf8().data(),filename.toUtf8().length()); return filename.toUtf8().length(); } quint16 SlaveCtrl::getSelectFile(FRAME_DATA &recv, FRAME_DATA &Sent) { QString path_name = QString::fromUtf8((const char *)recv.info,recv.Len-18); //qDebug()<<"111111"<= total_block) { Sent.RecState = FILE_DATA_ERR; } Sent.Db1 = (total_block>>8)&0xFF; Sent.Db2 = (total_block)&0xFF; Sent.Db3 = (smallBlock>>8)&0xFF; Sent.Db4 = (smallBlock)&0xFF; return Cnt_len; } Sent.RecState = OTHER_ERR; return 0; } quint16 SlaveCtrl::getVersion(FRAME_DATA &recv, FRAME_DATA &Sent) { Sent.RecState = recv.RecState; QString battname = phoneVersion; memcpy(Sent.info,battname.toUtf8().data(),battname.toUtf8().length()); return battname.toUtf8().length(); } void SlaveCtrl::SaveTestParam(const QString &fname,TEST_PARAM_XML &test_param) { if(ClassXML::CreateTestParamXml(fname,test_param)) //新建的 { } else //原有的 { ClassXML::ModifyTestParamXml(fname,test_param); } } void SlaveCtrl::NewBattFile(quint8 *info) { QString newname((const char *)info); if(work_page->batteryName != newname) { ClassXML::ModifyNewestPNameXml(newname); work_page->batteryName = newname; SaveTestParam(newname,work_page->test_param_xml); } } bool SlaveCtrl::SelectBatt(quint8 *info) { QString newname((const char *)info); TEST_PARAM_XML testParam; if(true == ClassXML::ReadTestParamXml(newname, testParam)) { ClassXML::ModifyNewestPNameXml(newname); work_page->batteryName = newname; emit sendParam(PARAM_PAGE_CMD_PARAM); return true; } return false; } void SlaveCtrl::DeleteBatt(quint8 *info) { QString newname((const char *)info); FileManage fileManage; if(newname == Default_Battery) { fileManage.clearDirectoryFiles(Default_Battery,fileManage.getFiles(Default_Battery,".FBO")); } else { fileManage.removeDir(dataDir+newname); } if(work_page->batteryName == newname) { newname = Default_Battery; ClassXML::ModifyNewestPNameXml(newname); work_page->batteryName = newname; emit sendParam(PARAM_PAGE_CMD_PARAM); } } //---------------------------------------------------------------------------------- void SlaveCtrl::SlaveClearHeart() { work_page->work_thread->localData.tcp_ctrl.heart_cnt = 0; } void SlaveCtrl::SlaveDisposeCMD(FRAME_DATA &recv, FRAME_DATA &Sent) { if((work_page->work_thread->localData.tcp_ctrl.Enter_ctrl == 0)&&(recv.CMD != EnterSlave)) { Sent.RecState = SLAVEMODE_ERR; return; } switch (recv.CMD) { case Heartbea: //SlaveClearHeart(dev); break; case ExitSlave: work_page->work_thread->localData.tcp_ctrl.Enter_ctrl = 0; break; case EnterSlave: if(work_page->work_thread->localData.tcp_ctrl.Enter_ctrl) { break; } // qDebug("get CMD = %x",recv.CMD); work_page->work_thread->localData.tcp_ctrl.Enter_ctrl = 1; if(work_page->work_thread->localData.SysWorkState == WorkStopped && work_page->work_thread->localData.pauseBtnState == 0) { emit SendInterface(FACE_HOME); } else { Sent.RecState = SLAVEMODE_ERR; } break; case StartDischarge: if((work_page->work_thread->localData.SysWorkState == WorkStopped||work_page->work_thread->localData.SysWorkState == Paused_Dischg)&& work_page->work_thread->localData.pauseBtnState!=2) emit sendParam(PARAM_PAGE_CMD_START_DIS);//emit sendStart(work_page->work_thread->CMD_StartDischarge,work_page->batteryName); else Sent.RecState = START_ERR; break; case PausetDischarge: if(work_page->work_thread->localData.SysWorkState == Discharging || work_page->work_thread->localData.SysWorkState == Paused_Dischg) emit sendParam(PARAM_PAGE_CMD_PAUSE);//emit sendStart(work_page->work_thread->CMD_PauseDischarge,work_page->batteryName); else Sent.RecState = START_ERR; break; case StopDischarge: if(work_page->work_thread->localData.SysWorkState == Paused_Dischg || work_page->work_thread->localData.SysWorkState == Discharging || work_page->work_thread->localData.SysWorkState == WaitForCharging ) emit sendParam(PARAM_PAGE_CMD_STOP);//emit sendStart(work_page->work_thread->CMD_StopDischarge,work_page->batteryName); else Sent.RecState = START_ERR; break; case StartCharge: if(work_page->work_thread->localData.SysWorkState == WorkStopped ||work_page->work_thread->localData.SysWorkState == Paused_charge) emit sendParam(PARAM_PAGE_CMD_START_CHR);//emit sendStart(work_page->work_thread->CMD_StartCharge,work_page->batteryName); else Sent.RecState = START_ERR; break; case PauseCharge: if(work_page->work_thread->localData.SysWorkState == Charging) emit sendParam(PARAM_PAGE_CMD_PAUSE);//emit sendStart(work_page->work_thread->CMD_PauseCharge,work_page->batteryName); else Sent.RecState = START_ERR; break; case StopCharge: if(work_page->work_thread->localData.SysWorkState == Paused_charge || work_page->work_thread->localData.SysWorkState == Charging) emit sendParam(PARAM_PAGE_CMD_STOP);//emit sendStart(work_page->work_thread->CMD_StopCharge,work_page->batteryName); else Sent.RecState = START_ERR; break; // case StartCycle: // if(work_page->work_thread->localData.SysWorkState == WorkStopped && work_page->work_thread->localData.deviceTestType == TYPE_CYCLE_TEST) // { // if(START_DISCHG == testParam.cycle_start) // emit sendParam(PARAM_PAGE_CMD_START_DIS); // else if(START_CHARGE == testParam.cycle_start) // emit sendParam(PARAM_PAGE_CMD_START_CHR); // else // Sent.RecState = START_ERR; // } // else // Sent.RecState = START_ERR; // break; // case PauseCycle: // if(work_page->work_thread->localData.SysWorkState != WorkStopped && work_page->work_thread->localData.deviceTestType == TYPE_CYCLE_TEST) // emit sendParam(PARAM_PAGE_CMD_PAUSE); // else // Sent.RecState = START_ERR; // break; // case StopCycle: // if(work_page->work_thread->localData.SysWorkState != WorkStopped && work_page->work_thread->localData.deviceTestType == TYPE_CYCLE_TEST) // emit sendParam(PARAM_PAGE_CMD_STOP); // else // Sent.RecState = START_ERR; // break; // case Adjust_StartDischarge: // if(work_page->work_thread->localData.SysWorkState == WorkStopped) // emit sendStart(work_page->work_thread->CMD_Adj_StartDis,work_page->batteryName); // else // Sent.RecState = START_ERR; // break; // case Adjust_StartCharge: // if(work_page->work_thread->localData.SysWorkState == WorkStopped) // emit sendStart(work_page->work_thread->CMD_Adj_StartChr,work_page->batteryName); // else // Sent.RecState = START_ERR; // break; // case Adjust_Stop: // if(work_page->work_thread->localData.SysWorkState == Discharging) // emit sendStart(work_page->work_thread->CMD_Adj_StopDis,work_page->batteryName); // else if(work_page->work_thread->localData.SysWorkState == Charging) // emit sendStart(work_page->work_thread->CMD_Adj_StopChr,work_page->batteryName); // else // Sent.RecState = START_ERR; // break; // case SetAdjustParm: // if(recv.RecState == ADJ_VOL) // emit SendCurrAdjCMD(work_page->work_thread->CMD_SetGroupVol, // (recv.type*256+recv.workState-work_page->work_thread->localData.sim_buf.ADCVdin)); // else if(recv.RecState == ADJ_DIS) // emit SendCurrAdjCMD(work_page->work_thread->CMD_SetDisChargCur, // (recv.type*256+recv.workState-work_page->work_thread->localData.sim_buf.ADCId)); // else if(recv.RecState == ADJ_CHR) // emit SendCurrAdjCMD(work_page->work_thread->CMD_SetChargCur, // (recv.type*256+recv.workState-work_page->work_thread->localData.sim_buf.ADCIc)); // else // Sent.RecState = START_ERR; // break; case SetDischargeParam: case SetChargeParam: case SetCycleParam: if(sizeof(COMM_TEST_PARAM) == (recv.Len - 18)) { TEST_PARAM_XML testParam; setTestCommParam(testParam,recv.info); //memcpy(addr,recv.info,sizeof(testParam)); SaveTestParam(work_page->batteryName,testParam); emit sendParam(PARAM_PAGE_CMD_PARAM); } break; case EnterHome: { quint8 pageIndex = 0; if(recv.Len > 18) { pageIndex = recv.info[0]; } else { pageIndex = recv.RecState; } //qDebug("pageIndex = %d,work_page->work_thread->localData.Interface=%d",pageIndex,work_page->work_thread->localData.Interface); if(pageIndex != work_page->work_thread->localData.Interface) { if(work_page->work_thread->localData.SysWorkState == Paused_Dischg || work_page->work_thread->localData.SysWorkState == Paused_charge || work_page->work_thread->localData.SysWorkState == Discharging || work_page->work_thread->localData.SysWorkState == Charging || work_page->work_thread->localData.SysWorkState == WaitForCharging) Sent.RecState = SYSTEM_WORKING; else { emit SendInterface(pageIndex); } } break; } case NewBatt: NewBattFile(recv.info); break; case ChangedBatt: if(!SelectBatt(recv.info)) Sent.RecState = OTHER_ERR; break; case DelBatt: DeleteBatt(recv.info); break; case ClearAlarm: work_page->work_thread->localData.popBox = 0; emit sendParam(PARAM_PAGE_CLOSE_BOX); break; case SetTKQState: emit sendParam(PARAM_PAGE_CMD_START_PSW); break; case SetFanState: emit sendParam(PARAM_PAGE_CMD_START_FAN); break; case GetBattName: case GetFileName: case GetSelectFile: case GetCellData: case GetDischargeParam: case GetChargeParam: case GetDischargeData: case GetChargeData: case GetCycleParam: case GetAdjustData: case GetFileInfo: case GetFile: default: break; } } void SlaveCtrl::SlaveSentFrame(FRAME_DATA &recv, FRAME_DATA &Sent) { static quint8 cnt = 0; static quint8 bak_state = 0; Sent.SYNCode = SYSCODE; Sent.CMD = recv.CMD; Sent.Len = 18; Sent.type = work_page->work_thread->localData.Interface + 0x80; if(work_page->work_thread->localData.SysWorkState == Discharging || work_page->work_thread->localData.SysWorkState == Paused_Dischg) { bak_state = work_page->work_thread->localData.SysWorkState; cnt = 5; } else cnt = 0; if((cnt > 0) && (work_page->work_thread->localData.SysWorkState == WorkStopped)) { cnt--; Sent.workState = bak_state; work_page->work_thread->fboData.SubCurrent[0] = 0; work_page->work_thread->fboData.SumCurrent = 0; } else { Sent.workState = work_page->work_thread->localData.SysWorkState; bak_state = work_page->work_thread->localData.SysWorkState; } if(work_page->work_thread->localData.TestType == TestTypeCharge) Sent.Alarm = work_page->work_thread->localData.WPAlarmState + work_page->work_thread->localData.popBox + 0x40; else Sent.Alarm = work_page->work_thread->localData.WPAlarmState + work_page->work_thread->localData.popBox; switch (recv.CMD) { case Heartbea: Sent.Db1 = work_page->work_thread->localData.tcp_ctrl.ID; memcpy(Sent.info,work_page->batteryName.toUtf8().data(),work_page->batteryName.toUtf8().length()); Sent.Len += work_page->batteryName.toUtf8().length(); break; case ExitSlave: case StartDischarge: case PausetDischarge: case StartCharge: case PauseCharge: case SetAdjustParm: case Adjust_StartDischarge: case Adjust_StartCharge: case Adjust_Stop: case NewBatt: case ChangedBatt: case DelBatt: case StopDischarge: case StopCharge: case ClearAlarm: case StartCycle: case PauseCycle: case StopCycle: case EnterHome: break; case EnterSlave: Sent.Db1 = Version; Sent.Db2 = 0; Sent.Db3 = 0xF4; break; case GetDischargeParam: case GetChargeParam: case GetCycleParam: // Sent.info = (quint8 *)&testParam; // Sent.Len += sizeof(testParam); getTestCommParam(work_page->test_param_xml,Sent.info); Sent.Len += sizeof(COMM_TEST_PARAM); break; case GetCellData: Sent.Db1 = work_page->test_param_xml.mon_number>>8; Sent.Db2 = work_page->test_param_xml.mon_number & 0xFF; Sent.Len += getMonData(Sent.info,work_page->work_thread->fboData.BattSum); break; case SetDischargeParam: case SetChargeParam: case SetCycleParam: Sent.Db1 = recv.Db1; break; case GetDischargeData: case GetChargeData: if(work_page->work_thread->localData.waitTimeCount) { Sent.Db2 = 1; quint16 timesec = work_page->work_thread->localData.waitTimeCount; Sent.Db3 = timesec/256; Sent.Db4 = timesec%256; } else if(((work_page->work_thread->localData.SysWorkState == Charging)&&(recv.CMD == GetDischargeData)) ||((work_page->work_thread->localData.SysWorkState == Discharging)&&(recv.CMD == GetChargeData))) { Sent.Db2 = 2; } Sent.Len += getTestData(Sent.info); break; // case GetAdjustData: // Sent.Len += getAdjData(Sent.info); // break; case GetFileInfo: Sent.Len += getPageFileData(recv, Sent); break; case GetFile: Sent.Len += getFileSmallBlock(recv,Sent); break; case GetBattName: Sent.Len += getBattName(recv,Sent); break; case GetFileName: Sent.Len += getfileName(recv,Sent); break; case GetSelectFile: Sent.Len += getSelectFile(recv,Sent); break; case GetVersion: Sent.Len += getVersion(recv,Sent); default: break; } Sent.CRC = CRC16::CalCRC16(&Sent,Sent.Len); WriteFrameData(&Sent); } void SlaveCtrl::SlaveResponse(FRAME_DATA &recv,FRAME_DATA &Sent) { if(Sent.RecState == SUCCEED) { SlaveClearHeart();//任何有效指令都当作心跳指令 SlaveDisposeCMD(recv,Sent); } SlaveSentFrame(recv,Sent); } //--------------------------------------------------------------------- void SlaveCtrl::SlaveMode(FRAME_DATA &recv,FRAME_DATA &Sent) { if(ReadFrameData(recv,Sent) == true) { //qDebug("recv.CMD = %x",recv.CMD); SlaveResponse(recv,Sent); } } /******************************************************************************************/ bool SlaveCtrl::MasterSentFrame(MASTER_CMD cmd_data) { FRAME_DATA Sent; memset(&Sent,0,sizeof(Sent)); Sent.SYNCode = SYSCODE; Sent.CMD = cmd_data.CMD; Sent.Len = 18; switch (cmd_data.CMD) { case Heartbea: case ExitSlave: break; case EnterSlave: Sent.RecState = 1; break; case GetDischargeParam: case GetChargeParam: case GetCycleParam: Sent.Db1 = cmd_data.Cid1; break; case SetDischargeParam: case SetChargeParam: case SetCycleParam: Sent.Db1 = cmd_data.Cid1; //Sent.info = (quint8 *)&testParam; getTestCommParam(work_page->test_param_xml,Sent.info); // memcpy(Sent.info,&testParam,sizeof()); Sent.Len += sizeof(COMM_TEST_PARAM); break; case GetBattName: case GetFileName: case GetSelectFile: case GetCellData: case GetDischargeData: case GetChargeData: case GetAdjustData: case StartCharge: case PauseCharge: case Adjust_StartDischarge: case Adjust_StartCharge: case Adjust_Stop: case StopDischarge: case StopCharge: case ChangedBatt: case DelBatt: case ClearAlarm: case StartCycle: case PauseCycle: case StopCycle: break; case NewBatt: memcpy(Sent.info,work_page->batteryName.toUtf8().data(),work_page->batteryName.toUtf8().length()); Sent.Len += work_page->batteryName.toUtf8().length(); break; case GetFileInfo: Sent.Db1 = cmd_data.Cid1; break; case GetFile: Sent.RecState = cmd_data.RecState; Sent.type = cmd_data.Cid1; Sent.workState = cmd_data.Cid2; Sent.Alarm = cmd_data.Alarm; break; case StartDischarge: case PausetDischarge: Sent.RecState = cmd_data.Cid1; break; case SetAdjustParm: Sent.RecState = cmd_data.Cid1; Sent.type = cmd_data.Cid2; Sent.workState = cmd_data.Alarm; break; case EnterHome: Sent.RecState = cmd_data.RecState; break; default: break; } Sent.CRC = CRC16::CalCRC16(Sent.info, Sent.Len); return WriteFrameData(&Sent); } void SlaveCtrl::MasterDisposeCMD(FRAME_DATA &recv) { work_page->work_thread->localData.master_data.Interface = recv.type; work_page->work_thread->localData.master_data.workState = recv.workState; work_page->work_thread->localData.master_data.Alarm = recv.Alarm; work_page->work_thread->localData.master_data.heart_cnt = 0; if(recv.RecState == SLAVEMODE_ERR) { work_page->work_thread->localData.master_data.Enter_ctrl = 0; return; } if(work_page->work_thread->localData.SysWorkState == WorkStopped) { if(work_page->work_thread->localData.master_data.workState == Discharging) { if(master_cmd.count() == 0) setMasterCmd(SlaveCtrl::StopDischarge); } } switch (recv.CMD) { case Heartbea: //work_page->work_thread->localData.master_data.heart_cnt = 0; //work_page->work_thread->localData.master_data.battname = QString::fromUtf8((const char *)recv.info,recv.Len-18); break; case ExitSlave: work_page->work_thread->localData.master_data.Enter_ctrl = 0; break; case EnterSlave: work_page->work_thread->localData.master_data.Enter_ctrl = 1; break; case GetBattName: case GetFileName: case GetSelectFile: case StartDischarge: case PausetDischarge: case StartCharge: case PauseCharge: case Adjust_StartDischarge: case Adjust_StartCharge: case Adjust_Stop: case SetAdjustParm: case SetDischargeParam: case SetChargeParam: case SetCycleParam: case GetDischargeParam: case GetChargeParam: case GetCycleParam: case StartCycle: case PauseCycle: case StopCycle: break; case GetCellData: if((quint16)(recv.Len-18) <= sizeof(MON_DATA)) { memcpy(&work_page->work_thread->localData.master_data.Cell_data,recv.info,recv.Len-18); } break; case GetDischargeData: case GetChargeData: if((quint16)(recv.Len-18) <= sizeof(TEST_DATA)) { memcpy(&work_page->work_thread->localData.master_data.test_data,recv.info,recv.Len-18); } break; case GetAdjustData: if((quint16)(recv.Len-18) <= sizeof(ADJ_DATA)) { memcpy(&work_page->work_thread->localData.master_data.adj_data,recv.info,recv.Len-18); } break; case GetFileInfo: case GetFile: case EnterHome: case StopDischarge: case StopCharge: case NewBatt: case ChangedBatt: case DelBatt: case ClearAlarm: break; default: break; } } void SlaveCtrl::MasterMode(FRAME_DATA &recv, FRAME_DATA &Sent) { if(waitRecvCnt) { --waitRecvCnt; if(ReadFrameData(recv,Sent) == true) { waitRecvCnt = 0; if(Sent.RecState == SUCCEED) { MasterDisposeCMD(recv); } } //qDebug("----%d",waitRecvCnt); } else { if(master_cmd.count() > 0) { if(MasterSentFrame(master_cmd.first()) == true) { waitRecvCnt = 5; master_cmd.removeFirst(); } } else if(work_page->work_thread->localData.master_data.Enter_ctrl) { setMasterCmd(GetDischargeData); } else { ReadFrameData(recv,Sent); } } } void SlaveCtrl::setMasterCmd(CMD_TYPE CMD, quint8 status, quint8 Cid1, quint8 Cid2,quint8 arm) { MASTER_CMD temp; temp.CMD = CMD; temp.RecState = status; temp.Cid1 = Cid1; temp.Cid2 = Cid2; temp.Alarm = arm; master_cmd.append(temp); } void SlaveCtrl::setTestCommParam(TEST_PARAM_XML &test_param,void *comm_param) { if(PageType == IDCE48CT) test_param.test_mode = OFFline_working; else if(PageType == FBI48CT) test_param.test_mode = ONline_working; else test_param.test_mode = ((COMM_TEST_PARAM *)comm_param)->test_mode; test_param.acstop_op = ((COMM_TEST_PARAM *)comm_param)->acstop_op; test_param.nominal_cap = ((COMM_TEST_PARAM *)comm_param)->nominal_cap; test_param.hourly_rate = ((COMM_TEST_PARAM *)comm_param)->hourly_rate; if(((COMM_TEST_PARAM *)comm_param)->preset_cur>=MinCur) test_param.preset_cur = ((COMM_TEST_PARAM *)comm_param)->preset_cur; else test_param.preset_cur = MinCur; test_param.preset_cap = ((COMM_TEST_PARAM *)comm_param)->preset_cap; test_param.preset_time = ((COMM_TEST_PARAM *)comm_param)->preset_time; test_param.mon_lower = ((COMM_TEST_PARAM *)comm_param)->mon_lower; test_param.group_lower = ((COMM_TEST_PARAM *)comm_param)->group_lower; test_param.mon_number = ((COMM_TEST_PARAM *)comm_param)->mon_number; test_param.group_number = ((COMM_TEST_PARAM *)comm_param)->group_number; test_param.lower_number = ((COMM_TEST_PARAM *)comm_param)->lower_number; test_param.mon_vol = ((COMM_TEST_PARAM *)comm_param)->mon_vol; if(PageType == FBO48CT || TYPE_FBI_10480 || TYPE_FBI_4548 || TYPE_FBI_20240) test_param.onlinevol_lowlimit = ((COMM_TEST_PARAM *)comm_param)->Reserved[0]; else test_param.onlinevol_lowlimit = onlinevollow; test_param.booster_ceiling = ((COMM_TEST_PARAM *)comm_param)->Reserved[1]; test_param.charge_limit = ((COMM_TEST_PARAM *)comm_param)->chrg_curr; test_param.temp_High = ((COMM_TEST_PARAM *)comm_param)->chrg_temp; test_param.discharge_mode = ((COMM_TEST_PARAM *)comm_param)->dischg_mode; test_param.preset_power = ((COMM_TEST_PARAM *)comm_param)->pre_power; if(test_param.group_number*test_param.mon_number > 300) test_param.mon_number = 300/test_param.group_number; if(test_param.group_number>4) test_param.group_number = 4; if(test_param.group_number*test_param.mon_number > 300) test_param.mon_number = 300/test_param.group_number; if(test_param.lower_number<=0) test_param.lower_number = 1; if(test_param.preset_time<=0) test_param.preset_time = 1; if(!(test_param.mon_vol == 20 || test_param.mon_vol == 40 || test_param.mon_vol == 60 || test_param.mon_vol == 120 || test_param.mon_vol == 12)) { test_param.mon_vol = work_page->test_param_xml.mon_vol; } } void SlaveCtrl::getTestCommParam(TEST_PARAM_XML &test_param, void *comm_param) { memset(comm_param,0x00,sizeof(COMM_TEST_PARAM)); ((COMM_TEST_PARAM *)comm_param)->test_mode = test_param.test_mode; ((COMM_TEST_PARAM *)comm_param)->acstop_op = test_param.acstop_op; ((COMM_TEST_PARAM *)comm_param)->nominal_cap = test_param.nominal_cap; ((COMM_TEST_PARAM *)comm_param)->hourly_rate = test_param.hourly_rate; ((COMM_TEST_PARAM *)comm_param)->preset_cur = test_param.preset_cur; ((COMM_TEST_PARAM *)comm_param)->preset_cap = test_param.preset_cap; ((COMM_TEST_PARAM *)comm_param)->preset_time = test_param.preset_time; ((COMM_TEST_PARAM *)comm_param)->mon_lower = test_param.mon_lower; ((COMM_TEST_PARAM *)comm_param)->group_lower = test_param.group_lower; ((COMM_TEST_PARAM *)comm_param)->mon_number = test_param.mon_number; ((COMM_TEST_PARAM *)comm_param)->group_number = test_param.group_number; ((COMM_TEST_PARAM *)comm_param)->lower_number = test_param.lower_number; ((COMM_TEST_PARAM *)comm_param)->mon_vol = test_param.mon_vol; ((COMM_TEST_PARAM *)comm_param)->Reserved[0] = test_param.onlinevol_lowlimit; ((COMM_TEST_PARAM *)comm_param)->Reserved[1] = test_param.booster_ceiling; ((COMM_TEST_PARAM *)comm_param)->chrg_curr = test_param.charge_limit; ((COMM_TEST_PARAM *)comm_param)->chrg_temp = test_param.temp_High; ((COMM_TEST_PARAM *)comm_param)->dischg_mode = test_param.discharge_mode; ((COMM_TEST_PARAM *)comm_param)->pre_power = test_param.preset_power; } void SlaveCtrl::dataReceived() { QByteArray buffer; //读取缓冲区数据 if(ServerFlag) buffer = tcpSocket->readAll(); else if(ClientFlag) buffer = tcpClient->readAll(); // qDebug()<isListening()|| ServerFlag || tcpServer->hasPendingConnections()) IF_CLOSEServer = true; qDebug()<setMaxPendingConnections(1); tcpSocket = new QTcpSocket(); tcpClient = new QTcpSocket(); Restartlisten(); bool timeOut = true; while(true) { if(work_page->work_thread->localData.tcp_ctrl.mode==0)//服务端 { if(!tcpServer->isListening())//开启监听 tcpServer->listen(QHostAddress::Any, 6666); if(tcpServer->waitForNewConnection(5000, &timeOut)&&(!IF_CLOSEServer)) { tcpSocket = tcpServer->nextPendingConnection(); if(NULL != tcpSocket) { ServerFlag = 1; while(1) { if(tcpSocket->waitForReadyRead(30000)&&(!IF_CLOSEServer)) { dataReceived(); } else { work_page->work_thread->localData.tcp_ctrl.heart_cnt = 0; work_page->work_thread->localData.tcp_ctrl.Enter_ctrl = 0; break; } } } } ServerFlag = 0; IF_CLOSEServer = false; tcpSocket->close(); tcpServer->close(); msleep(500); } else//客户端 { tcpClient->connectToHost(ClienthostName,Clientport); if(tcpClient->waitForConnected(5000)&&(!IF_CLOSEClient)) { if(NULL != tcpClient) { ClientFlag = 1; while(1) { if(tcpClient->waitForReadyRead(30000)&&(!IF_CLOSEClient)) { dataReceived(); } else { work_page->work_thread->localData.tcp_ctrl.heart_cnt = 0; work_page->work_thread->localData.tcp_ctrl.Enter_ctrl = 0; break; } } } } ClientFlag = 0; IF_CLOSEClient = false; tcpClient->close(); msleep(500); } } } //***********************************************************************************