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.h"
17 
18 #include "dm_anonymous.h"
19 #include "dm_crypto.h"
20 #include "dm_log.h"
21 #include "dm_radar_helper.h"
22 #include "nlohmann/json.hpp"
23 
24 namespace OHOS {
25 namespace DistributedHardware {
26 constexpr int32_t SESSION_SIDE_SERVER = 0;
27 constexpr int32_t SESSION_ID_INVALID = -1;
28 constexpr int32_t REPLY_SUCCESS = 0;
29 constexpr int32_t REPLY_FAILED = -1;
30 
31 constexpr int32_t MSG_TYPE_CREATE_PIN_HOLDER = 600;
32 constexpr int32_t MSG_TYPE_CREATE_PIN_HOLDER_RESP = 601;
33 constexpr int32_t MSG_TYPE_DESTROY_PIN_HOLDER = 650;
34 constexpr int32_t MSG_TYPE_DESTROY_PIN_HOLDER_RESP = 651;
35 constexpr int32_t MSG_TYPE_PIN_HOLDER_CHANGE = 700;
36 constexpr int32_t MSG_TYPE_PIN_HOLDER_CHANGE_RESP = 701;
37 constexpr int32_t MSG_TYPE_PIN_CLOSE_SESSION = 800;
38 
39 constexpr const char* PINHOLDER_CREATE_TIMEOUT_TASK = "deviceManagerTimer:pinholdercreate";
40 constexpr int32_t PIN_HOLDER_SESSION_CREATE_TIMEOUT = 60;
41 
42 constexpr const char* TAG_PIN_TYPE = "PIN_TYPE";
43 constexpr const char* TAG_PAYLOAD = "PAYLOAD";
44 constexpr const char* TAG_REPLY = "REPLY";
45 constexpr const char* TAG_REMOTE_DEVICE_ID = "REMOTE_DEVICE_ID";
46 
47 constexpr int32_t DM_OK = 0;
48 constexpr int32_t ERR_DM_FAILED = 96929744;
49 constexpr int32_t ERR_DM_TIME_OUT = 96929745;
50 constexpr int32_t ERR_DM_CREATE_PIN_HOLDER_BUSY = 96929821;
51 constexpr const char* TAG_MSG_TYPE = "MSG_TYPE";
52 constexpr const char* TAG_DM_VERSION = "DM_VERSION";
53 constexpr const char* DM_CONNECTION_DISCONNECTED = "DM_CONNECTION_DISCONNECTED";
54 constexpr int32_t DEVICE_UUID_LENGTH = 65;
55 constexpr int32_t ERR_DM_INPUT_PARA_INVALID = 96929749;
56 constexpr int32_t ERR_DM_BIND_PEER_UNSUPPORTED = 96929802;
PinHolder(std::shared_ptr<IDeviceManagerServiceListener> listener)57 PinHolder::PinHolder(std::shared_ptr<IDeviceManagerServiceListener> listener): listener_(listener)
58 {
59     if (session_ == nullptr) {
60         session_ = std::make_shared<PinHolderSession>();
61     }
62     if (timer_ == nullptr) {
63         timer_ = std::make_shared<DmTimer>();
64     }
65     sinkState_ = SINK_INIT;
66     sourceState_ = SOURCE_INIT;
67 }
68 
~PinHolder()69 PinHolder::~PinHolder()
70 {
71     if (session_ != nullptr) {
72         session_->UnRegisterSessionCallback();
73         session_ = nullptr;
74     }
75     if (timer_ != nullptr) {
76         timer_->DeleteAll();
77         timer_ = nullptr;
78     }
79 }
80 
RegisterPinHolderCallback(const std::string & pkgName)81 int32_t PinHolder::RegisterPinHolderCallback(const std::string &pkgName)
82 {
83     if (session_ == nullptr) {
84         LOGE("RegisterPinHolderCallback session is nullptr.");
85         return ERR_DM_FAILED;
86     }
87     registerPkgName_ = pkgName;
88     session_->RegisterSessionCallback(shared_from_this());
89     return DM_OK;
90 }
91 
CreatePinHolder(const std::string & pkgName,const PeerTargetId & targetId,DmPinType pinType,const std::string & payload)92 int32_t PinHolder::CreatePinHolder(const std::string &pkgName,
93     const PeerTargetId &targetId, DmPinType pinType, const std::string &payload)
94 {
95     LOGI("CreatePinHolder.");
96     if (registerPkgName_.empty() || registerPkgName_ != pkgName) {
97         LOGE("CreatePinHolder pkgName: %{public}s is not register callback.", pkgName.c_str());
98         return ERR_DM_FAILED;
99     }
100     int32_t ret = CheckTargetIdVaild(targetId);
101     if (ret != DM_OK) {
102         LOGE("CreatePinHolder targetId is invalid.");
103         return ret;
104     }
105     if (listener_ == nullptr || session_ == nullptr) {
106         LOGE("CreatePinHolder listener or session is nullptr.");
107         return ERR_DM_FAILED;
108     }
109     if (sourceState_ != SOURCE_INIT) {
110         LOGE("CreatePinHolder failed, state is %{public}d.", sourceState_);
111         return ERR_DM_FAILED;
112     }
113     if (sessionId_ != SESSION_ID_INVALID) {
114         LOGI("CreatePinHolder session already create, sessionId: %{public}d.", sessionId_);
115         CreateGeneratePinHolderMsg();
116         return DM_OK;
117     }
118 
119     sessionId_ = session_->OpenSessionServer(targetId);
120     int32_t stageRes =
121         sessionId_ > 0 ? static_cast<int32_t>(StageRes::STAGE_SUCC) : static_cast<int32_t>(StageRes::STAGE_FAIL);
122     DmRadarHelper::GetInstance().ReportCreatePinHolder(
123         registerPkgName_, sessionId_, targetId.deviceId, sessionId_, stageRes);
124     if (sessionId_ < 0) {
125         LOGE("[SOFTBUS]open session error, sessionId: %{public}d.", sessionId_);
126         listener_->OnCreateResult(registerPkgName_, sessionId_);
127         listener_->OnPinHolderEvent(registerPkgName_, DmPinHolderEvent::CREATE_RESULT,
128             sessionId_, "");
129         sessionId_ = SESSION_ID_INVALID;
130         return sessionId_;
131     }
132     pinType_ = pinType;
133     payload_ = payload;
134     return DM_OK;
135 }
136 
DestroyPinHolder(const std::string & pkgName,const PeerTargetId & targetId,DmPinType pinType,const std::string & payload)137 int32_t PinHolder::DestroyPinHolder(const std::string &pkgName, const PeerTargetId &targetId, DmPinType pinType,
138     const std::string &payload)
139 {
140     LOGI("DestroyPinHolder.");
141     if (listener_ == nullptr || session_ == nullptr) {
142         LOGE("DestroyPinHolder listener or session is nullptr.");
143         return ERR_DM_FAILED;
144     }
145     if (registerPkgName_.empty() || pkgName != registerPkgName_) {
146         LOGE("DestroyPinHolder pkgName: %{public}s is not register callback.", pkgName.c_str());
147         return ERR_DM_FAILED;
148     }
149     int32_t ret = CheckTargetIdVaild(targetId);
150     if (ret != DM_OK) {
151         LOGE("DestroyPinHolder targetId is invalid.");
152         return ret;
153     }
154     if (sessionId_ == SESSION_ID_INVALID) {
155         LOGI("DestroyPinHolder session already destroy.");
156         listener_->OnDestroyResult(registerPkgName_, ret);
157         listener_->OnPinHolderEvent(registerPkgName_, DmPinHolderEvent::DESTROY_RESULT, ret, "");
158         return ret;
159     }
160     if (sourceState_ != SOURCE_CREATE) {
161         LOGE("DestroyPinHolder failed, state is %{public}d.", sourceState_);
162         return ERR_DM_FAILED;
163     }
164     if (timer_ != nullptr) {
165         timer_->DeleteTimer(PINHOLDER_CREATE_TIMEOUT_TASK);
166     }
167 
168     nlohmann::json jsonObj;
169     jsonObj[TAG_MSG_TYPE] = MSG_TYPE_DESTROY_PIN_HOLDER;
170     jsonObj[TAG_PIN_TYPE] = pinType;
171     jsonObj[TAG_PAYLOAD] = payload;
172     pinType_ = pinType;
173     std::string message = jsonObj.dump();
174     LOGI("DestroyPinHolder, message type is: %{public}d, pin type is: %{public}d.", MSG_TYPE_DESTROY_PIN_HOLDER,
175         pinType);
176     ret = session_->SendData(sessionId_, message);
177     int32_t stageRes =
178         ret == DM_OK ? static_cast<int32_t>(StageRes::STAGE_SUCC) : static_cast<int32_t>(StageRes::STAGE_FAIL);
179     DmRadarHelper::GetInstance().ReportDestroyPinHolder(registerPkgName_,
180         targetId.deviceId, ret, stageRes);
181     if (ret != DM_OK) {
182         LOGE("[SOFTBUS]SendBytes failed, ret: %{public}d.", ret);
183         listener_->OnDestroyResult(registerPkgName_, ERR_DM_FAILED);
184         listener_->OnPinHolderEvent(registerPkgName_, DmPinHolderEvent::DESTROY_RESULT, ERR_DM_FAILED, "");
185         return ret;
186     }
187     return ret;
188 }
189 
CreateGeneratePinHolderMsg()190 int32_t PinHolder::CreateGeneratePinHolderMsg()
191 {
192     if (listener_ == nullptr || session_ == nullptr) {
193         LOGE("CreateGeneratePinHolderMsg listener or session is nullptr.");
194         return ERR_DM_FAILED;
195     }
196     if (timer_ != nullptr) {
197         timer_->DeleteAll();
198         timer_->StartTimer(std::string(PINHOLDER_CREATE_TIMEOUT_TASK), PIN_HOLDER_SESSION_CREATE_TIMEOUT,
199             [this] (std::string name) {
200                 PinHolder::CloseSession(name);
201             });
202     }
203     nlohmann::json jsonObj;
204     jsonObj[TAG_PIN_TYPE] = pinType_;
205     jsonObj[TAG_PAYLOAD] = payload_;
206     jsonObj[TAG_MSG_TYPE] = MSG_TYPE_CREATE_PIN_HOLDER;
207     jsonObj[TAG_DM_VERSION] = "";
208     std::string message = jsonObj.dump();
209     LOGI("CreateGeneratePinHolderMsg, message type is: %{public}d, pin type is: %{public}d.",
210         MSG_TYPE_CREATE_PIN_HOLDER, pinType_);
211     int32_t ret = session_->SendData(sessionId_, message);
212     int32_t bizStage = static_cast<int32_t>(PinHolderStage::SEND_CREATE_PIN_HOLDER_MSG);
213     DmRadarHelper::GetInstance().ReportSendOrReceiveHolderMsg(bizStage,
214         std::string("CreateGeneratePinHolderMsg"), "");
215     if (ret != DM_OK) {
216         LOGE("[SOFTBUS]SendBytes failed, ret: %{public}d.", ret);
217         listener_->OnCreateResult(registerPkgName_, ret);
218         listener_->OnPinHolderEvent(registerPkgName_, DmPinHolderEvent::CREATE_RESULT, ret, "");
219         return ret;
220     }
221     return ret;
222 }
223 
ParseMsgType(const std::string & message)224 int32_t PinHolder::ParseMsgType(const std::string &message)
225 {
226     nlohmann::json jsonObject = nlohmann::json::parse(message, nullptr, false);
227     if (jsonObject.is_discarded()) {
228         LOGE("ParseMsgType DecodeRequest jsonStr error");
229         return ERR_DM_FAILED;
230     }
231     if (!IsInt32(jsonObject, TAG_MSG_TYPE)) {
232         LOGE("ParseMsgType err json string.");
233         return ERR_DM_FAILED;
234     }
235     int32_t msgType = jsonObject[TAG_MSG_TYPE].get<int32_t>();
236     return msgType;
237 }
238 
ProcessCloseSessionMsg(const std::string & message)239 void PinHolder::ProcessCloseSessionMsg(const std::string &message)
240 {
241     if (listener_ == nullptr || session_ == nullptr) {
242         LOGE("ProcessCloseSessionMsg listener or session is nullptr.");
243         return;
244     }
245     LOGI("CloseSessionMsg, message type is: %{public}d.", MSG_TYPE_PIN_CLOSE_SESSION);
246     session_->CloseSessionServer(sessionId_);
247     sessionId_ = SESSION_ID_INVALID;
248     sourceState_ = SOURCE_INIT;
249     sinkState_ = SINK_INIT;
250     listener_->OnCreateResult(registerPkgName_, ERR_DM_CREATE_PIN_HOLDER_BUSY);
251 }
252 
ProcessCreateMsg(const std::string & message)253 void PinHolder::ProcessCreateMsg(const std::string &message)
254 {
255     if (listener_ == nullptr || session_ == nullptr) {
256         LOGE("ProcessCreateMsg listener or session is nullptr.");
257         return;
258     }
259     nlohmann::json jsonObject = nlohmann::json::parse(message, nullptr, false);
260     if (jsonObject.is_discarded()) {
261         LOGE("ProcessCreateMsg DecodeRequest jsonStr error");
262         return;
263     }
264     if (!IsInt32(jsonObject, TAG_PIN_TYPE) || !IsString(jsonObject, TAG_PAYLOAD)) {
265         LOGE("ProcessCreateMsg err json string.");
266         return;
267     }
268     DmPinType pinType = static_cast<DmPinType>(jsonObject[TAG_PIN_TYPE].get<int32_t>());
269     std::string payload = jsonObject[TAG_PAYLOAD].get<std::string>();
270     isRemoteSupported_ = jsonObject.contains(TAG_DM_VERSION);
271     int32_t bizStage = static_cast<int32_t>(PinHolderStage::RECEIVE_CREATE_PIN_HOLDER_MSG);
272     DmRadarHelper::GetInstance().ReportSendOrReceiveHolderMsg(bizStage, std::string("ProcessCreateMsg"), "");
273     nlohmann::json jsonObj;
274     jsonObj[TAG_MSG_TYPE] = MSG_TYPE_CREATE_PIN_HOLDER_RESP;
275     if (sinkState_ != SINK_INIT) {
276         jsonObj[TAG_REPLY] = REPLY_FAILED;
277     } else {
278         jsonObj[TAG_REPLY] = REPLY_SUCCESS;
279         sinkState_ = SINK_CREATE;
280         sourceState_ = SOURCE_CREATE;
281         listener_->OnPinHolderCreate(registerPkgName_, remoteDeviceId_, pinType, payload);
282         nlohmann::json jsonContent;
283         jsonContent[TAG_PIN_TYPE] = pinType;
284         jsonContent[TAG_PAYLOAD] = payload;
285         jsonContent[TAG_REMOTE_DEVICE_ID] = remoteDeviceId_;
286         std::string content = jsonContent.dump();
287         listener_->OnPinHolderEvent(registerPkgName_, DmPinHolderEvent::CREATE, DM_OK, content);
288     }
289     jsonObj[TAG_DM_VERSION] = "";
290 
291     std::string msg = jsonObj.dump();
292     LOGI("ProcessCreateMsg, message type is: %{public}d.", MSG_TYPE_CREATE_PIN_HOLDER_RESP);
293     int32_t ret = session_->SendData(sessionId_, msg);
294     if (ret != DM_OK) {
295         LOGE("[SOFTBUS]SendBytes failed, ret: %{public}d.", ret);
296         return;
297     }
298 }
299 
ProcessCreateRespMsg(const std::string & message)300 void PinHolder::ProcessCreateRespMsg(const std::string &message)
301 {
302     nlohmann::json jsonObject = nlohmann::json::parse(message, nullptr, false);
303     if (jsonObject.is_discarded()) {
304         LOGE("ProcessCreateRespMsg DecodeRequest jsonStr error.");
305         return;
306     }
307     if (!IsInt32(jsonObject, TAG_REPLY)) {
308         LOGE("ProcessCreateRespMsg err json string.");
309         return;
310     }
311     isRemoteSupported_ = jsonObject.contains(TAG_DM_VERSION);
312     int32_t reply = jsonObject[TAG_REPLY].get<int32_t>();
313     if (listener_ == nullptr || session_ == nullptr) {
314         LOGE("ProcessCreateRespMsg listener or session is nullptr.");
315         return;
316     }
317     if (reply == REPLY_SUCCESS) {
318         listener_->OnCreateResult(registerPkgName_, DM_OK);
319         listener_->OnPinHolderEvent(registerPkgName_, DmPinHolderEvent::CREATE_RESULT, DM_OK, "");
320         sourceState_ = SOURCE_CREATE;
321         sinkState_ = SINK_CREATE;
322     } else {
323         LOGE("ProcessCreateRespMsg remote state is wrong.");
324         listener_->OnCreateResult(registerPkgName_, ERR_DM_FAILED);
325         listener_->OnPinHolderEvent(registerPkgName_, DmPinHolderEvent::CREATE_RESULT, ERR_DM_FAILED, "");
326         session_->CloseSessionServer(sessionId_);
327         sessionId_ = SESSION_ID_INVALID;
328         destroyState_ = STATE_REMOTE_WRONG;
329         sourceState_ = SOURCE_INIT;
330         sinkState_ = SINK_INIT;
331     }
332 }
333 
ProcessDestroyMsg(const std::string & message)334 void PinHolder::ProcessDestroyMsg(const std::string &message)
335 {
336     if (listener_ == nullptr || session_ == nullptr) {
337         LOGE("ProcessDestroyMsg listener or session is nullptr.");
338         return;
339     }
340     nlohmann::json jsonObject = nlohmann::json::parse(message, nullptr, false);
341     if (jsonObject.is_discarded()) {
342         LOGE("ProcessDestroyMsg DecodeRequest jsonStr error.");
343         return;
344     }
345     if (!IsInt32(jsonObject, TAG_PIN_TYPE) || !IsString(jsonObject, TAG_PAYLOAD)) {
346         LOGE("ProcessDestroyMsg err json string.");
347         return;
348     }
349     DmPinType pinType = static_cast<DmPinType>(jsonObject[TAG_PIN_TYPE].get<int32_t>());
350     std::string payload = jsonObject[TAG_PAYLOAD].get<std::string>();
351     int32_t bizStage = static_cast<int32_t>(PinHolderStage::RECEIVE_DESTROY_PIN_HOLDER_MSG);
352     DmRadarHelper::GetInstance().ReportSendOrReceiveHolderMsg(bizStage, std::string("ProcessDestroyMsg"), "");
353     nlohmann::json jsonObj;
354     jsonObj[TAG_MSG_TYPE] = MSG_TYPE_DESTROY_PIN_HOLDER_RESP;
355     if (sinkState_ != SINK_CREATE) {
356         jsonObj[TAG_REPLY] = REPLY_FAILED;
357     } else {
358         jsonObj[TAG_REPLY] = REPLY_SUCCESS;
359         sinkState_ = SINK_INIT;
360         sourceState_ = SOURCE_INIT;
361         if (!isDestroy_.load()) {
362             listener_->OnPinHolderDestroy(registerPkgName_, pinType, payload);
363             nlohmann::json jsonContent;
364             jsonContent[TAG_PIN_TYPE] = pinType;
365             jsonContent[TAG_PAYLOAD] = payload;
366             std::string content = jsonContent.dump();
367             listener_->OnPinHolderEvent(registerPkgName_, DmPinHolderEvent::DESTROY, DM_OK, content);
368             isDestroy_.store(true);
369         }
370     }
371 
372     std::string msg = jsonObj.dump();
373     LOGI("ProcessDestroyMsg, message type is: %{public}d.", MSG_TYPE_DESTROY_PIN_HOLDER_RESP);
374     int32_t ret = session_->SendData(sessionId_, msg);
375     if (ret != DM_OK) {
376         LOGE("[SOFTBUS]SendBytes failed, ret: %{public}d.", ret);
377         return;
378     }
379 }
380 
CloseSession(const std::string & name)381 void PinHolder::CloseSession(const std::string &name)
382 {
383     LOGI("PinHolder::CloseSession start timer name %{public}s.", name.c_str());
384     if (session_ == nullptr) {
385         LOGE("CloseSession session is nullptr.");
386         return;
387     }
388     nlohmann::json jsonObj;
389     jsonObj[DM_CONNECTION_DISCONNECTED] = true;
390     std::string payload = jsonObj.dump();
391     if (listener_ != nullptr && !isDestroy_.load()) {
392         listener_->OnPinHolderDestroy(registerPkgName_, pinType_, payload);
393         nlohmann::json jsonContent;
394         jsonContent[TAG_PIN_TYPE] = pinType_;
395         jsonContent[TAG_PAYLOAD] = payload;
396         std::string content = jsonContent.dump();
397         listener_->OnPinHolderEvent(registerPkgName_, DmPinHolderEvent::DESTROY, ERR_DM_TIME_OUT, content);
398         isDestroy_.store(true);
399     }
400     session_->CloseSessionServer(sessionId_);
401     if (timer_ != nullptr) {
402         timer_->DeleteAll();
403     }
404     destroyState_ = STATE_TIME_OUT;
405     sessionId_ = SESSION_ID_INVALID;
406     sinkState_ = SINK_INIT;
407     sourceState_ = SOURCE_INIT;
408     remoteDeviceId_ = "";
409     isRemoteSupported_ = false;
410 }
411 
ProcessDestroyResMsg(const std::string & message)412 void PinHolder::ProcessDestroyResMsg(const std::string &message)
413 {
414     nlohmann::json jsonObject = nlohmann::json::parse(message, nullptr, false);
415     if (jsonObject.is_discarded()) {
416         LOGE("ProcessDestroyResMsg DecodeRequest jsonStr error.");
417         return;
418     }
419     if (!IsInt32(jsonObject, TAG_REPLY)) {
420         LOGE("ProcessDestroyResMsg err json string.");
421         return;
422     }
423     int32_t reply = jsonObject[TAG_REPLY].get<int32_t>();
424     if (listener_ == nullptr || session_ == nullptr) {
425         LOGE("ProcessDestroyResMsg listener or session is nullptr.");
426         return;
427     }
428     if (reply == REPLY_SUCCESS) {
429         listener_->OnDestroyResult(registerPkgName_, DM_OK);
430         listener_->OnPinHolderEvent(registerPkgName_, DmPinHolderEvent::DESTROY_RESULT, DM_OK, "");
431         sourceState_ = SOURCE_INIT;
432         sinkState_ = SINK_INIT;
433         if (timer_ != nullptr) {
434             timer_->DeleteAll();
435         }
436     } else {
437         LOGE("ProcessDestroyResMsg remote state is wrong.");
438         listener_->OnDestroyResult(registerPkgName_, ERR_DM_FAILED);
439         listener_->OnPinHolderEvent(registerPkgName_, DmPinHolderEvent::DESTROY_RESULT, ERR_DM_FAILED, "");
440         sinkState_ = SINK_INIT;
441         sourceState_ = SOURCE_INIT;
442     }
443     session_->CloseSessionServer(sessionId_);
444     sessionId_ = SESSION_ID_INVALID;
445     remoteDeviceId_ = "";
446 }
447 
OnDataReceived(int32_t sessionId,std::string message)448 void PinHolder::OnDataReceived(int32_t sessionId, std::string message)
449 {
450     int32_t msgType = ParseMsgType(message);
451     LOGI("OnDataReceived, msgType: %{public}d.", msgType);
452     int32_t sessionSide = GetSessionSide(sessionId);
453     if (sessionSide == SESSION_SIDE_SERVER && sessionId != sessionId_) {
454         LOGE("another session opened, close this sessionId: %{public}d.", sessionId);
455         nlohmann::json jsonObj;
456         jsonObj[TAG_MSG_TYPE] = MSG_TYPE_PIN_CLOSE_SESSION;
457         std::string msg = jsonObj.dump();
458         int32_t ret = session_->SendData(sessionId, msg);
459         if (ret != DM_OK) {
460             LOGE("[SOFTBUS] SendBytes failed. ret: %{public}d.", ret);
461             listener_->OnPinHolderEvent(registerPkgName_, DmPinHolderEvent::CREATE_RESULT, ERR_DM_FAILED, "");
462         }
463         return;
464     }
465     switch (msgType) {
466         case MSG_TYPE_PIN_CLOSE_SESSION:
467             ProcessCloseSessionMsg(message);
468             break;
469         case MSG_TYPE_CREATE_PIN_HOLDER:
470             ProcessCreateMsg(message);
471             break;
472         case MSG_TYPE_CREATE_PIN_HOLDER_RESP:
473             ProcessCreateRespMsg(message);
474             break;
475         case MSG_TYPE_DESTROY_PIN_HOLDER:
476             ProcessDestroyMsg(message);
477             break;
478         case MSG_TYPE_DESTROY_PIN_HOLDER_RESP:
479             ProcessDestroyResMsg(message);
480             break;
481         case MSG_TYPE_PIN_HOLDER_CHANGE:
482             ProcessChangeMsg(message);
483             break;
484         case MSG_TYPE_PIN_HOLDER_CHANGE_RESP:
485             ProcessChangeRespMsg(message);
486             break;
487         default:
488             break;
489     }
490 }
491 
GetPeerDeviceId(int32_t sessionId,std::string & udidHash)492 void PinHolder::GetPeerDeviceId(int32_t sessionId, std::string &udidHash)
493 {
494     char peerDeviceId[DEVICE_UUID_LENGTH] = {0};
495     int32_t ret = ::GetPeerDeviceId(sessionId, &peerDeviceId[0], DEVICE_UUID_LENGTH);
496     if (ret != DM_OK) {
497         LOGE("[SOFTBUS]GetPeerDeviceId failed for session: %{public}d.", sessionId);
498         udidHash = "";
499         return;
500     }
501     std::string deviceId = peerDeviceId;
502     char udidHashTmp[DM_MAX_DEVICE_ID_LEN] = {0};
503     if (Crypto::GetUdidHash(deviceId, reinterpret_cast<uint8_t *>(udidHashTmp)) != DM_OK) {
504         LOGE("get udidhash by udid: %{public}s failed.", GetAnonyString(deviceId).c_str());
505         udidHash = "";
506         return;
507     }
508     udidHash = udidHashTmp;
509     LOGI("GetPeerDeviceId udid hash: %{public}s success.", GetAnonyString(udidHash).c_str());
510 }
511 
OnSessionOpened(int32_t sessionId,int32_t sessionSide,int32_t result)512 void PinHolder::OnSessionOpened(int32_t sessionId, int32_t sessionSide, int32_t result)
513 {
514     isDestroy_.store(false);
515     destroyState_ = STATE_UNKNOW;
516     char peerDeviceId[DEVICE_UUID_LENGTH] = {0};
517     int32_t ret = ::GetPeerDeviceId(sessionId, &peerDeviceId[0], DEVICE_UUID_LENGTH);
518     if (ret != DM_OK) {
519         LOGE("[SOFTBUS]GetPeerDeviceId failed for session: %{public}d.", sessionId);
520     }
521     DmRadarHelper::GetInstance().ReportSendOrReceiveHolderMsg(static_cast<int32_t>(PinHolderStage::SESSION_OPENED),
522         std::string("OnSessionOpened"), std::string(peerDeviceId));
523     if (sessionSide == SESSION_SIDE_SERVER) {
524         LOGI("[SOFTBUS]onSesssionOpened success, side is sink. sessionId: %{public}d.", sessionId);
525         GetPeerDeviceId(sessionId, remoteDeviceId_);
526         if (sessionId_ == SESSION_ID_INVALID) {
527             sessionId_ = sessionId;
528         }
529         return;
530     }
531     sessionId_ = sessionId;
532     if (result == DM_OK) {
533         CreateGeneratePinHolderMsg();
534         return;
535     }
536     LOGE("[SOFTBUS]onSesssionOpened failed. sessionId: %{public}d.", sessionId);
537     sessionId_ = SESSION_ID_INVALID;
538     if (listener_ != nullptr) {
539         listener_->OnCreateResult(registerPkgName_, result);
540         listener_->OnPinHolderEvent(registerPkgName_, DmPinHolderEvent::CREATE_RESULT, result, "");
541     }
542     return;
543 }
544 
OnSessionClosed(int32_t sessionId)545 void PinHolder::OnSessionClosed(int32_t sessionId)
546 {
547     if (sessionId != sessionId_) {
548         return;
549     }
550     LOGI("[SOFTBUS]OnSessionClosed sessionId: %{public}d.", sessionId);
551     sessionId_ = SESSION_ID_INVALID;
552     sinkState_ = SINK_INIT;
553     sourceState_ = SOURCE_INIT;
554     remoteDeviceId_ = "";
555     isRemoteSupported_ = false;
556     nlohmann::json jsonObj;
557     jsonObj[DM_CONNECTION_DISCONNECTED] = true;
558     std::string payload = jsonObj.dump();
559     if (listener_ != nullptr && !isDestroy_.load()) {
560         listener_->OnPinHolderDestroy(registerPkgName_, pinType_, payload);
561         nlohmann::json jsonContent;
562         jsonContent[TAG_PIN_TYPE] = pinType_;
563         jsonContent[TAG_PAYLOAD] = payload;
564         std::string content = jsonContent.dump();
565         if (destroyState_ == STATE_UNKNOW) {
566             listener_->OnPinHolderEvent(registerPkgName_, DmPinHolderEvent::DESTROY, sessionId, content);
567         } else if (destroyState_ == STATE_REMOTE_WRONG) {
568             listener_->OnPinHolderEvent(registerPkgName_, DmPinHolderEvent::DESTROY, ERR_DM_FAILED, content);
569         } else if (destroyState_ == STATE_TIME_OUT) {
570             listener_->OnPinHolderEvent(registerPkgName_, DmPinHolderEvent::DESTROY, ERR_DM_TIME_OUT, content);
571         }
572         isDestroy_.store(true);
573     }
574     if (timer_ != nullptr) {
575         timer_->DeleteAll();
576     }
577     return;
578 }
579 
CheckTargetIdVaild(const PeerTargetId & targetId)580 int32_t PinHolder::CheckTargetIdVaild(const PeerTargetId &targetId)
581 {
582     if (targetId.deviceId.empty() && targetId.brMac.empty() && targetId.bleMac.empty() && targetId.wifiIp.empty()) {
583         LOGE("CheckTargetIdVaild failed. targetId is empty.");
584         return ERR_DM_INPUT_PARA_INVALID;
585     }
586     return DM_OK;
587 }
588 
NotifyPinHolderEvent(const std::string & pkgName,const std::string & event)589 int32_t PinHolder::NotifyPinHolderEvent(const std::string &pkgName, const std::string &event)
590 {
591     LOGI("NotifyPinHolderEvent.");
592     if (listener_ == nullptr || session_ == nullptr) {
593         LOGE("NotifyPinHolderEvent listener or session is nullptr.");
594         return ERR_DM_FAILED;
595     }
596     if (registerPkgName_.empty() || pkgName != registerPkgName_ || event.empty()) {
597         LOGE("NotifyPinHolderEvent pkgName: %{public}s is not register callback.", pkgName.c_str());
598         return ERR_DM_FAILED;
599     }
600     if (sessionId_ == SESSION_ID_INVALID) {
601         LOGE("NotifyPinHolderEvent session invalid.");
602         return ERR_DM_FAILED;
603     }
604     if (!isRemoteSupported_) {
605         LOGE("NotifyPinHolderEvent failed, remote not support.");
606         return ERR_DM_BIND_PEER_UNSUPPORTED;
607     }
608     nlohmann::json jsonObject = nlohmann::json::parse(event, nullptr, false);
609     if (jsonObject.is_discarded() || !IsInt32(jsonObject, TAG_PIN_TYPE)) {
610         LOGE("ProcessChangeMsg DecodeRequest jsonStr error.");
611         return ERR_DM_FAILED;
612     }
613     if (timer_ != nullptr) {
614         timer_->DeleteAll();
615         timer_->StartTimer(std::string(PINHOLDER_CREATE_TIMEOUT_TASK), PIN_HOLDER_SESSION_CREATE_TIMEOUT,
616             [this] (std::string name) {
617                 PinHolder::CloseSession(name);
618             });
619     }
620     DmPinType pinType = static_cast<DmPinType>(jsonObject[TAG_PIN_TYPE].get<int32_t>());
621     nlohmann::json jsonObj;
622     jsonObj[TAG_MSG_TYPE] = MSG_TYPE_PIN_HOLDER_CHANGE;
623     jsonObj[TAG_PIN_TYPE] = pinType;
624     std::string message = jsonObj.dump();
625     LOGI("NotifyPinHolderEvent, message type is: %{public}d, pin type is: %{public}d.",
626         MSG_TYPE_PIN_HOLDER_CHANGE, pinType);
627     int32_t ret = session_->SendData(sessionId_, message);
628     if (ret != DM_OK) {
629         LOGE("[SOFTBUS]SendBytes failed, ret: %{public}d.", ret);
630         listener_->OnPinHolderEvent(registerPkgName_, DmPinHolderEvent::PIN_TYPE_CHANGE_RESULT, ERR_DM_FAILED, "");
631         return ERR_DM_FAILED;
632     }
633     return ret;
634 }
635 
ProcessChangeMsg(const std::string & message)636 void PinHolder::ProcessChangeMsg(const std::string &message)
637 {
638     if (listener_ == nullptr || session_ == nullptr) {
639         LOGE("ProcessChangeMsg listener or session is nullptr.");
640         return;
641     }
642     nlohmann::json jsonObject = nlohmann::json::parse(message, nullptr, false);
643     if (jsonObject.is_discarded()) {
644         LOGE("ProcessChangeMsg DecodeRequest jsonStr error.");
645         return;
646     }
647     if (!IsInt32(jsonObject, TAG_PIN_TYPE)) {
648         LOGE("ProcessChangeMsg err json string.");
649         return;
650     }
651     DmPinType pinType = static_cast<DmPinType>(jsonObject[TAG_PIN_TYPE].get<int32_t>());
652 
653     nlohmann::json jsonObj;
654     jsonObj[TAG_MSG_TYPE] = MSG_TYPE_PIN_HOLDER_CHANGE_RESP;
655     if (sinkState_ != SINK_CREATE) {
656         jsonObj[TAG_REPLY] = REPLY_FAILED;
657     } else {
658         jsonObj[TAG_REPLY] = REPLY_SUCCESS;
659         nlohmann::json jsonContent;
660         jsonContent[TAG_PIN_TYPE] = pinType;
661         std::string content = jsonContent.dump();
662         listener_->OnPinHolderEvent(registerPkgName_, DmPinHolderEvent::PIN_TYPE_CHANGE, DM_OK, content);
663         if (timer_ != nullptr) {
664             timer_->DeleteAll();
665             timer_->StartTimer(std::string(PINHOLDER_CREATE_TIMEOUT_TASK), PIN_HOLDER_SESSION_CREATE_TIMEOUT,
666                 [this] (std::string name) {
667                     PinHolder::CloseSession(name);
668                 });
669         }
670     }
671 
672     std::string msg = jsonObj.dump();
673     LOGI("ProcessChangeMsg, message type is: %{public}d.", MSG_TYPE_PIN_HOLDER_CHANGE_RESP);
674     int32_t ret = session_->SendData(sessionId_, msg);
675     if (ret != DM_OK) {
676         LOGE("[SOFTBUS]SendBytes failed, ret: %{public}d.", ret);
677         return;
678     }
679 }
680 
ProcessChangeRespMsg(const std::string & message)681 void PinHolder::ProcessChangeRespMsg(const std::string &message)
682 {
683     nlohmann::json jsonObject = nlohmann::json::parse(message, nullptr, false);
684     if (jsonObject.is_discarded()) {
685         LOGE("ProcessChangeRespMsg DecodeRequest jsonStr error.");
686         return;
687     }
688     if (!IsInt32(jsonObject, TAG_REPLY)) {
689         LOGE("ProcessChangeRespMsg err json string.");
690         return;
691     }
692     int32_t reply = jsonObject[TAG_REPLY].get<int32_t>();
693     if (listener_ == nullptr || session_ == nullptr) {
694         LOGE("ProcessChangeRespMsg listener or session is nullptr.");
695         return;
696     }
697     if (reply == REPLY_SUCCESS) {
698         listener_->OnPinHolderEvent(registerPkgName_, DmPinHolderEvent::PIN_TYPE_CHANGE_RESULT, DM_OK, "");
699     } else {
700         LOGE("ProcessChangeRespMsg remote state is wrong.");
701         listener_->OnPinHolderEvent(registerPkgName_, DmPinHolderEvent::PIN_TYPE_CHANGE_RESULT, ERR_DM_FAILED, "");
702     }
703 }
704 } // namespace DistributedHardware
705 } // namespace OHOS