﻿#include "jidu.h"
#include "jidu_dataCenter.h"
#include "jidu_client.h"
#include "tracer.h"
#include "cJSON.h"
#include "jidu_vehicleConfig.h"
#include "jidu_envConfig.h"
#include "algorithm.h"
#include "FileUtils.h"

#include <fstream>  
#include <iostream>  
#include <string> 
#include "MyStringUtils.h"
#include <mutex>
#pragma warning(disable:4267)

ecu_node_t ecutable[JD_EUC_COUNT] = {
	//	{ ecuId,		ecuName,		doIp,		ccpId,	    voltage}
		{ 0x6011,       "BGM",			0x1001,     1547,	    0},
		{ 0x3011,	    "CDC",	 		0x1201,     1521,	    0},
		{ 0x3021,	    "AUD",	 		0x1280,     1395,	    0},
		{ 0x3031,	    "CD",	 		0x1281,     1443,	    0},
		{ 0x2011,	    "ACU",	 		0x1401,     1303,	    0},
		//{ 0x2021,	    "Lidar_L",		0x14AE,     1309,	    0},
		//{ 0x2031,	    "Lidar_R",		0x14BE,     1310,	    0},
		{ 0x2041,	    "FLR",	 		0x1444,     1554,	    0},
		{ 0x2061,	    "FSRL",	 		0x1460,     1465,	    0},
		{ 0x2071,	    "FSRR",	 		0x1461,     1466,	    0},
		{ 0x2081,	    "SODL",	 		0x1450,     1374,	    0},
		{ 0x2091,	    "SODR",	 		0x1451,     1375,	    0},
		{ 0x1011,	    "TCAM",	 		0x1011,     1548,	    0},
		{ 0x5031,	    "SRS",	 		0x1C01,     1346,	    0},
		{ 0x5021,	    "BBM",	 		0x1701,     1435,	    0},
		{ 0x5011,	    "VDDM",	 		0x1601,     1388,	    0},
		{ 0x5041,	    "EGSM",	 		0x1633,     1330,	    0},
		{ 0x5051,	    "BECM1_75", 	0x1635,     1307,	    1},
		{ 0x5052,	    "BECM1_102", 	0x1635,     1307,	    1},
		{ 0x5061,	    "MGM",	 		0x1631,     1312,	    1},
		{ 0x5071,	    "IEM_IGBT",	 	0x1637,     1336,	    1},
		{ 0x5072,	    "IEM_SIC",	 	0x1637,     1336,	    1},
		{ 0x5081,	    "HVCM",	 		0x1650,     1301,	    1},
		{ 0x5091,	    "ECM3",	 		0x1630,     1321,	    1},
		{ 0x5121,	    "SAS",	 		0x1672,     1376,	    0},
		{ 0x5101,	    "PSCM_1",		0x1670,     1353,	    0},
		{ 0x5111,	    "PSCM_2",		0x1720,     1353,	    0},
		{ 0x5131,	    "SUM1",	 		0x1614,     1381,	    0},
		{ 0x5141,	    "RML",	 		0x1510,     1364,	    0},
		{ 0x1031,	    "WPC",	 		0x1024,     1437,	    0},
		{ 0x1032,	    "WPC2",	 		0x1024,     1437,	    0},
		{ 0x1072,	    "WPC3",	 		0x1026,     1439,	    0},
		{ 0x1041,	    "NKR",	 		0x1025,     1313,	    0},
		{ 0x1021,	    "BNCM",	 		0x1023,     1520,	    0},
		{ 0x6201,	    "DRM_FL",		0x1030,     1314,	    0},
		{ 0x6211,	    "DRM_FR",		0x1031,     1315,	    0},
		{ 0x6221,	    "DRM_RL",		0x1032,     1316,	    0},
		{ 0x6231,	    "DRM_RR",		0x1033,     1317,	    0},
		{ 0x6061,	    "DPOD",	 		0x1A40,     1540,	    0},
		{ 0x6071,	    "PPOD",	 		0x1A41,     1539,	    0},
		{ 0x6081,	    "LPOD",	 		0x1A42,     1538,	    0},
		{ 0x6091,	    "RPOD",	 		0x1A43,     1537,	    0},
		{ 0x6021,	    "DDM",	 		0x1A12,     1318,	    0},
		{ 0x6031,	    "PDM",	 		0x1A13,     1345,	    0},
		{ 0x6041,	    "RLDM",	 		0x1A21,     1552,	    0},
		{ 0x6051,	    "RRDM",	 		0x1A22,     1551,	    0},
		{ 0x3041,	    "SWTL",	 		0x1A82,     1545,	    0},
		{ 0x3051,	    "SWTR",	 		0x1A83,     1544,	    0},
		{ 0x6101,	    "CCM",	 		0x1A11,     1311,	    0},
		{ 0x6121,	    "SMD",	 		0x1A27,     1474,	    0},
		{ 0x6111,	    "POT",	 		0x1A15,     1348,	    0},
		{ 0x1051,	    "ETCM",	 		0x1A16,     1319,	    0},
		{ 0x6131,	    "SMP",	 		0x1A28,     1475,	    0},
		{ 0x6141,	    "HCML",	 		0x1BB3,     1339,	    0},
		{ 0x6151,	    "HCMR",	 		0x1BB4,     1340,	    0},
		{ 0x6171,	    "RCML",	 		0x1BB5,     1518,	    0},
		{ 0x6181,	    "RCMR",	 		0x1BB6,     1519,	    0},
		{ 0x6191,	    "RCMM",	 		0x1BB7,     1517,	    0},
		{ 0x6241,	    "IPM",	 		0x1A52,     1333,	    0},
		{ 0x7011,	    "PSGM",	 		0x1615,     1329,	    0},
		{ 0x6251,	    "SMB",	 		0x1A30,     1473,	    0},

};

using namespace std;
static std::mutex mItemLock;

static vector<string> orderByInitial(vector<string>& vec) {

	for (int loop = 0; loop < vec.size(); loop++)
	{
		for (int i = 0; i < vec.size() - 1; i++) {
			if (vec.at(i) > vec.at(i + 1)) {
				swap(vec.at(i), vec.at(i + 1));
			}
		}
	}

	return vec;
}

int clearDataCenterCache()
{
	DataCenter::getInstance()->reset();

	return int();
}

int setFactory(const char* factory)
{
	DataCenter::getInstance()->factory = factory;
	Tracer::warn(__FUNCTION__, factory);

	JiduClient::getInstance()->loadEnvirment();
	JiduClient::getInstance()->loadParam();
	CVehicleConfig::getInstance();
	return int();
}

int setLanguage(const char* lang)
{
	DataCenter::getInstance()->language = lang;
	return int();
}

int callServer(int iType, const char* inParams, char* outBuffer, uint32_t outBufferSize)
{
	return JiduClient::getInstance()->callServer(iType, inParams, outBuffer, outBufferSize);
}

int getAppEnvironment(void)
{
	string envPath = EnvConfig::getInstance()->getEnvPath();
	if (envPath._Equal("Prod")) {
		return 1;
	}
	else if (envPath._Equal("Staging")) {
		return 2;
	}

	return 0;
}

int getLastErrMsg(char* outBuffer, uint32_t outBufferSize)
{
	memset(outBuffer, 0, outBufferSize);
	string tempString = DataCenter::getInstance()->errMsg;
	if (outBufferSize > tempString.length())
	{
		memcpy(outBuffer, tempString.c_str(), tempString.length());
		return tempString.length();
	}

	return -1;
}

bool jd_ecuflash_checkHighVoltage(const char* ecuName)
{
	for (int i = 0; i < JD_EUC_COUNT; i++) {
		if (ecutable[i].ecuName._Equal(ecuName)) {
			return ecutable[i].isHighPwr;
		}
	}

	return false;
}
int trans_jd_vinAscii(const char* inParams, uint32_t offset, uint32_t inLen, char* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	if (offset >= inLen) {
		Tracer::error(__FUNCTION__, "offset must less than inLen.");
		return -1;
	}
	else if (outBufferSize < inLen - offset) {
		return -1;
	}
	else if (inLen - offset != 17) {
		Tracer::error(__FUNCTION__, "vin.size must equre to 17");
		return -1;
	}
	memcpy(outBuffer, inParams + offset, inLen - offset);

	return 17;
}

int get_jd_tpmsId(uint8_t* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);

	//TODO 没有数据
	if (DataCenter::m_VehicleOrderInfo.strTpmsId.empty()) {
		string reqParam = string("vin=") + DataCenter::getInstance()->m_VehicleOrderInfo.strVin;
		if (callServer(4, reqParam.c_str(), NULL, 0) < 0) {
			return -1;
		}
	}

	string tempString = DataCenter::m_VehicleOrderInfo.strTpmsId;
	int rLen = radix_hex2Array(tempString.c_str(), tempString.size(), outBuffer, outBufferSize);

	Tracer::hex("tpmsId", outBuffer, rLen);
	return rLen;
}

int set_jd_vehicleInfo_ccp(uint8_t* ccp, uint32_t inLen)
{
	DataCenter::getInstance()->m_vehicleInfo.binCCP = CBinary(ccp, inLen);
	Tracer::hex(__FUNCTION__, ccp, inLen);

	//TODO //CCP#564 等于01是低配（无主动尾翼；等于02是高配（有尾翼）
	DataCenter::m_vehicleInfo.empennage = DataCenter::getInstance()->m_vehicleInfo.binCCP.GetAt(563);

	//TODO //CCP#962 获取高压平台电压(0:400V 02:800V)
	DataCenter::m_vehicleInfo.powerType = DataCenter::getInstance()->m_vehicleInfo.binCCP.GetAt(961);

	DataCenter::m_vehicleInfo.carType = DataCenter::getInstance()->m_vehicleInfo.binCCP.GetAt(949);

	if (DataCenter::m_vehicleInfo.carType == 0x01) {//MarsOne
		switch (DataCenter::getInstance()->m_vehicleInfo.binCCP.GetAt(965))
		{
		case 0x00:
			DataCenter::m_vehicleInfo.carTypeId = 61;
			break;
		case 0x01:
			DataCenter::m_vehicleInfo.carTypeId = 64;
			break;
		case 0x02:
			DataCenter::m_vehicleInfo.carTypeId = 63;
			break;
		case 0x03:
			DataCenter::m_vehicleInfo.carTypeId = 68;
			break;
		default:
			break;
		}
		
	}
	else if (DataCenter::m_vehicleInfo.carType == 0x02) {//Venus
		switch (DataCenter::getInstance()->m_vehicleInfo.binCCP.GetAt(966))
		{
		case 0x00:
			DataCenter::m_vehicleInfo.carTypeId = 62;
			break;
		case 0x01:
			DataCenter::m_vehicleInfo.carTypeId = 65;
			break;
		case 0x02:
			DataCenter::m_vehicleInfo.carTypeId = 66;
			break;
		case 0x03:
			DataCenter::m_vehicleInfo.carTypeId = 67;
			break;
		default:
			break;
		}
	}


	return true;
}

int set_jd_vehicleInfo_vehicleType(char* vehicleType)
{
	DataCenter::getInstance()->m_vehicleInfo.vehicleType = vehicleType;
	CVehicleConfig::getInstance()->setCurrentVehicleType(vehicleType);
	DataCenter::m_EcuStatus.clear();
	DataCenter::m_vehicleInfo.mapEcuInfo.clear();

	//TODO pver
#if true
	string appPath = EnvConfig::getInstance()->getAppPath();
	string pverPath = appPath.append("pver");
	FILE* fp = fopen(pverPath.c_str(), "r");
	if (fp == NULL) {
		Tracer::error("pver文件打开失败, errno", to_string(errno));
		return false;
	}

	fseek(fp, 0, SEEK_END);
	int fileSize = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	char* fileBuff = (char*)malloc(fileSize + 1);
	fread(fileBuff, 1, fileSize, fp);
	fclose(fp);

	cJSON* objRoot = cJSON_Parse(fileBuff);
	if (objRoot == NULL) {
		Tracer::error(__FUNCTION__, "pver json parse err.");
		cJSON_Delete(objRoot);
		return false;
	}

	if (cJSON_HasObjectItem(objRoot, "vehicleType")) {
		cJSON_ReplaceItemInObject(objRoot, "vehicleType", cJSON_CreateString(vehicleType));
	}
	else {
		cJSON_AddStringToObject(objRoot, "vehicleType", vehicleType);
	}

	char* temp = cJSON_Print(objRoot);
	fp = fopen(pverPath.c_str(), "w");
	fwrite(temp, 1, strlen(temp), fp);
	fclose(fp);
	cJSON_free(temp);
	cJSON_Delete(objRoot);
#endif

	return int();
}

int get_jd_vehicleInfo_ccpByte(uint32_t offset)
{
	if (offset > DataCenter::getInstance()->m_vehicleInfo.binCCP.GetSize()) {
		return -1;
	}
	return DataCenter::getInstance()->m_vehicleInfo.binCCP.GetAt(offset);
}

int get_jd_vehicleInfo_batteryCapacity()
{
	return DataCenter::getInstance()->getCarConfig(DataCenter::getInstance()->m_vehicleInfo.binCCP);
}

int set_jd_vehicleInfo_ecuSn(char* ecuName, char* ecuSn)
{
	uint16_t ecuId = get_jd_orderInfo_ecuId_byEcuName(ecuName);
	return set_jd_vehicleInfo_ecuSn_byEcuId(ecuId, ecuSn);
}

int set_jd_vehicleInfo_ecuSwpn(char* ecuName, char* ecuSwpn)
{
	uint16_t ecuId = get_jd_orderInfo_ecuId_byEcuName(ecuName);
	return set_jd_vehicleInfo_ecuSwpn_byEcuId(ecuId, ecuSwpn);
}

int set_jd_vehicleInfo_ecuHwpn(char* ecuName, char* ecuHwpn)
{
	uint16_t ecuId = get_jd_orderInfo_ecuId_byEcuName(ecuName);
	return set_jd_vehicleInfo_ecuHwpn_byEcuId(ecuId, ecuHwpn);
}

int set_jd_vehicleInfo_ecuSn_byEcuId(uint16_t ecuId, char* ecuSn)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	for (auto it = DataCenter::m_vehicleInfo.mapEcuInfo.begin(); it != DataCenter::m_vehicleInfo.mapEcuInfo.end(); it++) {
		if ((ecuId & 0xFFF0) == (it->first & 0xFFF0)) {
			ecuId = it->first;
			break;
		}
	}

	DataCenter::m_vehicleInfo.mapEcuInfo[ecuId].ecuSn = ecuSn;
	return int();
}

int set_jd_vehicleInfo_ecuSwpn_byEcuId(uint16_t ecuId, char* ecuSwpn)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	for (auto it = DataCenter::m_vehicleInfo.mapEcuInfo.begin(); it != DataCenter::m_vehicleInfo.mapEcuInfo.end(); it++) {
		if ((ecuId & 0xFFF0) == (it->first & 0xFFF0)) {
			ecuId = it->first;
			break;
		}
	}

	DataCenter::m_vehicleInfo.mapEcuInfo[ecuId].ecuSwpn = ecuSwpn;
	return int();
}

int set_jd_vehicleInfo_ecuHwpn_byEcuId(uint16_t ecuId, char* ecuHwpn)
{
	std::lock_guard<std::mutex> lock(mItemLock);

	DataCenter::m_vehicleInfo.mapEcuInfo[ecuId].ecuHwpn = ecuHwpn;
	//TODO 未设置EcuName 则预设一个ecuName
	if (DataCenter::m_vehicleInfo.mapEcuInfo[ecuId].ecuName.empty()) {
		char ecuName[32] = { 0 };
		get_jd_ecuName_byEcuId(ecuId, ecuName, 32);
		DataCenter::m_vehicleInfo.mapEcuInfo[ecuId].ecuName = ecuName;
	}

	char tempBuffer[32] = { 0 };
	Tracer::debug(__FUNCTION__, string("EcuId: ") + itoa(ecuId, tempBuffer, 16) + "; " + ecuHwpn);

	return int();
}

int set_jd_vehicleInfo_ecuName_byEcuId(uint16_t ecuId, char* ecuName)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	for (auto it = DataCenter::m_vehicleInfo.mapEcuInfo.begin(); it != DataCenter::m_vehicleInfo.mapEcuInfo.end(); it++) {
		if ((ecuId & 0xFFF0) == (it->first & 0xFFF0)) {
			ecuId = it->first;
			break;
		}
	}

	DataCenter::m_vehicleInfo.mapEcuInfo[ecuId].ecuName = ecuName;
	return int();
}

int set_jd_vehicleInfo_pkiName_byEcuId(uint16_t ecuId, char* pkiName)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	for (auto it = DataCenter::m_vehicleInfo.mapEcuInfo.begin(); it != DataCenter::m_vehicleInfo.mapEcuInfo.end(); it++) {
		if ((ecuId & 0xFFF0) == (it->first & 0xFFF0)) {
			ecuId = it->first;
			break;
		}
	}

	DataCenter::m_vehicleInfo.mapEcuInfo[ecuId].pkiName = pkiName;
	char tempBuffer[16] = { 0 };
	Tracer::debug(__FUNCTION__, string("EcuId: ") + itoa(ecuId, tempBuffer, 16) + "; " + "pkiName: " + pkiName);
	return int();
}

int get_jd_vehicleInfo_ecuHwpn_byEcuName(const char* ecuName, char* outBuffer, uint32_t outBufferSize)
{
	memset(outBuffer, 0, outBufferSize);

	uint16_t ecuId = get_jd_orderInfo_ecuId_byEcuName(ecuName);
	if (DataCenter::m_vehicleInfo.mapEcuInfo.find(ecuId) != DataCenter::m_vehicleInfo.mapEcuInfo.end()) {
		string ecuHwpn = DataCenter::m_vehicleInfo.mapEcuInfo.at(ecuId).ecuHwpn;

		if (outBufferSize > ecuHwpn.length())
		{
			memcpy(outBuffer, ecuHwpn.c_str(), ecuHwpn.length());
			return ecuHwpn.length();
		}
	}

	return -1;
}

int set_jd_vehicleInfo_baseLine(char* baseLine)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	DataCenter::m_vehicleInfo.baseLine = baseLine;
	return int();
}

int set_jd_vehicleInfo_tpmsId(char* tpmsId)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	DataCenter::m_vehicleInfo.tpmsId = tpmsId;
	return int();
}

OTX_API int set_jd_vehicleInfo_ssh_Status(int status)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	DataCenter::m_vehicleInfo.sshStaus = status;
	return int();
}

int set_jd_vehicleInfo_chargingIsOpen(int status)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	DataCenter::m_vehicleInfo.chargingIsOpen = status;
	return int();
}

int set_jd_vehicleInfo_gloveboxIsOpen(int status)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	DataCenter::m_vehicleInfo.gloveboxIsOpen = status;
	return int();
}

int set_jd_vehicleInfo_batteryRemin(char* soc)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	DataCenter::m_vehicleInfo.batteryRemain = soc;
	return int();
}

bool check_jd_ecuVersion_swpn(char* orderSwpn, char* vehicleSwpn)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	vector<string> vecOrderLSwpnist, vecVehicleSwpnList;
	MyStringUtils::split(vecOrderLSwpnist, orderSwpn, "\t");
	MyStringUtils::split(vecVehicleSwpnList, vehicleSwpn, "\t");

	if (vecOrderLSwpnist.size() == 0 || vecVehicleSwpnList.size() == 0) {
		return false;
	}

	if (vecOrderLSwpnist.size() != vecVehicleSwpnList.size()) {
		return false;
	}

	for (string tempVehicleSwpn : vecVehicleSwpnList) {
		MyStringUtils::trim(tempVehicleSwpn);
		if (tempVehicleSwpn.empty()) continue;
		if (vecOrderLSwpnist.end() == find(vecOrderLSwpnist.begin(), vecOrderLSwpnist.end(), tempVehicleSwpn)) {

			Tracer::error(__FUNCTION__, string("ecuSwpn: ") + tempVehicleSwpn + " not in orderSwpn: " + orderSwpn);
			return false;
		}
	}

	return true;
}

bool check_jd_ecuVersion_hwpn(char* orderHwpn, char* vehicleHwpn)
{
	std::lock_guard<std::mutex> lock(mItemLock);

	if (orderHwpn == "" || vehicleHwpn == "") {
		return false;
	}

	if (strcmp(orderHwpn, vehicleHwpn) == 0)
		return true;
	else
		return false;
}

