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 "pin_holder_session.h"
17 
18 #include "dm_anonymous.h"
19 #include "dm_crypto.h"
20 #include "dm_log.h"
21 #include "nlohmann/json.hpp"
22 
23 namespace OHOS {
24 namespace DistributedHardware {
25 std::shared_ptr<IPinholderSessionCallback> PinHolderSession::pinholderSessionCallback_ = nullptr;
26 constexpr int32_t DM_OK = 0;
27 constexpr int32_t ERR_DM_FAILED = 96929744;
28 constexpr const char* TAG_MSG_TYPE = "MSG_TYPE";
29 constexpr const char* DM_PIN_HOLDER_SESSION_NAME = "ohos.distributedhardware.devicemanager.pinholder";
PinHolderSession()30 PinHolderSession::PinHolderSession()
31 {
32     LOGD("PinHolderSession constructor.");
33 }
34 
~PinHolderSession()35 PinHolderSession::~PinHolderSession()
36 {
37     LOGD("PinHolderSession destructor.");
38 }
39 
RegisterSessionCallback(std::shared_ptr<IPinholderSessionCallback> callback)40 int32_t PinHolderSession::RegisterSessionCallback(std::shared_ptr<IPinholderSessionCallback> callback)
41 {
42     pinholderSessionCallback_ = callback;
43     return DM_OK;
44 }
45 
UnRegisterSessionCallback()46 int32_t PinHolderSession::UnRegisterSessionCallback()
47 {
48     pinholderSessionCallback_ = nullptr;
49     return DM_OK;
50 }
51 
OpenSessionServer(const PeerTargetId & targetId)52 int32_t PinHolderSession::OpenSessionServer(const PeerTargetId &targetId)
53 {
54     int32_t sessionId = -1;
55     ConnectionAddr addrInfo;
56     int32_t ret = GetAddrByTargetId(targetId, addrInfo);
57     if (ret != DM_OK) {
58         LOGE("[SOFTBUS]open session error, sessionId: %{public}d.", sessionId);
59         return ret;
60     }
61     sessionId = ::OpenAuthSession(DM_PIN_HOLDER_SESSION_NAME, &addrInfo, 1, nullptr);
62     if (sessionId < 0) {
63         LOGE("[SOFTBUS]open session error, sessionId: %{public}d.", sessionId);
64         return sessionId;
65     }
66     LOGI("OpenAuthSession success. sessionId: %{public}d.", sessionId);
67     return sessionId;
68 }
69 
CloseSessionServer(int32_t sessionId)70 int32_t PinHolderSession::CloseSessionServer(int32_t sessionId)
71 {
72     LOGD("CloseSessionServer.");
73     ::CloseSession(sessionId);
74     return DM_OK;
75 }
76 
OnSessionOpened(int sessionId,int result)77 int PinHolderSession::OnSessionOpened(int sessionId, int result)
78 {
79     if (pinholderSessionCallback_ == nullptr) {
80         LOGE("OnSessionOpened error, pinholderSessionCallback_ is nullptr.");
81         return ERR_DM_FAILED;
82     }
83     int32_t sessionSide = GetSessionSide(sessionId);
84     pinholderSessionCallback_->OnSessionOpened(sessionId, sessionSide, result);
85     LOGI("OnSessionOpened, success, sessionId: %{public}d.", sessionId);
86     return DM_OK;
87 }
88 
OnSessionClosed(int sessionId)89 void PinHolderSession::OnSessionClosed(int sessionId)
90 {
91     LOGI("[SOFTBUS]OnSessionClosed sessionId: %{public}d", sessionId);
92     if (pinholderSessionCallback_ == nullptr) {
93         LOGE("OnSessionClosed error, pinholderSessionCallback_ is nullptr.");
94         return;
95     }
96     pinholderSessionCallback_->OnSessionClosed(sessionId);
97     return;
98 }
99 
OnBytesReceived(int sessionId,const void * data,unsigned int dataLen)100 void PinHolderSession::OnBytesReceived(int sessionId, const void *data, unsigned int dataLen)
101 {
102     if (sessionId < 0 || data == nullptr || dataLen <= 0) {
103         LOGE("[SOFTBUS]fail to receive data from softbus with sessionId: %{public}d, dataLen: %{public}d.", sessionId,
104             dataLen);
105         return;
106     }
107     if (pinholderSessionCallback_ == nullptr) {
108         LOGE("OnBytesReceived error, pinholderSessionCallback_ is nullptr.");
109         return;
110     }
111     LOGI("start, sessionId: %{public}d, dataLen: %{public}d.", sessionId, dataLen);
112     std::string message = std::string(reinterpret_cast<const char *>(data), dataLen);
113     pinholderSessionCallback_->OnDataReceived(sessionId, message);
114     return;
115 }
116 
SendData(int32_t sessionId,const std::string & message)117 int32_t PinHolderSession::SendData(int32_t sessionId, const std::string &message)
118 {
119     nlohmann::json jsonObject = nlohmann::json::parse(message, nullptr, false);
120     if (jsonObject.is_discarded()) {
121         LOGE("extrasJson error, message: %{public}s.", GetAnonyString(message).c_str());
122         return ERR_DM_FAILED;
123     }
124     if (!IsInt32(jsonObject, TAG_MSG_TYPE)) {
125         LOGE("SoftbusSession::SendData err json string.");
126         return ERR_DM_FAILED;
127     }
128     int32_t msgType = jsonObject[TAG_MSG_TYPE].get<int32_t>();
129     LOGI("start, msgType: %{public}d.", msgType);
130     int32_t ret = SendBytes(sessionId, message.c_str(), strlen(message.c_str()));
131     if (ret != DM_OK) {
132         LOGE("[SOFTBUS]SendBytes failed, ret: %{public}d.", ret);
133         return ret;
134     }
135     return ret;
136 }
137 
GetAddrByTargetId(const PeerTargetId & targetId,ConnectionAddr & addr)138 int32_t PinHolderSession::GetAddrByTargetId(const PeerTargetId &targetId, ConnectionAddr &addr)
139 {
140     if (!targetId.wifiIp.empty() && targetId.wifiIp.length() <= IP_STR_MAX_LEN) {
141         addr.type = ConnectionAddrType::CONNECTION_ADDR_WLAN;
142         if (memcpy_s(addr.info.ip.ip, IP_STR_MAX_LEN, targetId.wifiIp.c_str(), targetId.wifiIp.length()) != DM_OK) {
143             LOGE("copy wifi data failed.");
144             return ERR_DM_FAILED;
145         }
146         addr.info.ip.port = targetId.wifiPort;
147     } else if (!targetId.brMac.empty() && targetId.brMac.length() <= BT_MAC_LEN) {
148         addr.type = ConnectionAddrType::CONNECTION_ADDR_BR;
149         if (memcpy_s(addr.info.br.brMac, BT_MAC_LEN, targetId.brMac.c_str(), targetId.brMac.length()) != DM_OK) {
150             LOGE("copy br data failed.");
151             return ERR_DM_FAILED;
152         }
153     } else if (!targetId.bleMac.empty() && targetId.bleMac.length() <= BT_MAC_LEN) {
154         addr.type = ConnectionAddrType::CONNECTION_ADDR_BLE;
155         if (memcpy_s(addr.info.ble.bleMac, BT_MAC_LEN, targetId.bleMac.c_str(), targetId.bleMac.length()) != DM_OK) {
156             LOGE("copy ble data failed.");
157             return ERR_DM_FAILED;
158         }
159         if (!targetId.deviceId.empty()) {
160             Crypto::ConvertHexStringToBytes(addr.info.ble.udidHash, UDID_HASH_LEN,
161                 targetId.deviceId.c_str(), targetId.deviceId.length());
162         }
163     }
164     return DM_OK;
165 }
166 } // namespace DistributedHardware
167 } // namespace OHOS