• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 #include "oaid_service.h"
16 #include <mutex>
17 #include <openssl/rand.h>
18 #include <singleton.h>
19 #include <string>
20 #include <unistd.h>
21 #include "oaid_common.h"
22 #include "system_ability.h"
23 #include "system_ability_definition.h"
24 #include "oaid_service_stub.h"
25 #include "oaid_service_define.h"
26 
27 using namespace std::chrono;
28 
29 namespace OHOS {
30 namespace Cloud {
31 namespace {
HexToChar(uint8_t hex)32 char HexToChar(uint8_t hex)
33 {
34     static const uint8_t MAX_SINGLE_DIGIT = 9; // 9 is the largest single digit
35     return (hex > MAX_SINGLE_DIGIT) ? (hex + 0x57) : (hex + 0x30);
36 }
37 
38 /**
39  * Get v4 uuid.
40  *
41  * @return std::string, uuid.
42  */
GetUUID()43 std::string GetUUID()
44 {
45     static const int8_t UUID_LENGTH = 16;  // The UUID is 128 bits, that is 16 bytes.
46     static const int8_t VERSION_INDEX = 6; // Obtain the seventh byte of the randomly generated UUID, that is uuid[6].
47     static const int8_t CHAR_LOW_WIDTH = 4; // Lower 4 bits of the char type
48     static const int8_t N_INDEX = 8;       // Reset the ninth byte of the UUID, that is UUID[8].
49     unsigned char uuid[UUID_LENGTH] = {0};
50     int re = RAND_bytes(uuid, sizeof(uuid));
51     if (re == 0) {
52         return "";
53     }
54 
55     /**
56      * xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
57      * M is uuid version: 4
58      * N is 8,9,a,b
59      */
60     uuid[VERSION_INDEX] = (uuid[VERSION_INDEX] & 0x0F) | 0x40;
61     int minN = 0x8;
62     int maxN = 0xb;
63     unsigned char randNumber[1] = {minN};
64     RAND_bytes(randNumber, sizeof(randNumber));
65     unsigned char num = static_cast<unsigned char>(randNumber[0] % (maxN - minN + 1) + minN);
66     uuid[N_INDEX] = (uuid[N_INDEX] & 0x0F) | (num << CHAR_LOW_WIDTH);
67 
68     static const size_t LINE_INDEX_MAX = 10;  // until i=10
69     static const size_t LINE_INDEX_MIN = 4;   // Add a hyphen (-) every two bytes starting from i=4.
70     static const size_t EVEN_FACTOR = 2; // the even factor is assigned to 2, and all even numbers are divisible by 2.
71     std::string formatUuid = "";
72     for (size_t i = 0; i < sizeof(uuid); i++) {
73         unsigned char value = uuid[i];
74         if (i >= LINE_INDEX_MIN && i <= LINE_INDEX_MAX && i % EVEN_FACTOR == 0) {
75             formatUuid += "-";
76         }
77         formatUuid += HexToChar(value >> CHAR_LOW_WIDTH);
78         unsigned char highValue = value & 0xF0;
79         if (highValue == 0) {
80             formatUuid += HexToChar(value);
81         } else {
82             formatUuid += HexToChar(value % (value & highValue));
83         }
84     }
85     return formatUuid;
86 }
87 }  // namespace
88 
89 REGISTER_SYSTEM_ABILITY_BY_ID(OAIDService, OAID_SYSTME_ID, true);
90 std::mutex OAIDService::mutex_;
91 sptr<OAIDService> OAIDService::instance_;
92 
OAIDService(int32_t systemAbilityId,bool runOnCreate)93 OAIDService::OAIDService(int32_t systemAbilityId, bool runOnCreate)
94     : SystemAbility(systemAbilityId, runOnCreate), state_(ServiceRunningState::STATE_NOT_START)
95 {
96     OAID_HILOGI(OAID_MODULE_SERVICE, "Start.");
97 }
98 
OAIDService()99 OAIDService::OAIDService() : state_(ServiceRunningState::STATE_NOT_START)
100 {}
101 
~OAIDService()102 OAIDService::~OAIDService() {};
103 
GetInstance()104 sptr<OAIDService> OAIDService::GetInstance()
105 {
106     if (instance_ == nullptr) {
107         std::lock_guard<std::mutex> autoLock(mutex_);
108         if (instance_ == nullptr) {
109             OAID_HILOGI(OAID_MODULE_SERVICE, "Instance success.");
110             instance_ = new OAIDService;
111         }
112     }
113     return instance_;
114 }
115 
OnStart()116 void OAIDService::OnStart()
117 {
118     if (state_ == ServiceRunningState::STATE_RUNNING) {
119         OAID_HILOGE(OAID_MODULE_SERVICE, " OAIDService is already running.");
120         return;
121     }
122 
123     if (Init() != ERR_OK) {
124         OAID_HILOGE(OAID_MODULE_SERVICE, "Init failed, Try again 10s later.");
125         return;
126     }
127     AddSystemAbilityListener(OAID_SYSTME_ID);
128 
129     OAID_HILOGI(OAID_MODULE_SERVICE, "Start OAID service success.");
130     return;
131 }
132 
Init()133 int32_t OAIDService::Init()
134 {
135     bool ret = Publish(OAIDService::GetInstance());
136     if (!ret) {
137         OAID_HILOGE(OAID_MODULE_SERVICE, "OAID service init failed.");
138         return ERR_SYSYTEM_ERROR;
139     }
140 
141     OAID_HILOGI(OAID_MODULE_SERVICE, "OAID service init Success.");
142     state_ = ServiceRunningState::STATE_RUNNING;
143     return ERR_OK;
144 }
145 
OnStop()146 void OAIDService::OnStop()
147 {
148     if (state_ != ServiceRunningState::STATE_RUNNING) {
149         return;
150     }
151 
152     state_ = ServiceRunningState::STATE_NOT_START;
153     OAID_HILOGI(OAID_MODULE_SERVICE, "Stop success.");
154 }
155 
InitOaidKvStore()156 bool OAIDService::InitOaidKvStore()
157 {
158     DistributedKv::DistributedKvDataManager manager;
159     DistributedKv::Options options;
160 
161     DistributedKv::AppId appId;
162     appId.appId = OAID_DATA_BASE_APP_ID;
163 
164     options.createIfMissing = true;
165     options.encrypt = true;
166     options.autoSync = false;
167     options.kvStoreType = DistributedKv::KvStoreType::SINGLE_VERSION;
168     options.area = DistributedKv::EL1;
169     options.baseDir = OAID_DATA_BASE_DIR + appId.appId;
170 
171     DistributedKv::StoreId storeId;
172     storeId.storeId = OAID_DATA_BASE_STORE_ID;
173     DistributedKv::Status status = DistributedKv::Status::SUCCESS;
174 
175     if (oaidKvStore_ == nullptr) {
176         uint32_t retries = 0;
177         do {
178             OAID_HILOGI(OAID_MODULE_SERVICE, "InitOaidKvStore: retries=%{public}u!", retries);
179             status = manager.GetSingleKvStore(options, appId, storeId, oaidKvStore_);
180             if (status == DistributedKv::Status::STORE_NOT_FOUND) {
181                 OAID_HILOGE(OAID_MODULE_SERVICE, "InitOaidKvStore: STORE_NOT_FOUND!");
182             }
183 
184             if ((status == DistributedKv::Status::SUCCESS) || (status == DistributedKv::Status::STORE_NOT_FOUND)) {
185                 break;
186             } else {
187                 OAID_HILOGE(OAID_MODULE_SERVICE, "Kvstore Connect failed! Retrying.");
188                 retries++;
189                 usleep(KVSTORE_CONNECT_RETRY_DELAY_TIME);
190             }
191         } while (retries <= KVSTORE_CONNECT_RETRY_COUNT);
192     }
193 
194     if (oaidKvStore_ == nullptr) {
195         if (status == DistributedKv::Status::STORE_NOT_FOUND) {
196             OAID_HILOGI(OAID_MODULE_SERVICE, "First Boot: Create OaidKvStore");
197             options.createIfMissing = true;
198             // [create and] open and initialize kvstore instance.
199             status = manager.GetSingleKvStore(options, appId, storeId, oaidKvStore_);
200             if (status == DistributedKv::Status::SUCCESS) {
201                 OAID_HILOGE(OAID_MODULE_SERVICE, "Create OaidKvStore success!");
202             } else {
203                 OAID_HILOGE(OAID_MODULE_SERVICE, "Create OaidKvStore Failed!");
204             }
205         }
206     }
207 
208     if (oaidKvStore_ == nullptr) {
209         OAID_HILOGE(OAID_MODULE_SERVICE, "InitOaidKvStore: Failed!");
210         return false;
211     }
212 
213     return true;
214 }
215 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)216 void OAIDService::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
217 {
218     OAID_HILOGI(OAID_MODULE_SERVICE, "OnAddSystemAbility OAIDService");
219     bool result = false;
220     switch (systemAbilityId) {
221         case OAID_SYSTME_ID:
222             OAID_HILOGI(OAID_MODULE_SERVICE, "OnAddSystemAbility kv data service start");
223             result = InitOaidKvStore();
224             OAID_HILOGI(OAID_MODULE_SERVICE, "OnAddSystemAbility InitOaidKvStore is %{public}d", result);
225             break;
226         default:
227             OAID_HILOGI(OAID_MODULE_SERVICE, "OnAddSystemAbility unhandled sysabilityId:%{public}d", systemAbilityId);
228             break;
229     }
230 }
231 
CheckKvStore()232 bool OAIDService::CheckKvStore()
233 {
234     if (oaidKvStore_ != nullptr) {
235         return true;
236     }
237 
238     bool result = InitOaidKvStore();
239     OAID_HILOGI(OAID_MODULE_SERVICE, "InitOaidKvStore: %{public}s", result == true ? "success" : "failed");
240     return result;
241 }
242 
ReadValueFromKvStore(const std::string & kvStoreKey,std::string & kvStoreValue)243 bool OAIDService::ReadValueFromKvStore(const std::string &kvStoreKey, std::string &kvStoreValue)
244 {
245     std::lock_guard<std::mutex> lock(mutex_);
246 
247     if (!CheckKvStore()) {
248         OAID_HILOGE(OAID_MODULE_SERVICE, "ReadValueFromKvStore:oaidKvStore_ is nullptr");
249         return false;
250     }
251 
252     DistributedKv::Key key(kvStoreKey);
253     DistributedKv::Value value;
254     DistributedKv::Status status = oaidKvStore_->Get(key, value);
255     if (status == DistributedKv::Status::SUCCESS) {
256         OAID_HILOGI(OAID_MODULE_SERVICE, "%{public}d get value from kvStore", status);
257     } else {
258         OAID_HILOGE(OAID_MODULE_SERVICE, "%{public}d get value from kvStore failed", status);
259         return false;
260     }
261     kvStoreValue = value.ToString();
262 
263     return true;
264 }
265 
WriteValueToKvStore(const std::string & kvStoreKey,const std::string & kvStoreValue)266 bool OAIDService::WriteValueToKvStore(const std::string &kvStoreKey, const std::string &kvStoreValue)
267 {
268     std::lock_guard<std::mutex> lock(mutex_);
269 
270     if (!CheckKvStore()) {
271         OAID_HILOGE(OAID_MODULE_SERVICE, "WriteValueToKvStore:oaidKvStore_ is nullptr");
272         return false;
273     }
274 
275     DistributedKv::Key key(kvStoreKey);
276     DistributedKv::Value value(kvStoreValue);
277     DistributedKv::Status status = oaidKvStore_->Put(key, value);
278     if (status == DistributedKv::Status::SUCCESS) {
279         OAID_HILOGI(OAID_MODULE_SERVICE, "%{public}d updated to kvStore", status);
280     } else {
281         OAID_HILOGE(OAID_MODULE_SERVICE, "%{public}d update to kvStore failed", status);
282         return false;
283     }
284 
285     return true;
286 }
287 
GainOAID()288 std::string OAIDService::GainOAID()
289 {
290     OAID_HILOGI(OAID_MODULE_SERVICE, "Gain OAID Begin.");
291     std::string oaid;
292     std::string oaidKvStoreStr = OAID_ALLZERO_STR;
293 
294     bool result = ReadValueFromKvStore(OAID_KVSTORE_KEY, oaidKvStoreStr);
295     OAID_HILOGI(OAID_MODULE_SERVICE, "ReadValueFromKvStore %{public}s", result == true ? "success" : "failed");
296 
297     if (oaidKvStoreStr != OAID_ALLZERO_STR && oaidKvStoreStr != "") {
298         if (!oaid_.empty() || oaid_ != "") {
299             oaid = oaid_;
300             OAID_HILOGI(OAID_MODULE_SERVICE, "get oaid from kvdb successfully");
301         } else {
302             oaid = oaidKvStoreStr;
303             oaid_ = oaidKvStoreStr;
304             OAID_HILOGW(OAID_MODULE_SERVICE, "The Oaid in the memory is empty,it get oaid from kvdb successfully");
305         }
306         return oaid;
307     } else {
308         if (oaid_.empty() || oaid_ == "") {
309             oaid_ = GetUUID();
310             OAID_HILOGI(OAID_MODULE_SERVICE, "The oaid has been regenerated.");
311         }
312     }
313 
314     oaid = oaid_;
315 
316     result = WriteValueToKvStore(OAID_KVSTORE_KEY, oaid);
317     OAID_HILOGI(OAID_MODULE_SERVICE, "WriteValueToKvStore %{public}s", result == true ? "success" : "failed");
318     OAID_HILOGI(OAID_MODULE_SERVICE, "Gain OAID Finish.");
319     return oaid;
320 }
321 
GetOAID()322 std::string OAIDService::GetOAID()
323 {
324     OAID_HILOGI(OAID_MODULE_SERVICE, "Begin.");
325 
326     std::string oaid = GainOAID();
327 
328     OAID_HILOGI(OAID_MODULE_SERVICE, "End.");
329     return oaid;
330 }
331 
ResetOAID()332 void OAIDService::ResetOAID()
333 {
334     OAID_HILOGI(OAID_MODULE_SERVICE, "ResetOAID.");
335     std::string resetOaid = GetUUID();
336     oaid_ = resetOaid;
337     bool result = WriteValueToKvStore(OAID_KVSTORE_KEY, resetOaid);
338     OAID_HILOGI(OAID_MODULE_SERVICE, "ResetOAID WriteValueToKvStore %{public}s", result == true ? "success" : "failed");
339 }
340 }  // namespace Cloud
341 }  // namespace OHOS
342