int check_jd_ecuVersion_report(char* statisticId, char* statisticName, char* blockId, char* blockName)
{
	string itemName = "Information Check and Record [参数比对]";

	if (MyStringUtils::toLong(string(blockId), 16) == 0x75)
		itemName = "Hardware Check and Record [参数比对]";

	JD_VEHICLE_ORDER_t orderInfo = DataCenter::getInstance()->m_VehicleOrderInfo;
	int check_result = 1;
	int check_hwpn_result = 1;//检查硬件号是否匹配
	vector<JD_ECU_INFO_t> vecOrderEcuInfo = orderInfo.vecListEcu;
	for (auto it = DataCenter::m_vehicleInfo.mapEcuInfo.begin(); it != DataCenter::m_vehicleInfo.mapEcuInfo.end(); it++) {

		uint16_t ecuId = it->first;

		char ecuName[32] = { 0 };
		get_jd_orderInfo_ecuName_byEcuId(ecuId, ecuName, 32);

		JD_VehicleEcuInfo_t vehicleInfo = it->second;
		check_hwpn_result = 1;//每次遍历前置1
		string orderEcuHwpn;
		vector<string> vecOrderEcuSwpn;
		for (int j = 0; j < vecOrderEcuInfo.size(); j++) {
			JD_ECU_INFO_t orderEcuInfo = vecOrderEcuInfo.at(j);
			if (orderEcuInfo.strEcuName._Equal(ecuName)) {
				orderEcuHwpn = orderEcuInfo.strEcuHwpn;
				for (JD_ECU_SWPN_INFO_t ecuSwpnInfo : orderEcuInfo.vecEcuSwpnList) {
					if (string(ecuName)._Equal("POT"))
					{
						VehicleCfg vehicleConfig;
						DataCenter::getInstance()->getCarConfig(DataCenter::m_vehicleInfo.binCCP, vehicleConfig);
						if (vehicleConfig.iEmpennage == 0x02 && MyStringUtils::startWith(ecuSwpnInfo.strEcuSwpn, "12")) {
							continue;
						}
						else if (vehicleConfig.iEmpennage == 0x01 && MyStringUtils::startWith(ecuSwpnInfo.strEcuSwpn, "13")) {
							continue;
						}
					}
					vecOrderEcuSwpn.push_back(ecuSwpnInfo.strEcuSwpn);
				}
				break;
			}
		}

		char ecuAddr[32] = { 0 };
		sprintf(ecuAddr, "0x%04X", get_jd_doIp_byEcuName(ecuName));

		string itemId = "01", expectedData = "size>=4";
		string itemInfo = string(blockId).append(",").append(itemName).append(",").append(itemId).append(",").append(ecuName).append(",").append(ecuAddr).append(",").append(expectedData);

		string tempString = blockId;

		//hwpn check
		uint8_t ecuHwpnAckBuffer[128] = { 0 };
		memcpy(ecuHwpnAckBuffer, "\x62\xF1\xAA", 3);
		memcpy(ecuHwpnAckBuffer + 3, vehicleInfo.ecuHwpn.c_str(), vehicleInfo.ecuHwpn.length());
		if (vehicleInfo.ecuHwpn.empty()) {
			string msg;
			msg.append(ecuName).append(":HW订单中心:").append(orderEcuHwpn).append("\t").append("当前:N/A");
			jd_report_addNokItem((char*)itemInfo.c_str(), (uint8_t*)"\x22\xF1\xAA", 3, NULL, 0, (char*)msg.c_str());
			check_result = 0;
			check_hwpn_result = 0;//硬件号不匹配
		}
		else if (!vehicleInfo.ecuHwpn._Equal(orderEcuHwpn)) {

			string msg;
			msg.append(ecuName).append(":HW订单中心:").append(orderEcuHwpn).append("\t").append("当前:").append(vehicleInfo.ecuHwpn);
			jd_report_addNokItem((char*)itemInfo.c_str(), (uint8_t*)"\x22\xF1\xAA", 3, ecuHwpnAckBuffer, vehicleInfo.ecuHwpn.length() + 3, (char*)msg.c_str());
			check_result = 0;
			check_hwpn_result = 0;//硬件号不匹配
		}
		else {
			jd_report_addOkItem((char*)itemInfo.c_str(), (uint8_t*)"\x22\xF1\xAA", 3, ecuHwpnAckBuffer, vehicleInfo.ecuHwpn.length() + 3);
		}


		if ((MyStringUtils::toLong(tempString, 16) == 0x000C) && (check_hwpn_result == 1)) {
			string orderEcuSwpn;
			for (string tempOrderEcuSwpn : vecOrderEcuSwpn) {
				//if (MyStringUtils::startWith(tempOrderEcuSwpn, "11")) {
				//	continue;//SBL版本不显示
				//}
				orderEcuSwpn.append(tempOrderEcuSwpn).append("\t");
			}


			//swpn check
			if (vehicleInfo.ecuSwpn.empty()) {
				string msg;
				msg.append(ecuName).append(":SW订单中心:").append(orderEcuSwpn).append("\t").append("当前:N/A");
				jd_report_addNokItem((char*)itemInfo.c_str(), (uint8_t*)"\x22\xF1\xAE", 3, NULL, 0, (char*)msg.c_str());
				check_result = 0;
			}
			else {
				vector<string> vecTemp;
				MyStringUtils::split(vecTemp, vehicleInfo.ecuSwpn, "\t");

				bool match = true;
				for (string tempSpwn : vecTemp) {
					MyStringUtils::trim(tempSpwn);
					if (MyStringUtils::startWith(tempSpwn, "11")) {
						continue;//SBL版本不比较
					}
					if (vecOrderEcuSwpn.end() == find(vecOrderEcuSwpn.begin(), vecOrderEcuSwpn.end(), tempSpwn)) {
						match = false;
						break;
					}
				}

				uint8_t ecuSwpnAckBuffer[128] = { 0 };
				memcpy(ecuSwpnAckBuffer, "\x62\xF1\xAE", 3);
				memcpy(ecuSwpnAckBuffer + 3, vehicleInfo.ecuSwpn.c_str(), vehicleInfo.ecuSwpn.length());
				if (match) {
					jd_report_addOkItem((char*)itemInfo.c_str(), (uint8_t*)"\x22\xF1\xAE", 3, ecuSwpnAckBuffer, vehicleInfo.ecuSwpn.length() + 3);
				}
				else {
					string msg;
					msg.append(ecuName).append(":SW订单中心:").append(orderEcuSwpn).append("当前:").append(vehicleInfo.ecuSwpn);
					check_result = 0;
					jd_report_addNokItem((char*)itemInfo.c_str(), (uint8_t*)"\x22\xF1\xAE", 3, ecuSwpnAckBuffer, vehicleInfo.ecuSwpn.length() + 3, (char*)msg.c_str());
				}
			}
		}
	}
	return check_result;
}

int get_jd_ecuStatus_byEcuName(char* ecuName)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	if (DataCenter::m_EcuStatus.find(ecuName) != DataCenter::m_EcuStatus.end())
	{
		return DataCenter::m_EcuStatus[ecuName].ecuStatus;
	}
	else {
		return int();
	}
}

int set_jd_ecuStatus_byEcuName(char* ecuName, int status)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	DataCenter::m_EcuStatus[ecuName].ecuStatus = (JIDU_ECU_STATUS)status;
	return int();
}

inline int get_ccpPos_byEcuId(int ecuId) {
	for (int i = 0; i < sizeof(ecutable); i++) {
		if (ecutable[i].ecuId == NULL) {
			Tracer::error("invalid ecuTable", "internal error");
			return -1;
		}
		if (ecuId == ecutable[i].ecuId) {
			return ecutable[i].ccpPose;
		}
	}

	return 0;
}

int check_jd_ecuStatus_byEcuName(char* ecuName)
{
	std::lock_guard<std::mutex> lock(mItemLock);

	JD_VEHICLE_ORDER_t vehicleOrderInfo = DataCenter::getInstance()->m_VehicleOrderInfo;
	vector<JD_ECU_INFO_t> ecuList = vehicleOrderInfo.vecListEcu;

	uint8_t tempBuffer[4096] = { 0 };
	int rLen = radix_hex2Array(vehicleOrderInfo.strCCPCode.c_str(), vehicleOrderInfo.strCCPCode.size(), tempBuffer, 4096);

	for (int i = 0; i < ecuList.size(); i++) {
		if (strcmp(ecuList.at(i).strEcuName.c_str(), ecuName) == 0) {

			int ecuId = ecuList.at(i).nEcuId;
			int iBytePos = get_ccpPos_byEcuId(ecuId);


			if ((rLen >= 1558) && (iBytePos > 0))
			{
				uint8_t bVal = tempBuffer[iBytePos - 1];
				//01=Not Mounted, 02 = Mounted
				if (bVal == 1)
				{
					return 0;
				}
				else if (bVal == 2)
				{
					return 1;
				}
			}

			Tracer::error("invalid ccp", vehicleOrderInfo.strCCPCode);
			return -1;
		}
	}

	Tracer::error("can't find ecuName", ecuName);
	return -1;
}

int get_jd_vehicleInfo_ecuCount()
{
	if (DataCenter::m_vehicleInfo.binCCP.GetSize() < 1500) {
		string source = DataCenter::m_VehicleOrderInfo.strCCPCode;
		CBinary bin = CBinary(source.length());

		int rLen = radix_hex2Array(source.c_str(), source.length(), bin.m_pData, bin.GetSize());
		if (rLen < 1500) {
			return -1;
		}
		DataCenter::m_vehicleInfo.binCCP = bin;
	}

	Tracer::debug(__FUNCTION__, DataCenter::m_VehicleOrderInfo.strCCPCode);

	DataCenter::m_vehicleInfo.vecEcuName.clear();
	VehicleCfg vehicleCfg;
	DataCenter::getInstance()->getCarConfig(DataCenter::m_vehicleInfo.binCCP, vehicleCfg);

	for (int i = 0; i < JD_EUC_COUNT; i++) {
		uint8_t val = DataCenter::m_vehicleInfo.binCCP.GetAt(ecutable[i].ccpPose - 1);
		//TODO 01=Not Mounted; 02=Mounted
		if (val == 0x02) {
			if (MyStringUtils::startWith(ecutable[i].ecuName, "BECM1")) {
				if (vehicleCfg.iBatteryCapacity == 75 && ecutable[i].ecuName._Equal("BECM1_75")) {
					DataCenter::m_vehicleInfo.vecEcuName.push_back("BECM1_75");
				}
				else if (vehicleCfg.iBatteryCapacity == 102 && ecutable[i].ecuName._Equal("BECM1_102")) {
					DataCenter::m_vehicleInfo.vecEcuName.push_back("BECM1_102");
				}
			}
			else if (MyStringUtils::startWith(ecutable[i].ecuName, "IEM")) {
				for (JD_ECU_INFO_t ecuInfo : DataCenter::m_VehicleOrderInfo.vecListEcu) {
					if (MyStringUtils::startWith(ecuInfo.strEcuName, "IEM")) {
						if (ecuInfo.nEcuId == 0x5071) {
							DataCenter::m_vehicleInfo.vecEcuName.push_back("IEM_IGBT");
						}
						else if (ecuInfo.nEcuId == 0x5072) {
							DataCenter::m_vehicleInfo.vecEcuName.push_back("IEM_SIC");
						}
						else if (ecuInfo.nEcuId == 0x5073) {
							DataCenter::m_vehicleInfo.vecEcuName.push_back("IEM2");
						}
						i++;
						break;
					}
				}
			}
			else if (MyStringUtils::startWith(ecutable[i].ecuName, "WPC")) {
				//TODO marsOne使用wpc; venus使用WPC2和WPC3
				if (MyStringUtils::startWith(DataCenter::m_vehicleInfo.vehicleType, "marsOne") && ecutable[i].ecuName._Equal("WPC")) {
					DataCenter::m_vehicleInfo.vecEcuName.push_back(ecutable[i].ecuName);
				}
				else if (ecutable[i].ecuName._Equal("WPC2") || ecutable[i].ecuName._Equal("WPC3")) {
					DataCenter::m_vehicleInfo.vecEcuName.push_back(ecutable[i].ecuName);
				}
			}
			else {
				DataCenter::m_vehicleInfo.vecEcuName.push_back(ecutable[i].ecuName);
			}
		}
		else {
			Tracer::warn("EcuName.vehicleInfo", ecutable[i].ecuName + ":Not Mounted");
		}
	}


	//TODO 复制一个ecuVector,按照首字母排序
	DataCenter::m_vehicleInfo.vecEcuNameOrderByInitial = DataCenter::m_vehicleInfo.vecEcuName;
	orderByInitial(DataCenter::m_vehicleInfo.vecEcuNameOrderByInitial);

	for (string tempString : DataCenter::m_vehicleInfo.vecEcuNameOrderByInitial) {
		Tracer::warn("EcuName", tempString + ":Mounted");
	}

	return DataCenter::m_vehicleInfo.vecEcuName.size();
}

int get_jd_vehicleInfo_ecuId(uint16_t ecuId)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	uint16_t ret = ecuId;
	return ret;
}

int get_jd_vehicleInfo_ecuHwpn_byEcuId(uint16_t ecuId, char* outBuffer, uint32_t outBufferSize)
{
	memset(outBuffer, 0, outBufferSize);
	if (DataCenter::m_vehicleInfo.mapEcuInfo.find(ecuId) != DataCenter::m_vehicleInfo.mapEcuInfo.end()) {

		JD_VehicleEcuInfo_t ecuInfo = DataCenter::m_vehicleInfo.mapEcuInfo.at(ecuId);
		string tempString = ecuInfo.ecuHwpn;
		if (outBufferSize > tempString.size())
		{
			memcpy(outBuffer, tempString.c_str(), tempString.size());
			return tempString.size();
		}
	}

	char tempBuffer[32] = { 0 };
	Tracer::error(__FUNCTION__, string("invalid ecuId") + itoa(ecuId, tempBuffer, 32));

	return -1;
}

int get_jd_vehicleInfo_ecuName(int index, char* outBuffer, uint32_t outBufferSize)
{
	memset(outBuffer, 0, outBufferSize);

	if (index < DataCenter::m_vehicleInfo.vecEcuName.size()) {
		string tempString = DataCenter::m_vehicleInfo.vecEcuName.at(index);
		if (outBufferSize > tempString.length()) {
			memcpy(outBuffer, tempString.c_str(), tempString.length());
			return tempString.length();
		}
	}

	return -1;
}



int get_jd_vehicleInfo_ecuName_orderByInitial(int index, char* outBuffer, uint32_t outBufferSize)
{
	memset(outBuffer, 0, outBufferSize);

	if (index < DataCenter::m_vehicleInfo.vecEcuNameOrderByInitial.size()) {

		string tempString = DataCenter::m_vehicleInfo.vecEcuNameOrderByInitial.at(index);
		if (outBufferSize > tempString.length()) {
			memcpy(outBuffer, tempString.c_str(), tempString.length());
			return tempString.length();
		}
	}

	return int();
}

int get_jd_vehicleInfo_doIP_byEcuName(char* ecuName, char* outBuffer, uint32_t outBufferSize)
{
	memset(outBuffer, 0, outBufferSize);

	string newName = ecuName;
	if (MyStringUtils::startWith(newName, "BGM"))
		newName = "BGM";
	if (MyStringUtils::startWith(newName, "ACU"))
		newName = "ACU";
	if (MyStringUtils::startWith(newName, "CDC"))
		newName = "CDC";

	for (int i = 0; i < JD_EUC_COUNT; i++) {
		if (ecutable[i].ecuName._Equal(newName)) {
			if (outBufferSize > 4) {
				int DoIp = ecutable[i].doIp;
				if (MyStringUtils::endWith(ecuName, "_MCU")) {
					DoIp += 1;
				}
				sprintf(outBuffer, "%04x", DoIp);
				return 4;
			}
			else {
				return -1;
			}
		}
	}

	return -1;
}

int get_jd_vehicleInfo_ecuName_byIpAddr(char* ipHex, char* outBuffer, uint32_t outBufferSize)
{
	string ipAddrString = ipHex;
	uint32_t ipAddr = MyStringUtils::toLong(ipAddrString, 16);
	if (ipAddr == 0x1002 || ipAddr == 0x1402 || ipAddr == 0x1202)
	{
		ipAddr -= 1;
	}

	memset(outBuffer, 0, outBufferSize);
	for (int i = 0; i < JD_EUC_COUNT; i++) {
		if (ecutable[i].doIp == ipAddr) {
			string ecuName = ecutable[i].ecuName;

			if (MyStringUtils::startWith(ecuName, "BECM1")) {
				int carConfig = DataCenter::getInstance()->getCarConfig(DataCenter::m_vehicleInfo.binCCP);
				ecuName = (carConfig == 75) ? "BECM1_75" : "BECM1_102";
			}

			if (outBufferSize > ecuName.size()) {
				memcpy(outBuffer, ecuName.c_str(), ecuName.size());
				return (int)ecuName.size();
			}
			else {
				return -1;
			}
		}
	}

	return -1;
}


int set_jd_ecuFotaStatus_byEcuName(char* ecuName, int status)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	DataCenter::m_EcuStatus[ecuName].ecuFotaStatus = (JIDU_ECU_FOTA_STATUS)status;
	return true;
}

int set_jd_ecuFotaStatus_byEcuId(uint16_t ecuId, int status)
{
	std::lock_guard<std::mutex> lock(mItemLock);

	char strStatus[32] = { 0x00 };

#if true
	for (JD_ECU_INFO_t orderInfo : DataCenter::getInstance()->m_VehicleOrderInfo.vecListEcu) {
		if ((orderInfo.nEcuId & 0xFFF0) == (ecuId & 0xFFF0)) {
			string ecuName = orderInfo.strEcuName;
			DataCenter::m_EcuStatus[ecuName].ecuFotaStatus = (JIDU_ECU_FOTA_STATUS)status;

			//Tracer::debug(__FUNCTION__, itoa(status, strStatus, 10)+": "+ecuName);
			return true;
		}
	}
#else
	for (int i = 0; i < JD_EUC_COUNT; i++) {
		if (ecutable[i].ecuId == ecuId) {
			string ecuName = ecutable[i].ecuName;
			DataCenter::m_EcuStatus[ecuName].ecuFotaStatus = (JIDU_ECU_FOTA_STATUS)status;
			return true;
		}
	}
#endif

	char strEcuId[32] = { 0x00 };
	Tracer::error(__FUNCTION__, string("invalid ecuId: 0x") + itoa(ecuId, strEcuId, 16));
	return false;
}

int check_jd_ecuFotaStatus_report(char* statisticId, char* statisticName, char* blockId, char* blockName)
{
	map<std::string, JD_EcuStatusInfo_t> m_EcuStatus = DataCenter::getInstance()->m_EcuStatus;
	JD_VEHICLE_ORDER_t orderInfo = DataCenter::getInstance()->m_VehicleOrderInfo;

	for (JD_ECU_INFO_t ecuInfo : orderInfo.vecListEcu) {
		string ecuName = ecuInfo.strEcuName;
		char ecuAddr[32] = { 0 };
		sprintf(ecuAddr, "0x%04X", get_jd_doIp_byEcuId(ecuInfo.nEcuId));

		char failReason[128] = { 0 };
		if (m_EcuStatus.find(ecuName) != m_EcuStatus.end()) {
			JIDU_ECU_FOTA_STATUS_t ecuFotaStatus = m_EcuStatus.at(ecuName).ecuFotaStatus;
			switch (ecuFotaStatus)
			{
			case JIDU_ECU_FOTA_STATUS_No_Reulst:
				sprintf(failReason, "%s:%02d %s", ecuName.c_str(), ecuFotaStatus, "无结果");	break;
			case JIDU_ECU_FOTA_STATUS_OffLine:
				sprintf(failReason, "%s:%02d %s", ecuName.c_str(), ecuFotaStatus, "ECU离线");	break;
			case JIDU_ECU_FOTA_STATUS_HW_ERROR:
				sprintf(failReason, "%s:%02d %s", ecuName.c_str(), ecuFotaStatus, "ECU硬件版本不匹配");	break;
			case JIDU_ECU_FOTA_STATUS_UpdateFail:
				sprintf(failReason, "%s:%02d %s", ecuName.c_str(), ecuFotaStatus, "ECU升级失败");	break;
			case JIDU_ECU_FOTA_STATUS_UpdateOK: {
				Tracer::debug("JIDU_ECU_FOTA_STATUS_UpdateOK", ecuName);
				continue;
			}
			case JIDU_ECU_FOTA_STATUS_Not_Mounted:
				sprintf(failReason, "%s:%02d %s", ecuName.c_str(), ecuFotaStatus, "选装件,不需要Fota");	break;
			default:
				sprintf(failReason, "%s:%02d %s", ecuName.c_str(), ecuFotaStatus, "未定义");	break;
			}
		}
		else {
			sprintf(failReason, "%s:%02d %s", ecuName.c_str(), 0, "无结果");
		}

		string itemName = "FOTA Result Check and Record [参数读取]", itemId = "06", expectedData = "正响应";
		string itemInfo = string(blockId).append(",").append(itemName).append(",").append(itemId).append(",").append(ecuName).append(",").append(ecuAddr).append(",").append(expectedData);
		jd_report_addNokItem((char*)itemInfo.c_str(), (uint8_t*)"\x00", 1, NULL, 0, failReason);
	}

	return int();
}

int get_jd_ecuFotaStatus_byEcuName(char* ecuName)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	if (DataCenter::m_EcuStatus.find(ecuName) != DataCenter::m_EcuStatus.end())
	{
		return DataCenter::m_EcuStatus[ecuName].ecuFotaStatus;
	}
	else {
		return 0;
	}
}

int get_jd_ecuFotaStatus_byEcuId(uint16_t ecuId)
{
	std::lock_guard<std::mutex> lock(mItemLock);

#if true
	for (JD_ECU_INFO_t orderInfo : DataCenter::getInstance()->m_VehicleOrderInfo.vecListEcu) {
		if ((orderInfo.nEcuId & 0xFFF0) == (ecuId & 0xFFF0)) {
			string ecuName = orderInfo.strEcuName;
			return DataCenter::m_EcuStatus[ecuName].ecuFotaStatus;
		}
	}
#else
	for (int i = 0; i < JD_EUC_COUNT; i++) {
		if (ecutable[i].ecuId == ecuId) {
			string ecuName = ecutable[i].ecuName;
			return DataCenter::m_EcuStatus[ecuName].ecuFotaStatus;
		}
	}
#endif
	return 0;
}

string currentTimestamp(void) {
	time_t ta = time(&ta);
	struct tm* timelocalinfo = localtime(&ta);
	char szTime[32] = { 0 };
	strftime(szTime, 32, "%Y-%m-%d %H:%M:%S", timelocalinfo);

	return szTime;
}

int get_jd_eolStationResult(const char* vin, const char* station) {
	std::lock_guard<std::mutex> lock(mItemLock);
	static string vin_bkp;
	static string station_bkp;

	if (vin_bkp.empty() || station_bkp.empty() || 0 != strcmp(vin_bkp.c_str(), vin) || 0 != strcmp(station_bkp.c_str(), station)) {
		char paramBuffer[128] = { 0 };
		sprintf(paramBuffer, "vin=%s&station=%s", vin, station);
		int rLen = callServer(28, paramBuffer, NULL, 0);
		if (rLen >= 0) {
			vin_bkp = vin;
			station_bkp = station;
		}
		else {
			return 3;
		}
	}

	if (DataCenter::m_summaryData.overallResult.empty()) {
		return 2;
	}
	else if (DataCenter::m_summaryData.overallResult._Equal("OK")) {
		return 1;
	}
	else if (DataCenter::m_summaryData.overallResult._Equal("NOK")) {
		return 0;
	}
	return 3;

}

int get_jd_eolStationBlockCount()
{
	std::lock_guard<std::mutex> lock(mItemLock);
	if (DataCenter::m_summaryData.testData.empty()) {
		return 0;
	}
	else {
		return (int)DataCenter::m_summaryData.testData.size();
	}
}

bool get_jd_eolStationBlockResult(int blockIndex)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	if (DataCenter::m_summaryData.testData.empty()) {
		return 0;
	}
	else {
		if (DataCenter::m_summaryData.testData.size() > blockIndex) {
			if (DataCenter::m_summaryData.testData.at(blockIndex).testBlockResult._Equal("OK")) {
				return 1;
			}

			return 0;
		}
	}

	Tracer::error("blockIndex", "outof the bound.");
	return 0;
}

int get_jd_eolStationBlockName(int blockIndex, char* blockNameBuffer, uint32_t blockNameBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	memset(blockNameBuffer, 0, blockNameBufferSize);
	if (DataCenter::m_summaryData.testData.empty()) {
		return 0;
	}
	else {
		if (DataCenter::m_summaryData.testData.size() > blockIndex) {
			string blockName = DataCenter::m_summaryData.testData.at(blockIndex).testBlockName;
			if (blockNameBufferSize > blockName.size())
			{
				memcpy(blockNameBuffer, blockName.c_str(), blockName.size());
				return (int)blockName.size();
			}

			Tracer::error("bufferSize", "too small to receive.");
			return -1;
		}
	}

	Tracer::error("blockIndex", "outof the bound.");
	return 0;
}

bool get_jd_eolStationBlockResultByBlockName(const char* blockName)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	if (DataCenter::m_summaryData.testData.empty()) {
		return 0;
	}
	else {
		for (int i = 0; i < DataCenter::m_summaryData.testData.size(); i++) {
			JD_SummaryData_TestData_t testItem = DataCenter::m_summaryData.testData.at(i);
			if (testItem.testBlockName._Equal(blockName)) {

				if (testItem.testBlockResult._Equal("OK")) {
					return 1;
				}
				else {
					return 0;
				}
			}
		}
	}
	return 1;
}

