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 <mutex>
17 #include <memory>
18 #include <algorithm>
19 #include <dlfcn.h>
20 #include <vector>
21
22 #include "static_profile_manager.h"
23
24 #include "distributed_device_profile_errors.h"
25 #include "distributed_device_profile_log.h"
26 #include "event_handler_factory.h"
27 #include "kv_data_change_listener.h"
28 #include "kv_store_death_recipient.h"
29 #include "kv_sync_completed_listener.h"
30 #include "kv_adapter.h"
31 #include "profile_cache.h"
32 #include "profile_control_utils.h"
33 #include "profile_utils.h"
34 #include "permission_manager.h"
35 #include "static_capability_loader.h"
36
37 namespace OHOS {
38 namespace DistributedDeviceProfile {
39 IMPLEMENT_SINGLE_INSTANCE(StaticProfileManager);
40 namespace {
41 const std::string TAG = "StaticProfileManager";
42 const std::string APP_ID = "distributed_device_profile_service";
43 const std::string STORE_ID = "dp_kv_static_store";
44 }
45
Init()46 int32_t StaticProfileManager::Init()
47 {
48 HILOGI("call!");
49 int32_t initResult = DP_MANAGER_INIT_FAIL;
50 {
51 std::lock_guard<std::mutex> lock(staticStoreMutex_);
52 staticProfileStore_ = std::make_shared<KVAdapter>(APP_ID, STORE_ID,
53 std::make_shared<KvDataChangeListener>(STORE_ID),
54 std::make_shared<KvSyncCompletedListener>(STORE_ID), std::make_shared<KvDeathRecipient>(STORE_ID),
55 DistributedKv::TYPE_STATICS);
56 initResult = staticProfileStore_->Init();
57 }
58 HILOGI("Init finish, res: %{public}d", initResult);
59 return initResult;
60 }
61
UnInit()62 int32_t StaticProfileManager::UnInit()
63 {
64 HILOGI("call!");
65 {
66 std::lock_guard<std::mutex> lock(staticStoreMutex_);
67 if (staticProfileStore_ == nullptr) {
68 HILOGE("staticProfileStore_ is nullptr!");
69 return DP_NULLPTR;
70 }
71 staticProfileStore_->UnInit();
72 staticProfileStore_ = nullptr;
73 }
74 return DP_SUCCESS;
75 }
76
ReInit()77 int32_t StaticProfileManager::ReInit()
78 {
79 HILOGI("call!");
80 UnInit();
81 return Init();
82 }
83
PutCharacteristicProfile(const CharacteristicProfile & charProfile)84 int32_t StaticProfileManager::PutCharacteristicProfile(const CharacteristicProfile& charProfile)
85 {
86 HILOGD("call!");
87 int32_t putResult = DP_PUT_CHARACTERISTIC_CACHE_ERR;
88 {
89 std::lock_guard<std::mutex> lock(staticStoreMutex_);
90 putResult = ProfileControlUtils::PutCharacteristicProfile(staticProfileStore_, charProfile);
91 }
92 HILOGI("PutCharacteristicProfile result: %{public}d!", putResult);
93 return putResult;
94 }
95
GetCharacteristicProfile(const std::string & deviceId,const std::string & serviceName,const std::string & characteristicKey,CharacteristicProfile & charProfile)96 int32_t StaticProfileManager::GetCharacteristicProfile(const std::string& deviceId, const std::string& serviceName,
97 const std::string& characteristicKey, CharacteristicProfile& charProfile)
98 {
99 HILOGD("call!");
100 if (!ProfileUtils::IsKeyValid(deviceId) || !ProfileUtils::IsKeyValid(serviceName) ||
101 !ProfileUtils::IsKeyValid(characteristicKey)) {
102 HILOGE("Params are invalid!");
103 return DP_INVALID_PARAMS;
104 }
105 HILOGD("deviceId: %{public}s, serviceName: %{public}s, charKey: %{public}s!",
106 ProfileUtils::GetAnonyString(deviceId).c_str(), serviceName.c_str(), characteristicKey.c_str());
107 if (ProfileCache::GetInstance().GetStaticCharacteristicProfile(deviceId, serviceName, characteristicKey,
108 charProfile) == DP_SUCCESS) {
109 HILOGI("profile: %{public}s!", charProfile.dump().c_str());
110 return DP_SUCCESS;
111 }
112 CharacteristicProfile staticCapabilityProfile;
113 int32_t getResult = DP_GET_KV_DB_FAIL;
114 {
115 std::lock_guard<std::mutex> lock(staticStoreMutex_);
116 getResult = ProfileControlUtils::GetCharacteristicProfile(staticProfileStore_, deviceId,
117 STATIC_CAPABILITY_SVR_ID, STATIC_CAPABILITY_CHAR_ID, staticCapabilityProfile);
118 }
119 if (getResult != DP_SUCCESS) {
120 HILOGE("GetCharacteristicProfile fail, reason: %{public}d!", getResult);
121 return getResult;
122 }
123 HILOGI("profile : %{public}s", staticCapabilityProfile.dump().c_str());
124 std::unordered_map<std::string, CharacteristicProfile> staticInfoProfiles;
125 int generateProfileResult = GenerateStaticInfoProfile(staticCapabilityProfile, staticInfoProfiles);
126 if (generateProfileResult != DP_SUCCESS) {
127 HILOGE("GenerateStaticInfoProfile fail, reason: %{public}d!", generateProfileResult);
128 return generateProfileResult;
129 }
130 std::string charProfileKey = ProfileUtils::GenerateCharProfileKey(deviceId, serviceName, characteristicKey);
131 if (staticInfoProfiles.find(charProfileKey) == staticInfoProfiles.end()) {
132 HILOGE("charKey not exist, deviceId: %{public}s, serviceName: %{public}s, characteristicKey: %{public}s",
133 ProfileUtils::GetAnonyString(deviceId).c_str(), serviceName.c_str(), characteristicKey.c_str());
134 return DP_NOT_FOUND_FAIL;
135 }
136 charProfile = staticInfoProfiles[charProfileKey];
137 ProfileCache::GetInstance().AddStaticCharProfileBatch(staticInfoProfiles);
138 return DP_SUCCESS;
139 }
140
GetAllCharacteristicProfile(std::vector<CharacteristicProfile> & staticCapabilityProfiles)141 int32_t StaticProfileManager::GetAllCharacteristicProfile(
142 std::vector<CharacteristicProfile>& staticCapabilityProfiles)
143 {
144 HILOGD("call!");
145 int32_t getAllResult = DP_GET_KV_DB_FAIL;
146 {
147 std::lock_guard<std::mutex> lock(staticStoreMutex_);
148 getAllResult = ProfileControlUtils::GetAllCharacteristicProfile(staticProfileStore_, staticCapabilityProfiles);
149 }
150 if (getAllResult != DP_SUCCESS) {
151 HILOGE("GetAllCharacteristicProfile fail, reason: %{public}d!", getAllResult);
152 return getAllResult;
153 }
154 return DP_SUCCESS;
155 }
156
GenerateStaticInfoProfile(const CharacteristicProfile & staticCapabilityProfile,std::unordered_map<std::string,CharacteristicProfile> & staticInfoProfiles)157 int32_t StaticProfileManager::GenerateStaticInfoProfile(const CharacteristicProfile& staticCapabilityProfile,
158 std::unordered_map<std::string, CharacteristicProfile>& staticInfoProfiles)
159 {
160 HILOGD("call!");
161 std::string charValue = staticCapabilityProfile.GetCharacteristicValue();
162 cJSON* charValueJson = cJSON_Parse(charValue.c_str());
163 if (!cJSON_IsObject(charValueJson)) {
164 HILOGE("cJSON_Parse fail! charValue : %{public}s", ProfileUtils::GetAnonyString(charValue).c_str());
165 cJSON_Delete(charValueJson);
166 return DP_PARSE_STATIC_CAP_FAIL;
167 }
168 cJSON* staticCapabilityVersionItem = cJSON_GetObjectItemCaseSensitive(charValueJson,
169 STATIC_CAPABILITY_VERSION.c_str());
170 if (!cJSON_IsString(staticCapabilityVersionItem) || (staticCapabilityVersionItem->valuestring == NULL)) {
171 HILOGE("staticCapabilityVersion is invalid!");
172 cJSON_Delete(charValueJson);
173 return DP_PARSE_STATIC_CAP_FAIL;
174 }
175 std::string staticCapabilityVersion = staticCapabilityVersionItem->valuestring;
176 cJSON* staticCapabilityValueItem = cJSON_GetObjectItemCaseSensitive(charValueJson, STATIC_CAPABILITY_VALUE.c_str());
177 if (!cJSON_IsString(staticCapabilityValueItem) || (staticCapabilityValueItem->valuestring == NULL)) {
178 HILOGE("staticCapabilityValue is invalid!");
179 cJSON_Delete(charValueJson);
180 return DP_PARSE_STATIC_CAP_FAIL;
181 }
182 std::string staticCapabilityValue = staticCapabilityValueItem->valuestring;
183 cJSON_Delete(charValueJson);
184 StaticCapabilityLoader::GetInstance().LoadStaticProfiles(staticCapabilityProfile.GetDeviceId(),
185 staticCapabilityValue, staticCapabilityVersion, staticInfoProfiles);
186 return DP_SUCCESS;
187 }
188
E2ESyncStaticProfile(const DistributedHardware::DmDeviceInfo deviceInfo)189 void StaticProfileManager::E2ESyncStaticProfile(const DistributedHardware::DmDeviceInfo deviceInfo)
190 {
191 HILOGD("call!");
192 auto task = [this, deviceInfo]() {
193 std::string remoteNetworkId = deviceInfo.networkId;
194 HILOGD("networkId:%{public}s", ProfileUtils::GetAnonyString(remoteNetworkId).c_str());
195 if (remoteNetworkId.empty()) {
196 HILOGE("networkId or extraData is empty!");
197 return;
198 }
199 if (!ProfileUtils::IsOHBasedDevice(deviceInfo.extraData)) {
200 HILOGI("device is not ohbase. remoteNetworkId=%{public}s",
201 ProfileUtils::GetAnonyString(remoteNetworkId).c_str());
202 return;
203 }
204 std::lock_guard<std::mutex> lock(staticStoreMutex_);
205 if (staticProfileStore_ == nullptr) {
206 HILOGE("staticProfileStore is nullptr");
207 return;
208 }
209 int32_t syncResult = staticProfileStore_->Sync({remoteNetworkId}, SyncMode::PUSH_PULL);
210 if (syncResult != DP_SUCCESS) {
211 HILOGE("E2ESyncStaticProfile fail, res: %{public}d!", syncResult);
212 return;
213 }
214 HILOGI("E2ESyncStaticProfile success!");
215 };
216 auto handler = EventHandlerFactory::GetInstance().GetEventHandler();
217 if (handler == nullptr || !handler->PostTask(task)) {
218 HILOGE("Post E2ESyncStaticProfile task fail!");
219 return;
220 }
221 }
222 } // namespace DistributedDeviceProfile
223 } // namespace OHOS
224