mirror of
https://gitee.com/jiuyilian/embedded-framework.git
synced 2025-01-06 10:16:51 -05:00
209 lines
7.8 KiB
C++
209 lines
7.8 KiB
C++
/*
|
|
* Copyright (c) 2023 Fancy Code.
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
#ifndef PROTOCOL_HANDLE_H
|
|
#define PROTOCOL_HANDLE_H
|
|
#include "ILog.h"
|
|
#include "StatusCode.h"
|
|
#include <functional>
|
|
#include <map>
|
|
#include <memory>
|
|
#include <mutex>
|
|
constexpr char ORDER_BIG_ENDIAN = 0x01;
|
|
constexpr char ORDER_LITTLE_ENDIAN = 0x02;
|
|
constexpr size_t KEY_HEAD_LENGTH = sizeof(short) + sizeof(unsigned int) + sizeof(short) + sizeof(short);
|
|
constexpr size_t CHECK_CODE_LENGTH = sizeof(short);
|
|
constexpr unsigned int SERIAL_NUMBER_NEED_TO_MAKE_A_LOCAL_ONE = 0;
|
|
#pragma pack(1)
|
|
typedef struct protocol_packet
|
|
{
|
|
short mHead;
|
|
unsigned int mSerialNumber;
|
|
short mCommand;
|
|
short mLength;
|
|
// char *mData;
|
|
short mCheckCode;
|
|
} ProtocolPacket;
|
|
#pragma pack()
|
|
constexpr unsigned short PROTOCOL_HEAD = 0xFAC1;
|
|
enum PROTOCOL_COMMAND
|
|
{
|
|
ASK_IPC_MISSION = 0x8101,
|
|
REPLY_IPC_MISSION = 0x0101,
|
|
ASK_CUT_OFF_PWOER_SUPPLY = 0x8102,
|
|
ASK_FEED_WATCH_DOG = 0x8103,
|
|
ASK_SET_FEEDING_CYCLE = 0x8104,
|
|
REPLY_SET_FEEDING_CYCLE = 0x0104,
|
|
ASK_SET_DATE_TIME = 0x8107,
|
|
REPLY_SET_DATE_TIME = 0x0107,
|
|
ASK_SET_PIR_SENSITIVITY = 0x8108,
|
|
REPLY_SET_PIR_SENSITIVITY = 0x0108,
|
|
ASK_CONTORL_INFRARED_LIGHT = 0x810A,
|
|
REPLY_CONTORL_INFRARED_LIGHT = 0x010A,
|
|
ASK_GET_PHOTOSENSITIVITY = 0x810B,
|
|
REPLY_GET_PHOTOSENSITIVITY = 0x010B,
|
|
/**
|
|
* @brief The protocol starting from here is a request sent from the other end.
|
|
*
|
|
*/
|
|
REPLY_OTHER_SIDE_ASK_SEND_IPC_MISSION = 0xC101,
|
|
OTHER_SIDE_ASK_SEND_IPC_MISSION = 0x4101,
|
|
PROTOCOL_COMMAND_END
|
|
};
|
|
constexpr unsigned char ZERO_MEANS_SHUTDOWN_WATCH_DOG = 0x00;
|
|
#pragma pack(1)
|
|
typedef struct watch_dog_param
|
|
{
|
|
watch_dog_param(const unsigned char &hour, const unsigned char &min, const unsigned char &second)
|
|
: mHour(hour), mMin(min), mSecond(second)
|
|
{
|
|
}
|
|
const unsigned char mHour;
|
|
const unsigned char mMin;
|
|
const unsigned char mSecond;
|
|
} WatchDogParam;
|
|
typedef struct set_date_time
|
|
{
|
|
set_date_time(const unsigned short &year, const unsigned char &mon, const unsigned char &day,
|
|
const unsigned char &hour, const unsigned char &min, const unsigned char &second)
|
|
: mYear(year), mMon(mon), mDay(day), mHour(hour), mMin(min), mSecond(second)
|
|
{
|
|
}
|
|
const unsigned short mYear;
|
|
const unsigned char mMon;
|
|
const unsigned char mDay;
|
|
const unsigned char mHour;
|
|
const unsigned char mMin;
|
|
const unsigned char mSecond;
|
|
} SetDateTime;
|
|
#pragma pack()
|
|
class VProtocolParam
|
|
{
|
|
public:
|
|
VProtocolParam(const PROTOCOL_COMMAND &command) : mCommand(command)
|
|
{
|
|
mSerialNumber = SERIAL_NUMBER_NEED_TO_MAKE_A_LOCAL_ONE;
|
|
}
|
|
virtual ~VProtocolParam() = default;
|
|
const PROTOCOL_COMMAND mCommand;
|
|
unsigned int mSerialNumber;
|
|
};
|
|
template <typename T>
|
|
class ProtocolParam : public VProtocolParam
|
|
{
|
|
|
|
public:
|
|
ProtocolParam(const PROTOCOL_COMMAND &command, T &value) : VProtocolParam(command), mData(value) {}
|
|
virtual ~ProtocolParam() = default;
|
|
|
|
public:
|
|
/**
|
|
* @brief
|
|
* Protocol data.
|
|
*/
|
|
T mData;
|
|
};
|
|
using MakePacketFunc = std::function<void(const std::shared_ptr<VProtocolParam> &)>;
|
|
using AnalyzePacketFunc = std::function<void(const ProtocolPacket &)>;
|
|
/**
|
|
* @brief Protocol processing classes need to focus on data size issues, and ProtocolHandle defaults to handling large
|
|
* end data.
|
|
*/
|
|
class ProtocolHandle
|
|
{
|
|
public:
|
|
ProtocolHandle(const std::shared_ptr<VProtocolParam> ¶m);
|
|
ProtocolHandle(const void *data, const size_t &length);
|
|
virtual ~ProtocolHandle();
|
|
void *GetProtocolDataBuff(void) { return mProtocolData; }
|
|
size_t GetProtocolDataLength(void) { return mProtocolDataLength; }
|
|
unsigned int GetSerialNumber(void) { return mProtocolSerialNumber; }
|
|
|
|
/**
|
|
* @brief These functions assemble scattered data into continuous memory protocol packets and complete the sending
|
|
* of protocol packets.
|
|
*/
|
|
private:
|
|
ProtocolPacket CreatePocketWithSerialNumber(void);
|
|
void MallocPacketDataBuff(const void *data, const size_t dataLength, const short &command);
|
|
void MakeProtocolPacket(const std::shared_ptr<VProtocolParam> ¶m);
|
|
void MakeNoUserDataPacket(const std::shared_ptr<VProtocolParam> ¶m);
|
|
void MakeAskIpcMissionPacket(const std::shared_ptr<VProtocolParam> ¶m);
|
|
void MakeAskCutOffPowerSupplyPacket(const std::shared_ptr<VProtocolParam> ¶m);
|
|
void MakeAskFeedWatchDogPacket(const std::shared_ptr<VProtocolParam> ¶m);
|
|
void MakeAskSetFeedingCyclePacket(const std::shared_ptr<VProtocolParam> ¶m);
|
|
void MakeAskSetDateTimePacket(const std::shared_ptr<VProtocolParam> ¶m);
|
|
void MakeAskSetPirSensitivityPacket(const std::shared_ptr<VProtocolParam> ¶m);
|
|
void MakeAskControlInfraredLightPacket(const std::shared_ptr<VProtocolParam> ¶m);
|
|
void MakeAskGetPhotosensitivityPacket(const std::shared_ptr<VProtocolParam> ¶m);
|
|
void MakeReplyOtherSideSendIpcMissionPacket(const std::shared_ptr<VProtocolParam> ¶m);
|
|
template <typename T>
|
|
void MakeProtocolData(const std::shared_ptr<VProtocolParam> ¶m)
|
|
{
|
|
constexpr int PARAM_DATA_LENGTH = sizeof(T);
|
|
std::shared_ptr<ProtocolParam<T>> SetParam = std::dynamic_pointer_cast<ProtocolParam<T>>(param);
|
|
if (!SetParam) {
|
|
LogError("Invalid param.\n");
|
|
return;
|
|
}
|
|
MallocPacketDataBuff(&(SetParam->mData), PARAM_DATA_LENGTH, param->mCommand);
|
|
}
|
|
|
|
private:
|
|
/**
|
|
* @brief These function implementations parse the received frame by frame continuous data into the data required by
|
|
* the application, completing the protocol unpacking.
|
|
*/
|
|
void AnalyzeProtocolPacket(void);
|
|
unsigned char ReplyOneBytePacketResult(const ProtocolPacket &packet);
|
|
void AnalyzeReplyResultPacket(const ProtocolPacket &packet);
|
|
void AnalyzeReplyIpcMissionPacket(const ProtocolPacket &packet);
|
|
void AnalyzeOtherSideSendIpcMissionPacket(const ProtocolPacket &packet);
|
|
|
|
private:
|
|
virtual void BigEndianConversion(ProtocolPacket &packet) {}
|
|
virtual short BigEndianConversion(const short &number) { return number; }
|
|
virtual void HostByteOrderConversion(ProtocolPacket &packet) {}
|
|
virtual bool CheckoutTheCheckCode(const ProtocolPacket &packet);
|
|
|
|
protected:
|
|
std::shared_ptr<VProtocolParam> mParam;
|
|
std::map<PROTOCOL_COMMAND, MakePacketFunc> mMakePacketFunc;
|
|
std::map<PROTOCOL_COMMAND, AnalyzePacketFunc> mAnalyzePacketFunc;
|
|
unsigned char *mProtocolData;
|
|
size_t mProtocolDataLength;
|
|
/**
|
|
* @brief Single protocol package serial number.
|
|
*
|
|
*/
|
|
unsigned int mProtocolSerialNumber;
|
|
/**
|
|
* @brief The global protocol packet serial number is used to bind the data content of the one question one answer
|
|
* protocol.
|
|
*
|
|
*/
|
|
static unsigned int mSerialNumber;
|
|
static std::mutex mMutex;
|
|
|
|
public:
|
|
static void Init(void);
|
|
static void UnInit(void);
|
|
static std::shared_ptr<ProtocolHandle> CreateProtocolData(const std::shared_ptr<VProtocolParam> ¶m);
|
|
static void ProtocolAnalysis(const void *data, const size_t &length);
|
|
static size_t GetKeyHeadLength(void);
|
|
static StatusCode GetDataLength(const void *keyHead, const size_t &headLength, size_t &dataLength);
|
|
static char GetByteOrder(void);
|
|
static void PrintHexadecimalData(const void *buf, const size_t &bufLength, const char *log = nullptr);
|
|
};
|
|
#endif |