• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef PROTOCOLPROTO_H
17 #define PROTOCOLPROTO_H
18 
19 #include <cstdint>
20 #include <memory>
21 #include "message.h"
22 #include "frame_header.h"
23 #include "parse_result.h"
24 #include "serial_buffer.h"
25 #include "message_transform.h"
26 #include "communicator_type_define.h"
27 #include "iprocess_communicator.h"
28 
29 namespace DistributedDB {
30 struct PhyHeaderInfo {
31     uint64_t sourceId;
32     uint32_t frameId;
33     FrameType frameType;
34 };
35 
36 struct FrameFragmentInfo {
37     uint8_t *oringinalBytesAddr;
38     uint32_t extendHeadSize;
39     uint32_t splitLength;
40     uint16_t fragCount;
41 };
42 
43 struct FragmentPacket {
44     uint8_t *ptrPacket;
45     uint32_t leftLength;
46 };
47 
48 class ProtocolProto {
49 public:
50     // For application layer frame
51     static uint32_t GetAppLayerFrameHeaderLength();
52     static uint32_t GetLengthBeforeSerializedData();
53 
54     // For communication layer frame
55     static uint32_t GetCommLayerFrameHeaderLength();
56 
57     // For handling application layer message. Return a heap object.
58     static SerialBuffer *ToSerialBuffer(const Message *inMsg, int &outErrorNo,
59         std::shared_ptr<ExtendHeaderHandle> &extendHandle, bool onlyMsgHeader = false);
60     static Message *ToMessage(const SerialBuffer *inBuff, int &outErrorNo, bool onlyMsgHeader = false);
61 
62     // For handling communication layer frame. Return a heap object.
63     static SerialBuffer *BuildEmptyFrameForVersionNegotiate(int &outErrorNo);
64     static SerialBuffer *BuildFeedbackMessageFrame(const Message *inMsg, const LabelType &inLabel, int &outErrorNo);
65     static SerialBuffer *BuildLabelExchange(uint64_t inDistinctValue, uint64_t inSequenceId,
66         const std::set<LabelType> &inLabels, int &outErrorNo);
67     static SerialBuffer *BuildLabelExchangeAck(uint64_t inDistinctValue, uint64_t inSequenceId, int &outErrorNo);
68 
69     // Return E_OK if no error happened. outPieces.size equal zero means not split, in this case, use ori buff.
70     static int SplitFrameIntoPacketsIfNeed(const SerialBuffer *inBuff, uint32_t inMtuSize,
71         std::vector<std::pair<std::vector<uint8_t>, uint32_t>> &outPieces);
72     static int AnalyzeSplitStructure(const ParseResult &inResult, uint32_t &outFragLen, uint32_t &outLastFragLen);
73 
74     // inFrame is the destination, pktBytes and pktLength are the source, fragOffset and fragLength give the boundary
75     static int CombinePacketIntoFrame(SerialBuffer *inFrame, const uint8_t *pktBytes, uint32_t pktLength,
76         uint32_t fragOffset, uint32_t fragLength);
77 
78     // Must not be called in multi-thread
79     // Return E_ALREADY_REGISTER if msgId is already registered
80     // Return E_INVALID_ARGS if member of inFunc not all valid
81     static int RegTransformFunction(uint32_t msgId, const TransformFunc &inFunc);
82 
83     static void UnRegTransformFunction(uint32_t msgId);
84 
85     // For application layer frame. In send case. Focus on frame.
86     static int SetDivergeHeader(SerialBuffer *inBuff, const LabelType &inCommLabel);
87 
88     // For both application and communication layer frame. In send case. Focus on frame.
89     static int SetPhyHeader(SerialBuffer *inBuff, const PhyHeaderInfo &inInfo);
90 
91     // In receive case, return error if parse fail.
92     static int CheckAndParsePacket(const std::string &srcTarget, const uint8_t *bytes, uint32_t length,
93         ParseResult &outResult);
94 
95     // The CommPhyHeader had already been parsed into outResult
96     static int CheckAndParseFrame(const SerialBuffer *inBuff, ParseResult &outResult);
97 
98     // Dfx method for helping debugging
99     static void DisplayPacketInformation(const uint8_t *bytes, uint32_t length);
100 
101     ProtocolProto() = delete;
102     ~ProtocolProto() = delete;
103 private:
104     static int CalculateXorSum(const uint8_t *bytes, uint32_t length, uint64_t &outSum);
105 
106     // For handling application layer message
107     static int CalculateDataSerializeLength(const Message *inMsg, uint32_t &outLength);
108     static int SerializeMessage(SerialBuffer *inBuff, const Message *inMsg);
109     static int DeSerializeMessage(const SerialBuffer *inBuff, Message *inMsg, bool onlyMsgHeader);
110     static bool IsSupportMessageVersion(uint16_t version);
111     static bool IsFeedbackErrorMessage(uint32_t errorNo);
112 
113     static int ParseCommPhyHeader(const std::string &srcTarget, const uint8_t *bytes, uint32_t length,
114         ParseResult &inResult);
115     static int ParseCommPhyHeaderCheckMagicAndVersion(const uint8_t *bytes, uint32_t length);
116     static int ParseCommPhyHeaderCheckField(const std::string &srcTarget, const CommPhyHeader &phyHeader,
117         const uint8_t *bytes, uint32_t length);
118     static int ParseCommPhyOptHeader(const uint8_t *bytes, uint32_t length, ParseResult &inResult);
119     static int ParseCommDivergeHeader(const uint8_t *bytes, uint32_t length, ParseResult &inResult);
120     static int ParseCommLayerPayload(const uint8_t *bytes, uint32_t length, ParseResult &inResult);
121     static int ParseLabelExchange(const uint8_t *bytes, uint32_t length, ParseResult &inResult);
122     static int ParseLabelExchangeAck(const uint8_t *bytes, uint32_t length, ParseResult &inResult);
123 
124     static int FrameFragmentation(const uint8_t *splitStartBytes, const FrameFragmentInfo &fragmentInfo,
125         const CommPhyHeader &framePhyHeader, std::vector<std::pair<std::vector<uint8_t>, uint32_t>> &outPieces);
126     static int FillFragmentPacket(const CommPhyHeader &phyHeader, const CommPhyOptHeader &phyOptHeader,
127         const uint8_t *fragBytes, uint32_t fragLen, FragmentPacket &outPacket);
128     static int FillFragmentPacketExtendHead(uint8_t *headBytesAddr, uint32_t headLen, FragmentPacket &outPacket);
129     static int GetExtendHeadDataSize(std::shared_ptr<ExtendHeaderHandle> &extendHandle, uint32_t &headSize);
130     static int FillExtendHeadDataIfNeed(std::shared_ptr<ExtendHeaderHandle> &extendHandle, SerialBuffer *buffer,
131         uint32_t headSize);
132 
133     static std::map<uint32_t, TransformFunc> msgIdMapFunc_;
134 };
135 } // namespace DistributedDB
136 
137 #endif // PROTOCOLPROTO_H
138