|
|
#pragma execution_character_set("utf-8")
|
|
|
#include "Frame.h"
|
|
|
#include "Utils.h"
|
|
|
#include <sstream>
|
|
|
#include "data/DateTimeData.h"
|
|
|
#include "data/NullData.h"
|
|
|
#include "data/IntegerData.h"
|
|
|
#include "data/StringData.h"
|
|
|
#include "data/StructData.h"
|
|
|
#include "data/DataFactory.h"
|
|
|
#include "crypto/CRC.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Frame::Frame()
|
|
|
: m_head(FRAME_HEAD)
|
|
|
, m_addr(0x0000)
|
|
|
, m_cmd(0x00)
|
|
|
, m_len(0x0000)
|
|
|
, m_crc(0x0000)
|
|
|
, m_data(nullptr)
|
|
|
, m_dataType(0)
|
|
|
, m_direct(0)
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
Frame::Frame(int cmd, int direct)
|
|
|
: m_head(FRAME_HEAD)
|
|
|
, m_addr(0x0000)
|
|
|
, m_cmd(cmd)
|
|
|
, m_len(0x0000)
|
|
|
, m_crc(0x0000)
|
|
|
, m_data(nullptr)
|
|
|
, m_direct(direct == 0 ? 0 : 1)
|
|
|
{
|
|
|
updateDataType();
|
|
|
}
|
|
|
|
|
|
Frame::~Frame()
|
|
|
{
|
|
|
destroyData();
|
|
|
}
|
|
|
|
|
|
void Frame::updateDataType()
|
|
|
{
|
|
|
// 根据cmd和direct判断m_hasData和m_dataType,决定Data的具体类型
|
|
|
switch(FRAME_TYPE(m_direct, m_cmd))
|
|
|
{
|
|
|
case FRAME_TYPE_SET_TIME_REQ : m_dataType = DATA_TYPE_DATETIME; break; // 设置日期时间请求
|
|
|
case FRAME_TYPE_SET_TIME_RSP : m_dataType = DATA_TYPE_NULL ; break; // 设置日期时间响应
|
|
|
case FRAME_TYPE_GET_TIME_REQ : m_dataType = DATA_TYPE_NULL ; break; // 获取日期时间请求
|
|
|
case FRAME_TYPE_GET_TIME_RSP : m_dataType = DATA_TYPE_DATETIME; break; // 获取日期时间响应
|
|
|
case FRAME_TYPE_SET_SERIAL_NUMBER_REQ : m_dataType = DATA_TYPE_STRING ; break;
|
|
|
case FRAME_TYPE_SET_SERIAL_NUMBER_RSP : m_dataType = DATA_TYPE_NULL ; break;
|
|
|
case FRAME_TYPE_GET_SERIAL_NUMBER_REQ : m_dataType = DATA_TYPE_NULL ; break;
|
|
|
case FRAME_TYPE_GET_SERIAL_NUMBER_RSP : m_dataType = DATA_TYPE_STRING ; break;
|
|
|
case FRAME_TYPE_SET_DEVICE_NAME_REQ : m_dataType = DATA_TYPE_STRING ; break;
|
|
|
case FRAME_TYPE_SET_DEVICE_NAME_RSP : m_dataType = DATA_TYPE_NULL ; break;
|
|
|
case FRAME_TYPE_GET_DEVICE_NAME_REQ : m_dataType = DATA_TYPE_NULL ; break;
|
|
|
case FRAME_TYPE_GET_DEVICE_NAME_RSP : m_dataType = DATA_TYPE_STRING ; break;
|
|
|
case FRAME_TYPE_SET_DEVICE_NUMBER_REQ : m_dataType = DATA_TYPE_STRING ; break;
|
|
|
case FRAME_TYPE_SET_DEVICE_NUMBER_RSP : m_dataType = DATA_TYPE_NULL ; break;
|
|
|
case FRAME_TYPE_GET_DEVICE_NUMBER_REQ : m_dataType = DATA_TYPE_NULL ; break;
|
|
|
case FRAME_TYPE_GET_DEVICE_NUMBER_RSP : m_dataType = DATA_TYPE_STRING ; break;
|
|
|
case FRAME_TYPE_SET_LOCK_STATUS_REQ : m_dataType = DATA_TYPE_STRING ; break;
|
|
|
case FRAME_TYPE_SET_LOCK_STATUS_RSP : m_dataType = DATA_TYPE_NULL ; break;
|
|
|
case FRAME_TYPE_SET_PASSWORD_REQ : m_dataType = DATA_TYPE_STRING ; break;
|
|
|
case FRAME_TYPE_SET_PASSWORD_RSP : m_dataType = DATA_TYPE_NULL ; break;
|
|
|
case FRAME_TYPE_SET_USAGE_COUNT_REQ : m_dataType = DATA_TYPE_INTEGER ; break;
|
|
|
case FRAME_TYPE_SET_USAGE_COUNT_RSP : m_dataType = DATA_TYPE_NULL ; break;
|
|
|
case FRAME_TYPE_GET_RECORD_REQ : m_dataType = DATA_TYPE_NULL ; break;
|
|
|
case FRAME_TYPE_GET_RECORD_RSP : m_dataType = DATA_TYPE_STRING ; break;
|
|
|
case FRAME_TYPE_CLS_RECORD_REQ : m_dataType = DATA_TYPE_NULL ; break;
|
|
|
case FRAME_TYPE_CLS_RECORD_RSP : m_dataType = DATA_TYPE_NULL ; break;
|
|
|
case FRAME_TYPE_SET_PARAM_FALLBACK_REQ: m_dataType = DATA_TYPE_STRUCT_OF_FALLBACK; break;
|
|
|
case FRAME_TYPE_SET_PARAM_FALLBACK_RSP: m_dataType = DATA_TYPE_NULL ; break;
|
|
|
case FRAME_TYPE_SET_OPERATOR_REQ : m_dataType = DATA_TYPE_STRING ; break;
|
|
|
case FRAME_TYPE_SET_OPERATOR_RSP : m_dataType = DATA_TYPE_NULL ; break;
|
|
|
case FRAME_TYPE_SET_PARAM_TORQUE_REQ : m_dataType = DATA_TYPE_STRUCT_OF_TORQUE ; break;
|
|
|
case FRAME_TYPE_SET_PARAM_TORQUE_RSP : m_dataType = DATA_TYPE_NULL ; break;
|
|
|
case FRAME_TYPE_SET_PARAM_BOLT_REQ : m_dataType = DATA_TYPE_STRUCT_OF_BOLT ; break;
|
|
|
case FRAME_TYPE_SET_PARAM_BOLT_RSP : m_dataType = DATA_TYPE_NULL ; break;
|
|
|
case FRAME_TYPE_SET_PARAM_ANGLE_REQ : m_dataType = DATA_TYPE_STRUCT_OF_ANGLE ; break;
|
|
|
case FRAME_TYPE_SET_PARAM_ANGLE_RSP : m_dataType = DATA_TYPE_NULL ; break;
|
|
|
case FRAME_TYPE_SET_PARAM_GEAR_REQ : m_dataType = DATA_TYPE_STRUCT_OF_GEAR ; break;
|
|
|
case FRAME_TYPE_SET_PARAM_GEAR_RSP : m_dataType = DATA_TYPE_NULL ; break;
|
|
|
case FRAME_TYPE_SET_PARAM_SENSOR_REQ : m_dataType = DATA_TYPE_STRUCT_OF_SENSOR ; break;
|
|
|
case FRAME_TYPE_SET_PARAM_SENSOR_RSP : m_dataType = DATA_TYPE_NULL ; break;
|
|
|
default : m_dataType = DATA_TYPE_NULL ; break;
|
|
|
|
|
|
}
|
|
|
|
|
|
createData();
|
|
|
}
|
|
|
|
|
|
void Frame::createData()
|
|
|
{
|
|
|
if(m_data != nullptr)
|
|
|
{
|
|
|
delete m_data;
|
|
|
m_data = nullptr;
|
|
|
}
|
|
|
m_data = DataFactory::GetInstance()->createData(m_dataType);
|
|
|
}
|
|
|
|
|
|
void Frame::destroyData()
|
|
|
{
|
|
|
if(m_data != nullptr)
|
|
|
{
|
|
|
delete m_data;
|
|
|
m_data = nullptr;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void Frame::setData(Data *data)
|
|
|
{
|
|
|
if(m_data != nullptr)
|
|
|
{
|
|
|
delete m_data;
|
|
|
}
|
|
|
m_data = data;
|
|
|
setLen(data->length());
|
|
|
}
|
|
|
|
|
|
std::string Frame::toStr()
|
|
|
{
|
|
|
std::stringstream ss;
|
|
|
ss << "协议头:" << Utils::strToHexStr(Utils::shortToByteStr(getHead())) << std::endl;
|
|
|
ss << "地址:" << Utils::strToHexStr(Utils::shortToByteStr(getAddr())) << std::endl;
|
|
|
ss << "命令:" << Utils::strToHexStr(Utils::charToByteStr(getCmd())) << std::endl;
|
|
|
ss << "长度:" << Utils::strToHexStr(Utils::shortToByteStr(getLen())) << std::endl;
|
|
|
ss << "数据:" << getData()->toStr() << std::endl;
|
|
|
ss << "校验:" << Utils::strToHexStr(Utils::shortToByteStr(getCrc())) << std::endl;
|
|
|
|
|
|
return ss.str();
|
|
|
}
|
|
|
|
|
|
std::string Frame::toByteStr()
|
|
|
{
|
|
|
std::string s;
|
|
|
// 协议头
|
|
|
s.append(Utils::shortToByteStr(getHead()));
|
|
|
// 地址
|
|
|
s.append(Utils::shortToByteStr(getAddr()));
|
|
|
// 命令
|
|
|
s.append(Utils::charToByteStr(getCmd()));
|
|
|
// 数据长度
|
|
|
s.append(Utils::shortToByteStr(getLen()));
|
|
|
// 数据
|
|
|
//if(getData() != nullptr && getLen() > 0)
|
|
|
if(m_data != nullptr && m_len > 0)
|
|
|
{
|
|
|
// 数据
|
|
|
//s.append(m_data->toByteStr(), m_data->toByteStr().length());
|
|
|
std::string s1 = m_data->toByteStr();
|
|
|
int l1 = m_data->toByteStr().size();
|
|
|
//s.append(s1, s.size(), l1);
|
|
|
for(int i=0; i<l1; i++)
|
|
|
{
|
|
|
s.push_back(s1.at(i));
|
|
|
}
|
|
|
}
|
|
|
// crc校验
|
|
|
unsigned short crc = CRC::crc16Table((unsigned char *)s.c_str(), (int)s.length());
|
|
|
s.append(Utils::shortToByteStr(crc));
|
|
|
return s;
|
|
|
}
|
|
|
|
|
|
std::string Frame::toHexStr()
|
|
|
{
|
|
|
return Utils::strToHexStr(toByteStr());
|
|
|
}
|
|
|
|
|
|
bool Frame::fromByteStr(std::string str)
|
|
|
{
|
|
|
if(str.length() < 9)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 判断帧起始字符 0x5A 0xA5
|
|
|
if(!((unsigned char)str.at(0) == 0x5A && (unsigned char)str.at(1) == 0xA5))
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
// 判断帧命令
|
|
|
if(!isCmdValid(str.at(4)))
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
// 判断帧长度,7为帧头,len为帧数据长度,2为帧尾
|
|
|
int len = Utils::charToShort(str.at(5), str.at(6));
|
|
|
if(str.length() != (size_t)(7 + len + 2))
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
setHead(FRAME_HEAD);
|
|
|
setAddr(Utils::charToShort(str.at(2), str.at(3)));
|
|
|
setCmd(str.at(4));
|
|
|
updateDataType();
|
|
|
setLen(len);
|
|
|
if(getLen() > 0 && getLen() < MAX_DATA_LEN) // 最大限制10K
|
|
|
{
|
|
|
//getData()->fromByteStr(str.substr(7, getLen()));
|
|
|
std::string sstr = str.substr(7, getLen());
|
|
|
getData()->fromByteStr(sstr);
|
|
|
}
|
|
|
setCrc(Utils::charToShort(str.at(getLen()) - 2, str.at(getLen()) - 1));
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
void Frame::updateLen()
|
|
|
{
|
|
|
if(m_data == nullptr)
|
|
|
{
|
|
|
m_len = 0;
|
|
|
return;
|
|
|
}
|
|
|
m_len = m_data->length();
|
|
|
}
|