Przeglądaj źródła

Z991239-968 #comment 上传DeviceControl的改动

gifur 5 lat temu
rodzic
commit
94e072ba11

+ 3 - 0
Module/include/EventCode.h

@@ -66,6 +66,9 @@ static const char* Device_Type_Table[] = {
 #define ERR_SYSTEMCUSTOMIZATION_LOAD_DLL             0x10B10007  //加载DLL错误
 /*----SystemCustomization--modify--by--LZM--at--2020/4/8----*/
 
+#define EVENT_MOD_DOWNLOAD_STARTSYNC			0x10500032		// 开始同步
+#define EVENT_MOD_DOWNLOAD_SYNCHRONIZED			0x10500031		// 完成同步
+
 /*----MaintainWatcher--modify--by--LZM--at--2020/4/8----*/
 #define EVENT_UKEY_INSERTED  						 0x21000001  //维护证书插入,检测到维护证书插入
 #define EVENT_UKEY_LOW_LEVEL  						 0x21000002  //具有维护权,插入的维护证书具有本机器的维护权限,用于驱动本地维护状态

+ 430 - 314
Module/mod_CustMngrAuth/CustMngrAuthFSM.cpp

@@ -16,6 +16,7 @@ using std::string;
 const int UPDATEINTERNAL = 10*60*1000;	//query data from branch server internal, 10min
 const int CONNECTINTERNAL = 30*1000;	//connect branch server internal, 30s
 const int FINGERNUM = 8;				//suuport max register finger num
+const int COLLECT_TIMES = 3;			//press finger times
 
 #define RUNINFOFILE "CustMngrAuth.ini"
 #define RUNINFOFILE_BAK "CustMngrAuth_bak.ini"
@@ -98,14 +99,13 @@ unsigned int CCustMngrAuthFSM::s2_on_event(FSMEvent* pEvt)
 			AuthorizeStartEvent *authorEvt = dynamic_cast<AuthorizeStartEvent*>(pEvt);
 			if (authorEvt->ctx->Req.TimeLimit <= 0)
 			{
-				Dbg("ERROR: receive timelimit lessequal than zero. ctx->Answer(error_Param)");
 				AuthorizeFinishedEvent *e = new AuthorizeFinishedEvent();
 				e->ctx = authorEvt->ctx;
 				e->param1 = Error_Param;
 				this->PostEventFIFO(e);
 				break;
 			}
-			//状态机流程会耗一些时间,这里要比前端传过来的时间小一些,及时返回给前端
+			//time here should be less than the web
 			m_TimeLimit = (authorEvt->ctx->Req.TimeLimit - 3) * 1000; 
 			m_bCancelAuthorize = false;
 			
@@ -117,7 +117,6 @@ unsigned int CCustMngrAuthFSM::s2_on_event(FSMEvent* pEvt)
 				m_ctx = authorEvt->ctx;
 			}
 			
-			//起指纹匹配线程
 			MatchFingerPrintTask *matchTask = new MatchFingerPrintTask(this);
 			matchTask->ctx = authorEvt->ctx;
 			GetEntityBase()->GetFunction()->PostThreadPoolTask(matchTask);
@@ -204,7 +203,7 @@ unsigned int CCustMngrAuthFSM::s3_on_event(FSMEvent* pEvt)
 			Dbg("Checking m_authCtx and answer ctx");
 			if(m_csMachineType.Compare("RVC.PAD", true))
 			{
-				//非PAD才去关闭U口
+				//close usb when device is not pad
 				SwitchUSB(false);
 			}
 			if (authorEvt->param1 == 0)
@@ -369,10 +368,7 @@ string CCustMngrAuthFSM::ClearStringSpaceHeadTail(string& line)
 bool CCustMngrAuthFSM::ReadDataIntoMemory(bool& bHasData)
 {
 	LOG_FUNCTION();
-	CSmartPointer<IConfigInfo> spConfig;
-	ErrorCodeEnum eErr;
 
-	CSimpleStringA strPath;
 	CSimpleStringA runInfoFile;
 	runInfoFile = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "runcfg" SPLIT_SLASH_STR RUNINFOFILE
 										, (const char*)m_RunInfoPath);
@@ -392,7 +388,8 @@ bool CCustMngrAuthFSM::ReadDataIntoMemory(bool& bHasData)
 		if(!tempLine.compare("[UpdateTime]") || string::npos != tempLine.find("UpdateTime")
 			|| !tempLine.compare("[LatestTime]") || string::npos != tempLine.find("LatestTime") 
 			|| !tempLine.compare("[FingerInfo]") || !tempLine.compare("[FaceInfo]")
-			|| string::npos != tempLine.find("FaceInfo1") || string::npos != tempLine.find("FaceInfo2")){
+			|| string::npos != tempLine.find("FaceInfo1") || string::npos != tempLine.find("FaceInfo2"))
+		{
 				continue;
 		}
 		string::size_type pos = tempLine.find("=");
@@ -446,22 +443,22 @@ bool CCustMngrAuthFSM::ReadDataIntoMemory(bool& bHasData)
 	return true;
 }
 
-void CCustMngrAuthFSM::TransDataFromServer(CAutoArray<CSimpleStringA> &dataArray
-										 , CSimpleStringA latestTime
-										 , bool& bResumeTrans
-										 , bool bIsFirstTimeQueryData)
+ErrorCodeEnum CCustMngrAuthFSM::ReceiveDataFromServer(CAutoArray<CSimpleStringA> &dataArray, RunInfoParams runInfoParam)
 {
 	LOG_FUNCTION();
-	int transTime = 0;
-	char currAgent[16]="";
-	char branchID[16]="";
+	char currAgent[16];
+	char branchID[16];
+	memset(currAgent, 0, sizeof(currAgent));
+	memset(branchID, 0, sizeof(currAgent));
+	bool bResumeTrans = true;
+	ErrorCodeEnum errCode = Error_Unexpect;
+
 	while(bResumeTrans)
 	{
-		transTime++;
-		if (bIsFirstTimeQueryData)
+		if (runInfoParam.IsFirstTimeQueryData)
 			m_pConnection->SendFeatReq(currAgent, branchID);
 		else
-			m_pConnection->SendFeatReq(currAgent, branchID, (const char*)latestTime);
+			m_pConnection->SendFeatReq(currAgent, branchID, (const char*)runInfoParam.LatestTime);
 
 		ResetEvent(m_pConnection->m_hPkgAnswer);
 		DWORD dw = WaitForSingleObject(m_pConnection->m_hPkgAnswer, 20000); //10->20  20200430@liuwentao
@@ -477,33 +474,42 @@ void CCustMngrAuthFSM::TransDataFromServer(CAutoArray<CSimpleStringA> &dataArray
 			break;
 		}
 		ResetEvent(m_pConnection->m_hPkgAnswer);
+
 		if (m_pConnection->m_reply == NULL)
 		{
 			Dbg("m_reply still null after m_hPkgAnswer handled");
 			break;
-		}else{
-			if (m_pConnection->m_GetErrMsg)
-			{
-				Dbg("get error message, check dbg log");
-				break;
-			}
-			if (m_pConnection->m_reply->ResultCode == 2)
+		}
+		if (m_pConnection->m_GetErrMsg)
+		{
+			Dbg("get error message, check dbg log");
+			break;
+		}
+		if (m_pConnection->m_reply->ResultCode == 2)
+		{
+			Dbg("remote server uninitialized yet, unable to excute query");
+			break;
+		}else {
+			if (m_pConnection->m_reply->ResultCode == 0)
 			{
-				Dbg("remote server uninitialized yet, unable to excute query");
-				break;
-			}else{
-				if (m_pConnection->m_reply->ResultCode == 0)
-				{
-					Dbg("All package downloaded from branch server.");
-					bResumeTrans = false;
-				}
-				memcpy(currAgent, m_pConnection->m_reply->CurrentAgent, 16);
-				memcpy(branchID, m_pConnection->m_reply->BranchID, 16);
-				CSimpleStringA jbuf(m_pConnection->m_reply->Data, m_pConnection->m_jsonLen);
-				dataArray.Append(&jbuf,0,1);
+				Dbg("All package downloaded from branch server.");
+				bResumeTrans = false;
+				errCode = Error_Succeed;
 			}
+			memcpy(currAgent, m_pConnection->m_reply->CurrentAgent, 16);
+			memcpy(branchID, m_pConnection->m_reply->BranchID, 16);
+			CSimpleStringA jbuf(m_pConnection->m_reply->Data, m_pConnection->m_jsonLen);
+			dataArray.Append(&jbuf, 0, 1);
 		}
 	}
+
+	if (bResumeTrans)
+		Dbg("some errors happened, check the related log");
+
+	if (dataArray.GetCount() <= 0)
+		Dbg("query no data from branchServer.");
+
+	return errCode;
 }
 
 bool CCustMngrAuthFSM::BackupFile(CSimpleStringA srcFile, CSimpleStringA dstFile)
@@ -556,205 +562,295 @@ void CCustMngrAuthFSM::InitBeforeUpdateData()
 	}
 }
 
-void CCustMngrAuthFSM::FeatureUpdate()
+ErrorCodeEnum CCustMngrAuthFSM::LoadRunConfig(CSmartPointer<IConfigInfo>& spConfig)
 {
-	LOG_FUNCTION();
-	//when start entity, read data into memory
-	InitBeforeUpdateData();
-	
-	while(1)
-	{		
-		int tWait = UPDATEINTERNAL;
-		int connectFailedTimes = 0;
-		ErrorCodeEnum eErr;
-		CSmartPointer<IConfigInfo> spConfig;
-		CAutoArray<CSimpleStringA> transArray;
-		m_pConnection = new FeatureUpdateConn(m_pEntity, this);
-		//connect branch server
-		if (m_pConnection->ConnectFromCentralSetting() && m_pConnection->IsConnectionOK()){
-			connectFailedTimes = 0;
-			tWait = UPDATEINTERNAL;
-			bool resumeTrans = true;
-			bool isFirstTimeQueryData = false;
-
-			EnterCriticalSection(&m_cs);//临时锁一下运行时,防止在写入
-			eErr = GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfig);
-			if (eErr != Error_Succeed){
-				Dbg("Open runcfg file failed before query data.");
-				LogError(Severity_High, Error_Unexpect
-						, LOG_ERR_CUSTMNGRAUTH_OPEN_RUNINFO_FAILED_UPDATE
-						, "open runcfg failed before query data.");
-				LeaveCriticalSection(&m_cs);
-				goto Err;
-			}
+	ErrorCodeEnum errCode = Error_Succeed;
 
-			CSimpleStringA latestTime(""), updateTime("");//latestTime表示最上一次传来的最新时间,updateTime表示更新日期(是否要做全量清除更新)
-			spConfig->ReadConfigValue("LatestTime", "LatestTime", latestTime);
-			spConfig->ReadConfigValue("UpdateTime", "UpdateTime", updateTime);
-			LeaveCriticalSection(&m_cs);
-			//query current time
-			CSimpleStringA newTime = GetCurrentDate();
+	errCode = GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfig);
 
-			//当前日期大于文件中日期时,需要做全量更新
-			if (updateTime.GetLength() <= 0
-				|| (updateTime.GetLength() > 0 && CompareTime(newTime, updateTime) > 0)
-				|| latestTime.GetLength() <= 0)
-			{
-				isFirstTimeQueryData = true;
-			}
+	if (errCode != Error_Succeed)
+	{
+		Dbg("Open runcfg file failed before query data.");
+		LogError(Severity_High, Error_Unexpect
+				, LOG_ERR_CUSTMNGRAUTH_OPEN_RUNINFO_FAILED_UPDATE
+				, "open runcfg failed before query data.");
+	}
+	return errCode;
+}
 
-			//多次续传从分行服务获取数据(增量更新时,大于latestTime的才传下来)
-			TransDataFromServer(transArray, latestTime, resumeTrans, isFirstTimeQueryData);
+void CCustMngrAuthFSM::InitTimeParams(RunInfoParams& runInfoParam, CSmartPointer<IConfigInfo> &spConfig)
+{
+	ErrorCodeEnum errCode = Error_Succeed;
 
-			if(resumeTrans){
-				Dbg("ERROR: The last update of feature ended with resumetrans as true, might be timeout or some errors happened");
-				goto Err;
-			}
-			if (transArray.GetCount() <= 0){
-				Dbg("query no data from branchServer.(exact no data or the sql was deleted)");
-				goto Err;
-			}
-			//续传成功结束,解析jbuf数组并写入本地
-			Dbg("Transmission finished successfully. Ready to decode json data and write into runcfg");
-
-			//写入文件前,先判断是否已存在CustMngrAuth.ini文件,若不存在则直接写入,若存在,则先备份该文件
-			CSimpleStringA srcFile(true);
-			CSimpleStringA backupFile(true);
-			srcFile = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "runcfg" SPLIT_SLASH_STR RUNINFOFILE
-											, (const char*)m_RunInfoPath);
-			backupFile = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "runcfg" SPLIT_SLASH_STR RUNINFOFILE_BAK
-											, (const char*)m_RunInfoPath);
-
-			EnterCriticalSection(&m_cs);
-			if(!BackupFile(srcFile, backupFile)){
-				Dbg("Backup runinfo file failed.");
-			}
-			if (isFirstTimeQueryData)
-			{
-				//首次更新,需清除数据,全量写入,并更新时间
-				ofstream fileOut((const char*)srcFile, ios::trunc);
-				fileOut.close();
-			}
+	runInfoParam.LatestTime = "";
+	runInfoParam.UpdateTime = "";
+	CSimpleStringA latestTime(""), updateTime("");
+	spConfig->ReadConfigValue("LatestTime", "LatestTime", latestTime);
+	spConfig->ReadConfigValue("UpdateTime", "UpdateTime", updateTime);
 
