/* * 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 MCU_PROTOCOL_H #define MCU_PROTOCOL_H #include "StatusCode.h" #include #include #include #include #include #include /** * @brief The context of protocol processing is used for the association binding of protocol data transmission and * reception, ensuring the correct logic of protocol question and answer. * */ class VProtocolContext { public: VProtocolContext() = default; virtual ~VProtocolContext() = default; unsigned int mSerialNumber; short mCheckCode; // TODO: Need to improve }; template class ProtocolContext : public VProtocolContext { public: ProtocolContext(T &value) : mData(value) { } virtual ~ProtocolContext() = default; public: T mData; }; class SingleMcuPacket { public: SingleMcuPacket(const void *buf, const size_t &length) : mBuf(buf), mLength(length) { } ~SingleMcuPacket() = default; const void *mBuf; const size_t mLength; }; class VProtocolBase { public: VProtocolBase() = default; virtual ~VProtocolBase() = default; protected: virtual std::shared_ptr SharedFromThis(void); virtual ssize_t WriteData(const void *buff, const size_t buffLength, std::shared_ptr &context, const unsigned int &serialNumber); protected: virtual size_t GetKeyHeadLength(void); virtual StatusCode GetDataLength(const void *keyHead, const size_t &headLength, size_t &dataLength); virtual void PushMcuData(const void *buf, const size_t &length); virtual StatusCode CheckHeader(void *header, size_t &headLength); }; enum class ReplyResult { SUCCEED = 1, FAILED, END }; class OtherSideReply { public: OtherSideReply() = default; virtual ~OtherSideReply() = default; virtual void GetIpcMissionReply(const unsigned int &serialNumber, const unsigned char &mission); virtual void OnlyResultReply(const unsigned int &serialNumber, const ReplyResult &result); }; class OtherSideAsk { public: OtherSideAsk() = default; virtual ~OtherSideAsk() = default; virtual void OtherSideSendIpcMission(const unsigned int &serialNumber, const unsigned char &mission); virtual void OtherSideSendHearBeat(const unsigned int &serialNumber); virtual void OtherSideSendGetIntervalStart(const unsigned int &serialNumber); virtual void OtherSideSendGetDateTime(const unsigned int &serialNumber); virtual void OtherSideSendGetPirSensitivity(const unsigned int &serialNumber); }; class VProtocolRecv : public OtherSideReply, public OtherSideAsk { public: VProtocolRecv() = default; virtual ~VProtocolRecv() = default; static std::shared_ptr &GetInstance(std::shared_ptr *impl = nullptr); }; class McuProtocol : virtual public VProtocolBase { public: McuProtocol() = default; virtual ~McuProtocol() = default; protected: const StatusCode Init(void); const StatusCode UnInit(void); const StatusCode GetIpcMission(std::shared_ptr &context); const StatusCode CutOffPowerSupply(std::shared_ptr &context); const StatusCode FeedWatchDog(std::shared_ptr &context); const StatusCode SetFeedingCycleForWatchDog(const unsigned char &hour, const unsigned char &min, const unsigned char &second, std::shared_ptr &context); const StatusCode McuSetDateTime(const unsigned short &year, const unsigned char &mon, const unsigned char &day, const unsigned char &hour, const unsigned char &min, const unsigned char &second, std::shared_ptr &context); const StatusCode SetPirSensitivity(const unsigned char &sensitivity, std::shared_ptr &context); const StatusCode ContorlInfraredLight(const unsigned char &control, std::shared_ptr &context); const StatusCode GetPhotosensitivityValue(std::shared_ptr &context); void DataHandleThread(void); protected: void ReplyOtherSideSendIpcMission(const ReplyResult &result, const unsigned int &serialNumber); void ReplyOtherSideSendHearBeat(const ReplyResult &result, const unsigned int &serialNumber); void ReplyOtherSideSendGetIntervalStart(const ReplyResult &result, const unsigned int &serialNumber, const unsigned char &hour, const unsigned char &min, const unsigned char &second); void ReplyOtherSideSendGetDateTime(const ReplyResult &result, const unsigned int &serialNumber, const unsigned short &year, const unsigned char &mon, const unsigned char &day, const unsigned char &hour, const unsigned char &min, const unsigned char &second); void ReplyOtherSideSendGetPirSensitivity(const ReplyResult &result, const unsigned int &serialNumber, const unsigned char &sensitivity); protected: size_t GetKeyHeadLength(void) override; StatusCode GetDataLength(const void *keyHead, const size_t &headLength, size_t &dataLength) override; void PushMcuData(const void *buf, const size_t &length) override; StatusCode CheckHeader(void *header, size_t &headLength) override; private: StatusCode WriteProtocolData(const void *buff, const size_t buffLength, std::shared_ptr &context, const unsigned int &serialNumber); private: std::mutex mMutex; sem_t mSem; bool mThreadRuning; std::thread mDataHandleThread; std::list mMcuDataList; }; #endif