bool get_jd_eolStationBlockResultByBlockId(const char* blockId)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	if (DataCenter::m_summaryData.testData.empty()) {
		return 0;
	}
	else {
		for (int i = 0; i < DataCenter::m_summaryData.testData.size(); i++) {
			JD_SummaryData_TestData_t testItem = DataCenter::m_summaryData.testData.at(i);
			if (testItem.testBlockId._Equal(blockId)) {

				if (testItem.testBlockResult._Equal("OK")) {
					return 1;
				}
				else {
					return 0;
				}
			}
		}
	}
	return 1;
}

int get_jd_vehicleConfig_pkgCount()
{
	std::lock_guard<std::mutex> lock(mItemLock);

	CVehicleConfig::getInstance()->reloadLoacalPkg();

	CVehicleConfig::getInstance()->reloadConfig();

	return CVehicleConfig::getInstance()->m_vecVehicleSoftVer.size();
}

int get_jd_vehicleConfig_pkgName(int index, char* outBuffer, int outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	vector<string> pkgList = CVehicleConfig::getInstance()->m_vecVehicleSoftVer;
	if (index >= pkgList.size()) {
		Tracer::error("index", "outof the bound.");
		return -1;
	}

	string tempString = pkgList.at(index);
	if (outBufferSize >= tempString.size())
	{
		memcpy(outBuffer, tempString.c_str(), tempString.size());
		return (int)tempString.size();
	}

	Tracer::error("bufferSize", "too small to receive.");
	return -1;
}

int set_jd_vehicleConfig_vehicleSoftVer(const char* vehicleSoftVer)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	bool flag = CVehicleConfig::getInstance()->setCurrentVehicleSoftVer(vehicleSoftVer);
	if (!flag) { return false; }

	vector<JD_ECU_INFO_t> vecOrderInfo;

	//TODO 按订单过滤整车包
	if (DataCenter::getInstance()->factory._Equal("PMA") || DataCenter::getInstance()->factory._Equal("DMA")) {
		vecOrderInfo = DataCenter::getInstance()->m_VehicleOrderInfo.vecListEcu;
		//TODO 按订单过滤整车包
		if (!vecOrderInfo.empty()) {

			JD_VEHICLE_CONFIG_t newConfig = CVehicleConfig::getInstance()->m_vehicleConfig;
			newConfig.vecListEcu.clear();

			for (JD_ECU_INFO_t ecuOrderInfo : vecOrderInfo) {
				uint16_t ecuOrderId = ecuOrderInfo.nEcuId;
				string ecuOrderHwpn = ecuOrderInfo.strEcuHwpn;
				vector<JD_ECU_SWPN_INFO_t> vecEcuOrderInfoSpwn = ecuOrderInfo.vecEcuSwpnList;
				string ecuOrderSpwn;
				for (JD_ECU_SWPN_INFO_t ecuSpwn : vecEcuOrderInfoSpwn) {
					ecuOrderSpwn.append(ecuSpwn.strEcuSwpn).append(";");
				}

				for (JD_ECU_CONFIG_t ecuConfig : CVehicleConfig::getInstance()->m_vehicleConfig.vecListEcu) {
					JD_ECU_CONFIG_t ecuNewConfig = ecuConfig;
					ecuNewConfig.vecMapping.clear();

					if (ecuConfig.nEcuId == ecuOrderId) {

						for (JD_MAPPING_CONFIG_t ecuMapping : ecuConfig.vecMapping) {
							JD_MAPPING_CONFIG_t ecuNewMapping = ecuMapping;
							ecuNewMapping.vecOderList.clear();

							if (ecuMapping.strHwpn._Equal(ecuOrderHwpn)) {
								for (JD_VSP_FLASH_INFO_t vspInfo : ecuMapping.vecOderList) {

									if (ecuOrderSpwn.find(vspInfo.strVersion) != string::npos) {
										ecuNewMapping.vecOderList.push_back(vspInfo);
									}
								}

								ecuNewConfig.vecMapping.push_back(ecuNewMapping);
							}

						}

						newConfig.vecListEcu.push_back(ecuNewConfig);
					}
				}

			}
			CVehicleConfig::getInstance()->m_vehicleConfig = newConfig;
		}
	}
	else {
		//TODO 售后和工程版需要预设车辆EcuId
		if (DataCenter::m_vehicleInfo.mapEcuInfo.size() == 0) {
			Tracer::warn(__FUNCTION__, "no vehicleInfo.ecuId，ignore pkg filtering");
		}
		else {
			JD_VEHICLE_CONFIG_t newConfig = CVehicleConfig::getInstance()->m_vehicleConfig;
			newConfig.vecListEcu.clear();
			for (auto ecuInfo : DataCenter::m_vehicleInfo.mapEcuInfo) {
				uint16_t ecuId = ecuInfo.first;
				string ecuHwpn = ecuInfo.second.ecuHwpn;
				for (JD_ECU_CONFIG_t ecuConfig : CVehicleConfig::getInstance()->m_vehicleConfig.vecListEcu) {
					JD_ECU_CONFIG_t ecuNewConfig = ecuConfig;
					ecuNewConfig.vecMapping.clear();
					//if (ecuConfig.nEcuId == ecuId) {
					if ((ecuConfig.nEcuId & 0xFFF0) == (ecuId & 0xFFF0)) {
						for (JD_MAPPING_CONFIG_t ecuMapping : ecuConfig.vecMapping) {
							JD_MAPPING_CONFIG_t ecuNewMapping = ecuMapping;
							ecuNewMapping.vecOderList.clear();

							if (ecuMapping.strHwpn._Equal(ecuHwpn)) {
								for (JD_VSP_FLASH_INFO_t vspInfo : ecuMapping.vecOderList) {
									ecuNewMapping.vecOderList.push_back(vspInfo);
								}
								ecuNewConfig.vecMapping.push_back(ecuNewMapping);
							}
						}
						if (!ecuNewConfig.vecMapping.empty())
							newConfig.vecListEcu.push_back(ecuNewConfig);
					}
				}
			}
			CVehicleConfig::getInstance()->m_vehicleConfig = newConfig;
		}
	}

	for (JD_ECU_CONFIG_t tempCfg : CVehicleConfig::getInstance()->m_vehicleConfig.vecListEcu) {
		string strEcuHwpn;
		for (JD_MAPPING_CONFIG_t mappig : tempCfg.vecMapping)
		{
			strEcuHwpn.append(mappig.strHwpn).append(";");
		}

		char strEcuId[32] = { 0 };
		Tracer::debug(string("newPkgHwpn: ") + itoa(tempCfg.nEcuId, strEcuId, 16) + "; " + tempCfg.strEcuName, strEcuHwpn);
	}

	return true;
}

int get_jd_vehicleConfig_ecuCount()
{
	std::lock_guard<std::mutex> lock(mItemLock);

	JD_VEHICLE_CONFIG_t vehicleCfg = CVehicleConfig::getInstance()->m_vehicleConfig;
	Tracer::warn("vehicleSoftVer", CVehicleConfig::getInstance()->getCurrentVehicleSoftVer());
	return vehicleCfg.vecListEcu.size();
}

int get_jd_vehicleConfig_ecuId(int index)
{
	std::lock_guard<std::mutex> lock(mItemLock);

	JD_VEHICLE_CONFIG_t vehicleCfg = CVehicleConfig::getInstance()->m_vehicleConfig;
	if (index < vehicleCfg.vecListEcu.size()) {
		uint16_t ecuId = vehicleCfg.vecListEcu.at(index).nEcuId;
		char tempBuffer[32] = { 0 };
		Tracer::warn(__FUNCTION__, itoa(ecuId, tempBuffer, 16));
		return ecuId;
	}

	return -1;
}

int get_jd_vehicleConfig_ecuName(int index, char* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	memset(outBuffer, 0, outBufferSize);
	JD_VEHICLE_CONFIG_t vehicleCfg = CVehicleConfig::getInstance()->m_vehicleConfig;
	if (index < vehicleCfg.vecListEcu.size()) {
		string tempString = vehicleCfg.vecListEcu.at(index).strEcuName;

		if (tempString.length() < outBufferSize) {

			memcpy(outBuffer, tempString.c_str(), tempString.length());
			return tempString.length();
		}
	}

	return -1;
}

int get_jd_vehicleConfig_ecuHwpn(int index, char* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	memset(outBuffer, 0, outBufferSize);
	JD_VEHICLE_CONFIG_t vehicleCfg = CVehicleConfig::getInstance()->m_vehicleConfig;
	if (index < vehicleCfg.vecListEcu.size()) {

		//TODO 获取车内Ecu硬件版本
		string vehicleHwpn;
		string ecuName = vehicleCfg.vecListEcu.at(index).strEcuName;
		uint16_t ecuId = vehicleCfg.vecListEcu.at(index).nEcuId;
		if (DataCenter::m_vehicleInfo.mapEcuInfo.find(ecuId) != DataCenter::m_vehicleInfo.mapEcuInfo.end()) {
			vehicleHwpn = DataCenter::m_vehicleInfo.mapEcuInfo[ecuId].ecuHwpn;
		}

		string tempString;
		vector<JD_MAPPING_CONFIG_t> vec_mapCfg = vehicleCfg.vecListEcu.at(index).vecMapping;
		for (JD_MAPPING_CONFIG_t mapCfg : vec_mapCfg) {
			if (mapCfg.strHwpn._Equal(vehicleHwpn)) {
				tempString = vehicleHwpn;
				break;
			}
			tempString.append(mapCfg.strHwpn).append("\t");
		}

		if (tempString.length() < outBufferSize) {
			memcpy(outBuffer, tempString.c_str(), tempString.length());
			return tempString.length();
		}
	}

	return -1;
}

int get_jd_vehicleConfig_ecuHwpnByEcuName(char* ecuName, char* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	memset(outBuffer, 0, outBufferSize);
	JD_VEHICLE_CONFIG_t vehicleCfg = CVehicleConfig::getInstance()->m_vehicleConfig;
	for (int index = 0; index < vehicleCfg.vecListEcu.size(); index++) {

		string tempName = vehicleCfg.vecListEcu.at(index).strEcuName;
		if (tempName._Equal(ecuName))
		{
			//TODO 获取车内Ecu硬件版本
			string vehicleHwpn;
			uint16_t ecuId = vehicleCfg.vecListEcu.at(index).nEcuId;
			if (DataCenter::m_vehicleInfo.mapEcuInfo.find(ecuId) != DataCenter::m_vehicleInfo.mapEcuInfo.end()) {
				vehicleHwpn = DataCenter::m_vehicleInfo.mapEcuInfo[ecuId].ecuHwpn;
			}

			string tempString;
			vector<JD_MAPPING_CONFIG_t> vec_mapCfg = vehicleCfg.vecListEcu.at(index).vecMapping;
			for (JD_MAPPING_CONFIG_t mapCfg : vec_mapCfg) {
				if (mapCfg.strHwpn._Equal(vehicleHwpn)) {
					tempString = vehicleHwpn;
					break;
				}
				tempString.append(mapCfg.strHwpn).append("\t");
			}

			if (tempString.length() < outBufferSize) {
				memcpy(outBuffer, tempString.c_str(), tempString.length());
				return tempString.length();
			}

			return -1;
		}
	}

	return -1;
}

int get_jd_vehicleConfig_ecuSwpn(int index, char* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	memset(outBuffer, 0, outBufferSize);
	JD_VEHICLE_CONFIG_t vehicleCfg = CVehicleConfig::getInstance()->m_vehicleConfig;
	if (index < vehicleCfg.vecListEcu.size()) {

		//TODO 获取车内Ecu硬件版本
		string vehicleHwpn;
		string ecuName = vehicleCfg.vecListEcu.at(index).strEcuName;
		uint16_t ecuId = vehicleCfg.vecListEcu.at(index).nEcuId;
		if (DataCenter::m_vehicleInfo.mapEcuInfo.find(ecuId) != DataCenter::m_vehicleInfo.mapEcuInfo.end()) {
			vehicleHwpn = DataCenter::m_vehicleInfo.mapEcuInfo[ecuId].ecuHwpn;
		}

		string tempString;
		vector<JD_MAPPING_CONFIG_t> vec_mapCfg = vehicleCfg.vecListEcu.at(index).vecMapping;
		for (JD_MAPPING_CONFIG_t mapCfg : vec_mapCfg) {

			if (mapCfg.strHwpn._Equal(vehicleHwpn))
			{
				for (JD_VSP_FLASH_INFO_t order : mapCfg.vecOderList) {
					if (order.strFileType._Equal("SBL"))
					{
						continue;
					}
					else if (MyStringUtils::startWith(order.strFileType, "DATA")) {
						//TODO POT 高配车用13开头的数据包;低配车12开头的数据包
						if (ecuName._Equal("POT"))
						{
							VehicleCfg vehicleConfig;
							DataCenter::getInstance()->getCarConfig(DataCenter::m_vehicleInfo.binCCP, vehicleConfig);
							if (vehicleConfig.iEmpennage == 0x02 && MyStringUtils::startWith(order.strVersion, "13")) {
								tempString.append(order.strVersion).append("\t");
							}
							else if (vehicleConfig.iEmpennage == 0x01 && MyStringUtils::startWith(order.strVersion, "12")) {
								tempString.append(order.strVersion).append("\t");
							}
						}
						else
						{
							tempString.append(order.strVersion).append("\t");
						}
					}
					else {
						tempString.append(order.strVersion).append("\t");
					}
				}
			}
		}

		if (tempString.length() < outBufferSize) {

			memcpy(outBuffer, tempString.c_str(), tempString.length());
			return tempString.length();
		}
	}

	return -1;
}

int get_jd_vehicleConfig_ecuSwpnByEcuName(char* ecuName, char* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	memset(outBuffer, 0, outBufferSize);
	JD_VEHICLE_CONFIG_t vehicleCfg = CVehicleConfig::getInstance()->m_vehicleConfig;
	for (int index = 0; index < vehicleCfg.vecListEcu.size(); index++) {

		string tempName = vehicleCfg.vecListEcu.at(index).strEcuName;
		if (tempName._Equal(ecuName))
		{
			//TODO 获取车内Ecu硬件版本
			string vehicleHwpn;
			uint16_t ecuId = vehicleCfg.vecListEcu.at(index).nEcuId;
			if (DataCenter::m_vehicleInfo.mapEcuInfo.find(ecuId) != DataCenter::m_vehicleInfo.mapEcuInfo.end()) {
				vehicleHwpn = DataCenter::m_vehicleInfo.mapEcuInfo[ecuId].ecuHwpn;
			}

			string tempString;
			vector<JD_MAPPING_CONFIG_t> vec_mapCfg = vehicleCfg.vecListEcu.at(index).vecMapping;
			for (JD_MAPPING_CONFIG_t mapCfg : vec_mapCfg) {

				if (mapCfg.strHwpn._Equal(vehicleHwpn))
				{
					JD_ECU_INFO_t ecuOrderInfo;
					for (JD_ECU_INFO_t tempEcuInfo : DataCenter::m_VehicleOrderInfo.vecListEcu) {
						if (tempEcuInfo.strEcuName._Equal(tempName)) {
							ecuOrderInfo = tempEcuInfo;
						}
					}
					for (JD_VSP_FLASH_INFO_t order : mapCfg.vecOderList) {

						bool isMatch = false;
						for (JD_ECU_SWPN_INFO_t swpnInfo : ecuOrderInfo.vecEcuSwpnList) {
							if (swpnInfo.strEcuSwpn._Equal(order.strVersion)) {
								isMatch = true;
							}
						}

						if (!isMatch) {
							Tracer::warn("skip ecuSpwn", string("Ecu: ") + tempName + ", swpn: " + order.strVersion);
							continue;
						}

						if (order.strFileType._Equal("SBL"))
						{
							continue;
						}
						else if (MyStringUtils::startWith(order.strFileType, "DATA")) {
							//TODO POT 高配车用13开头的数据包;低配车12开头的数据包
							if (tempName._Equal("POT"))
							{
								VehicleCfg vehicleConfig;
								DataCenter::getInstance()->getCarConfig(DataCenter::m_vehicleInfo.binCCP, vehicleConfig);
								if (vehicleConfig.iEmpennage == 0x02 && MyStringUtils::startWith(order.strVersion, "13")) {
									tempString.append(order.strVersion).append("\t");
								}
								else if (vehicleConfig.iEmpennage == 0x01 && MyStringUtils::startWith(order.strVersion, "12")) {
									tempString.append(order.strVersion).append("\t");
								}
							}
							else
							{
								tempString.append(order.strVersion).append("\t");
							}
						}
						else {
							tempString.append(order.strVersion).append("\t");
						}
					}
				}
			}

			if (tempString.length() < outBufferSize) {

				memcpy(outBuffer, tempString.c_str(), tempString.length());
				return tempString.length();
			}
			return -1;
		}
	}
	return -1;
}

int get_jd_vehicleConfig_ecuIdByEcuName(char* ecuName, char* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	memset(outBuffer, 0, outBufferSize);
	JD_VEHICLE_CONFIG_t vehicleCfg = CVehicleConfig::getInstance()->m_vehicleConfig;
	for (int index = 0; index < vehicleCfg.vecListEcu.size(); index++) {
		string tempName = vehicleCfg.vecListEcu.at(index).strEcuName;
		if (tempName._Equal(ecuName))
		{
			int ecuId = vehicleCfg.vecListEcu.at(index).nEcuId;
			string tempString = MyStringUtils::toString(ecuId, 16);
			memcpy(outBuffer, tempString.c_str(), tempString.length());
			return tempString.length();
		}
	}

	return -1;
}

int get_jd_vehicleConfig_ecuFlashFileSize(int index, char* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	memset(outBuffer, 0, outBufferSize);
	JD_VEHICLE_CONFIG_t vehicleCfg = CVehicleConfig::getInstance()->m_vehicleConfig;

	if (index < vehicleCfg.vecListEcu.size()) {

		//TODO 获取车内Ecu硬件版本
		string vehicleHwpn;
		string ecuName = vehicleCfg.vecListEcu.at(index).strEcuName;
		string boomEcuName = vehicleCfg.vecListEcu.at(index).strBoomEcuName;
		uint32_t ecuId = vehicleCfg.vecListEcu.at(index).nEcuId;
		if (DataCenter::m_vehicleInfo.mapEcuInfo.find(ecuId) != DataCenter::m_vehicleInfo.mapEcuInfo.end()) {
			vehicleHwpn = DataCenter::m_vehicleInfo.mapEcuInfo[ecuId].ecuHwpn;
		}

		if (vehicleHwpn.empty()) {
			Tracer::error(__FUNCTION__, string("vehicleHwpn is empty: ") + ecuName);
			return -1;
		}

		//TODO 兼容处理
		if (boomEcuName.empty()) {
			boomEcuName = ecuName;
			if (MyStringUtils::startWith("BECM1", boomEcuName)) {
				boomEcuName = "BECM1";
			}
		}

		vector<JD_MAPPING_CONFIG_t> vec_mapCfg = vehicleCfg.vecListEcu.at(index).vecMapping;

		uint64_t totalSize = 0;
		for (JD_MAPPING_CONFIG_t mapCfg : vec_mapCfg) {
			if (mapCfg.strHwpn._Equal(vehicleHwpn))
			{
				for (JD_VSP_FLASH_INFO_t order : mapCfg.vecOderList) {
					string ecuSwpn = order.strVersion;
					totalSize += CVehicleConfig::getInstance()->GetFlashFileSize(ecuId, boomEcuName, vehicleHwpn, ecuSwpn);
				}

				if (totalSize == 0)
				{
					sprintf(outBuffer, "---");
					Tracer::error(__FUNCTION__, boomEcuName + ": totalSize=0");
				}
				else if (totalSize / 1024 == 0)
				{
					float nValue = totalSize;
					sprintf(outBuffer, "%.2f bytes", nValue);
				}
				else if ((totalSize / 1024) / 1024 == 0)
				{
					float nValue = totalSize / ((float)1024.00);
					sprintf(outBuffer, "%.2f K", nValue);
				}
				else
				{
					float nValue = (totalSize / ((float)1024.00)) / ((float)1024.00);
					sprintf(outBuffer, "%.2f M", nValue);
				}

				return totalSize;
			}
		}
	}

	return 0;
}

int get_jd_vehicleConfig_ecuFlashFileSizeByEcuName(char* ecuName, char* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	memset(outBuffer, 0, outBufferSize);
	JD_VEHICLE_CONFIG_t vehicleCfg = CVehicleConfig::getInstance()->m_vehicleConfig;

	for (int index = 0; index < vehicleCfg.vecListEcu.size(); index++) {
		string tempName = vehicleCfg.vecListEcu.at(index).strEcuName;
		if (tempName._Equal(ecuName)) {
			string boomEcuName = vehicleCfg.vecListEcu.at(index).strBoomEcuName;
			uint32_t ecuId = vehicleCfg.vecListEcu.at(index).nEcuId;
			//TODO 获取车内Ecu硬件版本
			string vehicleHwpn;
			if (DataCenter::m_vehicleInfo.mapEcuInfo.find(ecuId) != DataCenter::m_vehicleInfo.mapEcuInfo.end()) {
				vehicleHwpn = DataCenter::m_vehicleInfo.mapEcuInfo.at(ecuId).ecuHwpn;
			}

			//TODO 兼容处理
			if (boomEcuName.empty()) {
				boomEcuName = ecuName;
				if (MyStringUtils::startWith("BECM1", boomEcuName)) {
					boomEcuName = "BECM1";
				}
			}

			vector<JD_MAPPING_CONFIG_t> vec_mapCfg = vehicleCfg.vecListEcu.at(index).vecMapping;

			uint64_t totalSize = 0;
			for (JD_MAPPING_CONFIG_t mapCfg : vec_mapCfg) {
				if (mapCfg.strHwpn._Equal(vehicleHwpn))
				{
					for (JD_VSP_FLASH_INFO_t order : mapCfg.vecOderList) {
						string ecuSwpn = order.strVersion;
						totalSize += CVehicleConfig::getInstance()->GetFlashFileSize(ecuId, boomEcuName, vehicleHwpn, ecuSwpn);
					}

					if (totalSize == 0)
					{
						sprintf(outBuffer, "---");
						Tracer::error(__FUNCTION__, boomEcuName + ": totalSize=0");
					}
					else if (totalSize / 1024 == 0)
					{
						float nValue = totalSize;
						sprintf(outBuffer, "%.2f bytes", nValue);
					}
					else if ((totalSize / 1024) / 1024 == 0)
					{
						float nValue = totalSize / ((float)1024.00);
						sprintf(outBuffer, "%.2f K", nValue);
					}
					else
					{
						float nValue = (totalSize / ((float)1024.00)) / ((float)1024.00);
						sprintf(outBuffer, "%.2f M", nValue);
					}

					return totalSize;
				}
			}

			return 0;
		}
	}

	return 0;
}

