You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

223 lines
7.7 KiB
C++

1 year ago
#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();
}