1 /*
2 * Copyright (c) 2022-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 "softbus_session.h"
17
18 #include "dm_anonymous.h"
19 #include "dm_constants.h"
20 #include "dm_dfx_constants.h"
21 #include "dm_hitrace.h"
22 #include "dm_log.h"
23 #include "nlohmann/json.hpp"
24 #include "softbus_connector.h"
25
26 namespace OHOS {
27 namespace DistributedHardware {
28 std::shared_ptr<ISoftbusSessionCallback> SoftbusSession::sessionCallback_ = nullptr;
29 constexpr const char* DM_HITRACE_AUTH_TO_OPPEN_SESSION = "DM_HITRACE_AUTH_TO_OPPEN_SESSION";
30 constexpr int32_t MAX_DATA_LEN = 65535;
31
OnShutdown(int32_t socket, ShutdownReason reason)32 static void OnShutdown(int32_t socket, ShutdownReason reason)
33 {
34 LOGI("[SOFTBUS]OnShutdown socket : %{public}d, reason: %{public}d", socket, (int32_t)reason);
35 SoftbusSession::OnSessionClosed(socket);
36 }
37
OnBytes(int32_t socket, const void *data, uint32_t dataLen)38 static void OnBytes(int32_t socket, const void *data, uint32_t dataLen)
39 {
40 LOGI("[SOFTBUS]OnBytes socket : %{public}d", socket);
41 SoftbusSession::OnBytesReceived(socket, data, dataLen);
42 }
43
OnQos(int32_t socket, QoSEvent eventId, const QosTV *qos, uint32_t qosCount)44 static void OnQos(int32_t socket, QoSEvent eventId, const QosTV *qos, uint32_t qosCount)
45 {
46 LOGI("[SOFTBUS]OnQos, socket: %{public}d, QoSEvent: %{public}d, qosCount: %{public}u", socket, (int32_t)eventId,
47 qosCount);
48 if (qosCount > QOS_TYPE_BUTT) {
49 LOGE("OnQos invalid qosCount");
50 return;
51 }
52 for (uint32_t idx = 0; idx < qosCount; idx++) {
53 LOGI("QosTV: type: %{public}d, value: %{public}d", (int32_t)qos[idx].qos, qos[idx].value);
54 }
55 }
56
SoftbusSession()57 SoftbusSession::SoftbusSession()
58 {
59 LOGD("SoftbusSession constructor.");
60 if (memset_s(&iSocketListener_, sizeof(ISocketListener), 0, sizeof(ISocketListener)) != DM_OK) {
61 LOGE("SoftbusSession::SoftbusSession memset_s failed.");
62 }
63
64 iSocketListener_.OnShutdown = OnShutdown;
65 iSocketListener_.OnBytes = OnBytes;
66 iSocketListener_.OnQos = OnQos;
67 iSocketListener_.OnFile = nullptr;
68 iSocketListener_.OnMessage = nullptr;
69 iSocketListener_.OnBind = nullptr;
70 iSocketListener_.OnStream = nullptr;
71 iSocketListener_.OnError = nullptr;
72 iSocketListener_.OnNegotiate = nullptr;
73 }
74
~SoftbusSession()75 SoftbusSession::~SoftbusSession()
76 {
77 LOGD("SoftbusSession destructor.");
78 }
79
RegisterSessionCallback(std::shared_ptr<ISoftbusSessionCallback> callback)80 int32_t SoftbusSession::RegisterSessionCallback(std::shared_ptr<ISoftbusSessionCallback> callback)
81 {
82 sessionCallback_ = callback;
83 return DM_OK;
84 }
85
UnRegisterSessionCallback()86 int32_t SoftbusSession::UnRegisterSessionCallback()
87 {
88 sessionCallback_ = nullptr;
89 return DM_OK;
90 }
91
OpenAuthSession(const std::string &deviceId)92 int32_t SoftbusSession::OpenAuthSession(const std::string &deviceId)
93 {
94 DmTraceStart(std::string(DM_HITRACE_AUTH_TO_OPPEN_SESSION));
95 int32_t sessionId = -1;
96 std::string connectAddr;
97 ConnectionAddr *addrInfo = SoftbusConnector::GetConnectAddr(deviceId, connectAddr);
98 if (addrInfo == nullptr) {
99 LOGE("[SOFTBUS]addrInfo is nullptr. sessionId: %{public}d.", sessionId);
100 return sessionId;
101 }
102 sessionId = ::OpenAuthSession(DM_SESSION_NAME, addrInfo, 1, nullptr);
103 if (sessionId < 0) {
104 LOGE("[SOFTBUS]open session error, sessionId: %{public}d.", sessionId);
105 return sessionId;
106 }
107 DmTraceEnd();
108 LOGI("OpenAuthSession success. sessionId: %{public}d.", sessionId);
109 return sessionId;
110 }
111
CloseAuthSession(int32_t sessionId)112 int32_t SoftbusSession::CloseAuthSession(int32_t sessionId)
113 {
114 LOGI("CloseAuthSession.");
115 ::CloseSession(sessionId);
116 return DM_OK;
117 }
118
GetPeerDeviceId(int32_t sessionId, std::string &peerDevId)119 int32_t SoftbusSession::GetPeerDeviceId(int32_t sessionId, std::string &peerDevId)
120 {
121 char peerDeviceId[DEVICE_UUID_LENGTH] = {0};
122 int32_t ret = ::GetPeerDeviceId(sessionId, &peerDeviceId[0], DEVICE_UUID_LENGTH);
123 if (ret == DM_OK) {
124 peerDevId = peerDeviceId;
125 LOGI("[SOFTBUS]GetPeerDeviceId success for session: %{public}d, peerDeviceId: %{public}s.", sessionId,
126 GetAnonyString(peerDevId).c_str());
127 return DM_OK;
128 }
129 LOGE("[SOFTBUS]GetPeerDeviceId failed for session: %{public}d, ret: %{public}d.", sessionId, ret);
130 peerDevId = "";
131 return ret;
132 }
133
SendData(int32_t sessionId, std::string &message)134 int32_t SoftbusSession::SendData(int32_t sessionId, std::string &message)
135 {
136 nlohmann::json jsonObject = nlohmann::json::parse(message, nullptr, false);
137 if (jsonObject.is_discarded()) {
138 LOGE("extrasJson error, message: %{public}s.", GetAnonyString(message).c_str());
139 return ERR_DM_FAILED;
140 }
141 if (!IsInt32(jsonObject, TAG_MSG_TYPE)) {
142 LOGE("SoftbusSession::SendData err json string.");
143 return ERR_DM_FAILED;
144 }
145 int32_t msgType = jsonObject[TAG_MSG_TYPE].get<int32_t>();
146 LOGI("start, msgType: %{public}d.", msgType);
147 if (sessionCallback_->GetIsCryptoSupport()) {
148 LOGI("SendData Start encryption.");
149 }
150 int32_t ret = SendBytes(sessionId, message.c_str(), strlen(message.c_str()));
151 if (ret != DM_OK) {
152 LOGE("[SOFTBUS]SendBytes failed.");
153 return ret;
154 }
155 return DM_OK;
156 }
157
SendHeartbeatData(int32_t sessionId, std::string &message)158 int32_t SoftbusSession::SendHeartbeatData(int32_t sessionId, std::string &message)
159 {
160 int32_t ret = SendBytes(sessionId, message.c_str(), strlen(message.c_str()));
161 if (ret != DM_OK) {
162 LOGE("[SOFTBUS]SendHeartbeatData failed.");
163 return ret;
164 }
165 return DM_OK;
166 }
167
OnSessionOpened(int sessionId, int result)168 int SoftbusSession::OnSessionOpened(int sessionId, int result)
169 {
170 int32_t sessionSide = GetSessionSide(sessionId);
171 sessionCallback_->OnSessionOpened(sessionId, sessionSide, result);
172 LOGD("OnSessionOpened, success, sessionId: %{public}d.", sessionId);
173 return DM_OK;
174 }
175
OnSessionClosed(int sessionId)176 void SoftbusSession::OnSessionClosed(int sessionId)
177 {
178 LOGD("OnSessionClosed, sessionId: %{public}d.", sessionId);
179 }
180
OnBytesReceived(int sessionId, const void *data, unsigned int dataLen)181 void SoftbusSession::OnBytesReceived(int sessionId, const void *data, unsigned int dataLen)
182 {
183 if (sessionId < 0 || data == nullptr || dataLen <= 0 || dataLen > MAX_DATA_LEN) {
184 LOGI("[SOFTBUS]fail to receive data from softbus with sessionId: %{public}d, dataLen: %{public}d.", sessionId,
185 dataLen);
186 return;
187 }
188 LOGI("start, sessionId: %{public}d, dataLen: %{public}d.", sessionId, dataLen);
189 if (sessionCallback_->GetIsCryptoSupport()) {
190 LOGI("Start decryption.");
191 }
192 std::string message = std::string(reinterpret_cast<const char *>(data), dataLen);
193 nlohmann::json jsonObject = nlohmann::json::parse(message, nullptr, false);
194 if (jsonObject.is_discarded()) {
195 LOGE("DecodeRequestAuth jsonStr error");
196 return;
197 }
198 if (!IsInt32(jsonObject, TAG_MSG_TYPE)) {
199 LOGE("err json string, first time");
200 return;
201 }
202 if (jsonObject[TAG_MSG_TYPE].get<int32_t>() == AUTH_DEVICE_REQ_NEGOTIATE ||
203 jsonObject[TAG_MSG_TYPE].get<int32_t>() == AUTH_DEVICE_RESP_NEGOTIATE) {
204 sessionCallback_->OnAuthDeviceDataReceived(sessionId, message);
205 } else {
206 sessionCallback_->OnDataReceived(sessionId, message);
207 }
208 LOGI("completed.");
209 }
210 } // namespace DistributedHardware
211 } // namespace OHOS
212