int get_jd_vehicleConfig_ecuHwpnByEcuId(uint16_t ecuId, char* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	memset(outBuffer, 0, outBufferSize);
	JD_VEHICLE_CONFIG_t vehicleCfg = CVehicleConfig::getInstance()->m_vehicleConfig;
	for (int index = 0; index < vehicleCfg.vecListEcu.size(); index++) {

		uint16_t tempEcuId = vehicleCfg.vecListEcu.at(index).nEcuId;
		if (tempEcuId == ecuId)
		{
			//TODO 获取车内Ecu硬件版本
			char vehicleHwpn[32] = { 0 };
			get_jd_vehicleInfo_ecuHwpn_byEcuId(ecuId, vehicleHwpn, 32);

			string tempString;
			vector<JD_MAPPING_CONFIG_t> vec_mapCfg = vehicleCfg.vecListEcu.at(index).vecMapping;
			for (JD_MAPPING_CONFIG_t mapCfg : vec_mapCfg) {
				if (mapCfg.strHwpn._Equal(vehicleHwpn)) {
					tempString = vehicleHwpn;
					break;
				}
				tempString.append(mapCfg.strHwpn).append("\t");
			}

			char tempBuffer[32] = { 0 };
			Tracer::debug(__FUNCTION__, string("EcuId: ") + itoa(ecuId, tempBuffer, 16) + "; vehicleHwpn: " + vehicleHwpn + "; pkgHwpn: " + tempString);

			if (tempString.length() < outBufferSize) {
				memcpy(outBuffer, tempString.c_str(), tempString.length());
				return tempString.length();
			}

			return -1;
		}
	}

	return -1;
}

int get_jd_vehicleConfig_ecuSwpnByEcuId(uint16_t ecuId, char* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	memset(outBuffer, 0, outBufferSize);
	JD_VEHICLE_CONFIG_t vehicleCfg = CVehicleConfig::getInstance()->m_vehicleConfig;
	for (int index = 0; index < vehicleCfg.vecListEcu.size(); index++) {

		uint16_t tempEcuId = vehicleCfg.vecListEcu.at(index).nEcuId;
		if (tempEcuId == ecuId)
		{
			//TODO 获取车内Ecu硬件版本
			char vehicleEcuHwpn[32] = { 0 };
			get_jd_vehicleInfo_ecuHwpn_byEcuId(ecuId, vehicleEcuHwpn, 32);

			string tempString;
			vector<JD_MAPPING_CONFIG_t> vec_mapCfg = vehicleCfg.vecListEcu.at(index).vecMapping;
			for (JD_MAPPING_CONFIG_t mapCfg : vec_mapCfg) {

				if (mapCfg.strHwpn._Equal(vehicleEcuHwpn))
				{
					for (JD_VSP_FLASH_INFO_t order : mapCfg.vecOderList) {
						if (order.strFileType._Equal("SBL"))
						{
							continue;
						}
						else {
							if (tempString.find(order.strVersion) != string::npos) {
								continue;
							}

							if (MyStringUtils::startWith(order.strFileType, "DATA")) {
								//TODO POT 高配车用13开头的数据包;低配车12开头的数据包
								if (tempEcuId == 0x6111)
								{
									VehicleCfg vehicleConfig;
									DataCenter::getInstance()->getCarConfig(DataCenter::m_vehicleInfo.binCCP, vehicleConfig);
									if (vehicleConfig.iEmpennage == 0x02 && MyStringUtils::startWith(order.strVersion, "13")) {
										tempString.append(order.strVersion).append("\t");
									}
									else if (vehicleConfig.iEmpennage == 0x01 && MyStringUtils::startWith(order.strVersion, "12")) {
										tempString.append(order.strVersion).append("\t");
									}
								}
								else
								{
									tempString.append(order.strVersion).append("\t");
								}
							}
							else {
								tempString.append(order.strVersion).append("\t");
							}
						}
					}
					break;
				}
			}

			if (tempString.length() < outBufferSize) {

				memcpy(outBuffer, tempString.c_str(), tempString.length());
				return tempString.length();
			}
			return -1;
		}
	}
	return -1;
}

int get_jd_vehicleConfig_ecuNameByEcuId(uint16_t ecuId, char* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	memset(outBuffer, 0, outBufferSize);
	JD_VEHICLE_CONFIG_t vehicleCfg = CVehicleConfig::getInstance()->m_vehicleConfig;
	for (int index = 0; index < vehicleCfg.vecListEcu.size(); index++) {
		uint16_t tempEcuId = vehicleCfg.vecListEcu.at(index).nEcuId;
		if (tempEcuId == ecuId)
		{
			string tempString = vehicleCfg.vecListEcu.at(index).strEcuName;
			memcpy(outBuffer, tempString.c_str(), tempString.length());
			return tempString.length();
		}
	}

	return -1;
}

int get_jd_vehicleConfig_ecuFlashFileSizeByEcuId(uint16_t ecuId, char* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	memset(outBuffer, 0, outBufferSize);
	JD_VEHICLE_CONFIG_t vehicleCfg = CVehicleConfig::getInstance()->m_vehicleConfig;

	//TODO 获取车内Ecu硬件版本
	char vehicleEcuHwpn[32] = { 0 };
	get_jd_vehicleInfo_ecuHwpn_byEcuId(ecuId, vehicleEcuHwpn, 32);

	for (int index = 0; index < vehicleCfg.vecListEcu.size(); index++) {
		uint16_t tempEcuId = vehicleCfg.vecListEcu.at(index).nEcuId;
		if (tempEcuId == ecuId)
		{
			string boomEcuName = vehicleCfg.vecListEcu.at(index).strBoomEcuName;
			string ecuName = vehicleCfg.vecListEcu.at(index).strEcuName;

			//TODO 兼容处理
			if (boomEcuName.empty()) {
				boomEcuName = ecuName;
			}

			vector<JD_MAPPING_CONFIG_t> vec_mapCfg = vehicleCfg.vecListEcu.at(index).vecMapping;

			uint64_t totalSize = 0;
			for (JD_MAPPING_CONFIG_t mapCfg : vec_mapCfg) {
				if (mapCfg.strHwpn._Equal(vehicleEcuHwpn))
				{
					for (JD_VSP_FLASH_INFO_t order : mapCfg.vecOderList) {
						string ecuSwpn = order.strVersion;
						totalSize += CVehicleConfig::getInstance()->GetFlashFileSize(ecuId, boomEcuName, vehicleEcuHwpn, ecuSwpn);
					}

					if (totalSize == 0)
					{
						sprintf(outBuffer, "---");
						Tracer::error(__FUNCTION__, boomEcuName + ": totalSize=0");
					}
					else if (totalSize / 1024 == 0)
					{
						float nValue = totalSize;
						sprintf(outBuffer, "%.2f bytes", nValue);
					}
					else if ((totalSize / 1024) / 1024 == 0)
					{
						float nValue = totalSize / ((float)1024.00);
						sprintf(outBuffer, "%.2f K", nValue);
					}
					else
					{
						float nValue = (totalSize / ((float)1024.00)) / ((float)1024.00);
						sprintf(outBuffer, "%.2f M", nValue);
					}

					return totalSize;
				}
			}

			return 0;
		}
	}

	return 0;
}

int get_jd_vehicleConfig_displayBaseLine(char* outBuffer, uint32_t outBufferSize) {
	std::lock_guard<std::mutex> lock(mItemLock);
	memset(outBuffer, 0, outBufferSize);

	string tempString = CVehicleConfig::getInstance()->m_vehicleConfig.strDisplayBaseLine;
	if (outBufferSize >= tempString.size())
	{
		memcpy(outBuffer, tempString.c_str(), tempString.size());
		return (int)tempString.size();
	}
	else {
		Tracer::error("bufferSize", "too small to receive.");
		return -1;
	}
}

int get_jd_vehicleConfig_latestAvailableSwpn(char* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	memset(outBuffer, 0, outBufferSize);
	vector<string> pkgList = CVehicleConfig::getInstance()->m_vecVehicleSoftVer;

	std::string latestConfig;
	for (string config : pkgList)
	{
		if (latestConfig.compare(config) < 0)
		{
			latestConfig = config;
		}
	}

	string tempString = latestConfig;
	if (outBufferSize >= tempString.size())
	{
		memcpy(outBuffer, tempString.c_str(), tempString.size());
		return (int)tempString.size();
	}

	Tracer::error("bufferSize", "too small to receive.");
	return -1;
}

int get_jd_vehicleConfig_latestBatchSwpn(char* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	memset(outBuffer, 0, outBufferSize);
	vector<string> pkgList = CVehicleConfig::getInstance()->m_vecVehicleSoftVer;

	std::string latestConfig;
	for (string config : pkgList)
	{
		//TODO 最新批量包
		if (CVehicleConfig::getInstance()->IsLatestBatch(DataCenter::m_vehicleInfo.vehicleType, config)) {
			if (latestConfig.compare(config) < 0)
			{
				latestConfig = config;
			}
		}
	}

	string tempString = latestConfig;
	if (outBufferSize >= tempString.size())
	{
		memcpy(outBuffer, tempString.c_str(), tempString.size());
		return (int)tempString.size();
	}
	else {
		Tracer::error("bufferSize", "too small to receive.");
		return -1;
	}

	return tempString.size();
}

int get_jd_SBL_verificationBlockStart(char* ecuName, char* hwpn, char* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	memset(outBuffer, 0, outBufferSize);

	char ecuHwpn[32] = { 0 };
	if (hwpn == NULL || 0 == strcmp(hwpn, "") || strlen(hwpn) == 0) {
		get_jd_orderInfo_ecuHwpn_byEcuName(ecuName, ecuHwpn, 32);
		hwpn = ecuHwpn;
	}

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	if (CVehicleConfig::getInstance()->getEcuFileInfo(ecuName, hwpn, vecFlashInfo)) {
		string tempString;
		for (int i = 0; i < vecFlashInfo.size(); i++) {
			JD_VSP_FLASH_CONFIG_t oneFlahsInfo = vecFlashInfo.at(i);
			VBFParserSmall* parser = oneFlahsInfo.pVBFParser;

			if (oneFlahsInfo.strFileType._Equal("SBL")) {
				tempString = parser->getHeader().getVerifBlockStart();
				if (outBufferSize >= tempString.size()) {
					memcpy(outBuffer, tempString.c_str(), tempString.size());
				}
				else {
					Tracer::error("bufferSize", "too small to receive.");
				}
			}

			delete parser;
		}

		return (int)tempString.size();
	}

	return -1;
}

int get_jd_SBL_verificationBlockLength(char* ecuName, char* hwpn)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	char ecuHwpn[32] = { 0 };
	if (hwpn == NULL || 0 == strcmp(hwpn, "") || strlen(hwpn) == 0) {
		get_jd_orderInfo_ecuHwpn_byEcuName(ecuName, ecuHwpn, 32);
		hwpn = ecuHwpn;
	}

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	if (CVehicleConfig::getInstance()->getEcuFileInfo(ecuName, hwpn, vecFlashInfo)) {
		int rBlockLength = 0;
		for (int i = 0; i < vecFlashInfo.size(); i++) {
			JD_VSP_FLASH_CONFIG_t oneFlahsInfo = vecFlashInfo.at(i);
			VBFParserSmall* parser = oneFlahsInfo.pVBFParser;

			if (oneFlahsInfo.strFileType._Equal("SBL")) {
				string tempString = parser->getHeader().getVerifBlockLength();
				rBlockLength = stoi(tempString);
			}

			delete parser;
		}

		return rBlockLength;
	}

	return -1;
}

int get_jd_SBL_blockCount(char* ecuName, char* hwpn)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	char ecuHwpn[32] = { 0 };
	if (hwpn == NULL || 0 == strcmp(hwpn, "") || strlen(hwpn) == 0) {
		get_jd_orderInfo_ecuHwpn_byEcuName(ecuName, ecuHwpn, 32);
		hwpn = ecuHwpn;
	}

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	if (CVehicleConfig::getInstance()->getEcuFileInfo(ecuName, hwpn, vecFlashInfo)) {
		int rBlockCount = 0;
		for (int i = 0; i < vecFlashInfo.size(); i++) {
			JD_VSP_FLASH_CONFIG_t oneFlahsInfo = vecFlashInfo.at(i);
			VBFParserSmall* parser = oneFlahsInfo.pVBFParser;

			if (oneFlahsInfo.strFileType._Equal("SBL")) {
				rBlockCount = parser->GetVBFBlocks().size();
			}

			delete parser;
		}

		return rBlockCount;
	}

	return -1;
}

int get_jd_SBL_blockCheckSumByIndex(char* ecuName, char* hwpn, int index, uint8_t* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	char ecuHwpn[32] = { 0 };
	if (hwpn == NULL || 0 == strcmp(hwpn, "") || strlen(hwpn) == 0) {
		get_jd_orderInfo_ecuHwpn_byEcuName(ecuName, ecuHwpn, 32);
		hwpn = ecuHwpn;
	}

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	if (CVehicleConfig::getInstance()->getEcuFileInfo(ecuName, hwpn, vecFlashInfo)) {
		int rcheckSum = 0;
		for (int i = 0; i < vecFlashInfo.size(); i++) {
			JD_VSP_FLASH_CONFIG_t oneFlahsInfo = vecFlashInfo.at(i);
			VBFParserSmall* parser = oneFlahsInfo.pVBFParser;

			if (oneFlahsInfo.strFileType._Equal("SBL")) {
				if (index > parser->GetVBFBlocks().size()) {
					Tracer::error("index", "outof the bound");
				}
				else {
					rcheckSum = parser->GetVBFBlocks().at(index).GetCheckSum();
				}

			}

			delete parser;
		}

		if (rcheckSum == 0) {
			return -1;
		}

		return radix_int2ByteArray(rcheckSum, outBuffer, outBufferSize);
	}

	return -1;
}

int get_jd_SBL_blockStartAddrByIndex(char* ecuName, char* hwpn, int index, uint8_t* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	char ecuHwpn[32] = { 0 };
	if (hwpn == NULL || 0 == strcmp(hwpn, "") || strlen(hwpn) == 0) {
		get_jd_orderInfo_ecuHwpn_byEcuName(ecuName, ecuHwpn, 32);
		hwpn = ecuHwpn;
	}

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	if (CVehicleConfig::getInstance()->getEcuFileInfo(ecuName, hwpn, vecFlashInfo)) {
		int startAddr = 0;
		for (int i = 0; i < vecFlashInfo.size(); i++) {
			JD_VSP_FLASH_CONFIG_t oneFlahsInfo = vecFlashInfo.at(i);
			VBFParserSmall* parser = oneFlahsInfo.pVBFParser;

			if (oneFlahsInfo.strFileType._Equal("SBL")) {
				if (index > parser->GetVBFBlocks().size()) {
					Tracer::error("index", "outof the bound");
				}
				else {
					startAddr = parser->GetVBFBlocks().at(index).GetStartAddress();
				}
			}

			delete parser;
		}
		if (startAddr == 0) {
			return -1;
		}
		return radix_int2ByteArray(startAddr, outBuffer, outBufferSize);
	}

	return -1;
}

int get_jd_SBL_blockLengthByIndex(char* ecuName, char* hwpn, int index, uint8_t* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	char ecuHwpn[32] = { 0 };
	if (hwpn == NULL || 0 == strcmp(hwpn, "") || strlen(hwpn) == 0) {
		get_jd_orderInfo_ecuHwpn_byEcuName(ecuName, ecuHwpn, 32);
		hwpn = ecuHwpn;
	}

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	if (CVehicleConfig::getInstance()->getEcuFileInfo(ecuName, hwpn, vecFlashInfo)) {
		int rLenth = 0;
		for (int i = 0; i < vecFlashInfo.size(); i++) {
			JD_VSP_FLASH_CONFIG_t oneFlahsInfo = vecFlashInfo.at(i);
			VBFParserSmall* parser = oneFlahsInfo.pVBFParser;

			if (oneFlahsInfo.strFileType._Equal("SBL")) {
				if (index > parser->GetVBFBlocks().size()) {
					Tracer::error("index", "outof the bound");
				}
				else {
					rLenth = parser->GetVBFBlocks().at(index).GetLength();
				}
			}

			delete parser;
		}
		if (rLenth == 0) {
			return -1;
		}
		return radix_int2ByteArray(rLenth, outBuffer, outBufferSize);

	}

	return -1;
}

int get_jd_SBL_blockDataLengthByIndex(char* ecuName, char* hwpn, int index, uint8_t* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	char ecuHwpn[32] = { 0 };
	if (hwpn == NULL || 0 == strcmp(hwpn, "") || strlen(hwpn) == 0) {
		get_jd_orderInfo_ecuHwpn_byEcuName(ecuName, ecuHwpn, 32);
		hwpn = ecuHwpn;
	}

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	if (CVehicleConfig::getInstance()->getEcuFileInfo(ecuName, hwpn, vecFlashInfo)) {
		int rLenth = 0;
		for (int i = 0; i < vecFlashInfo.size(); i++) {
			JD_VSP_FLASH_CONFIG_t oneFlahsInfo = vecFlashInfo.at(i);
			VBFParserSmall* parser = oneFlahsInfo.pVBFParser;

			if (oneFlahsInfo.strFileType._Equal("SBL")) {
				if (index > parser->GetVBFBlocks().size()) {
					Tracer::error("index", "outof the bound");
				}
				else {
					vector<uint8_t> bData = parser->GetVBFBlocks().at(index).GetBlockData();
					rLenth = bData.size();
				}
			}

			delete parser;
		}
		if (rLenth == 0) {
			return -1;
		}
		return radix_int2ByteArray(rLenth, outBuffer, outBufferSize);
	}

	return -1;
}

int get_jd_SBL_blockDataByIndex(char* ecuName, char* hwpn, int index, uint8_t* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	memset(outBuffer, 0, outBufferSize);

	char ecuHwpn[32] = { 0 };
	if (hwpn == NULL || 0 == strcmp(hwpn, "") || strlen(hwpn) == 0) {
		get_jd_orderInfo_ecuHwpn_byEcuName(ecuName, ecuHwpn, 32);
		hwpn = ecuHwpn;
	}

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	if (CVehicleConfig::getInstance()->getEcuFileInfo(ecuName, hwpn, vecFlashInfo)) {
		int rLenth = 0;
		for (int i = 0; i < vecFlashInfo.size(); i++) {
			JD_VSP_FLASH_CONFIG_t oneFlahsInfo = vecFlashInfo.at(i);
			VBFParserSmall* parser = oneFlahsInfo.pVBFParser;

			if (oneFlahsInfo.strFileType._Equal("SBL")) {
				if (index > parser->GetVBFBlocks().size()) {
					Tracer::error("index", "outof the bound");
				}
				else {
					vector<uint8_t> bData = parser->GetVBFBlocks().at(index).GetBlockData();

					if (outBufferSize >= bData.size()) {
						rLenth = bData.size();
						memcpy(outBuffer, bData.data(), rLenth);
					}
					else {
						Tracer::error("bufferSize", "too small to receive.");
					}
				}
			}

			delete parser;
		}

		return rLenth;
	}

	return -1;
}

int get_jd_SBL_swSignature(char* ecuName, char* hwpn, uint8_t* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	memset(outBuffer, 0, outBufferSize);

	char ecuHwpn[32] = { 0 };
	if (hwpn == NULL || 0 == strcmp(hwpn, "") || strlen(hwpn) == 0) {
		get_jd_orderInfo_ecuHwpn_byEcuName(ecuName, ecuHwpn, 32);
		hwpn = ecuHwpn;
	}

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	if (CVehicleConfig::getInstance()->getEcuFileInfo(ecuName, hwpn, vecFlashInfo)) {
		int rLenth = 0;
		for (int i = 0; i < vecFlashInfo.size(); i++) {
			JD_VSP_FLASH_CONFIG_t oneFlahsInfo = vecFlashInfo.at(i);
			VBFParserSmall* parser = oneFlahsInfo.pVBFParser;

			if (oneFlahsInfo.strFileType._Equal("SBL")) {
				string tempString = parser->getHeader().getSWSignature();

				if (outBufferSize >= tempString.length() / 2) {
					rLenth = radix_hex2Array(tempString.c_str(), tempString.length(), outBuffer, outBufferSize);
				}
				else {
					Tracer::error("bufferSize", "too small to receive.");
				}
			}

			delete parser;
		}

		return rLenth;
	}

	return -1;
}

int get_jd_SBL_dataFormatIdentifier(char* ecuName, char* hwpn, uint8_t* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	memset(outBuffer, 0, outBufferSize);

	char ecuHwpn[32] = { 0 };
	if (hwpn == NULL || 0 == strcmp(hwpn, "") || strlen(hwpn) == 0) {
		get_jd_orderInfo_ecuHwpn_byEcuName(ecuName, ecuHwpn, 32);
		hwpn = ecuHwpn;
	}

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	if (CVehicleConfig::getInstance()->getEcuFileInfo(ecuName, hwpn, vecFlashInfo)) {
		int rLenth = 0;
		for (int i = 0; i < vecFlashInfo.size(); i++) {
			JD_VSP_FLASH_CONFIG_t oneFlahsInfo = vecFlashInfo.at(i);
			VBFParserSmall* parser = oneFlahsInfo.pVBFParser;

			if (oneFlahsInfo.strFileType._Equal("SBL")) {
				string tempString = parser->getHeader().getDataFormatIndetifier();

				if (outBufferSize >= tempString.length() / 2) {
					rLenth = radix_hex2Array(tempString.c_str(), tempString.length(), outBuffer, outBufferSize);
				}
				else {
					Tracer::error("bufferSize", "too small to receive.");
				}
			}

			delete parser;
		}

		return rLenth;
	}

	return -1;
}

int get_jd_SBL_erraseInfo(char* ecuName, char* hwpn, uint8_t* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	memset(outBuffer, 0, outBufferSize);

	char ecuHwpn[32] = { 0 };
	if (hwpn == NULL || 0 == strcmp(hwpn, "") || strlen(hwpn) == 0) {
		get_jd_orderInfo_ecuHwpn_byEcuName(ecuName, ecuHwpn, 32);
		hwpn = ecuHwpn;
	}

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	if (CVehicleConfig::getInstance()->getEcuFileInfo(ecuName, hwpn, vecFlashInfo)) {
		int rLenth = 0;
		for (int i = 0; i < vecFlashInfo.size(); i++) {
			JD_VSP_FLASH_CONFIG_t oneFlahsInfo = vecFlashInfo.at(i);
			VBFParserSmall* parser = oneFlahsInfo.pVBFParser;

			if (oneFlahsInfo.strFileType._Equal("SBL")) {

				vector<string> vec = parser->getHeader().getListOfErase();
				string tempString;
				for (string temp : vec) {
					tempString.append(temp).append(";");
				}

				if (outBufferSize >= tempString.length() / 2) {
					rLenth = radix_hex2Array(tempString.c_str(), tempString.length(), outBuffer, outBufferSize);
				}
				else {
					Tracer::error("bufferSize", "too small to receive.");
				}
			}

			delete parser;
		}

		return rLenth;
	}

	return -1;
}

