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 IPROCESSCOMMUNICATOR_H
17 #define IPROCESSCOMMUNICATOR_H
18 
19 #include <cstdint>
20 #include <functional>
21 #include <memory>
22 #include <string>
23 #include <vector>
24 #include "store_types.h"
25 
26 namespace DistributedDB {
27 // The DeviceInfos may contain other fields(Can only be auxiliary information) besides identifier field in the future.
28 struct DeviceInfos {
29     std::string identifier; // An unique and fixed identifier representing a device, such as UUID.
30 };
31 
32 struct ExtendInfo {
33     std::string appId;
34     std::string storeId;
35     std::string userId;
36     std::string dstTarget;
37 };
38 
39 class ExtendHeaderHandle {
40 public:
ExtendHeaderHandle()41     ExtendHeaderHandle() {};
~ExtendHeaderHandle()42     virtual ~ExtendHeaderHandle() {};
43     // headSize should be 8 byte align
44     // return OK and headSize = 0 if no need to fill Head Data
45     // return OK and headSize > 0 if permit sync and will call FillHeadData
46     // return NO_PERMISSION if not permit sync
GetHeadDataSize(uint32_t & headSize)47     virtual DBStatus GetHeadDataSize(uint32_t &headSize)
48     {
49         headSize = 0;
50         return OK;
51     };
52     // return OK if fill data ok
53     // return not OK if fill data failed
FillHeadData(uint8_t * data,uint32_t headSize,uint32_t totalLen)54     virtual DBStatus FillHeadData(uint8_t *data, uint32_t headSize, uint32_t totalLen)
55     {
56         return OK;
57     };
58 };
59 
60 // In OnDeviceChange, all field of devInfo should be valid, isOnline true for online and false for offline.
61 // The concept of online or offline:
62 // 1: Can be at the physical device level, which means the remote device can be visible and communicable by local device
63 // 2: Can also be at the process level, which means the same ProcessCommunicator(with same processLabel) had been
64 //    started on the remote device and thus visible and communicable by this local ProcessCommunicator.
65 using OnDeviceChange = std::function<void(const DeviceInfos &devInfo, bool isOnline)>;
66 
67 // In OnDataReceive, all field of srcDevInfo should be valid
68 using OnDataReceive = std::function<void(const DeviceInfos &srcDevInfo, const uint8_t *data, uint32_t length)>;
69 
70 using OnSendAble = std::function<void(const DeviceInfos &deviceInfo, int softBusErrCode)>;
71 
72 // For all functions with returnType DBStatus:
73 // return DBStatus::OK if successful, otherwise DBStatus::DB_ERROR if anything wrong.
74 // Additional information of reason why failed can be present in the log by the implementation.
75 // For "Get" or "Is" functions, implementation should notice that concurrent call is possible.
76 class IProcessCommunicator {
77 public:
78     // The distributeddb in one process can only use one ProcessCommunicator at the same time
79     // The ProcessCommunicator can only Start one processLabel at the same time
80     // The ProcessCommunicator can Start again after stop
81     // The processLabel should not be an empty string
82     virtual DBStatus Start(const std::string &processLabel) = 0;
83 
84     // The Stop should only be called after Start successfully
85     virtual DBStatus Stop() = 0;
86 
87     // The register function can be called anytime regardless of whether started or stopped.
88     // There will only be one callback at the same time for each function
89     // If register again, the latter callback replace the former callback.
90     // Register nullptr as callback to do unregister semantic.
91     // For concurrency security of implementation, there should be lock between register_operation and callback_event.
92     virtual DBStatus RegOnDeviceChange(const OnDeviceChange &callback) = 0;
93     virtual DBStatus RegOnDataReceive(const OnDataReceive &callback) = 0;
94 
95     // The SendData function should only be called after Start successfully
96     // Only the identifier field of dstDevInfo must be valid, no requirement for other field.
97     virtual DBStatus SendData(const DeviceInfos &dstDevInfo, const uint8_t *data, uint32_t length) = 0;
98 
SendData(const DeviceInfos & dstDevInfo,const uint8_t * data,uint32_t length,uint32_t totalLength)99     virtual DBStatus SendData(const DeviceInfos &dstDevInfo, const uint8_t *data, uint32_t length, uint32_t totalLength)
100     {
101         (void)totalLength;
102         return SendData(dstDevInfo, data, length);
103     }
104 
105     // The GetMtuSize function can be called anytime regardless of whether started or stopped.
106     // The mtuSize should not less than 1K otherwise it will be regard as 1K.
107     // For run on OHOS, there is agreement that the mtuSize should be nearly 5M.
108     virtual uint32_t GetMtuSize() = 0;
109 
110     // The GetLocalDeviceInfos function should only be called after Start successfully
111     // All field of returned DeviceInfos must be valid, the identifier must not be empty and changed between time.
112     virtual DeviceInfos GetLocalDeviceInfos() = 0;
113 
114     // The GetRemoteOnlineDeviceInfosList function should only be called after Start successfully
115     // All field of returned DeviceInfos must be valid, should not contain duplicate device or local device
116     virtual std::vector<DeviceInfos> GetRemoteOnlineDeviceInfosList() = 0;
117 
118     // The IsSameProcessLabelStartedOnPeerDevice function should only be called after Start successfully
119     // Only the identifier field of peerDevInfo must be valid, no requirement for other field.
120     // If the peer device is offline, then return false.
121     // If the peer device is online but no ProcessCommunicator with same processLabel had started on it, return false.
122     // If the peer device is online and ProcessCommunicator with same processLabel had started on it, return true.
123     virtual bool IsSameProcessLabelStartedOnPeerDevice(const DeviceInfos &peerDevInfo) = 0;
124 
~IProcessCommunicator()125     virtual ~IProcessCommunicator() {};
126 
127     // For ABI compatibility reason, temporarily place this method at last and offer a fake implementation.
128     // The valid mtuSize range from 1K to 5M, value beyond this range will be set to the upper or lower limit.
GetMtuSize(const DeviceInfos & devInfo)129     virtual uint32_t GetMtuSize(const DeviceInfos &devInfo)
130     {
131         if (devInfo.identifier.empty()) {
132             // Error case(would never happen actually) to avoid "unused-parameter" warning.
133             return 0;
134         }
135         return GetMtuSize();
136     }
137 
138     // The valid timeout range from 5s to 60s, value beyond this range will be set to the upper or lower limit.
GetTimeout()139     virtual uint32_t GetTimeout()
140     {
141         return 5 * 1000; // 5 * 1000ms
142     };
143 
144     // The valid timeout range from 5s to 60s, value beyond this range will be set to the upper or lower limit.
GetTimeout(const DeviceInfos & devInfo)145     virtual uint32_t GetTimeout(const DeviceInfos &devInfo)
146     {
147         if (devInfo.identifier.empty()) {
148             // Error case(would never happen actually) to avoid "unused-parameter" warning.
149             return 5 * 1000; // 5 * 1000ms
150         }
151         return GetTimeout();
152     }
153 
GetExtendHeaderHandle(const ExtendInfo & paramInfo)154     virtual std::shared_ptr<ExtendHeaderHandle> GetExtendHeaderHandle(const ExtendInfo &paramInfo)
155     {
156         return nullptr;
157     }
158     // called after OnDataReceive
159     // return NO_PERMISSION while no need to handle the dataBuff if remote device userId is not mate with local userId
160     // return INVALID_FORMAT and headLength = 0 if data service can not deSerialize the buff
161     // return OK if deSerialize ok and get HeadLength/localUserId successfully
CheckAndGetDataHeadInfo(const uint8_t * data,uint32_t totalLen,uint32_t & headLength,std::vector<std::string> & userId)162     virtual DBStatus CheckAndGetDataHeadInfo(const uint8_t *data, uint32_t totalLen, uint32_t &headLength,
163         std::vector<std::string> &userId)
164     {
165         headLength = 0;
166         return OK;
167     }
168 
169     virtual void RegOnSendAble([[gnu::unused]] const OnSendAble &sendAbleCallback)
170     {
171     }
172 };
173 } // namespace DistributedDB
174 
175 #endif // IPROCESSCOMMUNICATOR_H
176