1 /*
2  * Copyright (c) 2024 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 OHOS_DSCHED_SOFTBUS_SESSION_H
17 #define OHOS_DSCHED_SOFTBUS_SESSION_H
18 
19 #include <memory>
20 #include <mutex>
21 
22 #include "dsched_data_buffer.h"
23 
24 namespace OHOS {
25 namespace DistributedSchedule {
26 struct SessionInfo {
27     int32_t sessionId = 0;
28     std::string myDeviceId;
29     std::string peerDeviceId;
30     std::string sessionName;
31     bool isServer = false;
32 };
33 
34 class DSchedSoftbusSession {
35 public:
36     DSchedSoftbusSession();
37     DSchedSoftbusSession(SessionInfo &info);
38     ~DSchedSoftbusSession();
39 
40     void OnConnect();
41     bool OnDisconnect();
42     int32_t OnBytesReceived(std::shared_ptr<DSchedDataBuffer> buffer);
43     int32_t SendData(std::shared_ptr<DSchedDataBuffer> dataBuffer, int32_t dataType);
44     std::string GetPeerDeviceId();
45 
46 private:
47     enum {
48         FRAG_NULL = 0,
49         FRAG_START,
50         FRAG_MID,
51         FRAG_END,
52         FRAG_START_END,
53     };
54 
55     enum {
56         TLV_TYPE_NULL = 0,
57         TLV_TYPE_VERSION = 1001,
58         TLV_TYPE_FRAG_FLAG = 1002,
59         TLV_TYPE_DATA_TYPE = 1003,
60         TLV_TYPE_SEQ_NUM = 1004,
61         TLV_TYPE_TOTAL_LEN = 1005,
62         TLV_TYPE_SUB_SEQ = 1006,
63         TLV_TYPE_DATA_LEN = 1007,
64     };
65 
66     enum {
67         DATA_TYPE_NULL = 0,
68         DATA_TYPE_CONTINUE,
69     };
70 
71     static const uint32_t BINARY_DATA_MAX_TOTAL_LEN = 100 * 1024 * 1024;
72     static const uint32_t BINARY_DATA_MAX_LEN = 4 * 1024 * 1024;
73     static const uint32_t BINARY_DATA_PACKET_RESERVED_BUFFER = 512;
74     static const uint16_t PROTOCOL_VERSION = 1;
75     static const uint16_t HEADER_UINT8_NUM = 1;
76     static const uint16_t HEADER_UINT16_NUM = 2;
77     static const uint16_t HEADER_UINT32_NUM = 4;
78     static const uint16_t HEADER_TLV_NUM = 7;
79     static const uint16_t BINARY_HEADER_FRAG_LEN = 49;
80 
81     const uint32_t DSCHED_SHIFT_8 = 8;
82     const uint32_t COUNT_INIT_NUM = 1;
83     const uint16_t UINT16_SHIFT_MASK_0 = 0x00ff;
84 
85     struct SessionDataHeader {
86         uint16_t version;
87         uint8_t fragFlag;
88         uint32_t dataType;
89         uint32_t seqNum;
90         uint32_t totalLen;
91         uint16_t subSeq;
92         uint32_t dataLen;
93     };
94 
95     struct TlvItem {
96         uint16_t type = 0;
97         uint16_t len = 0;
98         uint32_t value = 0;
99 
100         static const uint16_t HEADER_TYPE_BYTES = sizeof(type);
101         static const uint16_t HEADER_LEN_BYTES = sizeof(len);
102     };
103 
104     void PackRecvData(std::shared_ptr<DSchedDataBuffer> buffer);
105     void AssembleNoFrag(std::shared_ptr<DSchedDataBuffer> buffer, SessionDataHeader &headerPara);
106     void AssembleFrag(std::shared_ptr<DSchedDataBuffer> buffer, SessionDataHeader &headerPara);
107     int32_t UnPackSendData(std::shared_ptr<DSchedDataBuffer> buffer, int32_t dataType);
108     int32_t GetFragDataHeader(uint8_t *ptrPacket, SessionDataHeader& headerPara);
109     int32_t UnPackStartEndData(std::shared_ptr<DSchedDataBuffer> buffer, int32_t dataType);
110     int32_t CheckUnPackBuffer(SessionDataHeader& headerPara);
111     void ResetAssembleFrag();
112     void MakeFragDataHeader(const SessionDataHeader& headPara, uint8_t *header, uint32_t len);
113     int32_t ReadTlvToHeader(uint8_t *ptrPacket, SessionDataHeader& headerPara, uint16_t& index, uint16_t byteLeft);
114     void WriteTlvToBuffer(const TlvItem& tlvItem, uint8_t *buffer,  uint32_t bufLen);
115     void SetHeadParaDataLen(SessionDataHeader& headPara, const uint32_t totalLen, const uint32_t offset,
116         const uint32_t maxSendSize);
117     int64_t GetNowTimeStampUs();
118     uint16_t U16Get(const uint8_t *ptr);
119     std::shared_ptr<DSchedDataBuffer> packBuffer_;
120     bool isWaiting_;
121     uint32_t nowSeq_;
122     uint32_t nowSubSeq_;
123     uint32_t offset_;
124     uint32_t totalLen_;
125 
126 private:
127     int32_t sessionId_ = 0;
128     std::string myDeviceId_;
129     std::string peerDeviceId_;
130     std::string sessionName_;
131     std::atomic<int32_t> refCount_ = 0;
132     bool isServer_ = false;
133     int32_t maxSendBytesSize_ = 0;
134     int32_t maxQos_ = 0;
135 };
136 }  // namespace DistributedSchedule
137 }  // namespace OHOS
138 #endif  // OHOS_DSCHED_SOFTBUS_SESSION_H
139