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++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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