1 /*
2 * Copyright (c) 2025 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 "bluetooth_config_utils.h"
17
18 #include "bt_protocol_utils.h"
19 #include "directory_ex.h"
20 #include "edm_log.h"
21 #include <unistd.h>
22
23 namespace OHOS {
24 namespace EDM {
25 const std::string CONFIG_PATH = "/data/service/el1/public/edm/config/system/all/bluetooth/config.json";
26 const std::string CONFIG_SYSTEM_ALL_DIR = "/data/service/el1/public/edm/config/system/all";
27 const std::string BLUETOOTH_DIR = "bluetooth";
28 const std::string SEPARATOR = "/";
29 const char* const PROTOCOL_DENY_LIST = "ProtocolDenyList";
30 constexpr int32_t EDM_UID = 3057;
31 constexpr int32_t EDM_GID = 3057;
32
BluetoothConfigUtils()33 BluetoothConfigUtils::BluetoothConfigUtils()
34 {
35 EDMLOGI("BluetoothConfigUtils::BluetoothConfigUtils()");
36 std::vector<std::string> files;
37 OHOS::GetDirFiles(CONFIG_SYSTEM_ALL_DIR, files);
38 if (std::find(files.begin(), files.end(), BLUETOOTH_DIR) == files.end()) {
39 CreateBluetoothConfigDir(CONFIG_SYSTEM_ALL_DIR + SEPARATOR + BLUETOOTH_DIR);
40 }
41 }
42
~BluetoothConfigUtils()43 BluetoothConfigUtils::~BluetoothConfigUtils()
44 {
45 EDMLOGI("BluetoothConfigUtils::~BluetoothConfigUtils()");
46 if (root_) {
47 cJSON_Delete(root_);
48 }
49 }
50
UpdateProtocol(const std::string & userId,const std::string & protocol,bool isAdd)51 bool BluetoothConfigUtils::UpdateProtocol(const std::string &userId, const std::string &protocol, bool isAdd)
52 {
53 EDMLOGI("BluetoothConfigUtils::BluetoothConfigUtils()");
54 if (!root_ && !LoadConfig()) {
55 return false;
56 }
57 CheckProtocolDenyListExists();
58 cJSON* denyList = cJSON_GetObjectItem(root_, PROTOCOL_DENY_LIST);
59 cJSON* userItem = cJSON_GetObjectItem(denyList, userId.c_str());
60 if (isAdd) {
61 if (!userItem) {
62 userItem = cJSON_CreateArray();
63 cJSON_AddItemToArray(userItem, cJSON_CreateString(protocol.c_str()));
64 cJSON_AddItemToObject(denyList, userId.c_str(), userItem);
65 } else {
66 if (IsProtocolExist(protocol, userItem)) {
67 return true;
68 }
69 cJSON_AddItemToArray(userItem, cJSON_CreateString(protocol.c_str()));
70 }
71 } else {
72 if (!userItem) {
73 return true;
74 }
75
76 int indexToRemove = -1;
77 for (int i = 0; i < cJSON_GetArraySize(userItem); ++i) {
78 cJSON* item = cJSON_GetArrayItem(userItem, i);
79 if (strcmp(item->valuestring, protocol.c_str()) == 0) {
80 indexToRemove = i;
81 break;
82 }
83 }
84
85 if (indexToRemove >= 0) {
86 cJSON_DeleteItemFromArray(userItem, indexToRemove);
87 }
88
89 if (cJSON_GetArraySize(userItem) == 0) {
90 cJSON_DeleteItemFromObject(denyList, userId.c_str());
91 }
92 }
93 return SaveConfig();
94 }
95
IsProtocolExist(const std::string & protocol,cJSON * userItem)96 bool BluetoothConfigUtils::IsProtocolExist(const std::string &protocol, cJSON* userItem)
97 {
98 cJSON* protocolItem = nullptr;
99 cJSON_ArrayForEach(protocolItem, userItem) {
100 if (strcmp(protocolItem->valuestring, protocol.c_str()) == 0) {
101 return true;
102 }
103 }
104 return false;
105 }
106
CreateBluetoothConfigDir(const std::string dir)107 bool BluetoothConfigUtils::CreateBluetoothConfigDir(const std::string dir)
108 {
109 EDMLOGI("BluetoothConfigUtils::CreateBluetoothConfigDir");
110 if (!OHOS::ForceCreateDirectory(dir)) {
111 EDMLOGE("mkdir dir failed");
112 return false;
113 }
114 if (chown(dir.c_str(), EDM_UID, EDM_GID) != 0) {
115 EDMLOGE("fail to change dir ownership");
116 return false;
117 }
118 mode_t mode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH;
119 if (!OHOS::ChangeModeFile(dir, mode)) {
120 EDMLOGE("change mode failed, temp install dir");
121 return false;
122 }
123 return true;
124 }
125
QueryProtocols(const std::string & userId,std::vector<int32_t> & protocols)126 bool BluetoothConfigUtils::QueryProtocols(const std::string& userId, std::vector<int32_t> &protocols)
127 {
128 if (!root_ && !LoadConfig()) {
129 return false;
130 }
131 cJSON* denyList = cJSON_GetObjectItem(root_, PROTOCOL_DENY_LIST);
132 if (!denyList) {
133 return true;
134 }
135 cJSON* userItem = cJSON_GetObjectItem(denyList, userId.c_str());
136 if (!userItem) {
137 return true;
138 }
139 cJSON* protocolItem = nullptr;
140 cJSON_ArrayForEach(protocolItem, userItem) {
141 int32_t protocol = 0;
142 BtProtocolUtils::StrToProtocolInt(protocolItem->valuestring, protocol);
143 protocols.push_back(protocol);
144 }
145 return true;
146 }
147
RemoveUserIdItem(const std::string & userId)148 bool BluetoothConfigUtils::RemoveUserIdItem(const std::string &userId)
149 {
150 EDMLOGI("BluetoothConfigUtils::RemoveUserIdItem");
151 if (!root_ && !LoadConfig()) {
152 return false;
153 }
154 cJSON* denyList = cJSON_GetObjectItem(root_, PROTOCOL_DENY_LIST);
155 if (!denyList) {
156 return true;
157 }
158 cJSON_DeleteItemFromObject(denyList, userId.c_str());
159 return SaveConfig();
160 }
161
RemoveProtocolDenyList()162 bool BluetoothConfigUtils::RemoveProtocolDenyList()
163 {
164 EDMLOGI("BluetoothConfigUtils::RemoveProtocolDenyList");
165 if (!root_ && !LoadConfig()) {
166 return false;
167 }
168 cJSON_DeleteItemFromObject(root_, PROTOCOL_DENY_LIST);
169 return SaveConfig();
170 }
171
LoadConfig()172 bool BluetoothConfigUtils::LoadConfig()
173 {
174 EDMLOGI("BluetoothConfigUtils::loadConfig");
175 std::ifstream inFile(CONFIG_PATH, std::ios::binary);
176 if (inFile.good()) {
177 EDMLOGI("BluetoothConfigUtils::loadConfig inFile.good");
178 inFile.seekg(0, std::ios::end);
179 std::streamsize size = inFile.tellg();
180 if (size <= 0) {
181 inFile.close();
182 root_ = cJSON_CreateObject();
183 return true;
184 }
185 inFile.seekg(0, std::ios::beg);
186 std::string jsonStr(size, ' ');
187 inFile.read(&jsonStr[0], size);
188 inFile.close();
189 root_ = cJSON_Parse(jsonStr.c_str());
190 return root_ != nullptr;
191 }
192 EDMLOGI("BluetoothConfigUtils::loadConfig inFile fail");
193 inFile.close();
194 root_ = cJSON_CreateObject();
195 return true;
196 }
197
SaveConfig()198 bool BluetoothConfigUtils::SaveConfig()
199 {
200 EDMLOGI("BluetoothConfigUtils::saveConfig");
201 if (!root_) {
202 return false;
203 }
204 char* jsonStr = cJSON_Print(root_);
205 if (!jsonStr) {
206 return false;
207 }
208 std::ofstream file(CONFIG_PATH);
209 if (!file.is_open()) {
210 cJSON_free(jsonStr);
211 return false;
212 }
213 file << jsonStr;
214 file.close();
215 cJSON_free(jsonStr);
216 return true;
217 }
218
CheckProtocolDenyListExists()219 void BluetoothConfigUtils::CheckProtocolDenyListExists()
220 {
221 if (!root_) {
222 root_ = cJSON_CreateObject();
223 }
224 cJSON* denyList = cJSON_GetObjectItem(root_, PROTOCOL_DENY_LIST);
225 if (!denyList) {
226 cJSON_AddItemToObject(root_, PROTOCOL_DENY_LIST, cJSON_CreateObject());
227 }
228 }
229 } // namespace EDM
230 } // namespace OHOS