* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "dm_config_manager.h"
#include <dlfcn.h>
#include "dm_constants.h"
#include "dm_log.h"
#include "json_config.h"
#include "nlohmann/json.hpp"
namespace OHOS {
namespace DistributedHardware {
void from_json(const nlohmann::json &jsonObject, AdapterSoLoadInfo &soLoadInfo)
{
if (!jsonObject.contains("name") || !jsonObject.contains("type") || !jsonObject.contains("version") ||
!jsonObject.contains("funcName") || !jsonObject.contains("soName") || !jsonObject.contains("soPath")) {
LOGE("AdapterSoLoadInfo json key Not complete");
return;
}
jsonObject["name"].get_to(soLoadInfo.name);
jsonObject["type"].get_to(soLoadInfo.type);
jsonObject["version"].get_to(soLoadInfo.version);
jsonObject["funcName"].get_to(soLoadInfo.funcName);
jsonObject["soName"].get_to(soLoadInfo.soName);
jsonObject["soPath"].get_to(soLoadInfo.soPath);
}
void from_json(const nlohmann::json &jsonObject, AuthSoLoadInfo &soLoadInfo)
{
if (!jsonObject.contains("name") || !jsonObject.contains("type") || !jsonObject.contains("version") ||
!jsonObject.contains("funcName") || !jsonObject.contains("soName") || !jsonObject.contains("soPath") ||
!jsonObject.contains("authType")) {
LOGE("AuthSoLoadInfo json key Not complete");
return;
}
jsonObject["name"].get_to(soLoadInfo.name);
jsonObject["type"].get_to(soLoadInfo.type);
jsonObject["version"].get_to(soLoadInfo.version);
jsonObject["authType"].get_to(soLoadInfo.authType);
jsonObject["funcName"].get_to(soLoadInfo.funcName);
jsonObject["soName"].get_to(soLoadInfo.soName);
jsonObject["soPath"].get_to(soLoadInfo.soPath);
}
DmConfigManager &DmConfigManager::GetInstance()
{
static DmConfigManager instance;
return instance;
}
DmConfigManager::DmConfigManager()
{
LOGI("DmConfigManager constructor");
do {
nlohmann::json adapterJsonObject = nlohmann::json::parse(adapterJsonConfigString, nullptr, false);
if (adapterJsonObject.is_discarded()) {
LOGE("adapter json config string parse error");
break;
}
const char *jsonKey = ADAPTER_LOAD_JSON_KEY.c_str();
if (!adapterJsonObject.contains(jsonKey)) {
LOGE("adapter json config string key not exist");
break;
}
auto soLoadInfo = adapterJsonObject[jsonKey].get<std::vector<AdapterSoLoadInfo>>();
for (uint32_t i = 0; i < soLoadInfo.size(); i++) {
if (soLoadInfo[i].name.size() == 0 || soLoadInfo[i].type.size() == 0 || soLoadInfo[i].version.size() == 0 ||
soLoadInfo[i].funcName.size() == 0 || soLoadInfo[i].soName.size() == 0 ||
soLoadInfo[i].soPath.size() == 0) {
LOGE("adapter json config string exist invalid members");
continue;
}
soLoadInfo[i].soPath = LIB_LOAD_PATH;
soAdapterLoadInfo_[soLoadInfo[i].soName] = soLoadInfo[i];
LOGI("soAdapterLoadInfo name is: %s", soLoadInfo[i].name.c_str());
LOGI("soAdapterLoadInfo type is: %s", soLoadInfo[i].type.c_str());
LOGI("soAdapterLoadInfo version is: %s", soLoadInfo[i].version.c_str());
LOGI("soAdapterLoadInfo funcName is: %s", soLoadInfo[i].funcName.c_str());
LOGI("soAdapterLoadInfo soName is: %s", soLoadInfo[i].soName.c_str());
LOGI("soAdapterLoadInfo soPath is: %s", soLoadInfo[i].soPath.c_str());
}
} while (0);
do {
nlohmann::json authJsonObject = nlohmann::json::parse(authJsonConfigString, nullptr, false);
if (authJsonObject.is_discarded()) {
LOGE("auth json config string parse error!\n");
break;
}
const char *jsonKey = AUTH_LOAD_JSON_KEY.c_str();
if (!authJsonObject.contains(jsonKey)) {
LOGE("auth json config string key not exist!\n");
break;
}
auto soLoadInfo = authJsonObject[jsonKey].get<std::vector<AuthSoLoadInfo>>();
for (uint32_t i = 0; i < soLoadInfo.size(); i++) {
if (soLoadInfo[i].name.size() == 0 || soLoadInfo[i].type.size() == 0 || soLoadInfo[i].version.size() == 0 ||
soLoadInfo[i].funcName.size() == 0 || soLoadInfo[i].soName.size() == 0 ||
soLoadInfo[i].soPath.size() == 0) {
LOGE("adapter json config string exist invalid members");
continue;
}
soLoadInfo[i].soPath = LIB_LOAD_PATH;
soAuthLoadInfo_[soLoadInfo[i].authType] = soLoadInfo[i];
LOGI("soAuthLoadInfo name is: %s", soLoadInfo[i].name.c_str());
LOGI("soAuthLoadInfo type is: %s", soLoadInfo[i].type.c_str());
LOGI("soAuthLoadInfo version is: %s", soLoadInfo[i].version.c_str());
LOGI("soAuthLoadInfo funcName is: %s", soLoadInfo[i].funcName.c_str());
LOGI("soAuthLoadInfo soName is: %s", soLoadInfo[i].soName.c_str());
LOGI("soAuthLoadInfo soPath is: %s", soLoadInfo[i].soPath.c_str());
LOGI("soAuthLoadInfo authType is: %d", soLoadInfo[i].authType);
}
} while (0);
}
DmConfigManager::~DmConfigManager()
{
void *so_handle = nullptr;
for (auto iter = soAdapterLoadInfo_.begin(); iter != soAdapterLoadInfo_.end(); iter++) {
std::string soPathName = (iter->second).soPath + (iter->second).soName;
so_handle = dlopen(soPathName.c_str(), RTLD_NOW | RTLD_NOLOAD);
if (so_handle != nullptr) {
dlclose(so_handle);
}
}
for (auto iter = soAuthLoadInfo_.begin(); iter != soAuthLoadInfo_.end(); iter++) {
std::string soPathName = (iter->second).soPath + (iter->second).soName;
so_handle = dlopen(soPathName.c_str(), RTLD_NOW | RTLD_NOLOAD);
if (so_handle != nullptr) {
dlclose(so_handle);
}
}
LOGI("DmAdapterManager destructor");
}
std::shared_ptr<IDecisionAdapter> DmConfigManager::GetDecisionAdapter(const std::string &soName)
{
if (soName.empty()) {
LOGE("soName size is zero");
return nullptr;
}
auto soInfoIter = soAdapterLoadInfo_.find(soName);
if (soInfoIter == soAdapterLoadInfo_.end() || (soInfoIter->second).type != DECISION_JSON_TYPE_KEY) {
LOGE("not find so info or type key not match");
return nullptr;
}
std::unique_lock<std::mutex> locker(decisionAdapterMutex_);
auto ptrIter = decisionAdapterPtr_.find(soName);
if (ptrIter != decisionAdapterPtr_.end()) {
return decisionAdapterPtr_[soName];
}
void *so_handle = nullptr;
std::string soPathName = (soInfoIter->second).soPath + (soInfoIter->second).soName;
so_handle = dlopen(soPathName.c_str(), RTLD_NOW | RTLD_NOLOAD);
if (so_handle == nullptr) {
so_handle = dlopen(soPathName.c_str(), RTLD_NOW);
if (so_handle == nullptr) {
LOGE("load decision so %s failed", soName.c_str());
return nullptr;
}
}
dlerror();
auto func = (CreateIDecisionAdapterFuncPtr)dlsym(so_handle, (soInfoIter->second).funcName.c_str());
if (dlerror() != nullptr || func == nullptr) {
LOGE("Create object function is not exist");
return nullptr;
}
std::shared_ptr<IDecisionAdapter> iDecisionAdapter(func());
decisionAdapterPtr_[soName] = iDecisionAdapter;
return decisionAdapterPtr_[soName];
}
std::shared_ptr<IProfileAdapter> DmConfigManager::GetProfileAdapter(const std::string &soName)
{
if (soName.empty()) {
LOGE("soName size is zero");
return nullptr;
}
auto soInfoIter = soAdapterLoadInfo_.find(soName);
if (soInfoIter == soAdapterLoadInfo_.end() || (soInfoIter->second).type != PROFILE_JSON_TYPE_KEY) {
LOGE("not find so info or type key not match");
return nullptr;
}
std::unique_lock<std::mutex> locker(profileAdapterMutex_);
auto ptrIter = profileAdapterPtr_.find(soName);
if (ptrIter != profileAdapterPtr_.end()) {
return profileAdapterPtr_[soName];
}
void *so_handle = nullptr;
std::string soPathName = (soInfoIter->second).soPath + (soInfoIter->second).soName;
so_handle = dlopen(soPathName.c_str(), RTLD_NOW | RTLD_NOLOAD);
if (so_handle == nullptr) {
so_handle = dlopen(soPathName.c_str(), RTLD_NOW);
if (so_handle == nullptr) {
LOGE("load profile so %s failed", soName.c_str());
return nullptr;
}
}
dlerror();
auto func = (CreateIProfileAdapterFuncPtr)dlsym(so_handle, (soInfoIter->second).funcName.c_str());
if (dlerror() != nullptr || func == nullptr) {
LOGE("Create object function is not exist");
return nullptr;
}
std::shared_ptr<IProfileAdapter> iProfileAdapter(func());
profileAdapterPtr_[soName] = iProfileAdapter;
return profileAdapterPtr_[soName];
}
std::shared_ptr<ICryptoAdapter> DmConfigManager::GetCryptoAdapter(const std::string &soName)
{
if (soName.empty()) {
LOGE("soName size is zero");
return nullptr;
}
auto soInfoIter = soAdapterLoadInfo_.find(soName);
if (soInfoIter == soAdapterLoadInfo_.end() || (soInfoIter->second).type != CPYPTO_JSON_TYPE_KEY) {
LOGE("not find so info or type key not match");
return nullptr;
}
std::unique_lock<std::mutex> locker(cryptoAdapterMutex_);
auto ptrIter = cryptoAdapterPtr_.find(soName);
if (ptrIter != cryptoAdapterPtr_.end()) {
return cryptoAdapterPtr_[soName];
}
void *so_handle = nullptr;
std::string soPathName = (soInfoIter->second).soPath + (soInfoIter->second).soName;
so_handle = dlopen(soPathName.c_str(), RTLD_NOW | RTLD_NOLOAD);
if (so_handle == nullptr) {
so_handle = dlopen(soPathName.c_str(), RTLD_NOW);
if (so_handle == nullptr) {
LOGE("load crypto so %s failed", soName.c_str());
return nullptr;
}
}
dlerror();
auto func = (CreateICryptoAdapterFuncPtr)dlsym(so_handle, (soInfoIter->second).funcName.c_str());
if (dlerror() != nullptr || func == nullptr) {
LOGE("Create object function is not exist");
return nullptr;
}
std::shared_ptr<ICryptoAdapter> iCryptoAdapter(func());
cryptoAdapterPtr_[soName] = iCryptoAdapter;
return cryptoAdapterPtr_[soName];
}
void DmConfigManager::GetAuthAdapter(std::map<int32_t, std::shared_ptr<IAuthentication>> &authAdapter)
{
authAdapter.clear();
for (auto iter = soAuthLoadInfo_.begin(); iter != soAuthLoadInfo_.end(); iter++) {
if ((iter->second).type != AUTH_JSON_TYPE_KEY) {
LOGE("type key not match");
continue;
}
void *so_handle = nullptr;
std::string soPathName = (iter->second).soPath + (iter->second).soName;
so_handle = dlopen(soPathName.c_str(), RTLD_NOW | RTLD_NOLOAD);
if (so_handle == nullptr) {
so_handle = dlopen(soPathName.c_str(), RTLD_NOW);
if (so_handle == nullptr) {
LOGE("load auth so %s failed", (iter->second).soName.c_str());
continue;
}
}
dlerror();
auto func = (CreateIAuthAdapterFuncPtr)dlsym(so_handle, (iter->second).funcName.c_str());
if (dlerror() != nullptr || func == nullptr) {
LOGE("Create object function is not exist");
continue;
}
std::shared_ptr<IAuthentication> iAuthentication(func());
authAdapter[iter->first] = iAuthentication;
LOGI("so name: %s, auth type: %d", (iter->second).soName.c_str(), iter->first);
}
}
}
}