1 /*
2  * Copyright (c) 2021 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 "network/devsl_dispatcher.h"
17 
18 #include "device_manager.h"
19 #include "ipc/i_daemon.h"
20 #include "securec.h"
21 #include "utils_log.h"
22 
23 namespace OHOS {
24 namespace Storage {
25 namespace DistributedFile {
26 std::map<std::string, std::vector<std::weak_ptr<KernelTalker>>> DevslDispatcher::talkersMap_;
27 std::map<std::string, std::string> DevslDispatcher::idMap_;
28 std::mutex DevslDispatcher::mutex;
29 
Start()30 int32_t DevslDispatcher::Start()
31 {
32     int32_t status = DATASL_OnStart();
33     if (status != 0) {
34         LOGE("devsl dispatcher start error %{public}d", status);
35     }
36 
37     return status;
38 }
39 
Stop()40 void DevslDispatcher::Stop()
41 {
42     DATASL_OnStop();
43 }
44 
MakeDevslQueryParams(const std::string & udid)45 DEVSLQueryParams DevslDispatcher::MakeDevslQueryParams(const std::string &udid)
46 {
47     DEVSLQueryParams queryParams;
48     if (memcpy_s(queryParams.udid, MAX_UDID_LENGTH, udid.c_str(), udid.size())) {
49         LOGE("devsl dispatcher memcpy error");
50     }
51     queryParams.udidLen = udid.size();
52 
53     return queryParams;
54 }
55 
DevslGetRegister(const std::string & cid,std::weak_ptr<KernelTalker> talker)56 uint32_t DevslDispatcher::DevslGetRegister(const std::string &cid, std::weak_ptr<KernelTalker> talker)
57 {
58     std::string udid;
59     auto &deviceManager = DistributedHardware::DeviceManager::GetInstance();
60     deviceManager.GetUdidByNetworkId(IDaemon::SERVICE_NAME, cid, udid);
61 
62     std::lock_guard<std::mutex> lock(mutex);
63     DEVSLQueryParams queryParams = MakeDevslQueryParams(udid);
64     int status = DATASL_GetHighestSecLevelAsync(&queryParams, &DevslDispatcher::DevslGottonCallback);
65     if (status != 0) {
66         LOGE("devsl dispatcher register callback error %{public}d", status);
67         return 0;
68     }
69 
70     idMap_[udid] = cid;
71     auto iter = talkersMap_.find(udid);
72     if (iter == talkersMap_.end()) {
73         std::vector<std::weak_ptr<KernelTalker>> talkers;
74         talkers.push_back(talker);
75         talkersMap_.emplace(udid, talkers);
76     } else {
77         iter->second.push_back(talker);
78     }
79 
80     return 0;
81 }
82 
DevslGottonCallbackAsync(const std::string udid,uint32_t devsl)83 void DevslDispatcher::DevslGottonCallbackAsync(const std::string udid, uint32_t devsl)
84 {
85     std::lock_guard<std::mutex> lock(mutex);
86 
87     auto it = talkersMap_.find(udid);
88     if (it == talkersMap_.end()) {
89         LOGE("devsl dispatcher callback, there is no talker");
90         return;
91     }
92 
93     for (auto talker : it->second) {
94         auto realTalker = talker.lock();
95         if (!realTalker) {
96             continue;
97         }
98 
99         auto iter = idMap_.find(udid);
100         if (iter != idMap_.end()) {
101             realTalker->SinkDevslTokernel(iter->second, devsl);
102         }
103     }
104 
105     talkersMap_.erase(it);
106 }
107 
DevslGottonCallback(DEVSLQueryParams * queryParams,int32_t result,uint32_t levelInfo)108 void DevslDispatcher::DevslGottonCallback(DEVSLQueryParams *queryParams, int32_t result, uint32_t levelInfo)
109 {
110     LOGI("devsl dispatcher callback");
111     if (result != 0) {
112         levelInfo = DATA_SEC_LEVEL1;
113         LOGE("devsl dispatcher dsl get callback result : %{public}d", result);
114     }
115 
116     std::string udid(reinterpret_cast<char *>(queryParams->udid), queryParams->udidLen);
117     std::thread callbackThread =
118         std::thread([udid, levelInfo]() { DevslGottonCallbackAsync(udid, levelInfo); });
119     callbackThread.detach();
120 }
121 } // namespace DistributedFile
122 } // namespace Storage
123 } // namespace OHOS
124