int get_jd_SBL_activeAddress(char* ecuName, char* hwpn, uint8_t* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	memset(outBuffer, 0, outBufferSize);

	char ecuHwpn[32] = { 0 };
	if (hwpn == NULL || 0 == strcmp(hwpn, "") || strlen(hwpn) == 0) {
		get_jd_orderInfo_ecuHwpn_byEcuName(ecuName, ecuHwpn, 32);
		hwpn = ecuHwpn;
	}

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	if (CVehicleConfig::getInstance()->getEcuFileInfo(ecuName, hwpn, vecFlashInfo)) {
		int rLenth = 0;
		for (int i = 0; i < vecFlashInfo.size(); i++) {
			JD_VSP_FLASH_CONFIG_t oneFlahsInfo = vecFlashInfo.at(i);
			VBFParserSmall* parser = oneFlahsInfo.pVBFParser;

			if (oneFlahsInfo.strFileType._Equal("SBL")) {
				string tempString = parser->getHeader().getCall();

				if (outBufferSize >= tempString.length() / 2) {
					rLenth = radix_hex2Array(tempString.c_str(), tempString.length(), outBuffer, outBufferSize);
					if (rLenth > 0)
					{
						rLenth = tempString.length() / 2;
					}
				}
				else {
					Tracer::error("bufferSize", "too small to receive.");
				}
			}

			delete parser;
		}

		return rLenth;
	}

	return -1;
}

int get_jd_SBL_swSignatureDev(char* ecuName, char* hwpn, uint8_t* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	memset(outBuffer, 0, outBufferSize);

	char ecuHwpn[32] = { 0 };
	if (hwpn == NULL || 0 == strcmp(hwpn, "") || strlen(hwpn) == 0) {
		get_jd_orderInfo_ecuHwpn_byEcuName(ecuName, ecuHwpn, 32);
		hwpn = ecuHwpn;
	}

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	if (CVehicleConfig::getInstance()->getEcuFileInfo(ecuName, hwpn, vecFlashInfo)) {
		int rLenth = 0;
		for (int i = 0; i < vecFlashInfo.size(); i++) {
			JD_VSP_FLASH_CONFIG_t oneFlahsInfo = vecFlashInfo.at(i);
			VBFParserSmall* parser = oneFlahsInfo.pVBFParser;

			if (oneFlahsInfo.strFileType._Equal("SBL")) {
				string tempString = parser->getHeader().getSWSignatureDev();

				if (outBufferSize >= tempString.length() / 2) {
					rLenth = radix_hex2Array(tempString.c_str(), tempString.length(), outBuffer, outBufferSize);
				}
				else {
					Tracer::error("bufferSize", "too small to receive.");
				}
			}

			delete parser;
		}

		return rLenth;
	}

	return -1;
}



int get_jd_SBL_verificationBlockStart_byEcuId(int ecuId, char* hwpn, char* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	memset(outBuffer, 0, outBufferSize);

	char ecuHwpn[32] = { 0 };
	if (hwpn == NULL || 0 == strcmp(hwpn, "") || strlen(hwpn) == 0) {
		get_jd_orderInfo_ecuHwpn_byEcuId(ecuId, ecuHwpn, 32);
		hwpn = ecuHwpn;
	}

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	if (CVehicleConfig::getInstance()->getEcuFileInfo(ecuId, hwpn, vecFlashInfo)) {
		string tempString;
		for (int i = 0; i < vecFlashInfo.size(); i++) {
			JD_VSP_FLASH_CONFIG_t oneFlahsInfo = vecFlashInfo.at(i);
			VBFParserSmall* parser = oneFlahsInfo.pVBFParser;

			if (oneFlahsInfo.strFileType._Equal("SBL")) {
				tempString = parser->getHeader().getVerifBlockStart();
				if (outBufferSize >= tempString.size()) {
					memcpy(outBuffer, tempString.c_str(), tempString.size());
				}
				else {
					Tracer::error("bufferSize", "too small to receive.");
				}
			}

			delete parser;
		}

		return (int)tempString.size();
	}

	return -1;
}

int get_jd_SBL_verificationBlockLength_byEcuId(int ecuId, char* hwpn)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	char ecuHwpn[32] = { 0 };
	if (hwpn == NULL || 0 == strcmp(hwpn, "") || strlen(hwpn) == 0) {
		get_jd_orderInfo_ecuHwpn_byEcuId(ecuId, ecuHwpn, 32);
		hwpn = ecuHwpn;
	}

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	if (CVehicleConfig::getInstance()->getEcuFileInfo(ecuId, hwpn, vecFlashInfo)) {
		int rBlockLength = 0;
		for (int i = 0; i < vecFlashInfo.size(); i++) {
			JD_VSP_FLASH_CONFIG_t oneFlahsInfo = vecFlashInfo.at(i);
			VBFParserSmall* parser = oneFlahsInfo.pVBFParser;

			if (oneFlahsInfo.strFileType._Equal("SBL")) {
				string tempString = parser->getHeader().getVerifBlockLength();
				rBlockLength = stoi(tempString);
			}

			delete parser;
		}

		return rBlockLength;
	}

	return -1;
}

int get_jd_SBL_blockCount_byEcuId(int ecuId, char* hwpn)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	char ecuHwpn[32] = { 0 };
	if (hwpn == NULL || 0 == strcmp(hwpn, "") || strlen(hwpn) == 0) {
		get_jd_orderInfo_ecuHwpn_byEcuId(ecuId, ecuHwpn, 32);
		hwpn = ecuHwpn;
	}

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	if (CVehicleConfig::getInstance()->getEcuFileInfo(ecuId, hwpn, vecFlashInfo)) {
		int rBlockCount = 0;
		for (int i = 0; i < vecFlashInfo.size(); i++) {
			JD_VSP_FLASH_CONFIG_t oneFlahsInfo = vecFlashInfo.at(i);
			VBFParserSmall* parser = oneFlahsInfo.pVBFParser;

			if (oneFlahsInfo.strFileType._Equal("SBL")) {
				rBlockCount = parser->GetVBFBlocks().size();
			}

			delete parser;
		}

		return rBlockCount;
	}

	return -1;
}

int get_jd_SBL_blockCheckSum_byEcuId(int ecuId, char* hwpn, int index, uint8_t* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	char ecuHwpn[32] = { 0 };
	if (hwpn == NULL || 0 == strcmp(hwpn, "") || strlen(hwpn) == 0) {
		get_jd_orderInfo_ecuHwpn_byEcuId(ecuId, ecuHwpn, 32);
		hwpn = ecuHwpn;
	}

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	if (CVehicleConfig::getInstance()->getEcuFileInfo(ecuId, hwpn, vecFlashInfo)) {
		int rcheckSum = 0;
		for (int i = 0; i < vecFlashInfo.size(); i++) {
			JD_VSP_FLASH_CONFIG_t oneFlahsInfo = vecFlashInfo.at(i);
			VBFParserSmall* parser = oneFlahsInfo.pVBFParser;

			if (oneFlahsInfo.strFileType._Equal("SBL")) {
				if (index > parser->GetVBFBlocks().size()) {
					Tracer::error("index", "outof the bound");
				}
				else {
					rcheckSum = parser->GetVBFBlocks().at(index).GetCheckSum();
				}

			}

			delete parser;
		}

		if (rcheckSum == 0) {
			return -1;
		}

		return radix_int2ByteArray(rcheckSum, outBuffer, outBufferSize);
	}

	return -1;
}

int get_jd_SBL_blockStartAddr_byEcuId(int ecuId, char* hwpn, int index, uint8_t* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	char ecuHwpn[32] = { 0 };
	if (hwpn == NULL || 0 == strcmp(hwpn, "") || strlen(hwpn) == 0) {
		get_jd_orderInfo_ecuHwpn_byEcuId(ecuId, ecuHwpn, 32);
		hwpn = ecuHwpn;
	}

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	if (CVehicleConfig::getInstance()->getEcuFileInfo(ecuId, hwpn, vecFlashInfo)) {
		int startAddr = 0;
		for (int i = 0; i < vecFlashInfo.size(); i++) {
			JD_VSP_FLASH_CONFIG_t oneFlahsInfo = vecFlashInfo.at(i);
			VBFParserSmall* parser = oneFlahsInfo.pVBFParser;

			if (oneFlahsInfo.strFileType._Equal("SBL")) {
				if (index > parser->GetVBFBlocks().size()) {
					Tracer::error("index", "outof the bound");
				}
				else {
					startAddr = parser->GetVBFBlocks().at(index).GetStartAddress();
				}
			}

			delete parser;
		}
		if (startAddr == 0) {
			return -1;
		}
		return radix_int2ByteArray(startAddr, outBuffer, outBufferSize);
	}

	return -1;
}

int get_jd_SBL_blockLength_byEcuId(int ecuId, char* hwpn, int index, uint8_t* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	char ecuHwpn[32] = { 0 };
	if (hwpn == NULL || 0 == strcmp(hwpn, "") || strlen(hwpn) == 0) {
		get_jd_orderInfo_ecuHwpn_byEcuId(ecuId, ecuHwpn, 32);
		hwpn = ecuHwpn;
	}

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	if (CVehicleConfig::getInstance()->getEcuFileInfo(ecuId, hwpn, vecFlashInfo)) {
		int rLenth = 0;
		for (int i = 0; i < vecFlashInfo.size(); i++) {
			JD_VSP_FLASH_CONFIG_t oneFlahsInfo = vecFlashInfo.at(i);
			VBFParserSmall* parser = oneFlahsInfo.pVBFParser;

			if (oneFlahsInfo.strFileType._Equal("SBL")) {
				if (index > parser->GetVBFBlocks().size()) {
					Tracer::error("index", "outof the bound");
				}
				else {
					rLenth = parser->GetVBFBlocks().at(index).GetLength();
				}
			}

			delete parser;
		}
		if (rLenth == 0) {
			return -1;
		}
		return radix_int2ByteArray(rLenth, outBuffer, outBufferSize);

	}

	return -1;
}

int get_jd_SBL_blockDataLength_byEcuId(int ecuId, char* hwpn, int index, uint8_t* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	char ecuHwpn[32] = { 0 };
	if (hwpn == NULL || 0 == strcmp(hwpn, "") || strlen(hwpn) == 0) {
		get_jd_orderInfo_ecuHwpn_byEcuId(ecuId, ecuHwpn, 32);
		hwpn = ecuHwpn;
	}

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	if (CVehicleConfig::getInstance()->getEcuFileInfo(ecuId, hwpn, vecFlashInfo)) {
		int rLenth = 0;
		for (int i = 0; i < vecFlashInfo.size(); i++) {
			JD_VSP_FLASH_CONFIG_t oneFlahsInfo = vecFlashInfo.at(i);
			VBFParserSmall* parser = oneFlahsInfo.pVBFParser;

			if (oneFlahsInfo.strFileType._Equal("SBL")) {
				if (index > parser->GetVBFBlocks().size()) {
					Tracer::error("index", "outof the bound");
				}
				else {
					vector<uint8_t> bData = parser->GetVBFBlocks().at(index).GetBlockData();
					rLenth = bData.size();
				}
			}

			delete parser;
		}
		if (rLenth == 0) {
			return -1;
		}
		return radix_int2ByteArray(rLenth, outBuffer, outBufferSize);
	}

	return -1;
}

int get_jd_SBL_blockData_byEcuId(int ecuId, char* hwpn, int index, uint8_t* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	memset(outBuffer, 0, outBufferSize);

	char ecuHwpn[32] = { 0 };
	if (hwpn == NULL || 0 == strcmp(hwpn, "") || strlen(hwpn) == 0) {
		get_jd_orderInfo_ecuHwpn_byEcuId(ecuId, ecuHwpn, 32);
		hwpn = ecuHwpn;
	}

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	if (CVehicleConfig::getInstance()->getEcuFileInfo(ecuId, hwpn, vecFlashInfo)) {
		int rLenth = 0;
		for (int i = 0; i < vecFlashInfo.size(); i++) {
			JD_VSP_FLASH_CONFIG_t oneFlahsInfo = vecFlashInfo.at(i);
			VBFParserSmall* parser = oneFlahsInfo.pVBFParser;

			if (oneFlahsInfo.strFileType._Equal("SBL")) {
				if (index > parser->GetVBFBlocks().size()) {
					Tracer::error("index", "outof the bound");
				}
				else {
					vector<uint8_t> bData = parser->GetVBFBlocks().at(index).GetBlockData();

					if (outBufferSize >= bData.size()) {
						rLenth = bData.size();
						memcpy(outBuffer, bData.data(), rLenth);
					}
					else {
						Tracer::error("bufferSize", "too small to receive.");
					}
				}
			}

			delete parser;
		}

		return rLenth;
	}

	return -1;
}

int get_jd_SBL_swSignature_byEcuId(int ecuId, char* hwpn, uint8_t* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	memset(outBuffer, 0, outBufferSize);

	char ecuHwpn[32] = { 0 };
	if (hwpn == NULL || 0 == strcmp(hwpn, "") || strlen(hwpn) == 0) {
		get_jd_orderInfo_ecuHwpn_byEcuId(ecuId, ecuHwpn, 32);
		hwpn = ecuHwpn;
	}

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	if (CVehicleConfig::getInstance()->getEcuFileInfo(ecuId, hwpn, vecFlashInfo)) {
		int rLenth = 0;
		for (int i = 0; i < vecFlashInfo.size(); i++) {
			JD_VSP_FLASH_CONFIG_t oneFlahsInfo = vecFlashInfo.at(i);
			VBFParserSmall* parser = oneFlahsInfo.pVBFParser;

			if (oneFlahsInfo.strFileType._Equal("SBL")) {
				string tempString = parser->getHeader().getSWSignature();

				if (outBufferSize >= tempString.length() / 2) {
					rLenth = radix_hex2Array(tempString.c_str(), tempString.length(), outBuffer, outBufferSize);
				}
				else {
					Tracer::error("bufferSize", "too small to receive.");
				}
			}

			delete parser;
		}

		return rLenth;
	}

	return -1;
}

int get_jd_SBL_dataFormatIdentifier_byEcuId(int ecuId, char* hwpn, uint8_t* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	memset(outBuffer, 0, outBufferSize);

	char ecuHwpn[32] = { 0 };
	if (hwpn == NULL || 0 == strcmp(hwpn, "") || strlen(hwpn) == 0) {
		get_jd_orderInfo_ecuHwpn_byEcuId(ecuId, ecuHwpn, 32);
		hwpn = ecuHwpn;
	}

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	if (CVehicleConfig::getInstance()->getEcuFileInfo(ecuId, hwpn, vecFlashInfo)) {
		int rLenth = 0;
		for (int i = 0; i < vecFlashInfo.size(); i++) {
			JD_VSP_FLASH_CONFIG_t oneFlahsInfo = vecFlashInfo.at(i);
			VBFParserSmall* parser = oneFlahsInfo.pVBFParser;

			if (oneFlahsInfo.strFileType._Equal("SBL")) {
				string tempString = parser->getHeader().getDataFormatIndetifier();

				if (outBufferSize >= tempString.length() / 2) {
					rLenth = radix_hex2Array(tempString.c_str(), tempString.length(), outBuffer, outBufferSize);
				}
				else {
					Tracer::error("bufferSize", "too small to receive.");
				}
			}

			delete parser;
		}

		return rLenth;
	}

	return -1;
}

int get_jd_SBL_erraseInfo_byEcuId(int ecuId, char* hwpn, uint8_t* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	memset(outBuffer, 0, outBufferSize);

	char ecuHwpn[32] = { 0 };
	if (hwpn == NULL || 0 == strcmp(hwpn, "") || strlen(hwpn) == 0) {
		get_jd_orderInfo_ecuHwpn_byEcuId(ecuId, ecuHwpn, 32);
		hwpn = ecuHwpn;
	}

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	if (CVehicleConfig::getInstance()->getEcuFileInfo(ecuId, hwpn, vecFlashInfo)) {
		int rLenth = 0;
		for (int i = 0; i < vecFlashInfo.size(); i++) {
			JD_VSP_FLASH_CONFIG_t oneFlahsInfo = vecFlashInfo.at(i);
			VBFParserSmall* parser = oneFlahsInfo.pVBFParser;

			if (oneFlahsInfo.strFileType._Equal("SBL")) {

				vector<string> vec = parser->getHeader().getListOfErase();
				string tempString;
				for (string temp : vec) {
					tempString.append(temp).append(";");
				}

				if (outBufferSize >= tempString.length() / 2) {
					rLenth = radix_hex2Array(tempString.c_str(), tempString.length(), outBuffer, outBufferSize);
				}
				else {
					Tracer::error("bufferSize", "too small to receive.");
				}
			}

			delete parser;
		}

		return rLenth;
	}

	return -1;
}

int get_jd_SBL_activeAddress_byEcuId(int ecuId, char* hwpn, uint8_t* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	memset(outBuffer, 0, outBufferSize);

	char ecuHwpn[32] = { 0 };
	if (hwpn == NULL || 0 == strcmp(hwpn, "") || strlen(hwpn) == 0) {
		get_jd_orderInfo_ecuHwpn_byEcuId(ecuId, ecuHwpn, 32);
		hwpn = ecuHwpn;
	}

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	if (CVehicleConfig::getInstance()->getEcuFileInfo(ecuId, hwpn, vecFlashInfo)) {
		int rLenth = 0;
		for (int i = 0; i < vecFlashInfo.size(); i++) {
			JD_VSP_FLASH_CONFIG_t oneFlahsInfo = vecFlashInfo.at(i);
			VBFParserSmall* parser = oneFlahsInfo.pVBFParser;

			if (oneFlahsInfo.strFileType._Equal("SBL")) {
				string tempString = parser->getHeader().getCall();

				if (outBufferSize >= tempString.length() / 2) {
					rLenth = radix_hex2Array(tempString.c_str(), tempString.length(), outBuffer, outBufferSize);
					if (rLenth > 0)
					{
						rLenth = tempString.length() / 2;
					}
				}
				else {
					Tracer::error("bufferSize", "too small to receive.");
				}
			}

			delete parser;
		}

		return rLenth;
	}

	return -1;
}

int get_jd_SBL_swSignatureDev_byEcuId(int ecuId, char* hwpn, uint8_t* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	memset(outBuffer, 0, outBufferSize);

	char ecuHwpn[32] = { 0 };
	if (hwpn == NULL || 0 == strcmp(hwpn, "") || strlen(hwpn) == 0) {
		get_jd_orderInfo_ecuHwpn_byEcuId(ecuId, ecuHwpn, 32);
		hwpn = ecuHwpn;
	}

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	if (CVehicleConfig::getInstance()->getEcuFileInfo(ecuId, hwpn, vecFlashInfo)) {
		int rLenth = 0;
		for (int i = 0; i < vecFlashInfo.size(); i++) {
			JD_VSP_FLASH_CONFIG_t oneFlahsInfo = vecFlashInfo.at(i);
			VBFParserSmall* parser = oneFlahsInfo.pVBFParser;

			if (oneFlahsInfo.strFileType._Equal("SBL")) {
				string tempString = parser->getHeader().getSWSignatureDev();

				if (outBufferSize >= tempString.length() / 2) {
					rLenth = radix_hex2Array(tempString.c_str(), tempString.length(), outBuffer, outBufferSize);
				}
				else {
					Tracer::error("bufferSize", "too small to receive.");
				}
			}

			delete parser;
		}

		return rLenth;
	}

	return -1;
}



int jd_certBrush_callback(const char* deviceSn, char* vin, int carType, char* ecuName, char* ecuSn, int ackFlag, char* reason)
{
	std::lock_guard<std::mutex> lock(mItemLock);


	cJSON* jsonEcu = cJSON_CreateObject();
	cJSON_AddStringToObject(jsonEcu, "ecuType", ecuName);
	cJSON_AddStringToObject(jsonEcu, "sn", ecuSn);
	cJSON_AddNumberToObject(jsonEcu, "ackFlag", ackFlag);
	if (ackFlag == 0)
	{
		cJSON_AddStringToObject(jsonEcu, "reason", reason);
	}
	cJSON* jsonEcuList = cJSON_CreateArray();
	cJSON_AddItemToArray(jsonEcuList, jsonEcu);

	cJSON* jsonRequest = cJSON_CreateObject();
	cJSON_AddStringToObject(jsonRequest, "vin", vin);
	cJSON_AddNumberToObject(jsonRequest, "carType", carType);
	cJSON_AddStringToObject(jsonRequest, "deviceSn", deviceSn);
	cJSON_AddNumberToObject(jsonRequest, "ackFlag", ackFlag);
	cJSON_AddStringToObject(jsonRequest, "writeTime", currentTimestamp().c_str());
	cJSON_AddStringToObject(jsonRequest, "sendTime", currentTimestamp().c_str());
	cJSON_AddItemToObject(jsonRequest, "ecuList", jsonEcuList);

	char tempBuffer[1024] = { 0 };
	char* temp = cJSON_PrintUnformatted(jsonRequest);
	cJSON_Delete(jsonRequest);

	//TODO 售后访问61
	int callServerInterface = 24;
	if (DataCenter::getInstance()->factory.empty()) {
		callServerInterface = 61;
	}
	else {//TODO 工厂访问 24
		callServerInterface = 24;
	}

	int ret = callServer(callServerInterface, temp, tempBuffer, 1024);
	cJSON_free(temp);
	if (ret > 0)
	{
		cJSON* objRes = cJSON_Parse(tempBuffer);
		if (objRes != NULL) {
			cJSON* obj = cJSON_GetObjectItem(objRes, "code");
			if (cJSON_IsNumber(obj) && obj->valueint == 0)
			{
				cJSON_Delete(objRes);
				return 1;
			}
			else if (cJSON_IsString(obj) && strncmp("0", obj->valuestring, 1) == 0)
			{
				cJSON_Delete(objRes);
				return 1;
			}
			cJSON_Delete(objRes);
		}
	}
	return 0;
}

int jd_certRevoke_callback(const char* deviceSn, char* vin, int carType, char* ecuName, char* ecuSn)
{
	std::lock_guard<std::mutex> lock(mItemLock);

	cJSON* jsonRequest = cJSON_CreateObject();
	cJSON_AddStringToObject(jsonRequest, "vin", vin);
	cJSON_AddNumberToObject(jsonRequest, "carType", carType);
	cJSON_AddStringToObject(jsonRequest, "deviceSn", deviceSn);
	cJSON* jsonEcuList = cJSON_CreateArray();

	cJSON* jsonEcu = cJSON_CreateObject();
	cJSON_AddStringToObject(jsonEcu, "ecuType", ecuName);
	cJSON_AddStringToObject(jsonEcu, "sn", ecuSn);
	cJSON_AddItemToArray(jsonEcuList, jsonEcu);

	cJSON_AddItemToObject(jsonRequest, "ecuList", jsonEcuList);

	char tempBuffer[1024] = { 0 };
	char* temp = cJSON_PrintUnformatted(jsonRequest);
	cJSON_Delete(jsonRequest);
	int ret = callServer(66, temp, tempBuffer, 1024);
	cJSON_free(temp);
	if (ret > 0)
	{
		cJSON* objRes = cJSON_Parse(tempBuffer);
		if (objRes != NULL) {
			cJSON* obj = cJSON_GetObjectItem(objRes, "code");
			if (cJSON_IsNumber(obj) && obj->valueint == 0)
			{
				cJSON_Delete(objRes);
				return 1;
			}
			else if (cJSON_IsString(obj) && strncmp("0", obj->valuestring, 1) == 0)
			{
				cJSON_Delete(objRes);
				return 1;
			}
			cJSON_Delete(objRes);
		}
	}
	return 0;
}

