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