• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "ohos.systemCapability.proj.hpp"
16 #include "ohos.systemCapability.impl.hpp"
17 #include "taihe/runtime.hpp"
18 #include "stdexcept"
19 #include <cstdint>
20 #include <cstring>
21 #include <cstdlib>
22 #include <securec.h>
23 #include "syscap_interface.h"
24 #include "context_tool.h"
25 
26 using namespace taihe;
27 
28 namespace {
29 // To be implemented.
30 constexpr size_t OS_SYSCAP_U32_NUM = 30;
31 constexpr size_t PCID_MAIN_U32 = OS_SYSCAP_U32_NUM + 2;
32 constexpr size_t U32_TO_STR_MAX_LEN = 11;
33 constexpr size_t KEY_BUFFER_SIZE = 32;
34 
35 struct SystemCapabilityAsyncContext {
36     char key[KEY_BUFFER_SIZE] = { 0 };
37     size_t keyLen = 0;
38     char *value = nullptr;
39     size_t valueLen = 0;
40     int status = 0;
41 };
42 
CalculateAllStringLength(char osCapArray[PCID_MAIN_U32][U32_TO_STR_MAX_LEN],char (* priCapArray)[SINGLE_SYSCAP_LEN],bool retBool,int priCapArrayCnt)43 static char* CalculateAllStringLength(char osCapArray[PCID_MAIN_U32][U32_TO_STR_MAX_LEN],
44     char (*priCapArray)[SINGLE_SYSCAP_LEN], bool retBool, int priCapArrayCnt)
45 {
46     errno_t err = EOK;
47     char *temp = nullptr;
48     int retError;
49     int sumLen = 0;
50     char *allSyscapBuffer = nullptr;
51 
52     if (!retBool) {
53         PRINT_ERR("get encoded private syscap failed.");
54         return allSyscapBuffer;
55     }
56 
57     for (size_t i = 0; i < PCID_MAIN_U32; i++) {
58         sumLen += strlen(osCapArray[i]);
59     }
60     for (int i = 0; i < priCapArrayCnt; i++) {
61         sumLen += strlen(*(priCapArray + i));
62     }
63     sumLen += (PCID_MAIN_U32 + priCapArrayCnt + 1);  // split with ','
64 
65     // splicing string
66     allSyscapBuffer = (char *)malloc(sumLen);
67     if (allSyscapBuffer == nullptr) {
68         PRINT_ERR("malloc failed!");
69         return allSyscapBuffer;
70     }
71     err = memset_s(allSyscapBuffer, sumLen, 0, sumLen);
72     if (err != EOK) {
73         PRINT_ERR("memset failed!");
74         free(allSyscapBuffer);
75         return nullptr;
76     }
77     temp = *osCapArray;
78 
79     for (size_t i = 1; i < PCID_MAIN_U32; i++) {
80         retError = sprintf_s(allSyscapBuffer, sumLen, "%s,%s", temp, osCapArray[i]);
81         if (retError == -1) {
82             PRINT_ERR("splicing os syscap string failed.");
83             free(allSyscapBuffer);
84             return nullptr;
85         }
86         temp = allSyscapBuffer;
87     }
88     for (int i = 0; i < priCapArrayCnt; i++) {
89         retError = sprintf_s(allSyscapBuffer, sumLen, "%s,%s", temp, *(priCapArray + i));
90         if (retError == -1) {
91             PRINT_ERR("splicing pri syscap string failed.");
92             free(allSyscapBuffer);
93             return nullptr;
94         }
95         temp = allSyscapBuffer;
96     }
97     return allSyscapBuffer;
98 }
99 
GetSystemCapability()100 static char* GetSystemCapability()
101 {
102     bool retBool;
103     int retError;
104     int priOutputLen;
105     int priCapArrayCnt;
106     char osOutput[SINGLE_SYSCAP_LEN] = {};
107 
108     uint32_t *osCapU32 = nullptr;
109     char *priOutput = nullptr;
110 
111     char *allSyscapBuffer = nullptr;
112     char osCapArray[PCID_MAIN_U32][U32_TO_STR_MAX_LEN] = {};
113     char (*priCapArray)[SINGLE_SYSCAP_LEN] = nullptr;
114 
115     retBool = EncodeOsSyscap(osOutput, PCID_MAIN_BYTES);
116     if (!retBool) {
117         PRINT_ERR("get encoded os syscap failed.");
118         return nullptr;
119     }
120     retBool = EncodePrivateSyscap(&priOutput, &priOutputLen);
121     if (!retBool) {
122         PRINT_ERR("get encoded private syscap failed.");
123         goto FREE_PRIOUTPUT;
124     }
125 
126     osCapU32 = reinterpret_cast<uint32_t *>(osOutput);
127     for (size_t i = 0; i < PCID_MAIN_U32; i++) { // 2, header of pcid.sc
128         retError = sprintf_s(osCapArray[i], U32_TO_STR_MAX_LEN, "%u", osCapU32[i]);
129         if (retError == -1) {
130             PRINT_ERR("get uint32_t syscap string failed.");
131             goto FREE_PRIOUTPUT;
132         }
133     }
134     retBool = DecodePrivateSyscap(priOutput, &priCapArray, &priCapArrayCnt);
135     allSyscapBuffer = CalculateAllStringLength(osCapArray, priCapArray, retBool, priCapArrayCnt);
136     free(priCapArray);
137 
138 FREE_PRIOUTPUT:
139     free(priOutput);
140 
141     return allSyscapBuffer;
142 }
143 
querySystemCapabilitie()144 string querySystemCapabilitie()
145 {
146     SystemCapabilityAsyncContext *asyncContext = new SystemCapabilityAsyncContext();
147     char *syscapStr = GetSystemCapability();
148     if (syscapStr != nullptr) {
149         asyncContext->value = syscapStr;
150         asyncContext->status = 0;
151     } else {
152         asyncContext->status = 1;
153     }
154     string value = "";
155     if (!asyncContext->status) {
156         value = asyncContext->value;
157     } else {
158         taihe::set_business_error(-1, "key does not exist");
159     }
160     delete asyncContext;
161     return value;
162 }
163 }  // namespace
164 
165 // Since these macros are auto-generate, lint will cause false positive.
166 // NOLINTBEGIN
167 TH_EXPORT_CPP_API_querySystemCapabilitie(querySystemCapabilitie);
168 // NOLINTEND
169