int jd_keyBrush_callback(const char* deviceSn, char* vin, int carType, char* ecuName, int type, int ackFlag, char* message)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	cJSON* jsonRequest = cJSON_CreateObject();
	cJSON_AddStringToObject(jsonRequest, "vin", vin);
	cJSON_AddStringToObject(jsonRequest, "ecu", ecuName);
	cJSON_AddNumberToObject(jsonRequest, "carType", carType);
	cJSON_AddStringToObject(jsonRequest, "deviceSn", deviceSn);
	cJSON_AddNumberToObject(jsonRequest, "type", type);
	cJSON_AddBoolToObject(jsonRequest, "isSuccess", ackFlag);
	cJSON_AddStringToObject(jsonRequest, "message", message);
	cJSON_AddStringToObject(jsonRequest, "brushingTime", currentTimestamp().c_str());
	cJSON_AddStringToObject(jsonRequest, "sendTime", currentTimestamp().c_str());

	char tempBuffer[1024] = { 0 };
	char* temp = cJSON_PrintUnformatted(jsonRequest);

	//TODO 售后访问60
	int callServerInterface = 25;
	if (DataCenter::getInstance()->factory.empty()) {
		callServerInterface = 60;
	}
	else {//TODO 工厂访问 25
		callServerInterface = 25;
	}

	int ret = callServer(callServerInterface, temp, tempBuffer, 1024);
	cJSON_free(temp);
	if (ret > 0)
	{
		cJSON* objRes = cJSON_Parse(tempBuffer);
		if (objRes != NULL) {
			objRes = cJSON_GetObjectItem(objRes, "code");
			if (cJSON_IsNumber(objRes) && objRes->valueint == 0)
			{
				cJSON_Delete(objRes);
				return 1;
			}
			else if (cJSON_IsString(objRes) && strncmp("0", objRes->valuestring, 1) == 0)
			{
				cJSON_Delete(objRes);
				return 1;
			}
			cJSON_Delete(objRes);
		}
	}
	return 0;
}
int jd_reset_bncm_ecuCommonInfo()
{
	std::lock_guard<std::mutex> lock(mItemLock);
	DataCenter::m_EcuBncmCloudInfo.vecCommandInfo.clear();
	return 1;
}

int jd_add_bncm_ecuCommonInfo(char* commandKey, char* afterParseCommandRes, char* commandReq, char* commandRes)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	JD_ECU_CommandInfo_t cmdInfo;
	cmdInfo.commandKey = commandKey;
	cmdInfo.parseCommandRes = afterParseCommandRes;
	cmdInfo.commandReq = commandReq;
	cmdInfo.commandRes = commandRes;
	DataCenter::m_EcuBncmCloudInfo.vecCommandInfo.push_back(cmdInfo);

	return DataCenter::m_EcuBncmCloudInfo.vecCommandInfo.size();
}

int jd_upload_bncm_ecuCommonInfo(char* serialNo, char* vin, char* vid, char* deviceSn)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	cJSON* objcontent = cJSON_CreateObject();
	cJSON_AddStringToObject(objcontent, "vid", vid);
	cJSON_AddStringToObject(objcontent, "vin", vin);
	cJSON_AddStringToObject(objcontent, "deviceSn", deviceSn);
	cJSON_AddStringToObject(objcontent, "ecuType", "BNCM");
	cJSON_AddStringToObject(objcontent, "ecuId", "1021");

	cJSON* infoArray = cJSON_CreateArray();
	for (int i = 0; i < DataCenter::m_EcuBncmCloudInfo.vecCommandInfo.size(); i++) {
		JD_ECU_CommandInfo_t cmdInfo = DataCenter::m_EcuBncmCloudInfo.vecCommandInfo.at(i);

		cJSON* tempObj = cJSON_CreateObject();
		cJSON_AddStringToObject(tempObj, "commandKey", cmdInfo.commandKey.c_str());
		cJSON_AddStringToObject(tempObj, "afterParseCommandRes", cmdInfo.parseCommandRes.c_str());
		cJSON_AddStringToObject(tempObj, "commandReq", cmdInfo.commandReq.c_str());
		cJSON_AddStringToObject(tempObj, "commandRes", cmdInfo.commandRes.c_str());
		cJSON_AddItemToArray(infoArray, tempObj);
	}
	cJSON_AddItemToObject(objcontent, "ecuCommonInfo", infoArray);

	char* contentString = cJSON_PrintUnformatted(objcontent);
	cJSON_Delete(objcontent);

	int callServerInterface = 67;//TODO 售后访问67
	string factory = DataCenter::getInstance()->factory;
	if (factory._Equal("PMA") || factory._Equal("DMA")) {//TODO 工厂访问 29
		callServerInterface = 29;
	}

	char tempBuffer[1024] = { 0 };
	int rLen = callServer(callServerInterface, contentString, tempBuffer, 1024);
	cJSON_free(contentString);
	if (rLen > 0) {
		cJSON* objRes = cJSON_Parse(tempBuffer);
		cJSON* objCode = cJSON_GetObjectItem(objRes, "code");
		if (objCode->type == cJSON_Number && objCode->valueint == 200) {
			DataCenter::m_EcuBncmCloudInfo.vecCommandInfo.clear();

			cJSON_Delete(objRes);
			return objCode->valueint;
		}

		cJSON_Delete(objRes);
	}

	return rLen;
}

int jd_reset_ecuDiagnosticInfo()
{
	std::lock_guard<std::mutex> lock(mItemLock);
	DataCenter::m_vecEcuDiagnosticInfo.clear();
	return 1;
}
int jd_add_ecuDiagnosticInfo(char* ecuType, char* ecuId, char* commandKey, char* afterParseCommandRes, char* commandReq, char* commandRes)
{
	std::lock_guard<std::mutex> lock(mItemLock);

	JD_ECU_DIAGNOSTIC_INFO_t ecuDiagnosticInfo;
	int index = 0;
	for (index = 0; index < DataCenter::m_vecEcuDiagnosticInfo.size(); index++)
	{
		JD_ECU_DIAGNOSTIC_INFO_t tempInfo = DataCenter::m_vecEcuDiagnosticInfo.at(index);
		if (tempInfo.strEcuType._Equal(ecuType)) {
			ecuDiagnosticInfo = tempInfo;
			break;
		}
	}

	JD_ECU_CommandInfo_t cmdInfo;
	cmdInfo.commandKey = commandKey;
	cmdInfo.parseCommandRes = afterParseCommandRes;
	cmdInfo.commandReq = commandReq;
	cmdInfo.commandRes = commandRes;
	ecuDiagnosticInfo.vecCommandInfo.push_back(cmdInfo);

	if (ecuDiagnosticInfo.strEcuId.empty()) {
		ecuDiagnosticInfo.strEcuId = ecuId;
		ecuDiagnosticInfo.strEcuType = ecuType;

		DataCenter::m_vecEcuDiagnosticInfo.push_back(ecuDiagnosticInfo);
	}
	else {
		DataCenter::m_vecEcuDiagnosticInfo.at(index) = ecuDiagnosticInfo;
	}

	return int();
}

int jd_upload_ecuDiagnosticInfo(char* vin, char* vid, int carType, char* deviceSn, int reportType, char* baseline, char* displayBaseline, char* cdcModule)
{
	std::lock_guard<std::mutex> lock(mItemLock);

	cJSON* objcontent = cJSON_CreateObject();
	cJSON_AddStringToObject(objcontent, "deviceSn", deviceSn);
	cJSON_AddStringToObject(objcontent, "vid", vid);
	cJSON_AddStringToObject(objcontent, "vin", vin);
	cJSON_AddNumberToObject(objcontent, "carType", carType);
	cJSON_AddNumberToObject(objcontent, "reportType", reportType);
	cJSON_AddStringToObject(objcontent, "baseline", baseline);
	cJSON_AddStringToObject(objcontent, "displayBaseline", displayBaseline);
	cJSON_AddStringToObject(objcontent, "cdcModule", cdcModule);


	cJSON* ecuInfoArray = cJSON_CreateArray();
	for (JD_ECU_DIAGNOSTIC_INFO_t ecuInfo : DataCenter::m_vecEcuDiagnosticInfo) {

		cJSON* ecuDiagnosticInfoArray = cJSON_CreateArray();
		for (int i = 0; i < ecuInfo.vecCommandInfo.size(); i++) {
			JD_ECU_CommandInfo_t cmdInfo = ecuInfo.vecCommandInfo.at(i);

			cJSON* cmdObj = cJSON_CreateObject();
			cJSON_AddStringToObject(cmdObj, "commandKey", cmdInfo.commandKey.c_str());
			cJSON_AddStringToObject(cmdObj, "afterParseCommandRes", cmdInfo.parseCommandRes.c_str());
			cJSON_AddStringToObject(cmdObj, "commandReq", cmdInfo.commandReq.c_str());
			cJSON_AddStringToObject(cmdObj, "commandRes", cmdInfo.commandRes.c_str());
			cJSON_AddItemToArray(ecuDiagnosticInfoArray, cmdObj);
		}

		cJSON* ecuInfoItem = cJSON_CreateObject();
		cJSON_AddStringToObject(ecuInfoItem, "ecuType", ecuInfo.strEcuType.c_str());
		cJSON_AddStringToObject(ecuInfoItem, "ecuId", ecuInfo.strEcuId.c_str());
		cJSON_AddItemToObject(ecuInfoItem, "ecuDiagnosticInfo", ecuDiagnosticInfoArray);

		cJSON_AddItemToArray(ecuInfoArray, ecuInfoItem);
	}

	cJSON_AddItemToObject(objcontent, "ecuInfo", ecuInfoArray);

	char* reqBuffer = cJSON_PrintUnformatted(objcontent);
	int rLen = callServer(80, reqBuffer, NULL, 0);
	cJSON_Delete(objcontent);
	cJSON_free(reqBuffer);
	if (rLen > 0)
	{
		//DataCenter::m_vecEcuDiagnosticInfo.clear();
		return rLen;
	}

	return -1;
}

bool jd_check_diagnosisCertificate()
{
	std::lock_guard<std::mutex> lock(mItemLock);
	string appPath = EnvConfig::getInstance()->getAppPath();
	string dirPath = appPath + "Diagnosis\\certificate\\" + EnvConfig::getInstance()->getEnvPath() + "\\" + CVehicleConfig::getInstance()->getCurrentVehicleType();
	vector<string> vecFiles;
	if (FileUtils::subfile(dirPath, vecFiles)) {

		if (vecFiles.size() != 1) {
			return false;
		}

		string strRSAPrivateKeyFileName = vecFiles[0];
		std::string strSuffix = strRSAPrivateKeyFileName.substr(strRSAPrivateKeyFileName.length() - 4, 4);
		MyStringUtils::toUpper(strSuffix);

		if (strSuffix != ".BIN")
		{
			return false;
		}

		return true;
	}

	Tracer::error("no diagnosis cert in dir", dirPath);
	return false;
}

int jd_check_vehicleSwpn(const char* vehicleSoftVersions, int mode)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	if (mode == 0) {
		vector<string> vecFiles = CVehicleConfig::getInstance()->m_vecVehicleSoftVer;
		if (find(vecFiles.begin(), vecFiles.end(), vehicleSoftVersions) != vecFiles.end()) {

			if (CVehicleConfig::getInstance()->IsCompleted(CVehicleConfig::getInstance()->m_strVehicleType, vehicleSoftVersions))
				return 1;
			else
				return 0;
		}
		Tracer::error("can't find pkg from disk", vehicleSoftVersions);
		return -1;
	}
	else if (mode == 1) {
		cJSON* objReq = cJSON_CreateObject();
		cJSON_AddStringToObject(objReq, "serialNo", DataCenter::m_deviceSN.c_str());

		cJSON* arrayVer = cJSON_CreateArray();
		cJSON_AddItemToArray(arrayVer, cJSON_CreateString(vehicleSoftVersions));
		cJSON_AddItemToObject(objReq, "vehicleSoftVersions", arrayVer);

		char tempBuffer[1024] = { 0 };
		char* temp = cJSON_PrintUnformatted(objReq);
		int rLen = callServer(30, temp, tempBuffer, 1024);
		cJSON_free(temp);
		cJSON_Delete(objReq);

		if (rLen > 0) {

			//{
			//	"data": [
			//	{
			//		"vehicleSoftVersion": "6100000110 XX",
			//			"status" : 2
			//	}
			//	] ,
			//		"success": true,
			//		"msg" : "Success",
			//		"code" : 200
			//}
			cJSON* objRes = cJSON_Parse(tempBuffer);
			if (cJSON_IsObject(objRes)) {

				cJSON* objCode = cJSON_GetObjectItem(objRes, "code");
				if (cJSON_IsNumber(objCode) && objCode->valueint == 200) {
					cJSON* arrayData = cJSON_GetObjectItem(objRes, "data");
					for (int i = 0; i < cJSON_GetArraySize(arrayData); i++) {
						cJSON* objItem = cJSON_GetArrayItem(arrayData, i);
						if (cJSON_HasObjectItem(objItem, "vehicleSoftVersion")) {
							string tempVersion = cJSON_GetObjectItem(objItem, "vehicleSoftVersion")->valuestring;
							if (tempVersion._Equal(vehicleSoftVersions)) {
								int status = cJSON_GetObjectItem(objItem, "status")->valueint;
								cJSON_Delete(objRes);
								return status;
							}
						}
					}
					cJSON_Delete(objRes);
					return -1;
				}
			}
			cJSON_Delete(objRes);
		}

		Tracer::error("invalid pkg in order", vehicleSoftVersions);
		return -1;
	}

	return -2;
}

int jd_check_bridgeSwpn(int bridgeId)
{
	return CVehicleConfig::getInstance()->IsCompleted(bridgeId);
}


int get_jd_swdlConstants_byEcuName(const char* ecuName, uint8_t* outBuffer, uint32_t outBufferSize) {
	std::lock_guard<std::mutex> lock(mItemLock);

	string newEcuName = ecuName;
	if (MyStringUtils::startWith(ecuName, "ACU") || MyStringUtils::startWith(ecuName, "BGM") || MyStringUtils::startWith(ecuName, "CDC")) {
		newEcuName = newEcuName.substr(0, 3) + "_SOC";
	}

	JD_ECU_SAFETY_CONSTANT_t safetyConstant;
	if (DataCenter::getInstance()->getEcuSafetyConstant(newEcuName, safetyConstant)) {
		string tempString = safetyConstant.keySwdl;
		int rLen = radix_hex2Array(tempString.c_str(), tempString.size(), outBuffer, outBufferSize);

		Tracer::hex(string("swdlConstants:") + newEcuName, outBuffer, rLen);
		return rLen;
	}

	return -1;
}
int get_jd_immoConstants_byEcuName(const char* ecuName, uint8_t* outBuffer, uint32_t outBufferSize) {
	std::lock_guard<std::mutex> lock(mItemLock);

	string newEcuName = ecuName;
	if (MyStringUtils::startWith(ecuName, "ACU") || MyStringUtils::startWith(ecuName, "BGM") || MyStringUtils::startWith(ecuName, "CDC")) {
		newEcuName = newEcuName.substr(0, 3) + "_MCU";
	}

	JD_ECU_SAFETY_CONSTANT_t safetyConstant;
	if (DataCenter::getInstance()->getEcuSafetyConstant(newEcuName, safetyConstant)) {
		string tempString = safetyConstant.keyImmo;
		int rLen = radix_hex2Array(tempString.c_str(), tempString.size(), outBuffer, outBufferSize);

		Tracer::hex(string("immoConstants:") + newEcuName, outBuffer, rLen);
		return rLen;
	}

	return -1;
}
int get_jd_salConstants_byEcuName(const char* ecuName, uint8_t* outBuffer, uint32_t outBufferSize) {
	std::lock_guard<std::mutex> lock(mItemLock);

	string newEcuName = ecuName;
	if (MyStringUtils::startWith(ecuName, "ACU") || MyStringUtils::startWith(ecuName, "BGM") || MyStringUtils::startWith(ecuName, "CDC")) {
		newEcuName = newEcuName.substr(0, 3) + "_MCU";
	}

	JD_ECU_SAFETY_CONSTANT_t safetyConstant;
	if (DataCenter::getInstance()->getEcuSafetyConstant(newEcuName, safetyConstant)) {
		string tempString = safetyConstant.keySal;
		int rLen = radix_hex2Array(tempString.c_str(), tempString.size(), outBuffer, outBufferSize);

		Tracer::hex(string("salConstants:") + newEcuName, outBuffer, rLen);
		return rLen;
	}

	return -1;
}

int get_jd_commonConstants_byEcuName(const char* ecuName, uint8_t* outBuffer, uint32_t outBufferSize) {
	std::lock_guard<std::mutex> lock(mItemLock);

	string newEcuName = ecuName;
	if (MyStringUtils::startWith(ecuName, "ACU") || MyStringUtils::startWith(ecuName, "BGM") || MyStringUtils::startWith(ecuName, "CDC")) {
		newEcuName = newEcuName.substr(0, 3) + "_MCU";
	}

	JD_ECU_SAFETY_CONSTANT_t safetyConstant;
	if (DataCenter::getInstance()->getEcuSafetyConstant(newEcuName, safetyConstant)) {
		string tempString = safetyConstant.keyCommon;
		int rLen = radix_hex2Array(tempString.c_str(), tempString.size(), outBuffer, outBufferSize);

		Tracer::hex(string("commonConstants:") + newEcuName, outBuffer, rLen);
		return rLen;
	}

	return -1;
}

int get_jd_immoKeyEcm(uint8_t* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	string tempString = DataCenter::m_EolKey.immoKeyEcm;
	int rLen = radix_hex2Array(tempString.c_str(), tempString.size(), outBuffer, outBufferSize);

	Tracer::hex("immoKeyEcm", outBuffer, rLen);
	return rLen;
}

int get_jd_immoKeyIem(uint8_t* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	string tempString = DataCenter::m_EolKey.immoKeyIem;
	int rLen = radix_hex2Array(tempString.c_str(), tempString.size(), outBuffer, outBufferSize);

	Tracer::hex("immoKeyIem", outBuffer, rLen);
	return rLen;
}

int get_jd_immoKeyMgm(uint8_t* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	string tempString = DataCenter::m_EolKey.immoKeyMgm;
	int rLen = radix_hex2Array(tempString.c_str(), tempString.size(), outBuffer, outBufferSize);

	Tracer::hex("immoKeyMgm", outBuffer, rLen);
	return rLen;
}
int get_jd_immoKeyRemote(uint8_t* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	string tempString = DataCenter::m_EolKey.immoKeyRemote;
	int rLen = radix_hex2Array(tempString.c_str(), tempString.size(), outBuffer, outBufferSize);

	Tracer::hex("immoKeyRemote", outBuffer, rLen);
	return rLen;
}
int get_jd_dkBncmBgm(uint8_t* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	string tempString = DataCenter::m_EolKey.dkBncmBgm;
	int rLen = radix_hex2Array(tempString.c_str(), tempString.size(), outBuffer, outBufferSize);

	Tracer::hex("dkBncmBgm", outBuffer, rLen);
	return rLen;
}
int get_jd_powerRootKey(uint8_t* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	string tempString = DataCenter::m_EolKey.powerRootKey;
	int rLen = radix_hex2Array(tempString.c_str(), tempString.size(), outBuffer, outBufferSize);

	Tracer::hex("powerRootKey", outBuffer, rLen);
	return rLen;
}
int get_jd_powerRootKeyId(uint8_t* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	string tempString = DataCenter::m_EolKey.powerRootKeyId;
	int rLen = radix_hex2Array(tempString.c_str(), tempString.size(), outBuffer, outBufferSize);

	Tracer::hex("powerRootKeyId", outBuffer, rLen);
	return rLen;
}

int get_jd_aesKey_byEcuName(const char* ecuName, uint8_t* outBuffer, uint32_t outBufferSize)
{
	std::lock_guard<std::mutex> lock(mItemLock);
	memset(outBuffer, 0, outBufferSize);

	vector<string> vecTemp;
	MyStringUtils::split(vecTemp, ecuName, "_");
	string realKey = vecTemp.at(0);
	string tempString = DataCenter::m_aesKey[realKey];
	if (tempString.empty()) {
		Tracer::error("invalid key", "please callServer at first");
		return -1;
	}

	int rLen = base64_decode(tempString.c_str(), (int)tempString.size(), outBuffer, outBufferSize);
	Tracer::hex(string("aesKey[") + ecuName + "]", outBuffer, rLen);
	return rLen;
}

int get_jd_vehicleEnvStatus()
{
	if (DataCenter::m_callServerRecord.find(85) == DataCenter::m_callServerRecord.end()) {
		return -1;
	}

	string response = DataCenter::m_callServerRecord.at(85).response;
	int vehicleEnvStatus = -1;
	cJSON* objRoot = cJSON_Parse(response.c_str());
	if (NULL != objRoot) {
		if (cJSON_HasObjectItem(objRoot, "code")) {
			cJSON* objCode = cJSON_GetObjectItem(objRoot, "code");
			if (objCode->type == cJSON_Number && (objCode->valueint == 0 || objCode->valueint == 200)) {
				cJSON* objData = cJSON_GetObjectItem(objRoot, "data");

				//{
				//		"vehicleEnvStatus": 2,
				//		"vin" : "L6T79P2N3PP002429"
				//	}
				if (cJSON_HasObjectItem(objData, "vehicleEnvStatus")) {
					vehicleEnvStatus = cJSON_GetObjectItem(objData, "vehicleEnvStatus")->valueint;
				}
			}

			cJSON_Delete(objRoot);
		}
	}
	return vehicleEnvStatus;
}

int get_jd_vehicleEnvStatusName(uint8_t* outBuffer, uint32_t outBufferSize)
{
	memset(outBuffer, 0, outBufferSize);
	string tempString = "未知";
	switch (get_jd_vehicleEnvStatus())
	{
	case 1:
		tempString = "prod";
		break;
	case 2:
		tempString = "staging";
		break;
	case 3:
		tempString = "prod pki证书注销";
		break;
	case 4:
		tempString = "staging pki证书注销";
		break;
	case 5:
		tempString = "prod 诊断仪数据清除";
		break;
	case 6:
		tempString = "staging 诊断仪数据清除";
		break;
	default:
		tempString = "未知";
		break;
	}

	if (outBufferSize > tempString.size()) {

		memcpy(outBuffer, tempString.c_str(), tempString.size());
		return tempString.size();
	}
	return -1;
}

