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