-			eErr = GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfig);
-			if (eErr != Error_Succeed)
-			{
-				RecoverFile(srcFile, backupFile);//有失败情况,恢复原文件
-				Dbg("ERROR: Open runcfg failed with %s", SpStrError(eErr));
-				LeaveCriticalSection(&m_cs);
-				goto Err;
-			}
+	//query current time
+	CSimpleStringA newTime = GetCurrentDate();
 
-			spConfig->WriteConfigValue("UpdateTime", "UpdateTime", (const char*)newTime);
-			if (isFirstTimeQueryData){
-				//首次全量更新或存量无LatestTime字段
-				spConfig->WriteConfigValue("LatestTime", "LatestTime", "");
-			}
-			map<CSimpleStringA, FeatureData*> tempFeature;//如果是全量更新,需要更新后全量传给m_featureData
-			CSimpleStringA maxUpdateTime = latestTime;
-			for(int transTime = 0; transTime < transArray.GetCount(); ++transTime)
-			{
-				Json::Value root;
-				Json::Reader reader;
-				Json::FastWriter writer;
-				CSimpleStringA transBuffer = transArray[transTime];//一次传输受大小限制,只能有3~4条
-				if (reader.parse((const char*)transBuffer, root)){
-					for (int i = 0; i < (int)root.size(); ++i){
-						Json::Value jsonFingerInfo;
-						FeatureData *fd = new FeatureData();
-						fd->FingerIDArray.Init(FINGERNUM);
-						fd->FingerIDLenArray.Init(FINGERNUM);
-						for(int fingerIndex = 0; fingerIndex < FINGERNUM; ++fingerIndex){
-							char FingerID[20];//运行时文件是"FingerID"
-							char fingerId[20];//分行服务是"fingerId"    二者不一致,历史遗留
+	//当前日期大于文件中日期时,需要做全量更新
+	if (updateTime.GetLength() <= 0
+		|| (updateTime.GetLength() > 0 && CompareTime(newTime, updateTime) > 0)
+		|| latestTime.GetLength() <= 0)
+	{
+		runInfoParam.IsFirstTimeQueryData = true;
+	}
+}
+
+ErrorCodeEnum CCustMngrAuthFSM::InitBeforeQueryData(RunInfoParams& runInfoParam, CSmartPointer<IConfigInfo>& spConfig)
+{
+	ErrorCodeEnum errCode = Error_Succeed;
+
+	EnterCriticalSection(&m_cs);//临时锁一下运行时,防止在写入
+
+	errCode = LoadRunConfig(spConfig);
+	if (Error_Succeed != errCode)
+	{
+		LeaveCriticalSection(&m_cs);
+		return errCode;
+	}
+
+	InitTimeParams(runInfoParam, spConfig);
+	LeaveCriticalSection(&m_cs);
+
+	return errCode;
+}
+
+ErrorCodeEnum CCustMngrAuthFSM::BackupBeforeWriteData(RunInfoParams& runInfoParam, CSmartPointer<IConfigInfo>& spConfig)
+{
+	ErrorCodeEnum errCode = Error_Succeed;
+
+	runInfoParam.SrcFile = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "runcfg" SPLIT_SLASH_STR RUNINFOFILE
+												, (const char*)m_RunInfoPath);
+	runInfoParam.BackupFile = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "runcfg" SPLIT_SLASH_STR RUNINFOFILE_BAK
+												, (const char*)m_RunInfoPath);
+
+	EnterCriticalSection(&m_cs);
+	if (!BackupFile(runInfoParam.SrcFile, runInfoParam.BackupFile))
+		Dbg("Backup runinfo file failed.");
+	
+	if (runInfoParam.IsFirstTimeQueryData)
+	{
+		//首次更新,需清除数据,全量写入,并更新时间
+		ofstream fileOut((const char*)runInfoParam.SrcFile, ios::trunc);
+		fileOut.close();
+	}
+
+	errCode = GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfig);
+	if (errCode != Error_Succeed)
+	{
+		Dbg("error: open runcfg failed with errCode(%s)", SpStrError(errCode));
+		RecoverFile(runInfoParam.SrcFile, runInfoParam.BackupFile); // if backup fail, recover
+		LeaveCriticalSection(&m_cs);
+	}
+
+	spConfig->WriteConfigValue("UpdateTime", "UpdateTime", (const char*)runInfoParam.CurrentTime);
+	if (runInfoParam.IsFirstTimeQueryData)
+	{
+		spConfig->WriteConfigValue("LatestTime", "LatestTime", "");
+	}
+	return errCode;
+}
+
+ErrorCodeEnum CCustMngrAuthFSM::ProcessFeatureData(JsonParams& jsonParam, TempFeatureData& tmpFeatureData
+										, RunInfoParams runinfoParam, CSmartPointer<IConfigInfo>& spConfig)
+{
+	ErrorCodeEnum errCode = Error_Succeed;
+	FeatureData* fd = new FeatureData();
+	fd->FingerIDArray.Init(FINGERNUM);
+	fd->FingerIDLenArray.Init(FINGERNUM);
+	char FingerID[20];//runinfo file is named "FingerID"
+	char fingerId[20];//branchserver is named "fingerId" , history bug
+
+	for (int fingerIndex = 0; fingerIndex < FINGERNUM; ++fingerIndex)
+	{
+		ZeroMemory(FingerID, sizeof(FingerID));
+		ZeroMemory(fingerId, sizeof(fingerId));
 #ifdef RVC_OS_WIN
-							_snprintf_s(FingerID, 10, "FingerID%d", fingerIndex + 1);
-							_snprintf_s(fingerId, 10, "fingerId%d", fingerIndex + 1);
+		_snprintf_s(FingerID, 10, "FingerID%d", fingerIndex + 1);
+		_snprintf_s(fingerId, 10, "fingerId%d", fingerIndex + 1);
 #else
-							snprintf(FingerID, 10, "FingerID%d", fingerIndex + 1);
-							snprintf(fingerId, 10, "fingerId%d", fingerIndex + 1);
+		snprintf(FingerID, 10, "FingerID%d", fingerIndex + 1);
+		snprintf(fingerId, 10, "fingerId%d", fingerIndex + 1);
 #endif // RVC_OS_WIN
-							jsonFingerInfo[FingerID] = root[i][fingerId].asCString();
-							fd->FingerIDArray[fingerIndex] = CSimpleStringA(root[i][fingerId].asCString());
-							fd->FingerIDLenArray[fingerIndex] = fd->FingerIDArray[fingerIndex].GetLength();
-						}
-
-						//插入临时map
-						if(tempFeature.find(CSimpleStringA(root[i]["customerID"].asCString())) == tempFeature.end()){//不存在,直接插入
-							tempFeature[CSimpleStringA(root[i]["customerID"].asCString())] = fd;
-						}else{//已存在,需要释放原有内存
-							auto tempFD = tempFeature[CSimpleStringA(root[i]["customerID"].asCString())];
-							tempFeature[CSimpleStringA(root[i]["customerID"].asCString())] = fd;
-							if(tempFD){
-								delete tempFD;
-								tempFD = NULL;
-							}
-						}
-
-						CSimpleStringA tempMaxUpdateTime = CSimpleStringA(root[i]["updateTime"].asCString());
-						maxUpdateTime = GetMaxTime(maxUpdateTime, tempMaxUpdateTime);
-
-						int fingerDataState = root[i]["state"].asCString()[0] - '0';
-						if (fingerDataState == 0){
-							CSimpleStringA jsonFingerStr(writer.write(jsonFingerInfo).c_str());
-							int jlen = jsonFingerStr.GetLength()-1;
-							char *jstr = new char[jlen+1];
-							memcpy(jstr, jsonFingerStr.GetData(), jlen);
-							jstr[jlen]= '\0';
-
-							//不做这步处理的话runcfg里faceinfo节不同customerID间没有换行,fingerinfo节本来有,但以防万一也做同样处理。
-							eErr = spConfig->WriteConfigValue((const char*)m_FingerSection, root[i]["customerID"].asCString(), jstr);
-							delete []jstr;
-							if (eErr != Error_Succeed){
-								//如果写入失败,则将原文件恢复
-								RecoverFile(srcFile, backupFile);
-								LeaveCriticalSection(&m_cs);
-								goto Err;
-							}
-						}else if (fingerDataState == 2){
-							Dbg("state(2): customer %s is currently unavailable.", root[i]["customerID"].asCString());
-							spConfig->WriteConfigValue((const char*)m_FingerSection, root[i]["customerID"].asCString(), "");
-						}else{
-							Dbg("ERROR: unexpectedly customer(%s)'s state is either 0 or 2", root[i]["customerID"].asCString());
-						}
-					}
-				}else{
-					Dbg("ERROR: fail to parse transArray[%d]!", transTime);
-					//LogError(Severity_High, Error_Unexpect, LOG_ERR_CUSTMNGRAUTH_FEATUPDATE_WRITE_FAILED, "Failed to write fingerprint feature into runcfg.");
-					LeaveCriticalSection(&m_cs);
-					goto Err;
+		jsonParam.FingerInfo[FingerID] = jsonParam.Root[jsonParam.Index][fingerId].asCString();
+		fd->FingerIDArray[fingerIndex] = CSimpleStringA(jsonParam.Root[jsonParam.Index][fingerId].asCString());
+		fd->FingerIDLenArray[fingerIndex] = fd->FingerIDArray[fingerIndex].GetLength();
+	}
+
+	CSimpleStringA customerID = CSimpleStringA(jsonParam.Root[jsonParam.Index]["customerID"].asCString());
+	if (tmpFeatureData.tmpFeatureMap.find(customerID) == tmpFeatureData.tmpFeatureMap.end())
+	{
+		// if not exist , insert directly
+		tmpFeatureData.tmpFeatureMap[customerID] = fd;
+	}else {
+		auto tempFD = tmpFeatureData.tmpFeatureMap[customerID];
+		tmpFeatureData.tmpFeatureMap[customerID] = fd;
+		if (tempFD)
+		{
+			delete tempFD;
+			tempFD = NULL;
+		}
+	}
+
+	CSimpleStringA tempMaxUpdateTime = CSimpleStringA(jsonParam.Root[jsonParam.Index]["updateTime"].asCString());
+	tmpFeatureData.MaxUpdateTime = GetMaxTime(tmpFeatureData.MaxUpdateTime, tempMaxUpdateTime);
+
+	int fingerDataState = jsonParam.Root[jsonParam.Index]["state"].asCString()[0] - '0';
+	if (fingerDataState == 0) 
+	{
+		Json::FastWriter writer;
+		CSimpleStringA jsonFingerStr(writer.write(jsonParam.FingerInfo).c_str());
+		int jlen = jsonFingerStr.GetLength() - 1;
+		char* jstr = new char[jlen + 1];
+		memcpy(jstr, jsonFingerStr.GetData(), jlen);
+		jstr[jlen] = '\0';
+
+		//不做这步处理的话runcfg里faceinfo节不同customerID间没有换行,fingerinfo节本来有,但以防万一也做同样处理。
+		errCode = spConfig->WriteConfigValue((const char*)m_FingerSection, customerID.GetData(), jstr);
+		delete[] jstr;
+		if (errCode != Error_Succeed)
+		{
+			//如果写入失败,则将原文件恢复
+			RecoverFile(runinfoParam.SrcFile, runinfoParam.BackupFile); 
+			LeaveCriticalSection(&m_cs);
+			errCode = Error_Unexpect;
+		}
+	}else if (fingerDataState == 2)
+	{
+		Dbg("state(2): customer %s is currently unavailable.", customerID.GetData());
+		spConfig->WriteConfigValue((const char*)m_FingerSection, customerID.GetData(), "");
+	}else {
+		Dbg("unexpected customer(%s)'s state is either 0 or 2", customerID.GetData());
+	}
+
+	return errCode;
+}
+
+ErrorCodeEnum CCustMngrAuthFSM::WriteData(RunInfoParams& runInfoParam
+										  , CAutoArray<CSimpleStringA>& dataArray
+										  , CSmartPointer<IConfigInfo>& spConfig)
+{
+	ErrorCodeEnum errCode = Error_Unexpect;
+	bool bExitLoop = false;
+
+	TempFeatureData tmpFeatureData;
+	ZeroMemory(&tmpFeatureData, sizeof(tmpFeatureData));
+	tmpFeatureData.MaxUpdateTime = runInfoParam.LatestTime;
+
+	for (int transTime = 0; transTime < dataArray.GetCount(); ++transTime)
+	{
+		Json::Value root;
+		Json::Reader reader;
+		CSimpleStringA transBuffer = dataArray[transTime];//一次传输受大小限制,只能有3~4条
+
+		if (reader.parse((const char*)transBuffer, root)) 
+		{
+			for (int i = 0; i < (int)root.size(); ++i) 
+			{
+				JsonParams jsonParam;
+				jsonParam.Root = root;
+				jsonParam.Index = i;
+				errCode = ProcessFeatureData(jsonParam, tmpFeatureData, runInfoParam, spConfig);
+				if (Error_Succeed != errCode)
+				{
+					bExitLoop = true;
+					break;
 				}
 			}
-			//数据写完,将最新时间更新到本地
-			if (maxUpdateTime.GetLength() > 0){
-				spConfig->WriteConfigValue("LatestTime", "LatestTime", (const char*)maxUpdateTime);
-			}
-			Dbg("updateNum=%d", tempFeature.size());
-			//更新数据到内存
-			UpdateDataIntoMemory(tempFeature, isFirstTimeQueryData);
+			if(bExitLoop)
+				break;
+		}else {
+			Dbg("ERROR: fail to parse transArray[%d]!", transTime);
+			//LogError(Severity_High, Error_Unexpect, LOG_ERR_CUSTMNGRAUTH_FEATUPDATE_WRITE_FAILED, "Failed to write fingerprint feature into runcfg.");
 			LeaveCriticalSection(&m_cs);
-		}else{
-			Dbg("ERROR: Fail to connect remote server! Try again in %d mm.", CONNECTINTERNAL);
-			connectFailedTimes++;
-			Dbg("connect time = %d", connectFailedTimes);
-			if(connectFailedTimes >= 60) //如果一直连不上,则30分钟抛一次告警
+			bExitLoop = true;
+			break;
+		}
+	}
+	if (bExitLoop)
+		return Error_Unexpect;
+
+	if (tmpFeatureData.MaxUpdateTime.GetLength() > 0) 
+	{
+		spConfig->WriteConfigValue("LatestTime", "LatestTime", tmpFeatureData.MaxUpdateTime.GetData());
+	}
+	Dbg("updateNum=%d", tmpFeatureData.tmpFeatureMap.size());
+	
+	UpdateDataIntoMemory(tmpFeatureData.tmpFeatureMap, runInfoParam.IsFirstTimeQueryData);
+	LeaveCriticalSection(&m_cs);
+
+	return Error_Succeed;
+}
+
+void CCustMngrAuthFSM::FeatureUpdate()
+{
+	LOG_FUNCTION();
+	InitBeforeUpdateData();
+	int waitInternal = UPDATEINTERNAL;
+	
+	while(true)
+	{				
+		do 
+		{
+			int connectFailedTimes = 0;
+			m_pConnection = new FeatureUpdateConn(m_pEntity, this);
+
+			if (m_pConnection->ConnectFromCentralSetting() && m_pConnection->IsConnectionOK())
 			{
-				LogWarn(Severity_High, Error_Unexpect
-						, LOG_ERR_CUSTMNGRAUTH_FEATUPDATE_CONNECT_FAILED
-						, "Connect branch server failed.");
 				connectFailedTimes = 0;
+				waitInternal = UPDATEINTERNAL;
+
+				ErrorCodeEnum errCode;
+				CSmartPointer<IConfigInfo> spConfig;
+				CAutoArray<CSimpleStringA> transArray;
+				RunInfoParams runInfoParam;
+				memset(&runInfoParam, 0, sizeof(runInfoParam));
+
+				errCode = InitBeforeQueryData(runInfoParam, spConfig);
+				if(errCode != Error_Succeed)
+					break;
+
+				errCode = ReceiveDataFromServer(transArray, runInfoParam);
+				if(errCode != Error_Succeed)
+					break;
+
+				errCode = BackupBeforeWriteData(runInfoParam, spConfig);
+				if(errCode != Error_Succeed)
+					break;
+
+				errCode = WriteData(runInfoParam, transArray, spConfig);
+				if(errCode != Error_Succeed)
+					break;
+			}else {
+				connectFailedTimes++;
+				Dbg("connect branchserver failed for %d times, try again in %d ms."
+					, connectFailedTimes, CONNECTINTERNAL);
+
+				if (connectFailedTimes >= 60) 
+				{
+					//30min give a warn
+					LogWarn(Severity_High, Error_Unexpect
+							, LOG_ERR_CUSTMNGRAUTH_FEATUPDATE_CONNECT_FAILED
+							, "Connect branch server failed.");
+					connectFailedTimes = 0;
+				}
+				waitInternal = CONNECTINTERNAL;
 			}
-			tWait = CONNECTINTERNAL;
-		}
-	Err:
-		if(m_pConnection){
+		} while (0);
+
+		if(m_pConnection)
+		{
 			m_pConnection->Close();
 			m_pConnection->DecRefCount();
 			m_pConnection = NULL;
 		}
 		Dbg("Feature-update processed, wait until next");
-		//等待tWait时间后,进行下一次请求更新
-		if (WaitForSingleObject(hStopUpdate, tWait) == WAIT_OBJECT_0)
+		//wait for next query
+		if (WaitForSingleObject(hStopUpdate, waitInternal) == WAIT_OBJECT_0)
 			break;
 	}
 }