int get_jd_lastOtaVersion(uint8_t* outBuffer, uint32_t outBufferSize)
{
	memset(outBuffer, 0, outBufferSize);

	if (DataCenter::m_callServerRecord.find(86) == DataCenter::m_callServerRecord.end()) {
		return -1;
	}

	string response = DataCenter::m_callServerRecord.at(86).response;
	cJSON* objRoot = cJSON_Parse(response.c_str());
	if (NULL != objRoot) {
		if (cJSON_HasObjectItem(objRoot, "code")) {
			cJSON* objCode = cJSON_GetObjectItem(objRoot, "code");
			if (objCode->type == cJSON_Number && (objCode->valueint == 0 || objCode->valueint == 200)) {
				cJSON* objData = cJSON_GetObjectItem(objRoot, "data");

				//{
				//		"vid": "18eb87f4eb67cfa99e123457ff2hui70",
				//			"vin" : "L6T79P2N3PP002429",
				//			"taskName" : "整车详情快捷创建任务大于20辆",
				//			"taskUri" : "https://ota-portal.jidutest.com/ota/#/upgrade/detail/8043",
				//			"detectVersion" : null,
				//			"targetVersion" : "6100003449 AC",
				//			"upgradeStatus" : 15,
				//			"upgradeStatusDesc" : "推送成功",
				//			"remark" : "云网关推送任务时，车辆不在线下发超时",
				//			"updateTime" : 1711359830432
				//	}

				if (cJSON_IsArray(objData)) {
					objData = cJSON_GetArrayItem(objData, 0);
				}
				if (cJSON_HasObjectItem(objData, "targetVersion")) {
					string tempString = cJSON_GetObjectItem(objData, "targetVersion")->valuestring;
					if (outBufferSize > tempString.size()) {
						memcpy(outBuffer, tempString.c_str(), tempString.size());
						cJSON_Delete(objRoot);
						return tempString.size();
					}
				}
			}

			cJSON_Delete(objRoot);
		}
	}

	return -1;
}

int get_jd_vehicleSoftApps(const char* vin, int carType, const char* targetVersion)
{
	cJSON* objReq = cJSON_CreateObject();
	cJSON_AddStringToObject(objReq, "vin", vin);
	cJSON_AddStringToObject(objReq, "deviceSn", DataCenter::m_deviceSN.c_str());
	cJSON_AddStringToObject(objReq, "targetVersion", targetVersion);
	cJSON_AddNumberToObject(objReq, "carType", carType);

	cJSON* arrayEcu = cJSON_CreateArray();
	for (auto it = DataCenter::m_vehicleInfo.mapEcuInfo.begin(); it != DataCenter::m_vehicleInfo.mapEcuInfo.end(); it++) {

		JD_VehicleEcuInfo_t info = it->second;
		if (info.ecuHwpn.empty())
		{
			continue;
		}

		uint16_t ecuId = it->first;
		string ecuName = info.ecuName;
		string ecuSwpn = info.ecuSwpn;
		if (ecuSwpn.empty())
			ecuSwpn = "FFFFFFFFFFFFFFFF";
		cJSON* objEcu = cJSON_CreateObject();
		cJSON_AddStringToObject(objEcu, "name", ecuName.c_str());

		char tempBuffer[32] = { 0 };
		cJSON_AddStringToObject(objEcu, "ecuId", itoa(ecuId, tempBuffer, 16));
		cJSON_AddStringToObject(objEcu, "HWPN", info.ecuHwpn.c_str());
		cJSON_AddStringToObject(objEcu, "SWPN", MyStringUtils::replace(ecuSwpn, "\t", ",").c_str());

		if (ecuName._Equal("POT")) {
			VehicleCfg vehicleConfig;
			DataCenter::getInstance()->getCarConfig(DataCenter::m_vehicleInfo.binCCP, vehicleConfig);
			cJSON_AddStringToObject(objEcu, "differentiation", MyStringUtils::toString(vehicleConfig.iEmpennage).c_str());
		}

		cJSON_AddItemToArray(arrayEcu, objEcu);
	}
	cJSON_AddItemToObject(objReq, "ecu", arrayEcu);

	char* tempBuffer = (char*)malloc(40960);
	char* temp = cJSON_PrintUnformatted(objReq);
	int rLen = callServer(88, temp, NULL, 0);
	cJSON_free(temp);
	cJSON_Delete(objReq);

	return DataCenter::m_VehicleOrderInfo.vecListEcuNew.size();
}

int get_jd_vehicleSoftApps_ecuHwpn_byEcuId(uint16_t ecuId, uint8_t* outBuffer, uint32_t outBufferSize)
{
	memset(outBuffer, 0, outBufferSize);
	for (JD_ECU_INFO_t ecuInfo : DataCenter::m_VehicleOrderInfo.vecListEcuNew)
	{
		if ((ecuInfo.nEcuId & 0xFFF0) == (ecuId & 0xFFF0)) {
			string tempString = ecuInfo.strEcuHwpn;
			memcpy(outBuffer, tempString.c_str(), tempString.size());
			return tempString.size();
		}
	}

	return -1;
}

int get_jd_vehicleSoftApps_ecuSwpn_byEcuId(uint16_t ecuId, uint8_t* outBuffer, uint32_t outBufferSize)
{
	memset(outBuffer, 0, outBufferSize);
	for (JD_ECU_INFO_t ecuInfo : DataCenter::m_VehicleOrderInfo.vecListEcuNew) {
		if ((ecuInfo.nEcuId & 0xFFF0) == (ecuId & 0xFFF0)) {
			string tempString;
			for (JD_ECU_SWPN_INFO_t swpnInfo : ecuInfo.vecEcuSwpnList) {
				if (swpnInfo.strPackageType._Equal("SBL")) {
					continue;
				}
				tempString += swpnInfo.strEcuSwpn + "\t";
			}
			memcpy(outBuffer, tempString.c_str(), tempString.size());
			return tempString.size();
		}
	}

	return -1;
}

int get_jd_vehicleSoftApps_ecuHwpn_byEcuName(const char* ecuName, uint8_t* outBuffer, uint32_t outBufferSize)
{
	memset(outBuffer, 0, outBufferSize);
	for (JD_ECU_INFO_t ecuInfo : DataCenter::m_VehicleOrderInfo.vecListEcuNew) {
		if (ecuInfo.strEcuName._Equal(ecuName)) {
			string tempString = ecuInfo.strEcuHwpn;
			memcpy(outBuffer, tempString.c_str(), tempString.size());
			return tempString.size();
		}
	}

	return -1;
}

int get_jd_vehicleSoftApps_ecuSwpn_byEcuName(const char* ecuName, uint8_t* outBuffer, uint32_t outBufferSize)
{
	memset(outBuffer, 0, outBufferSize);
	for (JD_ECU_INFO_t ecuInfo : DataCenter::m_VehicleOrderInfo.vecListEcuNew) {
		if (ecuInfo.strEcuName._Equal(ecuName)) {
			string tempString;
			for (JD_ECU_SWPN_INFO_t swpnInfo : ecuInfo.vecEcuSwpnList) {
				if (swpnInfo.strPackageType._Equal("SBL")) {
					continue;
				}
				tempString += swpnInfo.strEcuSwpn + "\t";
			}

			memcpy(outBuffer, tempString.c_str(), tempString.size());
			return tempString.size();
		}
	}

	return -1;
}

int get_jd_vehicleSoftVerByEcu(char* outBuffer, uint32_t outBufferSize)
{
	if (DataCenter::m_callServerRecord.find(89) == DataCenter::m_callServerRecord.end()) {
		return -1;
	}

	string response = DataCenter::m_callServerRecord.at(89).response;
	int errCode = -1;
	cJSON* objRoot = cJSON_Parse(response.c_str());
	if (NULL != objRoot) {
		if (cJSON_HasObjectItem(objRoot, "code")) {
			cJSON* objCode = cJSON_GetObjectItem(objRoot, "code");
			if (objCode->type == cJSON_Number && (objCode->valueint == 0 || objCode->valueint == 200)) {
				cJSON* objData = cJSON_GetObjectItem(objRoot, "data");
				if (cJSON_HasObjectItem(objData, "vehicleSoftNumVer")) {
					cJSON* objVehicleSoftNumVer = cJSON_GetObjectItem(objData, "vehicleSoftNumVer");
					if (cJSON_IsString(objVehicleSoftNumVer)) {
						string tempString = objVehicleSoftNumVer->valuestring;
						memcpy(outBuffer, tempString.c_str(), tempString.size());
						errCode = tempString.size();
					}
				}
			}

			cJSON_Delete(objRoot);
		}
	}
	return errCode;
}

int get_jd_vehicleSoftVerByEcu_ecuUpgradePathList(char* outBuffer, uint32_t outBufferSize)
{
	if (DataCenter::m_callServerRecord.find(89) == DataCenter::m_callServerRecord.end()) {
		return -1;
	}

	string response = DataCenter::m_callServerRecord.at(89).response;
	int errCode = -1;
	cJSON* objRoot = cJSON_Parse(response.c_str());
	if (NULL != objRoot) {
		if (cJSON_HasObjectItem(objRoot, "code")) {
			cJSON* objCode = cJSON_GetObjectItem(objRoot, "code");
			if (objCode->type == cJSON_Number && (objCode->valueint == 0 || objCode->valueint == 200)) {
				cJSON* objData = cJSON_GetObjectItem(objRoot, "data");
				if (cJSON_HasObjectItem(objData, "ecuUpgradePathList")) {
					cJSON* tempObj = cJSON_GetObjectItem(objData, "ecuUpgradePathList");
					if (cJSON_IsArray(tempObj)) {
						cJSON* ecuUpgradePath = cJSON_GetArrayItem(tempObj, 0);

						char* temp = cJSON_Print(tempObj);
						string tempString = temp;
						cJSON_free(temp);
						memcpy(outBuffer, tempString.c_str(), tempString.size());
						errCode = tempString.size();
					}
				}
			}

			cJSON_Delete(objRoot);
		}
	}
	return errCode;
}

int get_jd_vehicleSoftUpgradePath(char* outBuffer, uint32_t outBufferSize)
{
	if (DataCenter::m_callServerRecord.find(90) == DataCenter::m_callServerRecord.end()) {
		return -1;
	}

	string response = DataCenter::m_callServerRecord.at(90).response;
	int errCode = -1;
	cJSON* objRoot = cJSON_Parse(response.c_str());
	if (NULL != objRoot) {
		if (cJSON_HasObjectItem(objRoot, "code")) {
			cJSON* objCode = cJSON_GetObjectItem(objRoot, "code");
			if (objCode->type == cJSON_Number && (objCode->valueint == 0 || objCode->valueint == 200)) {
				cJSON* objData = cJSON_GetObjectItem(objRoot, "data");

				//{
				//	"vehicleSoftUpgradePath": [
				//	{
				//		"vehicleSoftId": 6232,
				//			"vehicleSoftNumVer" : "6200000200 BC",
				//			"hasBridge" : false,
				//			"bridgeNumVer" : null,
				//			"isBridge" : null,
				//			"isOperation" : null
				//	}
				//	]
				//}

				string tempString;
				if (cJSON_HasObjectItem(objData, "vehicleSoftUpgradePath")) {
					cJSON* tempArray = cJSON_GetObjectItem(objData, "vehicleSoftUpgradePath");
					for (int i = 0; i < cJSON_GetArraySize(tempArray); i++) {
						cJSON* objTemp = cJSON_GetArrayItem(tempArray, i);
						tempString.append(cJSON_GetObjectItem(objTemp, "vehicleSoftNumVer")->valuestring).append(";");
					}
				}
				memcpy(outBuffer, tempString.c_str(), tempString.size());
				errCode = tempString.size();
			}

			cJSON_Delete(objRoot);
		}
	}
	return errCode;
}

int get_jd_vehicleVersionInfo(char* baselineVerBuffer, uint32_t baselineVerBufferSize, char* targetVerBuffer, uint32_t targetVerBufferSize)
{
	if (DataCenter::m_callServerRecord.find(91) == DataCenter::m_callServerRecord.end()) {
		return -1;
	}

	string response = DataCenter::m_callServerRecord.at(91).response;
	int errCode = -1;
	cJSON* objRoot = cJSON_Parse(response.c_str());
	if (NULL != objRoot) {
		if (cJSON_HasObjectItem(objRoot, "code")) {
			cJSON* objCode = cJSON_GetObjectItem(objRoot, "code");
			if (objCode->type == cJSON_Number && (objCode->valueint == 0 || objCode->valueint == 200)) {
				cJSON* objData = cJSON_GetObjectItem(objRoot, "data");

				//{
				//	"vehicleSoftId":        6255,
				//	"baselineVersion" : "V2.0.0 Beta1",
				//	"targetVersion" : "V2.0.0 Beta1"
				//}

				string tempString = cJSON_GetObjectItem(objData, "baselineVersion")->valuestring;
				memcpy(baselineVerBuffer, tempString.c_str(), tempString.size());

				tempString = cJSON_GetObjectItem(objData, "targetVersion")->valuestring;
				memcpy(targetVerBuffer, tempString.c_str(), tempString.size());
				errCode = tempString.size();
			}

			cJSON_Delete(objRoot);
		}
	}
	return errCode;
}

int get_jd_fotaCanNotDriveByVin_targetVehicleSoftVersion(char* outBuffer, uint32_t outBufferSize)
{
	if (DataCenter::m_callServerRecord.find(92) == DataCenter::m_callServerRecord.end()) {
		return -1;
	}

	string response = DataCenter::m_callServerRecord.at(92).response;
	int errCode = -1;
	cJSON* objRoot = cJSON_Parse(response.c_str());
	if (NULL != objRoot) {
		if (cJSON_HasObjectItem(objRoot, "code")) {
			cJSON* objCode = cJSON_GetObjectItem(objRoot, "code");
			if (objCode->type == cJSON_Number && (objCode->valueint == 0 || objCode->valueint == 200)) {
				cJSON* objData = cJSON_GetObjectItem(objRoot, "data");

				//{
				//	"targetVehicleSoftVersion": "",
				//	"statusOccurTimestamp" : "",
				//	"vehicleUpgradeSubStatusMsg" : ""
				//}

				cJSON* obj = cJSON_GetObjectItem(objData, "targetVehicleSoftVersion");
				if (cJSON_IsString(obj))
				{
					string tempString = obj->valuestring;
					if (outBufferSize > tempString.size())
					{
						memcpy(outBuffer, tempString.c_str(), tempString.size());
						errCode = tempString.size();
					}
				}
			}

			cJSON_Delete(objRoot);
		}
	}
	return errCode;
}

int get_jd_fotaCanNotDriveByVin_statusOccurTimestamp(char* outBuffer, uint32_t outBufferSize)
{
	if (DataCenter::m_callServerRecord.find(92) == DataCenter::m_callServerRecord.end()) {
		return -1;
	}

	string response = DataCenter::m_callServerRecord.at(92).response;
	int errCode = -1;
	cJSON* objRoot = cJSON_Parse(response.c_str());
	if (NULL != objRoot) {
		if (cJSON_HasObjectItem(objRoot, "code")) {
			cJSON* objCode = cJSON_GetObjectItem(objRoot, "code");
			if (objCode->type == cJSON_Number && (objCode->valueint == 0 || objCode->valueint == 200)) {
				cJSON* objData = cJSON_GetObjectItem(objRoot, "data");

				//{
				//	"targetVehicleSoftVersion": "",
				//	"statusOccurTimestamp" : "",
				//	"vehicleUpgradeSubStatusMsg" : ""
				//}

				cJSON* obj = cJSON_GetObjectItem(objData, "statusOccurTimestamp");
				if (cJSON_IsString(obj))
				{
					string tempString = obj->valuestring;
					if (outBufferSize > tempString.size())
					{
						memcpy(outBuffer, tempString.c_str(), tempString.size());
						errCode = tempString.size();
					}
				}
			}

			cJSON_Delete(objRoot);
		}
	}
	return errCode;
}

int get_jd_fotaCanNotDriveByVin_vehicleUpgradeSubStatusMsg(char* outBuffer, uint32_t outBufferSize)
{
	if (DataCenter::m_callServerRecord.find(92) == DataCenter::m_callServerRecord.end()) {
		return -1;
	}

	string response = DataCenter::m_callServerRecord.at(92).response;
	int errCode = -1;
	cJSON* objRoot = cJSON_Parse(response.c_str());
	if (NULL != objRoot) {
		if (cJSON_HasObjectItem(objRoot, "code")) {
			cJSON* objCode = cJSON_GetObjectItem(objRoot, "code");
			if (objCode->type == cJSON_Number && (objCode->valueint == 0 || objCode->valueint == 200)) {
				cJSON* objData = cJSON_GetObjectItem(objRoot, "data");

				//{
				//	"targetVehicleSoftVersion": "",
				//	"statusOccurTimestamp" : "",
				//	"vehicleUpgradeSubStatusMsg" : ""
				//}
				cJSON* obj = cJSON_GetObjectItem(objData, "vehicleUpgradeSubStatusMsg");
				if (cJSON_IsString(obj))
				{
					string tempString = obj->valuestring;
					if (outBufferSize > tempString.size())
					{
						memcpy(outBuffer, tempString.c_str(), tempString.size());
						errCode = tempString.size();
					}
				}
			}

			cJSON_Delete(objRoot);
		}
	}
	return errCode;
}

int get_jd_appBridgeFiles_swpn(int appId, char* outBuffer, uint32_t outBufferSize)
{
	cJSON* objRequest = cJSON_CreateObject();
	cJSON_AddStringToObject(objRequest, "deviceSn", DataCenter::m_deviceSN.c_str());
	cJSON_AddNumberToObject(objRequest, "appId", appId);
	char* temp = cJSON_PrintUnformatted(objRequest);
	cJSON_Delete(objRequest);
	int ret = callServer(93, temp, NULL, 0);
	cJSON_free(temp);

	if (DataCenter::m_callServerRecord.find(93) == DataCenter::m_callServerRecord.end()) {
		return -1;
	}
	string response = DataCenter::m_callServerRecord.at(93).response;

	string tempString;
	cJSON* objRes = cJSON_Parse(response.c_str());
	if (cJSON_IsObject(objRes)) {
		if (cJSON_HasObjectItem(objRes, "data")) {
			cJSON* objData = cJSON_GetObjectItem(objRes, "data");
			if (cJSON_HasObjectItem(objData, "appFileList")) {
				cJSON* arrayFileList = cJSON_GetObjectItem(objData, "appFileList");
				for (int i = 0; i < cJSON_GetArraySize(arrayFileList); i++) {
					cJSON* objAppFile = cJSON_GetArrayItem(arrayFileList, i);
					if (cJSON_HasObjectItem(objAppFile, "softName")) {
						string softName = cJSON_GetObjectItem(objAppFile, "softName")->valuestring;
						if (!softName.empty())
						{
							tempString.append(softName).append("\t");
						}
					}
				}
			}
		}

	}
	cJSON_Delete(objRes);

	if (outBufferSize > tempString.size()) {
		memcpy(outBuffer, tempString.c_str(), tempString.size());
		return tempString.size();
	}

	return -1;
}


int set_jd_deviceSn(char* deviceSn)
{
	DataCenter::getInstance()->m_deviceSN = deviceSn;
	return int();
}

int get_jd_deviceSn(char* outBuffer, uint32_t outBufferSize)
{
	string deviceSn = DataCenter::getInstance()->m_deviceSN;
	if (outBufferSize > deviceSn.size()) {

		memcpy(outBuffer, deviceSn.c_str(), deviceSn.size());
		return deviceSn.size();
	}
	return -1;
}

std::string GetTime()
{
	time_t now;
	struct tm* pTime;
	char buf[80];

	time(&now);
	pTime = localtime(&now);
	strftime(buf, 80, "%Y-%m-%d %H:%M:%S", pTime);

	return buf;
}

