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 #include <cinttypes>
17 #include <map>
18 #include <gtest/gtest.h>
19 #include "common.h"
20 #include "session.h"
21 #include "tmessenger.h"
22
23 #define WAIT_TIMEOUT 5
24
25 using namespace testing::ext;
26
27 namespace OHOS {
28 class StreamEncryptClientMt : public testing::Test {
29 public:
StreamEncryptClientMt()30 StreamEncryptClientMt() { }
~StreamEncryptClientMt()31 ~StreamEncryptClientMt() { }
32 static void SetUpTestCase(void);
33 static void TearDownTestCase(void);
SetUp()34 void SetUp() override { }
TearDown()35 void TearDown() override { }
36 };
37
SetUpTestCase(void)38 void StreamEncryptClientMt::SetUpTestCase(void)
39 {
40 int32_t ret = TestInit();
41 ASSERT_EQ(ret, SOFTBUS_OK);
42
43 ret = TMessenger::GetInstance().Open(PKG_NAME, TEST_NOTIFY_NAME, TEST_NOTIFY_SRV_NAME, false);
44 ASSERT_EQ(ret, SOFTBUS_OK);
45 }
46
TearDownTestCase(void)47 void StreamEncryptClientMt::TearDownTestCase(void)
48 {
49 int32_t ret = TestDeInit();
50 ASSERT_EQ(ret, SOFTBUS_OK);
51 TMessenger::GetInstance().Close();
52 }
53
OnShutdownClient(int32_t socket,ShutdownReason reason)54 void OnShutdownClient(int32_t socket, ShutdownReason reason)
55 {
56 LOGI(">> OnShutdownClient {socket:%d, reason:%d}", socket, reason);
57 }
58
59 static ISocketListener g_listener = {
60 .OnBind = nullptr,
61 .OnShutdown = OnShutdownClient,
62 .OnBytes = nullptr,
63 .OnMessage = nullptr,
64 .OnStream = nullptr,
65 .OnFile = nullptr,
66 .OnQos = nullptr,
67 };
68
IsTestOk(bool isLocalEncrypt,const std::string sendData,const std::shared_ptr<Response> & resp)69 bool IsTestOk(bool isLocalEncrypt, const std::string sendData, const std::shared_ptr<Response> &resp)
70 {
71 if (resp == nullptr) {
72 LOGE("the response is null");
73 return false;
74 }
75
76 bool isPeerEncrypt = resp->isEncrypt_;
77 std::string recvData = resp->recvData_;
78
79 LOGI("isLocalEncrypt:%d, sendData:%s", isLocalEncrypt, sendData.c_str());
80 LOGI("isPeerEncrypt:%d, recvData:%s", isPeerEncrypt, recvData.c_str());
81 if (isLocalEncrypt == isPeerEncrypt) {
82 return sendData == recvData;
83 } else {
84 return sendData != recvData;
85 }
86 }
87
SendStreamExt(int32_t socket)88 static int32_t SendStreamExt(int32_t socket)
89 {
90 std::string src = TEST_STREAM_DATA;
91 StreamData data = {
92 .buf = (char *)(src.c_str()),
93 .bufLen = src.size(),
94 };
95 StreamData ext = { 0 };
96 StreamFrameInfo param = { 0 };
97 return SendStream(socket, &data, &ext, ¶m);
98 }
99
100 /*
101 * @tc.name: RawStreamEncryptTest001
102 * @tc.desc: Unencrypted raw stream data transmission test
103 * @tc.type: FUNC
104 * @tc.require:
105 */
106 HWTEST_F(StreamEncryptClientMt, RawStreamEncryptTest001, TestSize.Level1)
107 {
108 /**
109 * @tc.steps: step 1. set dataType is DATA_TYPE_RAW_STREAM and create socket by 'Socket' function.
110 * @tc.expect: socket greater zero.
111 */
112 SocketInfo info = {
113 .name = (char *)TEST_SESSION_NAME,
114 .pkgName = (char *)PKG_NAME,
115 .peerName = (char *)TEST_SESSION_NAME_SRV,
116 .peerNetworkId = NULL,
117 .dataType = DATA_TYPE_RAW_STREAM,
118 };
119 info.peerNetworkId = WaitOnLineAndGetNetWorkId();
120 int32_t socket = Socket(info);
121 ASSERT_GT(socket, 0);
122
123 /**
124 * @tc.steps: step 2. set Qos data and call 'Bind' function.
125 * @tc.expect: 'Bind' function return SOFTBUS_OK.
126 */
127 QosTV qosInfo[] = {
128 {.qos = QOS_TYPE_MIN_BW, .value = 80 },
129 { .qos = QOS_TYPE_MAX_LATENCY, .value = 4000},
130 { .qos = QOS_TYPE_MIN_LATENCY, .value = 2000},
131 { .qos = QOS_TYPE_RTT_LEVEL, .value = RTT_LEVEL_LOW},
132 };
133 int32_t ret = Bind(socket, qosInfo, sizeof(qosInfo) / sizeof(qosInfo[0]), &g_listener);
134 ASSERT_EQ(ret, SOFTBUS_OK);
135
136 /**
137 * @tc.steps: step 3. call 'SendStream' to send unencrypted raw stream data.
138 * @tc.expect: 'SendStream' function return SOFTBUS_OK.
139 */
140 ret = SendStreamExt(socket);
141 ASSERT_EQ(ret, SOFTBUS_OK);
142
143 /**
144 * @tc.steps: step 4. call 'Wait' function to get test results returned by server side.
145 * @tc.expect: 'IsTestOk' function return true.
146 */
147 std::shared_ptr<Response> resp = TMessenger::GetInstance().QueryResult(WAIT_TIMEOUT);
148 bool testResult = IsTestOk(false, TEST_STREAM_DATA, resp);
149 ASSERT_TRUE(testResult);
150
151 Shutdown(socket);
152 }
153
154 /*
155 * @tc.name: RawStreamEncryptTest002
156 * @tc.desc: Encrypted raw stream data transmission test
157 * @tc.type: FUNC
158 * @tc.require:
159 */
160 HWTEST_F(StreamEncryptClientMt, RawStreamEncryptTest002, TestSize.Level1)
161 {
162 /**
163 * @tc.steps: step 1. set dataType is DATA_TYPE_RAW_STREAM_ENCRYPED and create socket by 'Socket' function.
164 * @tc.expect: socket greater zero.
165 */
166 SocketInfo info = {
167 .name = (char *)TEST_SESSION_NAME,
168 .pkgName = (char *)PKG_NAME,
169 .peerName = (char *)TEST_SESSION_NAME_SRV,
170 .peerNetworkId = nullptr,
171 .dataType = DATA_TYPE_RAW_STREAM_ENCRYPED,
172 };
173 info.peerNetworkId = WaitOnLineAndGetNetWorkId();
174 int32_t socket = Socket(info);
175 ASSERT_GT(socket, 0);
176
177 /**
178 * @tc.steps: step 2. set Qos data and call 'Bind' function.
179 * @tc.expect: 'Bind' function return SOFTBUS_OK.
180 */
181 QosTV qosInfo[] = {
182 {.qos = QOS_TYPE_MIN_BW, .value = 80 },
183 { .qos = QOS_TYPE_MAX_LATENCY, .value = 4000},
184 { .qos = QOS_TYPE_MIN_LATENCY, .value = 2000},
185 };
186 int32_t ret = Bind(socket, qosInfo, sizeof(qosInfo) / sizeof(qosInfo[0]), &g_listener);
187 ASSERT_EQ(ret, SOFTBUS_OK);
188
189 /**
190 * @tc.steps: step 3. call 'SendStream' to send encrypted raw stream data.
191 * @tc.expect: 'SendStream' function return SOFTBUS_OK.
192 */
193 ret = SendStreamExt(socket);
194 ASSERT_EQ(ret, SOFTBUS_OK);
195
196 /**
197 * @tc.steps: step 4. call 'Wait' function to get test results returned by server side.
198 * @tc.expect: 'IsTestOk' function return true.
199 */
200 std::shared_ptr<Response> resp = TMessenger::GetInstance().QueryResult(WAIT_TIMEOUT);
201 bool testResult = IsTestOk(true, TEST_STREAM_DATA, resp);
202 ASSERT_TRUE(testResult);
203
204 Shutdown(socket);
205 }
206
207 class SessionStateManager {
208 public:
GetInstance()209 static SessionStateManager &GetInstance()
210 {
211 static SessionStateManager instance;
212 return instance;
213 }
214
EnableSessionId(int32_t sessionId)215 void EnableSessionId(int32_t sessionId)
216 {
217 if (sessionId <= 0) {
218 return;
219 }
220
221 std::unique_lock<std::mutex> lock(sessionIdMutex_);
222 sessionIdMap_.insert({ sessionId, true });
223 lock.unlock();
224 sessionIdCond_.notify_one();
225 }
226
UnenableSessionId(int32_t sessionId)227 void UnenableSessionId(int32_t sessionId)
228 {
229 if (sessionId <= 0) {
230 return;
231 }
232
233 std::unique_lock<std::mutex> lock(sessionIdMutex_);
234 sessionIdMap_.erase(sessionId);
235 }
236
WaitEnableSession(int32_t sessionId,uint32_t timeout)237 bool WaitEnableSession(int32_t sessionId, uint32_t timeout)
238 {
239 bool isEnable = false;
240 std::unique_lock<std::mutex> lock(sessionIdMutex_);
241 sessionIdCond_.wait_for(lock, std::chrono::seconds(timeout), [&] {
242 auto it = sessionIdMap_.find(sessionId);
243 if (it == sessionIdMap_.end()) {
244 isEnable = false;
245 } else {
246 isEnable = it->second;
247 }
248 return isEnable;
249 });
250 return isEnable;
251 }
252
253 private:
254 SessionStateManager() = default;
255 SessionStateManager(const SessionStateManager &other) = delete;
256 SessionStateManager(const SessionStateManager &&other) = delete;
257 SessionStateManager &operator=(const SessionStateManager &other) = delete;
258 SessionStateManager &operator=(const SessionStateManager &&other) = delete;
259
260 std::mutex sessionIdMutex_;
261 std::condition_variable sessionIdCond_;
262 std::map<int32_t, bool> sessionIdMap_;
263 };
264
OnSessionOpened(int sessionId,int result)265 static int OnSessionOpened(int sessionId, int result)
266 {
267 LOGI(">> OnSessionOpenedServer {sessionId:%d, result=%d", sessionId, result);
268 if (sessionId <= 0 || result != SOFTBUS_OK) {
269 LOGE(">> OnSessionOpenedServer, session open failed");
270 return result;
271 }
272
273 SessionStateManager::GetInstance().EnableSessionId(sessionId);
274 return SOFTBUS_OK;
275 }
276
OnSessionClosed(int sessionId)277 static void OnSessionClosed(int sessionId)
278 {
279 LOGI(">> OnSessionClosedServer {sessionId:%d", sessionId);
280 SessionStateManager::GetInstance().EnableSessionId(sessionId);
281 }
282
283 /*
284 * @tc.name: RawStreamEncryptTest003
285 * @tc.desc: Encrypted raw stream data transmission test
286 * @tc.type: FUNC
287 * @tc.require:
288 */
289 HWTEST_F(StreamEncryptClientMt, RawStreamEncryptTest003, TestSize.Level1)
290 {
291 /**
292 * @tc.steps: step 1. call 'CreateSessionServer' function to create session server.
293 * @tc.expect: 'CreateSessionServer' function return SOFTBUS_OK.
294 */
295 ISessionListener sessionListener = {
296 .OnSessionOpened = OnSessionOpened,
297 .OnSessionClosed = OnSessionClosed,
298 };
299
300 int32_t ret = CreateSessionServer(PKG_NAME, TEST_SESSION_NAME, &sessionListener);
301 ASSERT_EQ(ret, SOFTBUS_OK);
302
303 SessionAttribute attr = { 0 };
304 attr.dataType = TYPE_STREAM;
305 attr.attr.streamAttr.streamType = RAW_STREAM;
306 attr.linkTypeNum = 4;
307 attr.linkType[0] = LINK_TYPE_WIFI_WLAN_5G;
308 attr.linkType[1] = LINK_TYPE_WIFI_WLAN_2G;
309 attr.linkType[2] = LINK_TYPE_BR;
310 attr.linkType[3] = LINK_TYPE_BLE;
311 attr.fastTransData = nullptr;
312 attr.fastTransDataSize = 0;
313
314 /**
315 * @tc.steps: step 2. call 'OpenSession' function to create session.
316 * @tc.expect: 'OpenSession' function return SOFTBUS_OK.
317 */
318 int32_t sessionId = OpenSession(TEST_SESSION_NAME, TEST_SESSION_NAME_SRV, WaitOnLineAndGetNetWorkId(), "reserved",
319 &attr);
320 ASSERT_GT(sessionId, 0) << "failed to OpenSession, ret=" << sessionId;
321
322 /**
323 * @tc.steps: step 3. call 'WaitEnableSession' function to wait for the session to be opened.
324 * @tc.expect: 'WaitEnableSession' function return true.
325 */
326 bool isEnable = SessionStateManager::GetInstance().WaitEnableSession(sessionId, 10);
327 ASSERT_TRUE(isEnable) << "failed to enable session, sessionId" << sessionId;
328
329
330 /**
331 * @tc.steps: step 4. call 'SendStream' function to send unencrypted raw stream data.
332 * @tc.expect: 'SendStream' function return SOFTBUS_OK.
333 */
334 ret = SendStreamExt(sessionId);
335 ASSERT_EQ(ret, SOFTBUS_OK);
336
337 /**
338 * @tc.steps: step 5. call 'Wait' function to get test results returned by server side.
339 * @tc.expect: 'IsTestOk' function return true.
340 */
341 std::shared_ptr<Response> resp = TMessenger::GetInstance().QueryResult(WAIT_TIMEOUT);
342 bool testResult = IsTestOk(false, TEST_STREAM_DATA, resp);
343 ASSERT_TRUE(testResult);
344
345 CloseSession(sessionId);
346 RemoveSessionServer(PKG_NAME, TEST_SESSION_NAME);
347 }
348 } // namespace OHOS