@@ -788,7 +884,7 @@ void CCustMngrAuthFSM::UpdateDataIntoMemory(map<CSimpleStringA, FeatureData*> te
 	}
 }
 
-ErrorCodeEnum CCustMngrAuthFSM::InitBeforeMatch()
+ErrorCodeEnum CCustMngrAuthFSM::ConnectFingerPrintEntity()
 {
 	ErrorCodeEnum errCode = Error_Succeed;
 	m_pFingerPrint = new FingerPrintService_ClientBase(m_pEntity);
@@ -802,7 +898,7 @@ ErrorCodeEnum CCustMngrAuthFSM::InitBeforeMatch()
 			m_pFingerPrint = NULL;
 		}
 		
-		errCode = Error_Unexpect;	//TODO::give one other errCode
+		errCode = Error_NoTarget;	//TODO::give one other errCode
 	}
 	return errCode;
 }
@@ -984,7 +1080,7 @@ ErrorCodeEnum CCustMngrAuthFSM::AnalyzeMatchResult(MatchParams* matchParam, bool
 ErrorCodeEnum CCustMngrAuthFSM::MatchFingerPrint(SpReqAnsContext<CustMngrAuthService_StartAuthorize_Req, CustMngrAuthService_StartAuthorize_Ans>::Pointer ctx, bool& bStopAuthorize)
 {
 	LOG_FUNCTION();
-	ErrorCodeEnum errCode = InitBeforeMatch();
+	ErrorCodeEnum errCode = ConnectFingerPrintEntity();
 	if (errCode != Error_Succeed)
 		return errCode;
 
@@ -1049,54 +1145,51 @@ void CCustMngrAuthFSM::BroadcastGetFinger(int status)
 					, evt);	
 }
 
