1 /******************************************************************************
2 *
3 * Copyright 2016 Google, Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 #include "osi/include/properties.h"
20
21 #include <string.h>
22
23 #include <algorithm>
24 #include <optional>
25 #include <string>
26
27 #include "os/system_properties.h"
28
29 #ifdef __ANDROID__
30 #undef PROPERTY_VALUE_MAX
31 #include <cutils/properties.h>
32 #if BUILD_SANITY_PROPERTY_VALUE_MAX != PROPERTY_VALUE_MAX
33 #error "PROPERTY_VALUE_MAX from osi/include/properties.h != the Android value"
34 #endif // GENERIC_PROPERTY_VALUE_MAX != PROPERTY_VALUE_MAX
35 #endif // __ANDROID__
36
osi_property_get(const char * key,char * value,const char * default_value)37 int osi_property_get(const char* key, char* value, const char* default_value) {
38 std::optional<std::string> result = bluetooth::os::GetSystemProperty(key);
39 if (result) {
40 memcpy(value, result->data(), result->size());
41 value[result->size()] = '\0';
42 return result->size();
43 } else if (default_value) {
44 int len = std::min(strlen(default_value), (size_t)(PROPERTY_VALUE_MAX - 1));
45 memcpy(value, default_value, len);
46 value[len] = '\0';
47 return len;
48 } else {
49 return 0;
50 }
51 }
52
osi_property_set(const char * key,const char * value)53 int osi_property_set(const char* key, const char* value) {
54 bool success = bluetooth::os::SetSystemProperty(key, value);
55 return success ? 0 : -1;
56 }
57
osi_property_get_int32(const char * key,int32_t default_value)58 int32_t osi_property_get_int32(const char* key, int32_t default_value) {
59 std::optional<std::string> result = bluetooth::os::GetSystemProperty(key);
60 if (result) {
61 return stoi(*result, nullptr);
62 } else {
63 return default_value;
64 }
65 }
66
osi_property_get_bool(const char * key,bool default_value)67 bool osi_property_get_bool(const char* key, bool default_value) {
68 std::optional<std::string> result = bluetooth::os::GetSystemProperty(key);
69 if (result) {
70 return *result == std::string("true");
71 } else {
72 return default_value;
73 }
74 }
75
osi_property_get_uintlist(const char * key,const std::vector<uint32_t> default_value)76 std::vector<uint32_t> osi_property_get_uintlist(const char* key,
77 const std::vector<uint32_t> default_value) {
78 std::optional<std::string> result = bluetooth::os::GetSystemProperty(key);
79 if (!result || result->empty() || result->size() > PROPERTY_VALUE_MAX) {
80 return default_value;
81 }
82
83 std::vector<uint32_t> list;
84 for (size_t i = 0; i < result->size(); i++) {
85 // Build a string of all the chars until the next comma or end of the
86 // string is reached. If any char is not a digit, then return the default.
87 std::string value;
88 while ((*result)[i] != ',' && i < result->size()) {
89 char c = (*result)[i];
90 if (!std::isdigit(c)) {
91 return default_value;
92 }
93 value += c;
94 i++;
95 }
96
97 // grab value
98 list.push_back(static_cast<uint32_t>(std::stoul(value)));
99 }
100
101 return list;
102 }
103