static unsigned short DayOfMonths[2][12] =
{
	{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
	{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
};

time_t GetUnixTimeStamp(int year, int month, int day, int hour, int minute, int second)
{
	if (second > 59 || minute > 59 || hour > 23
		|| day > 31 || month > 12 || year - 1 < 1969) return 0;

	time_t unixtime = 0;
	unixtime += minute * 60 + hour * 3600 + (day - 1) * 86400;
	int leap = ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) ? 1 : 0;
	for (int i = 0; i < month - 1; ++i)
	{
		unixtime += DayOfMonths[leap][i] * 86400;
	}
	if (year > 1970)
	{
		unixtime += 365 * 86400;
		if (year > 1971)
		{
			unixtime += 365 * 86400;
			if (year > 1972)
			{
				unixtime += 366 * 86400;
				int leftYear = year - 1973;
				unixtime += (leftYear / 4 * (365 * 4 + 1) + (leftYear % 4) * 365) * 86400;
			}
		}
	}
	return unixtime;
}

int GetEcuDtcSnapShotGlobalRealTime(uint32_t timestamp, char* outBuffer, int outBufferSize)
{
	if (timestamp == 0xFFFFFFFF || timestamp > 0xBC1FAB00)
	{
		return -1;
	}

	std::string globaltime;
	uint32_t days = timestamp / (10 * 60 * 60 * 24);
	uint32_t year = days / 365;

	std::string currentTime = GetTime();
	uint32_t currentYear = std::stoi(currentTime.substr(0, 4));

	uint32_t baseyear;
	if ((currentYear % 10) >= year || year >= 10)
	{
		baseyear = (currentYear / 10) * 10;
	}
	else
	{
		baseyear = (currentYear / 10 - 1) * 10;
	}

	time_t unixtime = GetUnixTimeStamp(baseyear, 1, 1, 0, 0, 0);
	unixtime += (timestamp / 10); // 快照时间精度为100ms

	struct tm ptm;
	//gmtime_s(&ptm, &unixtime);
	localtime_s(&ptm, &unixtime);  // 根据系统时区计算时间
	int msec = timestamp % 10;

	sprintf(outBuffer, "%4d-%02d-%02d %02d:%02d:%02d.%d", ptm.tm_year + 1900, ptm.tm_mon + 1, ptm.tm_mday, ptm.tm_hour, ptm.tm_min, ptm.tm_sec, msec);
	return strlen(outBuffer);
}

bool IsFodSyncVinCcpSuccess(uint8_t* resp, uint32_t respSize)
{
	string strCcp = DataCenter::m_VehicleOrderInfo.strCCPCode;
	uint8_t binCcp[4096] = { 0 };
	int rLen = radix_hex2Array(strCcp.c_str(), strCcp.length(), binCcp, 4096);

	CBinary binResp(resp, respSize);
	binResp.RemoveAt(0, 6);
	for (int i = 0; i + 2 <= binResp.GetSize(); i += 3)
	{
		char buf[5] = { 0 };
		sprintf(buf, "%02X%02X", binResp[i], binResp[i + 1]);
		string temp = buf;
		int pos = MyStringUtils::toLong(temp, 10);
		if (rLen >= pos && pos > 0)
		{
			if (binCcp[pos - 1] != binResp[i + 2])
			{
				return false;
			}
		}
	}
	return true;
}

int GetSecurityMask(int doipId, uint8_t* outBuffer, uint32_t outBufferSize)
{
	CBinary binMask;
	switch (doipId)//根据ECU地址匹配安全常数信息
	{
	case 0x1001:
		binMask = CBinary("\x19\xB8\x34\xDC\xA2", 5);
		break;
	case 0x1002://234D24C06D
		binMask = CBinary("\x19\xB8\x34\xDC\xA2", 5);
		/*binMask = CBinary("\x23\x4D\x24\xC0\x6D", 5);*/
		break;
	case 0x1201:
		binMask = CBinary("\x71\xCF\x05\xA2\xED", 5);
		break;
	case 0x1202:
		binMask = CBinary("\x71\xCF\x05\xA2\xED", 5);
		break;
	case 0x1401:
		binMask = CBinary("\xA5\x79\xF8\xED\xC1", 5);
		break;
	case 0x1402:
		binMask = CBinary("\xA5\x79\xF8\xED\xC1", 5);
		break;
	case 0x1011:
		binMask = CBinary("\xF5\x6B\x94\xCD\x8A", 5);
		break;
	case 0x1280:
		binMask = CBinary("\xE7\x52\x0B\x1F\x68", 5);
		break;
	case 0x1281:
		binMask = CBinary("\xA3\x5F\xEC\x16\x02", 5);
		break;
	case 0x1444:
		binMask = CBinary("\x29\x64\xA7\xB0\x3C", 5);
		break;
	case 0x14AE:
		binMask = CBinary("\x72\x65\x9F\xBA\x04", 5);
		break;
	case 0x14BE:
		binMask = CBinary("\x72\x65\x9F\xBA\x04", 5);
		break;
	case 0x1460:
		binMask = CBinary("\x61\x9B\xAE\x85\x7D", 5);
		break;
	case 0x1461:
		binMask = CBinary("\x61\x9B\xAE\x85\x7D", 5);
		break;
	case 0x1450:
		binMask = CBinary("\x61\x9B\xAE\x85\x7D", 5);
		break;
	case 0x1451:
		binMask = CBinary("\x61\x9B\xAE\x85\x7D", 5);
		break;
	case 0x1023:
		binMask = CBinary("\x83\x04\x1F\xB6\x2D", 5);
		break;
	case 0x1024:
		binMask = CBinary("\xFA\x0B\x6E\x13\x2C", 5);
		break;
	case 0x1025:
		binMask = CBinary("\x3C\x8E\xB4\x5A\x9F", 5);
		break;
	case 0x1030:
		binMask = CBinary("\x4F\x0C\xB6\xED\x89", 5);
		break;
	case 0x1031:
		binMask = CBinary("\x4F\x0C\xB6\xED\x89", 5);
		break;
	case 0x1032:
		binMask = CBinary("\x4F\x0C\xB6\xED\x89", 5);
		break;
	case 0x1033:
		binMask = CBinary("\x4F\x0C\xB6\xED\x89", 5);
		break;
	case 0x1601:
		binMask = CBinary("\x71\x35\xDB\x03\x7A", 5);
		break;
	case 0x1701:
		binMask = CBinary("\x82\x6D\xA7\x23\xE2", 5);
		break;
	case 0x1C01:
		binMask = CBinary("\x53\x52\x56\x47\x35", 5);
		break;
	case 0x1633:
		binMask = CBinary("\x83\x4D\xFB\x5A\x6E", 5);
		break;
	case 0x1635://BECM1_102
		binMask = CBinary("\x87\x5C\x0E\xB1\x10", 5);
		break;
		//case 0x1635://BECM1_75
		//	binMask = CBinary("\x4C\x1B\x93\xAF\x05", 5);
		//	break;
	case 0x1631:
		binMask = CBinary("\x64\x9A\x72\x5D\x83", 5);
		break;
	case 0x1637:
		binMask = CBinary("\x4A\x0E\x11\x8B\x7F", 5);
		break;
	case 0x1650:
		binMask = CBinary("\x15\x1E\x09\xCA\x8A", 5);
		break;
	case 0x1630:
		binMask = CBinary("\xB6\xA6\x54\x9E\xC3", 5);
		break;
	case 0x1670:
		binMask = CBinary("\x88\xD0\xE5\x81\xE6", 5);
		break;
	case 0x1720:
		binMask = CBinary("\x88\xD0\xE5\x81\xE6", 5);
		break;
	case 0x1672:
		binMask = CBinary("\x3C\xEB\x87\x2A\xD9", 5);
		break;
	case 0x1614:
		binMask = CBinary("\x97\x0A\x8C\x28\x59", 5);//\x8D\xF7\x51\x43\xBA  -> 970A8C2859  
		break;
	case 0x1A12:
		binMask = CBinary("\xC4\xAC\x3D\x76\x9F", 5);
		break;
	case 0x1A13:
		binMask = CBinary("\x15\xB9\x43\x5B\x61", 5);
		break;
	case 0x1A21:
		binMask = CBinary("\xE6\xA5\xAB\x73\xF9", 5);
		break;
	case 0x1A22:
		binMask = CBinary("\x83\x78\x8B\x67\x7E", 5);
		break;
	case 0x1A40:
		binMask = CBinary("\x9A\x27\xB4\xE8\xF3", 5);
		break;
	case 0x1A41:
		binMask = CBinary("\x9A\x27\xB4\xE8\xF3", 5);
		break;
	case 0x1A42:
		binMask = CBinary("\x9A\x27\xB4\xE8\xF3", 5);
		break;
	case 0x1A43:
		binMask = CBinary("\x9A\x27\xB4\xE8\xF3", 5);
		break;
	case 0x1A11:
		binMask = CBinary("\x30\xA9\x2D\xF9\x01", 5);
		break;
	case 0x1A16:
		binMask = CBinary("\x5A\xC6\x74\xE0\xD1", 5);
		break;
	case 0x1A15:
		binMask = CBinary("\x54\x9E\x18\x7F\x26", 5);
		break;
	case 0x1A27:
		binMask = CBinary("\x4B\xDE\xF2\x69\x06", 5);
		break;
	case 0x1A28:
		binMask = CBinary("\x39\xE4\xAE\xD3\xB1", 5);
		break;
	case 0x1A82:
		binMask = CBinary("\x46\xA9\xE7\x8D\xB3", 5);
		break;
	case 0x1A83:
		binMask = CBinary("\x46\xA9\xE7\x8D\xB3", 5);
		break;
	case 0x1BB3:
		binMask = CBinary("\x3C\xF6\xE5\x4A\x2B", 5);
		break;
	case 0x1BB4:
		binMask = CBinary("\x3C\xF6\xE5\x4A\x2B", 5);
		break;
	case 0x1BB5:
		binMask = CBinary("\x51\x7C\xE6\xAF\x98", 5);
		break;
	case 0x1BB6:
		binMask = CBinary("\x51\x7C\xE6\xAF\x98", 5);
		break;
	case 0x1BB7:
		binMask = CBinary("\x51\x7C\xE6\xAF\x98", 5);
		break;
	default:
		binMask = CBinary("\x41\xAA\x42\xBB\x43", 5);  // 默认值
		break;
	}

	memset(outBuffer, 0, outBufferSize);
	if (outBufferSize > binMask.GetSize()) {

		memcpy(outBuffer, binMask.GetBuffer(), binMask.GetSize());
		return binMask.GetSize();
	}

	return -1;
}


void test_bncm_report(const char* csvFilepath) {

	std::ifstream inFile(csvFilepath, std::ifstream::binary);
	std::string line;

	if (inFile.is_open()) {
		string result;

		while (getline(inFile, line)) {
			if (line.find("vin,id,vehicle_info_id") != string::npos) {
				vector<string> vecTitle;
				MyStringUtils::split(vecTitle, line, ",");
				if (!vecTitle.at(0)._Equal("vin") || !vecTitle.at(5)._Equal("vid") || !vecTitle.at(6)._Equal("seid") || !vecTitle.at(7)._Equal("mac") || !vecTitle.at(3)._Equal("card_id"))
				{
					Tracer::error("invalid csv format", csvFilepath);
					return;
				}
				continue;
			}

			vector<string> vecString;
			MyStringUtils::split(vecString, line, ",");

			string vin = vecString.at(0);
			string vid = vecString.at(5);
			string SEID_0xD90C = vecString.at(6);
			string MACAddress_0xD90D = vecString.at(7);
			string EntityKeyWhiteLists_0xD90E = vecString.at(3);

			cJSON* objRoot = cJSON_CreateObject();
			cJSON_AddStringToObject(objRoot, "vin", vin.c_str());
			cJSON_AddStringToObject(objRoot, "vid", vid.c_str());
			cJSON_AddStringToObject(objRoot, "deviceSn", "DP01000045");
			cJSON_AddStringToObject(objRoot, "ecuType", "BNCM");
			cJSON_AddStringToObject(objRoot, "ecuId", "1021");
			cJSON* objSeid = cJSON_CreateObject();
			cJSON_AddStringToObject(objSeid, "commandKey", "SEID_0xD90C");
			cJSON_AddStringToObject(objSeid, "afterParseCommandRes", SEID_0xD90C.c_str());
			cJSON_AddStringToObject(objSeid, "commandReq", "22D90C");
			cJSON_AddStringToObject(objSeid, "commandRes", ("62D90C" + SEID_0xD90C).c_str());
			cJSON* objMac = cJSON_CreateObject();
			cJSON_AddStringToObject(objMac, "commandKey", "MACAddress_0xD90D");
			cJSON_AddStringToObject(objMac, "afterParseCommandRes", MACAddress_0xD90D.c_str());
			cJSON_AddStringToObject(objMac, "commandReq", "22D90D");
			cJSON_AddStringToObject(objMac, "commandRes", ("62D90D" + MACAddress_0xD90D).c_str());
			cJSON* objKey = cJSON_CreateObject();
			cJSON_AddStringToObject(objKey, "commandKey", "EntityKeyWhiteLists_0xD90E");
			cJSON_AddStringToObject(objKey, "afterParseCommandRes", EntityKeyWhiteLists_0xD90E.c_str());
			cJSON_AddStringToObject(objKey, "commandReq", "22D90E");
			cJSON_AddStringToObject(objKey, "commandRes", ("62D90E" + EntityKeyWhiteLists_0xD90E).c_str());
			cJSON* array = cJSON_CreateArray();
			cJSON_AddItemToArray(array, objSeid);
			cJSON_AddItemToArray(array, objMac);
			cJSON_AddItemToArray(array, objKey);
			cJSON_AddItemToObject(objRoot, "ecuCommonInfo", array);
			char* temp = cJSON_PrintUnformatted(objRoot);
			callServer(29, temp, NULL, 0);
			cJSON_free(temp);
			cJSON_Delete(objRoot);
		}
	}
	else {
		std::cout << "Unable to open file" << csvFilepath << endl;
	}
	inFile.close();
}


int get_jd_SBL_verificationBlockStart_byBridgeId(int bridgeId, char* hwpn, char* outBuffer, uint32_t outBufferSize)
{
	memset(outBuffer, 0, outBufferSize);

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	CVehicleConfig::getInstance()->getBridgeEcuFileInfo(bridgeId, hwpn, vecFlashInfo);
	string tempString;
	for (JD_VSP_FLASH_CONFIG_t oneFlashInfo : vecFlashInfo) {

		VBFParserSmall* parser = oneFlashInfo.pVBFParser;
		if (oneFlashInfo.strFileType._Equal("SBL")) {
			tempString = parser->getHeader().getVerifBlockStart();
		}

		delete parser;
	}

	if (outBufferSize >= tempString.size()) {
		memcpy(outBuffer, tempString.c_str(), tempString.size());
		return tempString.size();
	}
	else {
		Tracer::error("bufferSize", "too small to receive.");
		return -1;
	}
}

int get_jd_SBL_verificationBlockLength_byBridgeId(int bridgeId, char* hwpn)
{
	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	CVehicleConfig::getInstance()->getBridgeEcuFileInfo(bridgeId, hwpn, vecFlashInfo);
	int rBlockLength = 0;
	for (JD_VSP_FLASH_CONFIG_t oneFlashInfo : vecFlashInfo) {

		VBFParserSmall* parser = oneFlashInfo.pVBFParser;
		if (oneFlashInfo.strFileType._Equal("SBL")) {
			string tempString = parser->getHeader().getVerifBlockLength();
			rBlockLength = stoi(tempString);
		}

		delete parser;
	}

	return rBlockLength;
}

int get_jd_SBL_swSignatureDev_byBridgeId(int bridgeId, char* hwpn, uint8_t* outBuffer, uint32_t outBufferSize)
{
	memset(outBuffer, 0, outBufferSize);

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	CVehicleConfig::getInstance()->getBridgeEcuFileInfo(bridgeId, hwpn, vecFlashInfo);
	string tempString;
	for (JD_VSP_FLASH_CONFIG_t oneFlashInfo : vecFlashInfo) {

		VBFParserSmall* parser = oneFlashInfo.pVBFParser;
		if (oneFlashInfo.strFileType._Equal("SBL")) {
			string tempString = parser->getHeader().getSWSignatureDev();
		}

		delete parser;
	}


	if (outBufferSize >= tempString.length() / 2) {
		int rLenth = radix_hex2Array(tempString.c_str(), tempString.length(), outBuffer, outBufferSize);
		return rLenth;
	}
	else {
		Tracer::error("bufferSize", "too small to receive.");
		return -1;
	}
}

int get_jd_SBL_swSignature_byBridgeId(int bridgeId, char* hwpn, uint8_t* outBuffer, uint32_t outBufferSize)
{
	memset(outBuffer, 0, outBufferSize);

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	CVehicleConfig::getInstance()->getBridgeEcuFileInfo(bridgeId, hwpn, vecFlashInfo);
	string tempString;
	for (JD_VSP_FLASH_CONFIG_t oneFlashInfo : vecFlashInfo) {

		VBFParserSmall* parser = oneFlashInfo.pVBFParser;
		if (oneFlashInfo.strFileType._Equal("SBL")) {
			string tempString = parser->getHeader().getSWSignature();
		}

		delete parser;
	}

	if (outBufferSize >= tempString.length() / 2) {
		int rLenth = radix_hex2Array(tempString.c_str(), tempString.length(), outBuffer, outBufferSize);
		return rLenth;
	}
	else {
		Tracer::error("bufferSize", "too small to receive.");
		return -1;
	}
}

int get_jd_SBL_dataFormatIdentifier_byBridgeId(int bridgeId, char* hwpn, uint8_t* outBuffer, uint32_t outBufferSize)
{
	memset(outBuffer, 0, outBufferSize);

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	CVehicleConfig::getInstance()->getBridgeEcuFileInfo(bridgeId, hwpn, vecFlashInfo);
	string tempString;
	for (JD_VSP_FLASH_CONFIG_t oneFlashInfo : vecFlashInfo) {

		VBFParserSmall* parser = oneFlashInfo.pVBFParser;
		if (oneFlashInfo.strFileType._Equal("SBL")) {
			tempString = parser->getHeader().getDataFormatIndetifier();
		}

		delete parser;
	}

	if (outBufferSize >= tempString.length() / 2) {
		int rLenth = radix_hex2Array(tempString.c_str(), tempString.length(), outBuffer, outBufferSize);
		return rLenth;
	}
	else {
		Tracer::error("bufferSize", "too small to receive.");
		return -1;
	}
}
int get_jd_SBL_erraseInfo_byBridgeId(int bridgeId, char* hwpn, uint8_t* outBuffer, uint32_t outBufferSize)
{
	memset(outBuffer, 0, outBufferSize);

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	CVehicleConfig::getInstance()->getBridgeEcuFileInfo(bridgeId, hwpn, vecFlashInfo);
	string tempString;
	for (JD_VSP_FLASH_CONFIG_t oneFlashInfo : vecFlashInfo) {

		VBFParserSmall* parser = oneFlashInfo.pVBFParser;
		if (oneFlashInfo.strFileType._Equal("SBL")) {
			vector<string> vec = parser->getHeader().getListOfErase();
			string tempString;
			for (string temp : vec) {
				tempString.append(temp).append(";");
			}
		}

		delete parser;
	}

	if (outBufferSize >= tempString.length() / 2) {
		int rLenth = radix_hex2Array(tempString.c_str(), tempString.length(), outBuffer, outBufferSize);
		return rLenth;
	}
	else {
		Tracer::error("bufferSize", "too small to receive.");
		return -1;
	}
}

int get_jd_SBL_activeAddress_byBridgeId(int bridgeId, char* hwpn, uint8_t* outBuffer, uint32_t outBufferSize)
{
	memset(outBuffer, 0, outBufferSize);

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	CVehicleConfig::getInstance()->getBridgeEcuFileInfo(bridgeId, hwpn, vecFlashInfo);
	string tempString;
	for (JD_VSP_FLASH_CONFIG_t oneFlashInfo : vecFlashInfo) {

		VBFParserSmall* parser = oneFlashInfo.pVBFParser;
		if (oneFlashInfo.strFileType._Equal("SBL")) {
			string tempString = parser->getHeader().getCall();
		}

		delete parser;
	}

	if (outBufferSize >= tempString.length() / 2) {
		int rLenth = radix_hex2Array(tempString.c_str(), tempString.length(), outBuffer, outBufferSize);
		if (rLenth > 0)
		{
			rLenth = tempString.length() / 2;
		}
		return rLenth;
	}
	else {
		Tracer::error("bufferSize", "too small to receive.");
		return -1;
	}

}

int get_jd_SBL_blockCount_byBridgeId(int bridgeId, char* hwpn)
{
	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	CVehicleConfig::getInstance()->getBridgeEcuFileInfo(bridgeId, hwpn, vecFlashInfo);
	int rBlockCount = 0;
	for (JD_VSP_FLASH_CONFIG_t oneFlashInfo : vecFlashInfo) {

		VBFParserSmall* parser = oneFlashInfo.pVBFParser;
		if (oneFlashInfo.strFileType._Equal("SBL")) {
			rBlockCount = parser->GetVBFBlocks().size();
		}

		delete parser;
	}
	return rBlockCount;
}

int get_jd_SBL_blockCheckSum_byBridgeId(int bridgeId, char* hwpn, int index, uint8_t* outBuffer, uint32_t outBufferSize)
{
	memset(outBuffer, 0, outBufferSize);

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	CVehicleConfig::getInstance()->getBridgeEcuFileInfo(bridgeId, hwpn, vecFlashInfo);
	uint32_t rcheckSum = 0;
	for (JD_VSP_FLASH_CONFIG_t oneFlashInfo : vecFlashInfo) {

		VBFParserSmall* parser = oneFlashInfo.pVBFParser;
		if (oneFlashInfo.strFileType._Equal("SBL")) {
			if (index > parser->GetVBFBlocks().size()) {
				Tracer::error("index", "outof the bound");
			}
			else {
				rcheckSum = parser->GetVBFBlocks().at(index).GetCheckSum();
			}
		}

		delete parser;
	}

	if (rcheckSum == 0) {
		return -1;
	}

	return radix_int2ByteArray(rcheckSum, outBuffer, outBufferSize);
}

int get_jd_SBL_blockStartAddr_byBridgeId(int bridgeId, char* hwpn, int index, uint8_t* outBuffer, uint32_t outBufferSize)
{
	memset(outBuffer, 0, outBufferSize);

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	CVehicleConfig::getInstance()->getBridgeEcuFileInfo(bridgeId, hwpn, vecFlashInfo);
	uint32_t startAddr = 0;
	for (JD_VSP_FLASH_CONFIG_t oneFlashInfo : vecFlashInfo) {

		VBFParserSmall* parser = oneFlashInfo.pVBFParser;
		if (oneFlashInfo.strFileType._Equal("SBL")) {
			if (index > parser->GetVBFBlocks().size()) {
				Tracer::error("index", "outof the bound");
			}
			else {
				startAddr = parser->GetVBFBlocks().at(index).GetStartAddress();
			}
		}

		delete parser;
	}

	if (startAddr == 0) {
		return -1;
	}
	return radix_int2ByteArray(startAddr, outBuffer, outBufferSize);

	return -1;
}

int get_jd_SBL_blockLength_byBridgeId(int bridgeId, char* hwpn, int index, uint8_t* outBuffer, uint32_t outBufferSize)
{
	memset(outBuffer, 0, outBufferSize);

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	CVehicleConfig::getInstance()->getBridgeEcuFileInfo(bridgeId, hwpn, vecFlashInfo);
	uint32_t rLenth = 0;
	for (JD_VSP_FLASH_CONFIG_t oneFlashInfo : vecFlashInfo) {

		VBFParserSmall* parser = oneFlashInfo.pVBFParser;
		if (oneFlashInfo.strFileType._Equal("SBL")) {
			if (index > parser->GetVBFBlocks().size()) {
				Tracer::error("index", "outof the bound");
			}
			else {
				rLenth = parser->GetVBFBlocks().at(index).GetLength();
			}
		}

		delete parser;
	}

	if (rLenth == 0) {
		return -1;
	}
	return radix_int2ByteArray(rLenth, outBuffer, outBufferSize);
}

int get_jd_SBL_blockDataLength_byBridgeId(int bridgeId, char* hwpn, int index, uint8_t* outBuffer, uint32_t outBufferSize)
{
	memset(outBuffer, 0, outBufferSize);

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	CVehicleConfig::getInstance()->getBridgeEcuFileInfo(bridgeId, hwpn, vecFlashInfo);
	uint32_t rLenth = 0;
	for (JD_VSP_FLASH_CONFIG_t oneFlashInfo : vecFlashInfo) {

		VBFParserSmall* parser = oneFlashInfo.pVBFParser;
		if (oneFlashInfo.strFileType._Equal("SBL")) {
			if (index > parser->GetVBFBlocks().size()) {
				Tracer::error("index", "outof the bound");
			}
			else {
				rLenth = parser->GetVBFBlocks().at(index).GetBlockData().size();
			}
		}

		delete parser;
	}

	if (rLenth == 0) {
		return -1;
	}
	return radix_int2ByteArray(rLenth, outBuffer, outBufferSize);
}

int get_jd_SBL_blockData_byBridgeId(int bridgeId, char* hwpn, int index, uint8_t* outBuffer, uint32_t outBufferSize)
{
	memset(outBuffer, 0, outBufferSize);

	vector<JD_VSP_FLASH_CONFIG_t> vecFlashInfo;
	CVehicleConfig::getInstance()->getBridgeEcuFileInfo(bridgeId, hwpn, vecFlashInfo);
	uint32_t rLenth = -1;
	for (JD_VSP_FLASH_CONFIG_t oneFlashInfo : vecFlashInfo) {

		VBFParserSmall* parser = oneFlashInfo.pVBFParser;
		if (oneFlashInfo.strFileType._Equal("SBL")) {
			if (index > parser->GetVBFBlocks().size()) {
				Tracer::error("index", "outof the bound");
			}
			else {
				vector<uint8_t> bData = parser->GetVBFBlocks().at(index).GetBlockData();
				rLenth = bData.size();

				if (outBufferSize >= bData.size()) {
					rLenth = bData.size();
					memcpy(outBuffer, bData.data(), rLenth);
				}
				else {
					Tracer::error("bufferSize", "too small to receive.");
					rLenth = -1;
				}
			}
		}

		delete parser;
	}

	return rLenth;
}