-ErrorCodeEnum CCustMngrAuthFSM::CollectFingerPrint(SpReqAnsContext<CustMngrAuthService_CollectFingerPrint_Req, CustMngrAuthService_CollectFingerPrint_Ans>::Pointer ctx, DWORD& dwUserErrCode)
+ErrorCodeEnum CCustMngrAuthFSM::CollectProcess(SpReqAnsContext<CustMngrAuthService_CollectFingerPrint_Req, CustMngrAuthService_CollectFingerPrint_Ans>::Pointer &ctx, DWORD& dwUserErrCode)
 {
-	LOG_FUNCTION();
-	ErrorCodeEnum eErr;
-	m_pFingerPrint = new FingerPrintService_ClientBase(GetEntityBase());
-	eErr = m_pFingerPrint->Connect();
-	if (eErr!= Error_Succeed)
-	{
-		m_pFingerPrint->SafeDelete();
-		m_pFingerPrint = NULL;
-		return Error_NoTarget;
-	}
-	//need to collect for 3 times
-	const int NUM_COLLECT = 3;
-	ctx->Ans.FingerImgs.Init(NUM_COLLECT);
-	CAutoArray<CSimpleStringA> imgPaths;
-	CSimpleStringA strPath;
-	imgPaths.Init(NUM_COLLECT);
-	m_pEntity->GetFunction()->GetPath("Dep", strPath);
+	ErrorCodeEnum errCode = Error_Succeed;
+
+	CAutoArray<CSimpleStringA> imgFullPaths;
+	imgFullPaths.Init(COLLECT_TIMES);
+	ctx->Ans.FingerImgs.Init(COLLECT_TIMES);
+	CSimpleStringA depPath;
+	m_pEntity->GetFunction()->GetPath("Dep", depPath);
 	int getImgNum = 0;
-	for(int i = 0; i < NUM_COLLECT; ++i){
+
+	for (int i = 0; i < COLLECT_TIMES; ++i) 
+	{
 		if (i)
 			std::this_thread::sleep_for(std::chrono::milliseconds(2000));
 
-		BroadcastPressFinger(i+1, true);//press finger
-
-		FingerPrintService_GetImageAndFeature_Req gifReq;
-		FingerPrintService_GetImageAndFeature_Ans gifAns;
-		gifReq.times = i+1;//the num from 1 start , 1/2/3
-
-		if (m_pFingerPrint == NULL || m_pFingerPrint->QuerySessionClosed()){
+		if (m_pFingerPrint == NULL || m_pFingerPrint->QuerySessionClosed()) 
+		{
 			Dbg("m_pFingerPrint is NULL or connection closed.");
-			return Error_NoTarget;
+			return errCode;
 		}
-		eErr = m_pFingerPrint->GetImageAndFeature(gifReq, gifAns, 16000, dwUserErrCode);//fingerprint entity loop duration is 15s
-		if (eErr == Error_Succeed){
+
+		BroadcastPressFinger(i + 1, true);//press finger
+
+		FingerPrintService_GetImageAndFeature_Req collecetReq;
+		FingerPrintService_GetImageAndFeature_Ans collecetAns;
+		collecetReq.times = i + 1;//the num from 1 start , 1/2/3
+		errCode = m_pFingerPrint->GetImageAndFeature(collecetReq, collecetAns, 16000, dwUserErrCode);//fingerprint entity loop duration is 15s
+		if (errCode == Error_Succeed)
+		{
+			BroadcastPressFinger(i + 1, false);//lift finger
+
 			getImgNum += 1;
-			BroadcastPressFinger(i+1, false);//lift finger
 			CBlob data;
-			CSimpleStringA tempFullPath;
-			tempFullPath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s"
-												, (const char*)strPath, (const char*)gifAns.imageName);
-			eErr = GetImgBlob(data, tempFullPath);
-			if (eErr != Error_Succeed){
+			imgFullPaths[i] = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s"
+				, (const char*)depPath, (const char*)collecetAns.imageName);
+			errCode = GetImgBlob(data, imgFullPaths[i]);
+
+			if (errCode != Error_Succeed) 
+			{
 				Dbg("Failed to load finger image.");
+				errCode = Error_Unexpect;
 				break;
 			}
-			switch(i)
+			switch (i)
 			{
 			case 0:
 				ctx->Ans.FingerImg1 = data;
@@ -1109,39 +1202,48 @@ ErrorCodeEnum CCustMngrAuthFSM::CollectFingerPrint(SpReqAnsContext<CustMngrAuthS
 				break;
 			}
 			ctx->Ans.FingerImgs[i] = data;
-			imgPaths[i] = gifAns.imageName;
 		}
 		else
 		{
-			Dbg("failed to collect fingerprint %th times, also failed to generate template failed.");
+			Dbg("invoke GetImageAndFeature failed in %dth time, errCode(%s)", i + 1, SpStrError(errCode));
 			break;
 		}
 
 		//third times, get th template success
-		if (i == (NUM_COLLECT-1)){
-			ctx->Ans.feature = gifAns.feature;	
+		if (i == (COLLECT_TIMES - 1))
+		{
+			ctx->Ans.feature = collecetAns.feature;
 		}
 	}
 
 	//delete bmp files in dep
 	for (int j = 0; j < getImgNum; ++j)
 	{
-		CSimpleStringA tempFullPath(true);
-		tempFullPath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s"
-											, (const char*)strPath, (const char*)imgPaths[j]);
-
-		if(remove((const char*)tempFullPath) == 0)
-			Dbg("finger image %s deleted!", (const char*)tempFullPath);
+		if (remove(imgFullPaths[j].GetData()) == 0)
+			Dbg("finger image %s deleted!", imgFullPaths[j].GetData());
 		else
-			Dbg("fail to delete image %s!", (const char*)tempFullPath);
+			Dbg("fail to delete image %s!", imgFullPaths[j].GetData());
 	}
+
+	return errCode;
+}
+
+ErrorCodeEnum CCustMngrAuthFSM::CollectFingerPrint(SpReqAnsContext<CustMngrAuthService_CollectFingerPrint_Req, CustMngrAuthService_CollectFingerPrint_Ans>::Pointer ctx, DWORD& dwUserErrCode)
+{
+	LOG_FUNCTION();
+	ErrorCodeEnum errCode = ConnectFingerPrintEntity();
+	if (errCode != Error_Succeed)
+		return errCode;
+
+	errCode = CollectProcess(ctx, dwUserErrCode);
 	
-	if (eErr == Error_Succeed){
+	if (errCode == Error_Succeed)
+	{
 		Dbg("Register FingerPrint successfully.");
 		return Error_Succeed;
 	}else{
 		Dbg("Register FingerPrint failed!");
-		return Error_Unexpect;
+		return errCode;
 	}
 }
 
@@ -1151,37 +1253,43 @@ ErrorCodeEnum CCustMngrAuthFSM::SaveFingerPrint(SpReqAnsContext<CustMngrAuthServ
 	EnterCriticalSection(&m_cs);
 	CSmartPointer<IConfigInfo> spConfig;
 	Json::FastWriter writer;
-	ErrorCodeEnum eErr;
-	eErr = GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfig);
-	if (eErr != Error_Succeed){
-		Dbg("ERROR: open config failed! eErr: %d", eErr);
-		LogError(Severity_High, Error_DevLoadFileFailed, LOG_ERR_CUSTMNGRAUTH_OPEN_RUNINFO_FAILED_SAVEFINGERPRINT, "open runinfo file failed while save data to local.");
+	ErrorCodeEnum errCode;
+	errCode = GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfig);
+	if (errCode != Error_Succeed){
+		LogError(Severity_High, Error_DevLoadFileFailed
+				, LOG_ERR_CUSTMNGRAUTH_OPEN_RUNINFO_FAILED_SAVEFINGERPRINT
+				, "open runinfo file failed while save data to local.");
 		LeaveCriticalSection(&m_cs);
 		return Error_Unexpect;
 	}
-	Dbg("open Config_Run succeed, prepare to write feature data.");		
-	Json::Value fingerInfo;
-
+	
 	int fingerIDNum = ctx->Req.FingerIdList.GetCount();
-	FeatureData *fd = new FeatureData();
 	Dbg("FingerIDNum=%d", fingerIDNum);
+	FeatureData *fd = new FeatureData();
 	fd->FingerIDArray.Init(fingerIDNum);
 	fd->FingerIDLenArray.Init(fingerIDNum);
-	for (int i = 0; i < fingerIDNum; ++i){
-		char a[20]={0};
+	char fingerID[20];
+	Json::Value fingerInfo;
+
+	for (int i = 0; i < fingerIDNum; ++i)
+	{
+		memset(fingerID, 0, sizeof(fingerID));
 
 #ifdef RVC_OS_WIN
-		_snprintf_s(a, 10, "FingerID%d", ctx->Req.FingerIdList[i]);
+		_snprintf_s(fingerID, 10, "FingerID%d", ctx->Req.FingerIdList[i]);
 #else
-		snprintf(a, 10, "FingerID%d", ctx->Req.FingerIdList[i]);
+		snprintf(fingerID, 10, "FingerID%d", ctx->Req.FingerIdList[i]);
 #endif // RVC_OS_WIN
 
-		Dbg("writing %s",a);
-		fingerInfo[a] = (const char*)ctx->Req.FPFeatureList[i];
+		Dbg("writing %s", fingerID);
+		fingerInfo[fingerID] = (const char*)ctx->Req.FPFeatureList[i];
 		fd->FingerIDArray[i] = ctx->Req.FPFeatureList[i];
 		fd->FingerIDLenArray[i] = fd->FingerIDArray[i].GetLength();
 	}
-	if(m_featureData.find(ctx->Req.CustomerID) == m_featureData.end()){//不存在,直接插入
+
+	if(m_featureData.find(ctx->Req.CustomerID) == m_featureData.end())
+	{
+		//not exist, insert directly
 		m_featureData[ctx->Req.CustomerID] = fd;
 	}else{
 		auto tempFD = m_featureData[ctx->Req.CustomerID];
@@ -1192,31 +1300,36 @@ ErrorCodeEnum CCustMngrAuthFSM::SaveFingerPrint(SpReqAnsContext<CustMngrAuthServ
 		}
 	}
 
-	Dbg("jsonvalue for fingerinfo created, writing config value......");
-	eErr = spConfig->WriteConfigValue((const char*)m_FingerSection, (const char*)ctx->Req.CustomerID, writer.write(fingerInfo).c_str());
-	Dbg("spConfig->WriteConfigValue done");
-	if (eErr != Error_Succeed){
-		Dbg("write data into runinfo failed when commit.");
-		LogError(Severity_High, Error_DevLoadFileFailed, LOG_ERR_CUSTMNGRAUTH_REGISTER_WRITE_RUNINFO_FAILED, "write data into runinfo failed when commit.");
+	errCode = spConfig->WriteConfigValue((const char*)m_FingerSection
+									, (const char*)ctx->Req.CustomerID
+									, writer.write(fingerInfo).c_str());
+	if (errCode != Error_Succeed)
+	{
+		LogError(Severity_High, Error_DevLoadFileFailed
+				, LOG_ERR_CUSTMNGRAUTH_REGISTER_WRITE_RUNINFO_FAILED
+				, "write data into runinfo failed when commit.");
 		LeaveCriticalSection(&m_cs);
 		return Error_Unexpect;
 	}
 	Dbg("write data into runinfo success when commit.");
 	LeaveCriticalSection(&m_cs);
-	return eErr;
+	return errCode;
 }
 
 ErrorCodeEnum CCustMngrAuthFSM::SwitchUSB(bool bOpen)
 {
 	LOG_FUNCTION();
-	ErrorCodeEnum eErr;
-	//connect devicecontrol and open usb
+
 	Dbg("connecting DeviceControl");
+	ErrorCodeEnum errCode;
 	m_pDeviceControl = new DeviceControlService_ClientBase(GetEntityBase());
-	if(m_pDeviceControl != NULL){
-		eErr = m_pDeviceControl->Connect();
-		if (eErr != Error_Succeed){
-			Dbg("m_pDeviceControl connect failed with eErr %x0x", eErr);
+
+	if(m_pDeviceControl != NULL)
+	{
+		errCode = m_pDeviceControl->Connect();
+		if (errCode != Error_Succeed)
+		{
+			Dbg("m_pDeviceControl connect failed with errCode(%s)", SpStrError(errCode));
 		}else{
 			if(bOpen)
 				Dbg("Open USB");
@@ -1225,8 +1338,8 @@ ErrorCodeEnum CCustMngrAuthFSM::SwitchUSB(bool bOpen)
 			DeviceControlService_USB_Req usbReq;
 			DeviceControlService_USB_Ans usbAns;
 			usbReq.open = bOpen;//open or close usb
-			eErr = m_pDeviceControl->USB(usbReq, usbAns, 2000);
-			if (eErr != Error_Succeed)
+			errCode = m_pDeviceControl->USB(usbReq, usbAns, 2000);
+			if (errCode != Error_Succeed)
 				Dbg("Open/Close usb failed.");
 			else
 				Dbg("Open/Close usb success.");
@@ -1234,7 +1347,7 @@ ErrorCodeEnum CCustMngrAuthFSM::SwitchUSB(bool bOpen)
 		}
 		m_pDeviceControl->SafeDelete();
 		m_pDeviceControl = NULL;
-		return eErr;
+		return errCode;
 	}else{
 		Dbg("DeviceControl is null.");
 		return Error_Unexpect;
@@ -1243,10 +1356,11 @@ ErrorCodeEnum CCustMngrAuthFSM::SwitchUSB(bool bOpen)
 
 ErrorCodeEnum CCustMngrAuthFSM::GetImgBlob(CBlob &data, CSimpleStringA imgPath)
 {
-	Dbg("########Openning imgpath: %s", (const char*)imgPath);
-	ErrorCodeEnum eErr;
+	Dbg("image full path: %s", (const char*)imgPath);
+	
 	FILE* fp = fopen(imgPath, "rb");
-	if (fp) {
+	if (fp) 
+	{
 		Dbg("fopen succeed.");
 		fseek(fp, 0, SEEK_END);
 		long flen = ftell(fp);
@@ -1254,18 +1368,17 @@ ErrorCodeEnum CCustMngrAuthFSM::GetImgBlob(CBlob &data, CSimpleStringA imgPath)
 		data.Alloc(flen);
 		fread(data.m_pData, 1, flen, fp);
 		fclose(fp);
-		eErr = Error_Succeed;
+		return Error_Succeed;
 	}
 	else {
-		Dbg("fopen %s failed!", (LPCSTR)imgPath);
-		eErr = Error_IO;
+		Dbg("fopen %s failed!", (const char*)imgPath);
+		return Error_IO;
 	}
-	return eErr;
 }
 
+//compare if the same day
 int CCustMngrAuthFSM::CompareTime(CSimpleStringA time1, CSimpleStringA time2)
 {
-	//这里只比较是否是同一天
 	if (time1.GetLength() > 0 && time2.GetLength() > 0)
 	{
 		int year1 = atoi((const char*)time1.SubString(0, 4));
@@ -1324,14 +1437,17 @@ CSimpleStringA CCustMngrAuthFSM::GetCurrentDate()
 
 CSimpleStringA CCustMngrAuthFSM::GetMaxTime(CSimpleStringA maxTime, CSimpleStringA tempTime)
 {
-	if (tempTime.GetLength() > 0){
-		if (maxTime.GetLength() <= 0){
+	if (tempTime.GetLength() <= 0)
+		return maxTime;
+	
+	if (maxTime.GetLength() <= 0)
+	{
+		maxTime = tempTime;
+	}else {
+		int compareResult = CompareUpdateTime((const char*)maxTime, (const char*)tempTime);
+		if (compareResult == 0)
+		{
 			maxTime = tempTime;
-		}else{
-			int compareResult = CompareUpdateTime((const char*)maxTime, (const char*)tempTime);
-			if (compareResult == 0){
-				maxTime = tempTime;
-			}
 		}
 	}
 	return maxTime;

+ 34 - 4
Module/mod_CustMngrAuth/CustMngrAuthFSM.h

@@ -38,11 +38,13 @@ struct FeatReply
 	char CurrentAgent[16];
 	char Data[0];//no more than 45k
 };
-struct FeatureData{
+struct FeatureData
+{
 	CAutoArray<CSimpleStringA> FingerIDArray;
 	CAutoArray<int> FingerIDLenArray;
 };
-struct TemplateInfo{
+struct TemplateInfo
+{
 	CSimpleStringA CustomerID;
 	int TemplateNum;
 };
@@ -53,6 +55,27 @@ struct MatchParams
 	vector<TemplateInfo> sFingerCount;
 	int sTotalNumOfTemplate; //Total Num of template which is not empty
 };
+struct JsonParams
+{
+	Json::Value Root;
+	int Index;
+	Json::Value FingerInfo;
+};
+struct TempFeatureData
+{
+	CSimpleStringA MaxUpdateTime;
+	map<CSimpleStringA, FeatureData*> tmpFeatureMap;
+};
+struct RunInfoParams
+{
+	CSimpleStringA LatestTime;
+	CSimpleStringA UpdateTime;
+	CSimpleStringA CurrentTime;
+	bool IsFirstTimeQueryData;
+
+	CSimpleStringA SrcFile;
+	CSimpleStringA BackupFile;
+};
 
 #pragma pack()
 
@@ -351,16 +374,23 @@ public:
 	void UpdateDataIntoMemory(map<CSimpleStringA, FeatureData*> tempFeature, bool bIsFirstTimeQueryData);
 	string ClearStringSpaceHeadTail(string& line);
 	CSimpleStringA GetCurrentDate();
-	void TransDataFromServer(CAutoArray<CSimpleStringA> &dataArray, CSimpleStringA latestTime, bool& bResumeTrans, bool bIsFirstTimeQueryData);
+	ErrorCodeEnum ReceiveDataFromServer(CAutoArray<CSimpleStringA>& dataArray, RunInfoParams runInfoParam);
 	bool BackupFile(CSimpleStringA srcFile, CSimpleStringA dstFile);
 	CSimpleStringA GetMaxTime(CSimpleStringA maxTime, CSimpleStringA tempTime);
 	CSimpleString GenerateAlarmJson(CSimpleString entityName, int cost);
 	void BroadcastGetFinger(int status);
 	void InitBeforeUpdateData();
-	ErrorCodeEnum InitBeforeMatch();
+	ErrorCodeEnum ConnectFingerPrintEntity();
 	ErrorCodeEnum PrepareDataBeforeMatch(MatchParams *matchParam);
 	ErrorCodeEnum MatchProcess(MatchParams* matchParam, bool& bStopAuthorize);
 	ErrorCodeEnum AnalyzeMatchResult(MatchParams* matchParam, bool& bStopAuthorize);
+	ErrorCodeEnum CollectProcess(SpReqAnsContext<CustMngrAuthService_CollectFingerPrint_Req, CustMngrAuthService_CollectFingerPrint_Ans>::Pointer &ctx, DWORD& dwUserErrCode);
+	ErrorCodeEnum LoadRunConfig(CSmartPointer<IConfigInfo>& spConfig);
+	void InitTimeParams(RunInfoParams & runInfoParam, CSmartPointer<IConfigInfo> &spConfig);
+	ErrorCodeEnum InitBeforeQueryData(RunInfoParams& runInfoParam, CSmartPointer<IConfigInfo>& spConfig);
+	ErrorCodeEnum BackupBeforeWriteData(RunInfoParams& runInfoParam, CSmartPointer<IConfigInfo>& spConfig);
+	ErrorCodeEnum WriteData(RunInfoParams& runInfoParam, CAutoArray<CSimpleStringA>& dataArray, CSmartPointer<IConfigInfo>& spConfig);
+	ErrorCodeEnum ProcessFeatureData(JsonParams &jsonParam, TempFeatureData &tmpFeatureData, RunInfoParams runinfoParam, CSmartPointer<IConfigInfo>& spConfig);
 
 private:
 	DeviceControlService_ClientBase *m_pDeviceControl;

+ 105 - 56
Module/mod_DeviceControl/DeviceControlFSM.cpp

@@ -1,23 +1,25 @@
 #include "stdafx.h"
 #include "DeviceControlFSM.h"
-#include "CommDevEntityErrorCode.h"
 #include "GetDevInfoHelper.h"
 #include "EventCode.h"
-#include "path.h"
 
 ErrorCodeEnum CDeviceControlFSM::OnInit()
 {
-    LOG_FUNCTION();
-    GET_DEV_ENTITY_BASE_POINTER()->InitializeVendorLogSwitch();
-
+	LOG_FUNCTION();
+	/*------2020-02-27------*/
+	//modify by LZM
+	VendorLogControler(this,"DeviceControl");
+	/*---------------------*/
 	HRESULT hr;
 	int initTries = 0;
 	bool bClosePort = false;
 	ErrorCodeEnum eErr;
 
+	m_csMachineType = "RVC.PAD";
 	CSystemStaticInfo sysInfo;
 	eErr = GetEntityBase()->GetFunction()->GetSystemStaticInfo(sysInfo);
-	if (eErr != Error_Succeed) {
+	if (eErr != Error_Succeed)
+	{
 		Dbg("Get System Static info failed(%d).", eErr);
 	}
 	m_csMachineType = sysInfo.strMachineType;
@@ -35,84 +37,116 @@ ErrorCodeEnum CDeviceControlFSM::OnInit()
 		if (eErr == Error_Succeed)
 		{
 			Dbg("not RVC.PAD or is FWB(%d),to use default dll.", m_bFWB);
-			CSimpleStringA csBackslash(SPLIT_SLASH_STR);
-
-#ifdef RVC_OS_WIN
-            dllName = csDepPath + csBackslash + "DeviceControl.cmbsz.1.1.dll";
-#else
-            dllName = csDepPath + csBackslash + "libDeviceControl.cmbsz.1.1.so";
-#endif
+			CSimpleStringA csBackslash("\\");
+			dllName = csDepPath + csBackslash + "DeviceControl.cc.1.1.dll";
 		}
 	}
 	else
 	{
-        auto pEntity = GET_DEV_ENTITY_BASE_POINTER();
-		eErr = pEntity->ExtractVendorLibFullPath(dllName);
-        if (eErr != Error_Succeed) {
-            Dbg("Fetch Vendor dllName failed %s.", (LPCTSTR)dllName);
+		eErr = SpGetDevAdaptorPath(m_pEntity, GetEntityBase()->GetEntityName(), dllName);
+		if (eErr != Error_Succeed)
+		{
+			Dbg("load vendor dll(%s) failed.", (LPCTSTR)dllName);
+			return Error_DevLoadFileFailed;
+		}
+		Dbg("%s", (LPCTSTR)dllName);
+		eErr = spEntityFunction->OpenConfig(Config_Root, spConfig);
+		if (eErr != Error_Succeed) {
+			Dbg("open cfg file failed!");
 			return eErr;
-        }
+		}
 	}
-	eErr = m_hDevHelper.LoadUp(dllName);
-	if (eErr != Error_Succeed) {
+
+	m_hVerdorDll = LoadLibraryA(dllName);
+	if (m_hVerdorDll == NULL)
+	{
 		Dbg("Load dll failed.%d",GetLastError());
 		return Error_DevLoadFileFailed;
-	} else {
+	}
+	else
 		Dbg("load vendor dll suc.");
+	if ((CreateDevComponent = (lpCreateDevCom)GetProcAddress(m_hVerdorDll,"CreateDevComponent")) == NULL)
+	{
+		Dbg("Get CreateDevComponent failed.");
+		return Error_DevLoadFileFailed;
+	}
+	if ((ReleaseDevComponent = (lpReleaseDevCom)GetProcAddress(m_hVerdorDll,"ReleaseDevComponent")) == NULL)
+	{
+		Dbg("Get ReleaseDevComponent failed.");
+		return Error_DevLoadFileFailed;
 	}
-
-#ifdef RVC_OS_WIN
-
 	CSimpleStringA csDepPath("");
+
 	eErr = GetEntityBase()->GetFunction()->GetPath("Dep", csDepPath);
 	if (eErr != Error_Succeed)
 	{
 		Dbg("Get dep Path failed (%d).",eErr);
+		//return Error_Param;
 	}
 	else
 	{
 		CSimpleStringA csAQUkeyDll,csBackslash("\\");
 		csAQUkeyDll = csDepPath + csBackslash + "token.dll";
-		m_hTokenDll = LoadLibraryA(csAQUkeyDll);
-		if (m_hTokenDll == NULL) {
+		m_hVerdorDll = LoadLibraryA(csAQUkeyDll);
+		if (m_hVerdorDll == NULL)
+		{
 			Dbg("Load aq dll failed.%d",GetLastError());
 			return Error_DevLoadFileFailed;
-
-		} else {
-
-			if ((AQGetUKeyID = (lpGetUKeyID)GetProcAddress(m_hTokenDll,"GetUKeyID")) == NULL) {
+		}
+		else
+		{
+			if ((AQGetUKeyID = (lpGetUKeyID)GetProcAddress(m_hVerdorDll,"GetUKeyID")) == NULL)
+			{
 				Dbg("Get GetUKeyID failed.");
 				return Error_DevLoadFileFailed;
 			}
-			if ((AQInitToken = (lpInitToken)GetProcAddress(m_hTokenDll,"InitToken")) == NULL) {
+			if ((AQInitToken = (lpInitToken)GetProcAddress(m_hVerdorDll,"InitToken")) == NULL)
+			{
 				Dbg("Get InitToken failed.");
 				return Error_DevLoadFileFailed;
 			}
 			Dbg("Load aq suc.");
 		}
-	}
 
-#endif // RVC_OS_WIN
+	}
 
 	if (strnicmp(m_csMachineType, "RVC.PAD", strlen("RVC.PAD")) == 0 && !m_bFWB)//RVC.PAD to read root.ini
 	{
 		int baudRate, port;
+
 		spConfig->ReadConfigValueInt("Device.DeviceControl", "Baudrate", baudRate);
 		spConfig->ReadConfigValueInt("Device.DeviceControl", "Port", port);
-        Dbg("%d,%d", port, baudRate);
-		eErr = m_hDevHelper->DevOpen(port, baudRate);
-        if (eErr != Error_Succeed) {
-            Dbg("打开设备失败");
-            return Error_DevConnFailed;
-        }
-        Dbg("打开设备成功.");
+		do{
+			if (m_pDevCtrl == NULL)
+			{
+				if (CreateDevComponent((DeviceBaseClass *&)m_pDevCtrl) != Error_Succeed)
+				{
+					LOG_TRACE("创建设备控制模块失败");
+					initTries++;
+					continue;
+				}
+			}
+			Dbg("%d,%d", port, baudRate);
+			eErr = m_pDevCtrl->DevOpen(port, baudRate);
+			if (eErr != Error_Succeed)
+			{
+				Dbg("打开设备失败");
+				return Error_DevConnFailed;
+			}
+			Dbg("打开设备成功.");
+			//m_pDevCtrl->PortControl(USB_PORT_ENABLE);
+			break;
 
-        // 不是大机,打开USB 
-		// by XKM @20151112
-		//修改为:是PAD才打开USB  by oilyang 20160621
-		m_hDevHelper->PortControl(USB_PORT_ENABLE);
+		} while (initTries < 3);
 	}
 
+	// 不是大机,打开USB 
+	// by XKM @20151112
+	//修改为:是PAD才打开USB  by oilyang 20160621
+	if (strnicmp(m_csMachineType, "RVC.PAD", strlen("RVC.PAD")) ==0 && !m_bFWB)
+	{
+		m_pDevCtrl->PortControl(USB_PORT_ENABLE);
+	}
 	return Error_Succeed;
 }
 ErrorCodeEnum CDeviceControlFSM::OnExit()
@@ -268,32 +302,47 @@ int CDeviceControlFSM::UsbControl(SpReqAnsContext<DeviceControlService_USB_Req,D
 {
 	Dbg("open %d",ctx->Req.open);
 	ControlType eType;
+	bool bIsNeedOpenUsb = true;
+
+	if(Error_Succeed != IsNeedOpenUsb(m_pEntity, bIsNeedOpenUsb)){
+		Dbg("usb control failed: get device info failed.");
+		return 1;
+	}
+	if(!bIsNeedOpenUsb){
+		Dbg("no need open/close usb, this machine's usb is always open.");
+		ctx->Answer(Error_Succeed);
+		return 0;
+	}
+
 	if (ctx->Req.open)
 	{
 		eType = USB_PORT_ENABLE;
-		LogEvent(Severity_Middle,LOG_EVT_USB_CONTROL_ON,"usb on");//just for Stand2S
-		LogEvent(Severity_Middle,LOG_EVT_USB_LIGHT_ON,"usb on");//just for Stand2S
+		LogEvent(Severity_Middle,LOG_EVT_USB_CONTROL_ON,"usb on");//control by gpio
+		LogEvent(Severity_Middle,LOG_EVT_USB_LIGHT_ON,"usb on");//control by gpio
 	}
 	else
 	{
 		eType = USB_PORT_DISABLE;
-		LogEvent(Severity_Middle,LOG_EVT_USB_CONTROL_OFF,"usb off");//just for Stand2S
-		LogEvent(Severity_Middle,LOG_EVT_USB_LIGHT_OFF,"usb off");//just for Stand2S
+		LogEvent(Severity_Middle,LOG_EVT_USB_CONTROL_OFF,"usb off");//control by gpio
+		LogEvent(Severity_Middle,LOG_EVT_USB_LIGHT_OFF,"usb off");//control by gpio
 	}
-	if (_strnicmp(m_csMachineType,"RVC.PAD",strlen("RVC.PAD")) != 0 || m_bFWB)
+	ctx->Answer(Error_Succeed);
+	return 0;
+
+	/*if (_strnicmp(m_csMachineType,"RVC.PAD",strlen("RVC.PAD")) != 0 || m_bFWB)
 	{
-		Dbg("not rvc.pad");
-		ctx->Answer(Error_Succeed);
-		return 0;
+	Dbg("not rvc.pad");
+	ctx->Answer(Error_Succeed);
+	return 0;
 	}
-	ErrorCodeEnum eErr = m_hDevHelper->PortControl(eType);
+	ErrorCodeEnum eErr = m_pDevCtrl->PortControl(eType);
 	if (eErr != Error_Succeed)
 	{
-		Dbg("usb control failed %d.",eErr);
-		return 1;
+	Dbg("usb control failed %d.",eErr);
+	return 1;
 	}
 	ctx->Answer(Error_Succeed);
-	return 0;
+	return 0;*/
 }
 
 int CDeviceControlFSM::GetUkeyIDx(SpReqAnsContext<DeviceControlService_GetUkeyID_Req, DeviceControlService_GetUkeyID_Ans>::Pointer ctx)

+ 1 - 1
Module/mod_DeviceControl/DeviceControl_def_g.h

@@ -5,7 +5,7 @@
 
 // This code is generated by spgen tool!
 
-#include "SpHelper.h"
+#include "spHelper.h"
 
 namespace DeviceControl {
 //

+ 11 - 4
Module/mod_download/CMakeLists.txt

@@ -19,6 +19,13 @@ set(${MODULE_PREFIX}_SRCS
 set(MOD_VERSION_STRING "1.0.0-dev1")
 add_module_libraries(${MODULE_PREFIX} ${MODULE_NAME} ${MOD_VERSION_STRING})
 #附加包含的目录
+
+conan_cmake_run(REQUIRES scew/1.1.7@LR04.02_ThirdParty/stable
+BASIC_SETUP CMAKE_TARGETS
+BUILD missing)
+
+
+
 target_include_directories(${MODULE_NAME} PRIVATE
 	${RVC_FRAMEWORK_INCLUDES_DIR}
 	${CONAN_INCLUDE_DIRS_SCEW}
@@ -28,14 +35,14 @@ target_include_directories(${MODULE_NAME} PRIVATE
 target_link_directories(${MODULE_NAME} PRIVATE
 	${CONAN_LIB_DIRS_SCEW}
 	${CONAN_LIB_DIRS_EXPAT}
-)
-
-target_link_directories(${MODULE_NAME} PRIVATE
 	${ThirdPartyLib}
 )
 
 # 添加实体需要依赖的其他共享库(包括系统库):连接器包含的包
-set(${MODULE_PREFIX}_LIBS ${MODULE_BASE_ALL_LIBS} scew expat Advapi32)
+set(${MODULE_PREFIX}_LIBS ${MODULE_BASE_ALL_LIBS} scew expat)
+if(WIN32)
+target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS} Advapi32)  
+endif(WIN32)
 
 target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})  
 

+ 24 - 2
Module/mod_download/DownloadFSM.cpp

@@ -925,7 +925,8 @@ void DownloadFSM::s3_on_entry()
 
 	if(m_currentFileTask->size()>0){
 		Dbg("sendListreq ,count [%d]",m_currentFileTask->size());
-		m_pConnection->SendListReq();//发送获取文件列表请求
+		//m_pConnection->SendListReq();//发送获取文件列表请求
+		m_pConnection->SendListNReq();//发送获取新国密文件列表请求
 	}else{
 		//无任务时跳回S1
 		Dbg("no new files to download");
@@ -1082,10 +1083,19 @@ unsigned int DownloadFSM::s4_on_event(FSMEvent* event)
 
 				if (m_current->offset_block_id<<15 >= file->length){
 					//因需要计算md5值,故需要先关闭前面连接句柄,否则打开文件失败
+#ifdef RVC_OS_WIN
 					if (m_current->temp_handle != INVALID_HANDLE_VALUE) {
 						CloseHandle(m_current->temp_handle);
 						m_current->temp_handle = INVALID_HANDLE_VALUE;
 					}
+#else
+					if (m_current->temp_handle != NULL) {
+						fclose(m_current->temp_handle);
+						m_current->temp_handle = NULL;
+					}
+#endif // RVC_OS_WIN
+
+
 					//判断是否MD5一致,一致则下载成功,否则删除临时文件,重新等待下次下载
 					int flag = download_check_MD5(m_current,file);
 					if(flag==0){
@@ -1145,7 +1155,13 @@ void DownloadFSM::s5_on_entry()
 		for (i = 0; i < arr->nelts; ++i) {
 			char *path = (char*)ARRAY_IDX(arr, i, char*);
 			if (str_has_suffix(path, ".temp") || str_has_suffix(path, ".info")) {
+#ifdef RVC_OS_WIN
 				DeleteFileA(path);
+#else
+				remove(path);
+#endif // RVC_OS_WIN
+
+				
 			}
 		}
 		toolkit_array_free2(arr);
@@ -1185,11 +1201,17 @@ void DownloadFSM::nextTask(){
 			//打开文件成功,判断是否完成
 			if (m_current->offset_block_id<<15 >= file->length) { // finished!
 				//因需要计算md5值,故需要先关闭前面连接句柄,否则打开文件失败
+#ifdef RVC_OS_WIN
 				if (m_current->temp_handle != INVALID_HANDLE_VALUE) {
 					CloseHandle(m_current->temp_handle);
 					m_current->temp_handle = INVALID_HANDLE_VALUE;
 				}
-
+#else
+				if (m_current->temp_handle != NULL) {
+					fclose(m_current->temp_handle);
+					m_current->temp_handle = NULL;
+				}
+#endif // RVC_OS_WIN
 				int flag = download_check_MD5(m_current,file);
 
 				//判断是否MD5一致,一致则下载成功,否则删除临时文件,重新等待下次下载

+ 76 - 2
Module/mod_download/DownloadFSM.h

@@ -22,6 +22,19 @@ struct ListAns
 	int ResultCode;
 	char ListXmlContent[0]; // no more than 32k
 };
+//新国密文件列表接口20200210 lwt
+// [StructName("LISTNREQ")]
+struct ListNReq
+{
+	char TerminalNo[16];
+};
+//[StructName("LISTNANS")]
+struct ListNAns
+{
+	int ResultCode;
+	char ListXmlContent[0]; // no more than 50k
+};
+
 //[StructName("FILEREQ")]
 struct FileReq
 {
@@ -91,6 +104,37 @@ struct ListAnsEvent : public FSMEvent
 	ListAns *m_reply;
 	int m_xml_length;
 };
+//新国密文件列表回应报文
+struct ListNAnsEvent : public FSMEvent
+{
+	ListNAnsEvent(BYTE *pBuf, int nLen) : FSMEvent(USER_EVT_FILEINO_ANS) {
+		int size = nLen;
+		int nprefix = strlen(XML_US_ASCII_PREFIX);
+		int offset = 0;
+		if (memcmp(pBuf + sizeof(ListAns), "<?", 2) != 0) {
+			size += nprefix;
+		}
+		LPBYTE pData = new BYTE[size+1];
+		if (size != nLen) {
+			memcpy(pData, pBuf, sizeof(ListAns));
+			offset = sizeof(ListAns);
+			memcpy(pData+offset, XML_US_ASCII_PREFIX, nprefix);
+			offset += nprefix;
+			memcpy(pData+offset, pBuf+sizeof(ListAns), nLen-sizeof(ListAns));
+			offset += nLen-sizeof(ListAns);
+			pData[offset] = 0;
+			m_xml_length = nLen - sizeof(ListAns) + nprefix;
+		} else {
+			memcpy(pData, pBuf, nLen);
+			pData[nLen] = 0;
+			m_xml_length = nLen - sizeof(ListAns);
+		}
+		m_reply = (ListAns*)pData;
+	}
+	virtual ~ListNAnsEvent() { delete (LPBYTE)m_reply; }
+	ListAns *m_reply;
+	int m_xml_length;
+};
 
 struct FileAnsEvent : public FSMEvent
 {
@@ -263,6 +307,21 @@ public:
 		SendPackage(pkt);
 	}
 
+	void SendListNReq()
+	{
+		ListNReq req = {0};
+		CSystemStaticInfo si;
+		{
+			m_pEntity->GetFunction()->GetSystemStaticInfo(si);
+		}
+		strcpy(&req.TerminalNo[0], si.strTerminalID);
+
+		CSmartPointer<IPackage> pkt = CreateNewPackage("LISTNREQ");
+		pkt->AddStruct("LISTNREQ", false, false, (LPBYTE)&req, sizeof(ListNReq));
+
+		SendPackage(pkt);
+	}
+
 	void SendFileReq(const char *file, int block_id)
 	{
 		FileReq req = {0};
@@ -314,7 +373,22 @@ protected:
 						Dbg("create invalid fileInfo_Ans packet!");
 						OnDisconnect();
 					}
-					delete pBuf;
+					delete[] pBuf;
+				}
+			} else if (serviceCode == "LISTNREQ") {//新国密列表文件
+				int nLen = pRecvPkg->GetStructLen("LISTNANS");
+				if (nLen > 0) {
+					BYTE *pBuf = new BYTE[nLen];
+					memset(pBuf, 0, nLen);
+					int nArrayNum = 0;
+					if (pRecvPkg->GetStructData("LISTNANS", pBuf, &nLen, &nArrayNum)) {
+						FSMEvent *evt = new ListNAnsEvent(pBuf, nLen);
+						m_pFSM->PostEventFIFO(evt);
+					} else {
+						Dbg("create invalid fileNewInfo_Ans packet!");
+						OnDisconnect();
+					}
+					delete[] pBuf;
 				}
 			} else if (serviceCode == "LFILEREQ") {
 				int nLen = pRecvPkg->GetStructLen("LFILEANS");
@@ -329,7 +403,7 @@ protected:
 						Dbg("create invalid file_Ans packet!");
 						OnDisconnect();
 					}
-					delete pBuf;
+					delete[] pBuf;
 				}
 			} else {
 				Dbg("unknown service code!");

+ 398 - 90
Module/mod_download/download.cpp

@@ -5,12 +5,27 @@
 #include "download.h"
 
 #include <fileutil.h>
-#include <WinCrypt.h>
-
 #include <memutil.h>
+#include "RVCComm.h"
 
 #include "scew.h"
 
+#include <string> 
+#include <locale>  
+#include <codecvt>  
+
+#ifdef RVC_OS_WIN
+#include <WinCrypt.h>
+#else
+#include <sys/stat.h>
+#include <errno.h>
+#endif // RVC_OS_WIN
+
+using namespace std;
+
+
+
+
 static __inline int char2hex(char c)
 {
 	if (c >= '0' && c<= '9')
@@ -23,7 +38,7 @@ static __inline int char2hex(char c)
 		assert(0);
 	return 0;
 }
-
+//废弃方法
 static void parse_md5_hex(const char *str, char md5[16])
 {
 	int i;
@@ -33,26 +48,68 @@ static void parse_md5_hex(const char *str, char md5[16])
 		md5[i] = (h << 4) | l;
 	}
 }
+static void parse_SM3_hex(const char *str, char md5[32])
+{
+	int i;
+	for (i = 0; i < 32; ++i) {
+		int h = char2hex(str[2*i]);
+		int l = char2hex(str[2*i+1]);
+		md5[i] = (h << 4) | l;
+	}
+}
 
+//src必须是UTF8否则抛异常
+wstring utf8_to_wstr(const string& src)
+{
+	wstring_convert<codecvt_utf8<wchar_t>> converter;
+	return converter.from_bytes(src);
+}
 
-char* ConvertUtf8ToGBK(char* strUtf8)
+string wstr_to_utf8(const wstring& src)
 {
-    int len = MultiByteToWideChar(CP_UTF8, 0, strUtf8, -1, NULL, 0);
-    WCHAR* wszGBK = new WCHAR[len + 1];
-    memset(wszGBK, 0, len * 2 + 2);
-    MultiByteToWideChar(CP_UTF8, 0, strUtf8, -1, wszGBK, len);
+	wstring_convert<codecvt_utf8<wchar_t>> convert;
+	return convert.to_bytes(src);
+}
 
-    len = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL);
-    char* szGBK = new char[len + 1];
-    memset(szGBK, 0, len + 1);
-    WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, szGBK, len, NULL, NULL);
-    delete[] wszGBK;
+string utf8_to_gbk(const string& str)
+{
+	wstring wStr = utf8_to_wstr(str);//utf8转wstring
+	wstring_convert<chs_codecvt> converter;
+	return converter.to_bytes(wStr);//wstring转GBK
+}
+
+string gbk_to_utf8(const string& str)
+{
+	wstring_convert<chs_codecvt> converter;
+	wstring wStr = converter.from_bytes(str);//GBK转wstring
+	return wstr_to_utf8(wStr);//wstring 转utf8
+}
+
+
+
+char* ConvertUtf8ToGBK(char* strUtf8)
+{
+#ifdef RVC_OS_WIN
+	int len = MultiByteToWideChar(CP_UTF8, 0, strUtf8, -1, NULL, 0);
+	WCHAR* wszGBK = new WCHAR[len + 1];
+	memset(wszGBK, 0, len * 2 + 2);
+	MultiByteToWideChar(CP_UTF8, 0, strUtf8, -1, wszGBK, len);
+
+	len = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL);
+	char* szGBK = new char[len + 1];
+	memset(szGBK, 0, len + 1);
+	WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, szGBK, len, NULL, NULL);
+	delete[] wszGBK;
 
 	return szGBK;
+#else
+	return NULL;	
+#endif // RVC_OS_WIN
 }
 
 char* ConvertGBKToUtf8(char* gbk, int *n)
 {
+#ifdef RVC_OS_WIN
 	int len = MultiByteToWideChar(CP_ACP, 0, gbk, -1, NULL, 0);
     WCHAR* wszGBK = new WCHAR[len + 1];
     memset(wszGBK, 0, len * 2 + 2);
@@ -66,6 +123,10 @@ char* ConvertGBKToUtf8(char* gbk, int *n)
     delete[] wszGBK;
 	*n = len  - 1;
 	return szUtf8;
+#else:
+	return NULL;
+#endif
+	
 }
 
 
@@ -77,9 +138,15 @@ static download_file_t *parse_file_object(scew_element *elem)
 		if (attr) {
 			const char *str = scew_attribute_value(attr);
 			if (str) {
+#ifdef RVC_OS_WIN
 				char *pGBK = ConvertUtf8ToGBK((char*)str);
 				strncpy(file->name, pGBK, sizeof(file->name)-1);
 				delete[] pGBK;
+#else
+				string inputUtf8Str = str;
+				string outGBkStr = utf8_to_gbk(inputUtf8Str);
+				strncpy(file->name, outGBkStr.c_str(), sizeof(file->name) - 1);
+#endif
 			} else {
 				goto on_error;
 			}
@@ -101,7 +168,9 @@ static download_file_t *parse_file_object(scew_element *elem)
 		if (attr) {
 			const char *str = scew_attribute_value(attr);
 			if (str) {
-				parse_md5_hex(str, file->md5);
+				//采用新国密SM3解析接口
+				//parse_md5_hex(str, file->md5);
+				parse_SM3_hex(str,file->md5);
 			} else {
 				goto on_error;
 			}
@@ -124,6 +193,8 @@ array_header_t* download_parse_filelist1(const char *xml, int n)
 	scew_tree *tree = NULL;
 	array_header_t *arr = NULL;
 	scew_element *root;	
+	scew_error code;
+	scew_list* lst = NULL;
 	
 	reader = scew_reader_buffer_create(xml, n);
 	if (!reader) {			
@@ -133,7 +204,7 @@ array_header_t* download_parse_filelist1(const char *xml, int n)
 	parser = scew_parser_create();
 	tree = scew_parser_load(parser, reader);
 	if (!tree) {
-		scew_error code = scew_error_code();
+		code = scew_error_code();
 		if (code == scew_error_expat) {
 		  enum XML_Error expat_code = scew_error_expat_code(parser);
 		  Dbg("scew parse error:%d, line:%d column:%d %s", expat_code, scew_error_expat_line(parser), 
@@ -149,7 +220,7 @@ array_header_t* download_parse_filelist1(const char *xml, int n)
 		goto on_error;
 	}
 
-	scew_list *lst = scew_element_children(root);
+	lst = scew_element_children(root);
 	if (lst) {
 		arr = array_make(scew_list_size(lst), sizeof(download_file_t*));
 		for (scew_list *it = scew_list_first(lst); it; it = scew_list_next(it)) {
@@ -184,7 +255,18 @@ array_header_t* download_parse_filelist(const char *xml, int n)
 	memcpy(pBuf, xml, n);
 	
 	int nLen = 0;
-	char *pUtf8 = ConvertGBKToUtf8(pBuf, &nLen);
+#ifdef RVC_OS_WIN
+	char* pUtf8 = ConvertGBKToUtf8(pBuf, &nLen);
+#else
+	string inputGBKStr = pBuf;
+	string outUtf8Str = gbk_to_utf8(inputGBKStr);
+	char* pUtf8 = new char[inputGBKStr.length() + 1];
+	memset(pUtf8, 0, inputGBKStr.length() + 1);
+	memcpy(pUtf8, inputGBKStr.c_str(), inputGBKStr.length());
+	nLen = strlen(pUtf8);
+#endif // RVC_OS_WIN
+
+	
 	auto arr = download_parse_filelist1(pUtf8,  nLen);
 
 	if (arr == NULL)
@@ -208,14 +290,16 @@ void download_free_filelist(array_header_t* arr)
 		free(arr);
 	}
 }
+//废弃方法
 static int download_get_file_md5(const char *path, char md5[16])
 {
+#ifdef RVC_OS_WIN
 	HCRYPTPROV hCryptProv;
-	if (CryptAcquireContextA(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT|CRYPT_MACHINE_KEYSET)) {
+	if (CryptAcquireContextA(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) {
 		int rc = Error_Unexpect;
 		HCRYPTHASH hHash;
 		if (CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash)) {
-			HANDLE hFile = CreateFileA(path, FILE_GENERIC_READ, 
+			HANDLE hFile = CreateFileA(path, FILE_GENERIC_READ,
 				FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
 			if (hFile != INVALID_HANDLE_VALUE) {
 				char tmp[8192];
@@ -231,58 +315,103 @@ static int download_get_file_md5(const char *path, char md5[16])
 				DWORD dwLen = 16;
 				CryptGetHashParam(hHash, HP_HASHVAL, (LPBYTE)&md5[0], &dwLen, 0);
 				rc = Error_Succeed;
-			} else {
+			}
+			else {
 				Dbg("file open failed, may be %s does not exist! GetLastError:%d", path, GetLastError());
 			}
 			CryptDestroyHash(hHash);
-		} else {
+		}
+		else {
 			Dbg("create hash failed!GetLastError:%d", GetLastError());
 		}
 		CryptReleaseContext(hCryptProv, 0);
 		return (ErrorCodeEnum)rc;
-	} else {
+	}
+	else {
 		Dbg("acquire ctx failed!GetLastError:%d", GetLastError());
 		return Error_Unexpect;
 	}
+#else
+	//等国密版本
+#endif // RVC_OS_WIN
+	return Error_Unexpect;
+	
 }
-
-int download_check_filelist(const char *base_dir, array_header_t* arr)
+static int new_download_get_file_md5(const char *path, BYTE md5[32])
 {
-	int i;
-	char tmp[MAX_PATH];
-	assert(base_dir);
-	assert(arr);
-	i = 0;
-	while (i < arr->nelts) {
-		download_file_t *file = (download_file_t*)ARRAY_IDX(arr, i, download_file_t*);
-		assert(file);
-		sprintf(tmp, "%s\\%s", base_dir, file->name);
-		WIN32_FILE_ATTRIBUTE_DATA attr_data;
-		if (GetFileAttributesExA(tmp, GetFileExInfoStandard, &attr_data)) {
-			if (attr_data.nFileSizeHigh == 0 && attr_data.nFileSizeLow == file->length) { 
-				char md5[16];
-				int rc = download_get_file_md5(tmp, md5);
-				if (rc == 0) {
-					if (memcmp(md5, file->md5, 16) == 0) { // already have remove this file
-						Dbg("file %s the same, remove it!", file->name);
-						ARRAY_DEL(arr, i, download_file_t*);
-						free(file);
-					} else {
-						++i;
-					}
-				} else {
-					++i;
-				}
-			} else {
-				++i;
-			}
-		} else {
-			++i;
+	if(path==NULL){
+		Dbg("file path is null");
+		return -1;
+	}
+	int nlen = strlen(path);
+	char* pchar = new char[nlen+1];
+	strcpy(pchar,path);
+	try
+	{
+		if(SM3File(pchar,md5)){
+			delete pchar;
+			return 0;
+		}else{
+			delete pchar;
+			Dbg("下载文件sm3国密加密失败,file=%s",path);
+			return -1;
 		}
 	}
-	return 0;
+	catch (...)
+	{
+		delete pchar;
+		Dbg("下载文件sm3国密加密异常失败,file=%s",path);
+		return -2;
+	}
+	
 }
 
+//废弃方法
+//int download_check_filelist(const char *base_dir, array_header_t* arr)
+//{
+//	int i;
+//	char tmp[MAX_PATH];
+//	assert(base_dir);
+//	assert(arr);
+//	i = 0;
+//	while (i < arr->nelts) {
+//		download_file_t *file = (download_file_t*)ARRAY_IDX(arr, i, download_file_t*);
+//		assert(file);
+//		sprintf(tmp, "%s\\%s", base_dir, file->name);
+//#ifdef RVC_OS_WIN
+//		WIN32_FILE_ATTRIBUTE_DATA attr_data;
+//		if (GetFileAttributesExA(tmp, GetFileExInfoStandard, &attr_data)) {
+//			if (attr_data.nFileSizeHigh == 0 && attr_data.nFileSizeLow == file->length) {
+//				char md5[16];
+//				int rc = download_get_file_md5(tmp, md5);
+//				if (rc == 0) {
+//					if (memcmp(md5, file->md5, 16) == 0) { // already have remove this file
+//						Dbg("file %s the same, remove it!", file->name);
+//						ARRAY_DEL(arr, i, download_file_t*);
+//						free(file);
+//					}
+//					else {
+//						++i;
+//					}
+//				}
+//				else {
+//					++i;
+//				}
+//			}
+//			else {
+//				++i;
+//			}
+//		}
+//		else {
+//			++i;
+//		}
+//#endif // RVC_OS_WIN
+//
+//		
+//	}
+//	return 0;
+//}
+
 int new_download_check_filelist(const char *base_dir, array_header_t* arr,download_file_t *downloadFile){
 	int ret=0;	//表示下载的文件在文件列表里不存在
 	int i;
@@ -293,67 +422,177 @@ int new_download_check_filelist(const char *base_dir, array_header_t* arr,downlo
 	while (i<arr->nelts){
 		download_file_t *file = (download_file_t*)ARRAY_IDX(arr, i, download_file_t*);
 		assert(file);
-		Dbg("download_check_filelist request downloadFile->name:[%s] ,fileList->name : [%s]",downloadFile->name,(LPCSTR)file->name);
-		if(strcmp((LPCSTR)downloadFile->name,(LPCSTR)file->name)==0){
+
+		Dbg("download_check_filelist request downloadFile->name:[%s] ,fileList->name : [%s]", downloadFile->name, (const char*)file->name);
+		if (strcmp((const char* )downloadFile->name, (const char*)file->name) == 0) {
 			sprintf(tmp, "%s\\%s", base_dir, downloadFile->name);
+#ifdef RVC_OS_WIN
 			WIN32_FILE_ATTRIBUTE_DATA attr_data;
-
 			if (GetFileAttributesExA(tmp, GetFileExInfoStandard, &attr_data)) {
 				if (attr_data.nFileSizeHigh == 0 && attr_data.nFileSizeLow == file->length) { 
-					char md5[16];
-					int rc = download_get_file_md5(tmp, md5);
+					//char md5[16];
+					BYTE md5[32];
+					int rc = new_download_get_file_md5(tmp, md5);
 					if(rc==0){
-						if (memcmp(md5, file->md5, 16) == 0) {// already have remove this file
+						//if (memcmp(md5, file->md5, 16) == 0) {
+						if (memcmp(md5, file->md5, 32) == 0) {
 							//文件长度,md5完全相同,告知下载完成
 							Dbg("file %s the same, remove it!", file->name);
-							ret=2;
+							ret = 2;
 							break;
 						}else{
 							//md5不相等,需要下载
-							ret=1;
+							ret = 1;
 							downloadFile->length = file->length;
-							memcpy(downloadFile->md5,file->md5,16);
+							memcpy(downloadFile->md5, file->md5, 16);
 							break;
 						}
 					}else{
 						//获取md5报错,需要下载
-						ret=1;
+						ret = 1;
 						downloadFile->length = file->length;
-						memcpy(downloadFile->md5,file->md5,16);
+						//memcpy(downloadFile->md5,file->md5,16);
+						memcpy(downloadFile->md5,file->md5,32);
 						break;
 					}
 				}else{
 					//文件长度不相同,需要下载
-					ret=1;
+					ret = 1;
 					downloadFile->length = file->length;
-					memcpy(downloadFile->md5,file->md5,16);
+					//memcpy(downloadFile->md5,file->md5,16);
+					memcpy(downloadFile->md5,file->md5,32);
 					break;
 				}
 			}else{
 				//获取不到文件,需要下载
-				Dbg("file is not exist , fileName is [%s]",(LPCSTR)tmp);
-				ret=1;
+				Dbg("file is not exist , fileName is [%s]", (LPCSTR)tmp);
+				ret = 1;
 				downloadFile->length = file->length;
-				memcpy(downloadFile->md5,file->md5,16);
+				//memcpy(downloadFile->md5,file->md5,16);
+				memcpy(downloadFile->md5,file->md5,32);
 				break;
 			}
-		}else{
+#else   
+//需要修改
+			struct stat attr_of_src;
+			if (lstat(tmp, &attr_of_src) == 0)
+			{
+				if (attr_of_src.st_size== file->length) {
+					char md5[16];
+					int rc = download_get_file_md5(tmp, md5);
+					if (rc == 0) {
+						if (memcmp(md5, file->md5, 16) == 0) {// already have remove this file
+							//文件长度,md5完全相同,告知下载完成
+							Dbg("file %s the same, remove it!", file->name);
+							ret = 2;
+							break;
+						}
+						else {
+							//md5不相等,需要下载
+							ret = 1;
+							downloadFile->length = file->length;
+							memcpy(downloadFile->md5, file->md5, 16);
+							break;
+						}
+					}
+					else {
+						//获取md5报错,需要下载
+						ret = 1;
+						downloadFile->length = file->length;
+						memcpy(downloadFile->md5, file->md5, 16);
+						break;
+					}
+				}
+				else {
+					//文件长度不相同,需要下载
+					ret = 1;
+					downloadFile->length = file->length;
+					memcpy(downloadFile->md5, file->md5, 16);
+					break;
+				}
+			}
+			else 
+			{
+				//获取不到文件,需要下载
+				Dbg("file is not exist , fileName is [%s]", (const char*)tmp);
+				ret = 1;
+				downloadFile->length = file->length;
+				memcpy(downloadFile->md5, file->md5, 16);
+				break;
+			}
+#endif
+		}
+		else {
 			i++;
 		}
+
+		
 	}
 	return ret;
 }
 
+//SM3Byte is 16 or 32
+//SM3_len is 32 or 64
+char* SM3_Str (BYTE * SM3Byte, int SM3_len)  
+{
+	if(SM3Byte == NULL){
+		return NULL;
+	}
+	int i; 
+	char* file_SM3 = (char*)malloc((SM3_len + 1) * sizeof(char)); 
+	if(file_SM3 == NULL)  
+	{  
+		fprintf(stderr, "SM3 malloc failed.\n");  
+		return NULL;  
+	} 
+	memset(file_SM3, 0, (SM3_len + 1));  
+
+	if(SM3_len == 32)  
+	{  
+		for(i=0; i<16; i++)  
+		{  
+			sprintf(&file_SM3[i*2], "%02X", SM3Byte[i]);  
+		}  
+	}  
+	else if(SM3_len == 64)  
+	{  
+		for(i=0; i<32; i++)  
+		{  
+			sprintf(&file_SM3[i*2], "%02X", SM3Byte[i]);  
+		}  
+	}  
+	else  
+	{  
+		free(file_SM3);  
+		return NULL;  
+	}   
+	return file_SM3;  
+}
+
 int download_check_MD5(download_storage_t *storage,download_file_t *dfile){
 	int ret=0;
-	char md5[16];
-	int rc = download_get_file_md5(storage->temp_path, md5);//计算出临时文件md5值
+	//char md5[16];
+	BYTE md5[32]={0};
+	//计算sm3的加密时间
+	CSmallDateTime beginT = CSmallDateTime::GetNow();
+	int rc = new_download_get_file_md5(storage->temp_path, md5);//计算出临时文件md5值
+	CSmallDateTime endT = CSmallDateTime::GetNow();
+	Dbg("下载文件国密获取的SM3耗时%d秒",(DWORD)(endT-beginT));
+	
 	if(rc==0){
-		if (memcmp(md5, dfile->md5, 16) == 0) {
+		//试着打印已下载文件的SM3的16进制值
+		char* fSM3 = SM3_Str(md5,64);
+		if(fSM3!=NULL){
+			Dbg("下载文件国密获取的SM3=%s",fSM3);
+			free(fSM3);
+		}
+		//if (memcmp(md5, dfile->md5, 16) == 0) {
+		if (memcmp(md5, dfile->md5, 32) == 0) {
 			//下载临时文件和文件列表md5一致
 			ret=0;
 		}else{
 			//下载临时文件和文件列表md5不一致,需要下载
+			Dbg("下载文件SM3值和服务器文件SM3值不同,需要重新下载");
 			ret=1;
 		}
 	}else{
@@ -373,15 +612,30 @@ int download_delete_file(const char *base_dir,download_file_t *downloadFile){
 		return 1;
 	}else{
 		fclose(fh);//先关闭文件
-		if(DeleteFileA(tmp)){
-			Dbg("same download file [%s] delete success ",(LPCSTR)tmp);
+#ifdef RVC_OS_WIN
+		if (DeleteFileA(tmp)) {
+			Dbg("same download file [%s] delete success ", (LPCSTR)tmp);
 			return 1;
-		}else{
+		}
+		else {
 			DWORD err = GetLastError();
-			char * pErrmsg = strerror((int)err);
-			Dbg("same download file [%s] delete fail , errno [%d] , errmsg [%s]",(LPCSTR)tmp,err,(LPCSTR)pErrmsg);
+			char* pErrmsg = strerror((int)err);
+			Dbg("same download file [%s] delete fail , errno [%d] , errmsg [%s]", (LPCSTR)tmp, err, (LPCSTR)pErrmsg);
+			return 0;
+		}
+#else
+		if (remove(tmp)) {
+			Dbg("same download file [%s] delete success ", (const char*)tmp);
+			return 1;
+		}
+		else {
+			char* pErrmsg = strerror(errno);
+			Dbg("same download file [%s] delete fail , errno [%d] , errmsg [%s]", (const char*)tmp, errno, (const char*)pErrmsg);
 			return 0;
 		}
+#endif // RVC_OS_WIN
+
+		
 	}
 
 }
@@ -400,7 +654,8 @@ int download_get_storage_block_id(const char *base_dir, download_file_t *file, i
 
 typedef struct storage_info_t {
 	int block_id;
-	char md5[16];
+	//char md5[16];
+	char md5[32];
 	int length;
 }storage_info_t;
 
@@ -408,6 +663,7 @@ download_storage_t *download_storage_open(const char *base_dir, download_file_t
 {
 	if (base_dir && file) {
 		download_storage_t *storage = ZALLOC_T(download_storage_t);//清零初始化
+#ifdef RVC_OS_WIN
 		if (storage) {
 			sprintf(storage->temp_path, "%s\\%s.temp", base_dir, file->name);//临时内容文件
 			sprintf(storage->info_path, "%s\\%s.info", base_dir, file->name);//控制信息文件
@@ -421,7 +677,8 @@ download_storage_t *download_storage_open(const char *base_dir, download_file_t
 					storage_info_t info;
 					DWORD dwLen;
 					info.length = file->length;
-					memcpy(info.md5, file->md5, 16);
+					//memcpy(info.md5, file->md5, 16);
+					memcpy(info.md5, file->md5, 32);
 					info.block_id = 0;
 					WriteFile(storage->info_handle, &info, sizeof(info), &dwLen, NULL);
 					FlushFileBuffers(storage->info_handle);
@@ -431,13 +688,15 @@ download_storage_t *download_storage_open(const char *base_dir, download_file_t
 				DWORD dwLen;
 				BOOL bRet = ReadFile(storage->info_handle, &info, sizeof(info), &dwLen, NULL);
 				if (bRet && dwLen == sizeof(info)) {
-					if (info.length == file->length && memcmp(info.md5, file->md5, 16) == 0) {
+					//if (info.length == file->length && memcmp(info.md5, file->md5, 16) == 0) {
+                    if (info.length == file->length && memcmp(info.md5, file->md5, 32) == 0) {
 						// 续传
 						storage->offset_block_id = info.block_id;
 					} else {
 						// 文件已改变,重新传输
 						info.length = file->length;
-						memcpy(info.md5, file->md5, 16);
+						//memcpy(info.md5, file->md5, 16);
+						memcpy(info.md5, file->md5, 32);
 						info.block_id = 0;
 						WriteFile(storage->info_handle, &info, sizeof(info), &dwLen, NULL);
 						FlushFileBuffers(storage->info_handle);
@@ -445,7 +704,8 @@ download_storage_t *download_storage_open(const char *base_dir, download_file_t
 				} else {
 					//新文件,新传输
 					info.length = file->length;
-					memcpy(info.md5, file->md5, 16);
+					//memcpy(info.md5, file->md5, 16);
+					memcpy(info.md5, file->md5, 32);
 					info.block_id = 0;
 					WriteFile(storage->info_handle, &info, sizeof(info), &dwLen, NULL);
 					FlushFileBuffers(storage->info_handle);
@@ -477,6 +737,9 @@ download_storage_t *download_storage_open(const char *base_dir, download_file_t
 				storage=NULL;
 			}
 		}
+#else
+
+#endif // RVC_OS_WIN
 		return storage;
 	} else {
 		return NULL;
@@ -486,6 +749,7 @@ download_storage_t *download_storage_open(const char *base_dir, download_file_t
 //renameFlag:下载完是否改名称,deleteFlag:删除临时文件
 void download_storage_close(download_storage_t *storage,bool renameFlag,bool deleteFlag)
 {
+#ifdef RVC_OS_WIN
 	if (storage) {
 		if (storage->info_handle != INVALID_HANDLE_VALUE) {
 			CloseHandle(storage->info_handle);
@@ -495,28 +759,63 @@ void download_storage_close(download_storage_t *storage,bool renameFlag,bool del
 			CloseHandle(storage->temp_handle);
 			storage->temp_handle = INVALID_HANDLE_VALUE;
 		}
-		if(renameFlag){
-			if (storage->offset_block_id<<15 >= storage->length) {
+		if (renameFlag) {
+			if (storage->offset_block_id << 15 >= storage->length) {
 				char tmp[MAX_PATH];
 				strcpy(tmp, storage->temp_path);
-				tmp[strlen(tmp)-5] = 0;
-				/*CopyFileA(storage->temp_path, tmp, TRUE);			
+				tmp[strlen(tmp) - 5] = 0;
+				/*CopyFileA(storage->temp_path, tmp, TRUE);
 				DeleteFileA(storage->temp_path);*/
 				MoveFileA(storage->temp_path, tmp);
 				DeleteFileA(storage->info_path);
 			}
 		}
-		if(deleteFlag){
+		if (deleteFlag) {
 			DeleteFileA(storage->temp_path);
 			DeleteFileA(storage->info_path);
 		}
 		free(storage);
 	}
+#else
+	if (storage) {
+		if (storage->info_handle != NULL) {
+			fclose(storage->info_handle);
+			storage->info_handle = NULL;
+		}
+		if (storage->temp_handle != NULL) {
+			fclose(storage->temp_handle);
+			storage->temp_handle = NULL;
+		}
+		if (renameFlag) {
+			if (storage->offset_block_id << 15 >= storage->length) {
+				char tmp[MAX_PATH];
+				strcpy(tmp, storage->temp_path);
+				tmp[strlen(tmp) - 5] = 0;
+				/*CopyFileA(storage->temp_path, tmp, TRUE);
+				DeleteFileA(storage->temp_path);*/
+
+				//MoveFileA(storage->temp_path, tmp);
+				rename(storage->temp_path, tmp);
+				remove(storage->info_path);
+				//DeleteFileA(storage->info_path);
+			}
+		}
+		if (deleteFlag) {
+			//DeleteFileA(storage->temp_path);
+			//DeleteFileA(storage->info_path);
+			remove(storage->temp_path);
+			remove(storage->info_path);
+
+		}
+		free(storage);
+	}
+#endif // RVC_OS_WIN
 }
 
 int download_storage_update(download_storage_t *storage, char *buf, int n)
 {
 	assert(storage);
+#ifdef RVC_OS_WIN
 	DWORD dwLen;
 	WriteFile(storage->temp_handle, buf, n, &dwLen, NULL);
 	FlushFileBuffers(storage->temp_handle);
@@ -524,6 +823,15 @@ int download_storage_update(download_storage_t *storage, char *buf, int n)
 	SetFilePointer(storage->info_handle, 0, NULL, FILE_BEGIN);
 	WriteFile(storage->info_handle, &storage->offset_block_id, 4, &dwLen, NULL);		// 只更新块号字段
 	FlushFileBuffers(storage->info_handle);
+#else
+	fwrite(buf, n, 1, storage->temp_handle);
+	fflush(storage->temp_handle);
+	storage->offset_block_id++;
+	fseek(storage->info_handle, 0, SEEK_SET);
+	fwrite(&storage->offset_block_id, 4, 1, storage->info_handle);
+	fflush(storage->info_handle);
+#endif // RVC_OS_WIN
+
 	return 0;
 }
 

+ 23 - 2
Module/mod_download/download.h

@@ -1,19 +1,35 @@
 #pragma once
 
 #include <array.h>
+#include <locale>
+#include <codecvt> 
+#include <string>
+
+//GBK转UTF码类
+class chs_codecvt : public std::codecvt_byname<wchar_t, char, std::mbstate_t> {
+public:
+	//因不同平台,名称不同,故这里做转换,统一取出不同平台下面的GBK码
+#ifdef RVC_OS_WIN
+	chs_codecvt() : codecvt_byname("chs") { }//zh_CN.GBK or .936
+#else
+	chs_codecvt() : codecvt_byname("zh_CN.GBK") { }
+#endif // RVC_OS_WIN
+};
+
 
 
 typedef struct download_file_t {
 	//char name[64];
 	char name[256];
 	int length;
-	char md5[16];
+	//char md5[16];
+	char md5[32];
 }download_file_t;
 
 // xml must be have <?xml version="1.0" encoding="utf-8" ?>
 array_header_t* download_parse_filelist(const char *xml, int n);
 void download_free_filelist(array_header_t* arr);
-int download_check_filelist(const char *base_dir, array_header_t* arr);
+//int download_check_filelist(const char *base_dir, array_header_t* arr);
 
 //0:表示下载的文件在文件列表里不存在 1:需要下载 2:下载完成
 int new_download_check_filelist(const char *base_dir, array_header_t* arr,download_file_t *downloadFile);
@@ -24,8 +40,13 @@ int download_delete_file(const char *base_dir,download_file_t *downloadFile);
 typedef struct download_storage_t {
 	char temp_path[MAX_PATH];
 	char info_path[MAX_PATH];
+#ifdef RVC_OS_WIN
 	HANDLE temp_handle;
 	HANDLE info_handle;
+#else
+	FILE* temp_handle;
+	FILE* info_handle;
+#endif 
 	int offset_block_id;
 	int length;
 }download_storage_t;

+ 27 - 12
Module/mod_download/mod_download.h

@@ -142,11 +142,12 @@ public:
 			ctx->Ans.iDownloadState = 2;
 			return Error_Succeed;
 		}
+		return Error_Succeed;
 
 		CSimpleStringA str;
 		GetFunction()->GetPath("Download", str);
 		char tmp[MAX_PATH];
-		WIN32_FIND_DATAA fd;
+		
 		strcpy(tmp, str.GetData());
 		if (str_has_suffix(str.GetData(), "\\")) {
 			strcat(tmp, filename);
@@ -155,29 +156,43 @@ public:
 			strcat(tmp, "\\");
 			strcat(tmp, filename);
 		}
-
-		HANDLE hFind = FindFirstFileA(tmp, &fd);
-
-		if (hFind != INVALID_HANDLE_VALUE) {
-			FindClose(hFind);
+		//WIN32_FIND_DATAA fd;
+		//HANDLE hFind = FindFirstFileA(tmp, &fd);
+
+		//if (hFind != INVALID_HANDLE_VALUE) {
+		//	FindClose(hFind);
+		//	ctx->Ans.iDownloadState = 3;
+		//	return Error_Succeed;
+		//}
+		//else {
+		//	FindClose(hFind);
+		//	ctx->Ans.iDownloadState = 4;
+		//	return Error_Succeed;
+		//}
+		FILE* fp = fopen(tmp, "rb");
+		if(fp!=NULL)
+		{
+			fclose(fp);
 			ctx->Ans.iDownloadState = 3;
 			return Error_Succeed;
 		}
-		else {
-			FindClose(hFind);
+		else
+		{ 
 			ctx->Ans.iDownloadState = 4;
 			return Error_Succeed;
 		}
+
+		
 	}
 
 private:
-	ErrorCodeEnum MakeFileList(std::list<CSimpleStringA>& fileList)
+	/*ErrorCodeEnum MakeFileList(std::list<CSimpleStringA>& fileList)
 	{
 		CSimpleStringA str;
 		GetFunction()->GetPath("Download", str);
 		return __MakeFileList(str, fileList);
-	}
-	ErrorCodeEnum __MakeFileList(const char* base_dir, std::list<CSimpleStringA>& fileList)
+	}*/
+	/*ErrorCodeEnum __MakeFileList(const char* base_dir, std::list<CSimpleStringA>& fileList)
 	{
 		char tmp[MAX_PATH];
 		WIN32_FIND_DATAA fd;
@@ -198,7 +213,7 @@ private:
 			FindClose(hFind);
 		}
 		return Error_Succeed;
-	}
+	}*/
 
 
 private:

+ 6 - 6
Module/mod_upload/CMakeLists.txt

@@ -39,15 +39,15 @@ set(MOD_VERSION_STRING "1.0.0-dev1")
 add_module_libraries(${MODULE_PREFIX} ${MODULE_NAME} ${MOD_VERSION_STRING})
 #¸½¼Ó°üº¬µÄĿ¼
 
-if(WIN32)
-conan_cmake_run(REQUIRES zlib/1.2.11@LR04.02_ThirdParty/testing
-BASIC_SETUP CMAKE_TARGETS
-BUILD missing)
-else(WIN32)
+#if(WIN32)
+#conan_cmake_run(REQUIRES zlib/1.2.11@LR04.02_ThirdParty/testing
+#BASIC_SETUP CMAKE_TARGETS
+#BUILD missing)
+#else(WIN32)
 conan_cmake_run(REQUIRES zlib/1.2.11@LR04.02_ThirdParty/stable
 BASIC_SETUP CMAKE_TARGETS
 BUILD missing)
-endif(WIN32)
+#endif(WIN32)
 
 target_include_directories(${MODULE_NAME} PRIVATE
 	${RVC_FRAMEWORK_INCLUDES_DIR}