1bae44755Sopenharmony_ci/*
2bae44755Sopenharmony_ci * Copyright (C) 2022-2022 Huawei Device Co., Ltd.
3bae44755Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4bae44755Sopenharmony_ci * you may not use this file except in compliance with the License.
5bae44755Sopenharmony_ci * You may obtain a copy of the License at
6bae44755Sopenharmony_ci *
7bae44755Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
8bae44755Sopenharmony_ci *
9bae44755Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10bae44755Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11bae44755Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12bae44755Sopenharmony_ci * See the License for the specific language governing permissions and
13bae44755Sopenharmony_ci * limitations under the License.
14bae44755Sopenharmony_ci */
15bae44755Sopenharmony_ci
16bae44755Sopenharmony_ci#include <errno.h>
17bae44755Sopenharmony_ci#include <stdbool.h>
18bae44755Sopenharmony_ci#include <stdlib.h>
19bae44755Sopenharmony_ci#include <stdio.h>
20bae44755Sopenharmony_ci#include <string.h>
21bae44755Sopenharmony_ci#include <sys/stat.h>
22bae44755Sopenharmony_ci#include <securec.h>
23bae44755Sopenharmony_ci#include <limits.h>
24bae44755Sopenharmony_ci#include "cJSON.h"
25bae44755Sopenharmony_ci#include "syscap_tool.h"
26bae44755Sopenharmony_ci#include "endian_internal.h"
27bae44755Sopenharmony_ci#include "syscap_interface.h"
28bae44755Sopenharmony_ci#include "context_tool.h"
29bae44755Sopenharmony_ci#include "common_method.h"
30bae44755Sopenharmony_ci
31bae44755Sopenharmony_ci#ifdef SYSCAP_DEFINE_EXTERN_ENABLE
32bae44755Sopenharmony_ci#include "syscap_define_custom.h"
33bae44755Sopenharmony_ci#else
34bae44755Sopenharmony_ci#include "syscap_define.h"
35bae44755Sopenharmony_ci#endif
36bae44755Sopenharmony_ci
37bae44755Sopenharmony_ci#define OS_SYSCAP_BYTES 120
38bae44755Sopenharmony_ci#define SYSCAP_PREFIX_LEN 17
39bae44755Sopenharmony_ci#define SINGLE_FEAT_LEN (SINGLE_SYSCAP_LEN - SYSCAP_PREFIX_LEN)
40bae44755Sopenharmony_ci#define RPCID_OUT_BUFFER 32
41bae44755Sopenharmony_ci#define PCID_OUT_BUFFER RPCID_OUT_BUFFER
42bae44755Sopenharmony_ci#define UINT8_BIT 8
43bae44755Sopenharmony_ci#define INT_BIT 32
44bae44755Sopenharmony_ci#define U32_TO_STR_MAX_LEN 11
45bae44755Sopenharmony_ci
46bae44755Sopenharmony_ci#define FREE_MALLOC_PRISYSCAP_AFTER_DECODE_RPCID 1
47bae44755Sopenharmony_ci#define FREE_MALLOC_OSSYSCAP_AFTER_DECODE_RPCID 2
48bae44755Sopenharmony_ci#define FREE_WHOLE_SYSCAP_AFTER_DECODE_RPCID 3
49bae44755Sopenharmony_ci#define FREE_RPCID_ROOT_AFTER_DECODE_RPCID 4
50bae44755Sopenharmony_ci#define FREE_CONTEXT_OUT_AFTER_DECODE_RPCID 5
51bae44755Sopenharmony_ci
52bae44755Sopenharmony_citypedef struct ProductCompatibilityID {
53bae44755Sopenharmony_ci    uint16_t apiVersion : 15;
54bae44755Sopenharmony_ci    uint16_t apiVersionType : 1;
55bae44755Sopenharmony_ci    uint16_t systemType : 3;
56bae44755Sopenharmony_ci    uint16_t reserved : 13;
57bae44755Sopenharmony_ci    uint32_t manufacturerID;
58bae44755Sopenharmony_ci    uint8_t osSyscap[OS_SYSCAP_BYTES];
59bae44755Sopenharmony_ci} PCIDMain;
60bae44755Sopenharmony_ci
61bae44755Sopenharmony_cistatic const char *PCID_PATH = "/system/etc/pcid.sc";
62bae44755Sopenharmony_ci
63bae44755Sopenharmony_cistruct FreeAfterDecodeRpcidInfo {
64bae44755Sopenharmony_ci    char *priSyscap;
65bae44755Sopenharmony_ci    char *contextBuffer;
66bae44755Sopenharmony_ci    cJSON *sysCapDefine;
67bae44755Sopenharmony_ci    cJSON *rpcidRoot;
68bae44755Sopenharmony_ci    uint16_t *osSysCapIndex;
69bae44755Sopenharmony_ci    int32_t sysCapArraySize;
70bae44755Sopenharmony_ci};
71bae44755Sopenharmony_ci
72bae44755Sopenharmony_cistruct PcidPriSyscapInfo {
73bae44755Sopenharmony_ci    uint32_t rpcidPriSyscapLen;
74bae44755Sopenharmony_ci    uint32_t pcidPriSyscapLen;
75bae44755Sopenharmony_ci    char *rpcidPriSyscap;
76bae44755Sopenharmony_ci    char *pcidPriSyscap;
77bae44755Sopenharmony_ci    uint16_t ossyscapFlag;
78bae44755Sopenharmony_ci    int32_t ret;
79bae44755Sopenharmony_ci};
80bae44755Sopenharmony_ci
81bae44755Sopenharmony_cibool EncodeOsSyscap(char *output, int len)
82bae44755Sopenharmony_ci{
83bae44755Sopenharmony_ci    int32_t ret;
84bae44755Sopenharmony_ci    int32_t res;
85bae44755Sopenharmony_ci    char *contextBuffer = NULL;
86bae44755Sopenharmony_ci    uint32_t bufferLen;
87bae44755Sopenharmony_ci
88bae44755Sopenharmony_ci    if (len != PCID_MAIN_BYTES) {
89bae44755Sopenharmony_ci        PRINT_ERR("Os Syscap input len(%d) must be equal to 128.\n", len);
90bae44755Sopenharmony_ci        return false;
91bae44755Sopenharmony_ci    }
92bae44755Sopenharmony_ci
93bae44755Sopenharmony_ci    ret = GetFileContext(PCID_PATH, &contextBuffer, &bufferLen);
94bae44755Sopenharmony_ci    if (ret != 0) {
95bae44755Sopenharmony_ci        PRINT_ERR("GetFileContext failed, input file : /system/etc/pcid.sc\n");
96bae44755Sopenharmony_ci        return false;
97bae44755Sopenharmony_ci    }
98bae44755Sopenharmony_ci
99bae44755Sopenharmony_ci    res = memcpy_s(output, PCID_MAIN_BYTES, contextBuffer, PCID_MAIN_BYTES);
100bae44755Sopenharmony_ci    if (res != 0) {
101bae44755Sopenharmony_ci        PRINT_ERR("memcpy_s failed.");
102bae44755Sopenharmony_ci        FreeContextBuffer(contextBuffer);
103bae44755Sopenharmony_ci        return false;
104bae44755Sopenharmony_ci    }
105bae44755Sopenharmony_ci
106bae44755Sopenharmony_ci    FreeContextBuffer(contextBuffer);
107bae44755Sopenharmony_ci    return true;
108bae44755Sopenharmony_ci}
109bae44755Sopenharmony_ci
110bae44755Sopenharmony_cibool EncodePrivateSyscap(char **output, int *outputLen)
111bae44755Sopenharmony_ci{
112bae44755Sopenharmony_ci    int32_t ret;
113bae44755Sopenharmony_ci    char *contextBuffer = NULL;
114bae44755Sopenharmony_ci    char *outputStr = NULL;
115bae44755Sopenharmony_ci    uint32_t bufferLen;
116bae44755Sopenharmony_ci
117bae44755Sopenharmony_ci    ret = GetFileContext(PCID_PATH, &contextBuffer, &bufferLen);
118bae44755Sopenharmony_ci    if (ret != 0) {
119bae44755Sopenharmony_ci        PRINT_ERR("GetFileContext failed, input file : /system/etc/pcid.sc\n");
120bae44755Sopenharmony_ci        return false;
121bae44755Sopenharmony_ci    }
122bae44755Sopenharmony_ci
123bae44755Sopenharmony_ci    if (bufferLen < (PCID_MAIN_BYTES + 1) || bufferLen > INT32_MAX) {
124bae44755Sopenharmony_ci        PRINT_ERR("Parameter bufferLen out of range.");
125bae44755Sopenharmony_ci        FreeContextBuffer(contextBuffer);
126bae44755Sopenharmony_ci        return false;
127bae44755Sopenharmony_ci    }
128bae44755Sopenharmony_ci    uint32_t priLen = bufferLen - PCID_MAIN_BYTES - 1;
129bae44755Sopenharmony_ci    if ((int)priLen <= 0) {
130bae44755Sopenharmony_ci        *outputLen = 0;
131bae44755Sopenharmony_ci        FreeContextBuffer(contextBuffer);
132bae44755Sopenharmony_ci        return false;
133bae44755Sopenharmony_ci    }
134bae44755Sopenharmony_ci    outputStr = (char *)calloc(priLen, sizeof(char));
135bae44755Sopenharmony_ci    if (outputStr == NULL) {
136bae44755Sopenharmony_ci        PRINT_ERR("malloc buffer failed, size = %u, errno = %d\n", priLen, errno);
137bae44755Sopenharmony_ci        *outputLen = 0;
138bae44755Sopenharmony_ci        FreeContextBuffer(contextBuffer);
139bae44755Sopenharmony_ci        return false;
140bae44755Sopenharmony_ci    }
141bae44755Sopenharmony_ci
142bae44755Sopenharmony_ci    ret = strncpy_s(outputStr, priLen, contextBuffer + PCID_MAIN_BYTES, priLen - 1);
143bae44755Sopenharmony_ci    if (ret != 0) {
144bae44755Sopenharmony_ci        PRINT_ERR("strcpy_s failed.");
145bae44755Sopenharmony_ci        FreeContextBuffer(contextBuffer);
146bae44755Sopenharmony_ci        free(outputStr);
147bae44755Sopenharmony_ci        *outputLen = 0;
148bae44755Sopenharmony_ci        return false;
149bae44755Sopenharmony_ci    }
150bae44755Sopenharmony_ci
151bae44755Sopenharmony_ci    FreeContextBuffer(contextBuffer);
152bae44755Sopenharmony_ci    *outputLen = (int)strlen(outputStr);
153bae44755Sopenharmony_ci    *output = outputStr;
154bae44755Sopenharmony_ci    return true;
155bae44755Sopenharmony_ci}
156bae44755Sopenharmony_ci
157bae44755Sopenharmony_cibool DecodeOsSyscap(const char input[PCID_MAIN_BYTES], char (**output)[SINGLE_SYSCAP_LEN], int *outputCnt)
158bae44755Sopenharmony_ci{
159bae44755Sopenharmony_ci    errno_t nRet = 0;
160bae44755Sopenharmony_ci    uint16_t indexOfSyscap[CHAR_BIT * OS_SYSCAP_BYTES] = {0};
161bae44755Sopenharmony_ci    uint16_t countOfSyscap = 0;
162bae44755Sopenharmony_ci    uint16_t i, j;
163bae44755Sopenharmony_ci
164bae44755Sopenharmony_ci    uint8_t *osSyscap = (uint8_t *)(input + 8); // 8, int[2] of pcid header
165bae44755Sopenharmony_ci
166bae44755Sopenharmony_ci    for (i = 0; i < OS_SYSCAP_BYTES; i++) {
167bae44755Sopenharmony_ci        for (j = 0; j < CHAR_BIT; j++) {
168bae44755Sopenharmony_ci            if (osSyscap[i] & (0x01 << j)) {
169bae44755Sopenharmony_ci                indexOfSyscap[countOfSyscap++] = i * CHAR_BIT + j;
170bae44755Sopenharmony_ci            }
171bae44755Sopenharmony_ci        }
172bae44755Sopenharmony_ci    }
173bae44755Sopenharmony_ci
174bae44755Sopenharmony_ci    *outputCnt = countOfSyscap;
175bae44755Sopenharmony_ci    char (*strSyscap)[SINGLE_SYSCAP_LEN] = NULL;
176bae44755Sopenharmony_ci    strSyscap = (char (*)[SINGLE_SYSCAP_LEN])malloc(countOfSyscap * SINGLE_SYSCAP_LEN);
177bae44755Sopenharmony_ci    if (strSyscap == NULL) {
178bae44755Sopenharmony_ci        PRINT_ERR("malloc failed.");
179bae44755Sopenharmony_ci        *outputCnt = 0;
180bae44755Sopenharmony_ci        return false;
181bae44755Sopenharmony_ci    }
182bae44755Sopenharmony_ci    (void)memset_s(strSyscap, countOfSyscap * SINGLE_SYSCAP_LEN, 0, countOfSyscap * SINGLE_SYSCAP_LEN);
183bae44755Sopenharmony_ci    *output = strSyscap;
184bae44755Sopenharmony_ci
185bae44755Sopenharmony_ci    for (i = 0; i < countOfSyscap; i++) {
186bae44755Sopenharmony_ci        for (j = 0; j < sizeof(g_arraySyscap) / sizeof(SyscapWithNum); j++) {
187bae44755Sopenharmony_ci            if (g_arraySyscap[j].num != indexOfSyscap[i]) {
188bae44755Sopenharmony_ci                continue;
189bae44755Sopenharmony_ci            }
190bae44755Sopenharmony_ci            nRet = strcpy_s(*strSyscap, SINGLE_SYSCAP_LEN, g_arraySyscap[j].str);
191bae44755Sopenharmony_ci            if (nRet != EOK) {
192bae44755Sopenharmony_ci                printf("strcpy_s failed. error = %d\n", nRet);
193bae44755Sopenharmony_ci                *outputCnt = 0;
194bae44755Sopenharmony_ci                free(strSyscap);
195bae44755Sopenharmony_ci                strSyscap = NULL;
196bae44755Sopenharmony_ci                return false;
197bae44755Sopenharmony_ci            }
198bae44755Sopenharmony_ci            strSyscap++;
199bae44755Sopenharmony_ci            break;
200bae44755Sopenharmony_ci        }
201bae44755Sopenharmony_ci    }
202bae44755Sopenharmony_ci
203bae44755Sopenharmony_ci    return true;
204bae44755Sopenharmony_ci}
205bae44755Sopenharmony_ci
206bae44755Sopenharmony_ciint32_t GetPriSyscapCount(char *input)
207bae44755Sopenharmony_ci{
208bae44755Sopenharmony_ci    int32_t syscapCnt = 0;
209bae44755Sopenharmony_ci
210bae44755Sopenharmony_ci    char *inputPos = input;
211bae44755Sopenharmony_ci    while (*inputPos != '\0') {
212bae44755Sopenharmony_ci        if (*inputPos == ',') {
213bae44755Sopenharmony_ci            syscapCnt++;
214bae44755Sopenharmony_ci        }
215bae44755Sopenharmony_ci        inputPos++;
216bae44755Sopenharmony_ci    }
217bae44755Sopenharmony_ci
218bae44755Sopenharmony_ci    return syscapCnt;
219bae44755Sopenharmony_ci}
220bae44755Sopenharmony_ci
221bae44755Sopenharmony_cibool DecodePrivateSyscap(char *input, char (**output)[SINGLE_SYSCAP_LEN], int *outputCnt)
222bae44755Sopenharmony_ci{
223bae44755Sopenharmony_ci    char *inputPos = input;
224bae44755Sopenharmony_ci    char (*outputArray)[SINGLE_SYSCAP_LEN] = NULL;
225bae44755Sopenharmony_ci
226bae44755Sopenharmony_ci    if (input == NULL) {
227bae44755Sopenharmony_ci        return false;
228bae44755Sopenharmony_ci    }
229bae44755Sopenharmony_ci
230bae44755Sopenharmony_ci    int syscapCnt = GetPriSyscapCount(inputPos);
231bae44755Sopenharmony_ci    *outputCnt = syscapCnt;
232bae44755Sopenharmony_ci    if (syscapCnt == 0) {
233bae44755Sopenharmony_ci        return true;
234bae44755Sopenharmony_ci    }
235bae44755Sopenharmony_ci
236bae44755Sopenharmony_ci    int bufferLen = SINGLE_SYSCAP_LEN * syscapCnt;
237bae44755Sopenharmony_ci    outputArray = (char (*)[SINGLE_SYSCAP_LEN])malloc(bufferLen);
238bae44755Sopenharmony_ci    if (outputArray == NULL) {
239bae44755Sopenharmony_ci        return false;
240bae44755Sopenharmony_ci    }
241bae44755Sopenharmony_ci    (void)memset_s(outputArray, bufferLen, 0, bufferLen);
242bae44755Sopenharmony_ci
243bae44755Sopenharmony_ci    *output = outputArray;
244bae44755Sopenharmony_ci    inputPos = input;
245bae44755Sopenharmony_ci    char buffer[SINGLE_FEAT_LEN] = {0};
246bae44755Sopenharmony_ci    char *bufferPos = buffer;
247bae44755Sopenharmony_ci    while (*inputPos != '\0') {
248bae44755Sopenharmony_ci        if (*inputPos == ',') {
249bae44755Sopenharmony_ci            *bufferPos = '\0';
250bae44755Sopenharmony_ci            if (sprintf_s(*outputArray, SINGLE_SYSCAP_LEN, "SystemCapability.%s", buffer) == -1) {
251bae44755Sopenharmony_ci                free(outputArray);
252bae44755Sopenharmony_ci                outputArray = NULL;
253bae44755Sopenharmony_ci                return false;
254bae44755Sopenharmony_ci            }
255bae44755Sopenharmony_ci            bufferPos = buffer;
256bae44755Sopenharmony_ci            outputArray++;
257bae44755Sopenharmony_ci            inputPos++;
258bae44755Sopenharmony_ci            continue;
259bae44755Sopenharmony_ci        }
260bae44755Sopenharmony_ci        *bufferPos++ = *inputPos++;
261bae44755Sopenharmony_ci    }
262bae44755Sopenharmony_ci
263bae44755Sopenharmony_ci    return true;
264bae44755Sopenharmony_ci}
265bae44755Sopenharmony_ci
266bae44755Sopenharmony_cistatic int SetOsSysCapBitMap(uint8_t *out, uint16_t outLen, const uint16_t *index, uint16_t indexLen)
267bae44755Sopenharmony_ci{
268bae44755Sopenharmony_ci    uint16_t sector, pos;
269bae44755Sopenharmony_ci
270bae44755Sopenharmony_ci    if (outLen != OS_SYSCAP_BYTES) {
271bae44755Sopenharmony_ci        PRINT_ERR("Input array error.\n");
272bae44755Sopenharmony_ci        return -1;
273bae44755Sopenharmony_ci    }
274bae44755Sopenharmony_ci
275bae44755Sopenharmony_ci    for (uint16_t i = 0; i < indexLen; i++) {
276bae44755Sopenharmony_ci        sector = index[i] / UINT8_BIT;
277bae44755Sopenharmony_ci        pos = index[i] % UINT8_BIT;
278bae44755Sopenharmony_ci        if (sector >= OS_SYSCAP_BYTES) {
279bae44755Sopenharmony_ci            PRINT_ERR("Syscap num(%u) out of range(120).\n", sector);
280bae44755Sopenharmony_ci            return -1;
281bae44755Sopenharmony_ci        }
282bae44755Sopenharmony_ci        out[sector] |= (1 << pos);
283bae44755Sopenharmony_ci    }
284bae44755Sopenharmony_ci    return 0;
285bae44755Sopenharmony_ci}
286bae44755Sopenharmony_ci
287bae44755Sopenharmony_cistatic int32_t ParseRpcidToJson(char *input, uint32_t inputLen, cJSON *rpcidJson)
288bae44755Sopenharmony_ci{
289bae44755Sopenharmony_ci    uint32_t i;
290bae44755Sopenharmony_ci    int32_t ret = 0;
291bae44755Sopenharmony_ci    uint16_t sysCapLength = NtohsInter(*(uint16_t *)(input + sizeof(uint32_t)));
292bae44755Sopenharmony_ci    uint16_t sysCapCount = sysCapLength / SINGLE_FEAT_LEN;
293bae44755Sopenharmony_ci    char *sysCapBegin = input + sizeof(RPCIDHead) + sizeof(uint32_t);
294bae44755Sopenharmony_ci    RPCIDHead *rpcidHeader = (RPCIDHead *)input;
295bae44755Sopenharmony_ci    cJSON *sysCapJson = cJSON_CreateArray();
296bae44755Sopenharmony_ci    if (sysCapJson == NULL) {
297bae44755Sopenharmony_ci        PRINT_ERR("Get sysCapJson failed, sysCapJson is empty.\n");
298bae44755Sopenharmony_ci        ret = -1;
299bae44755Sopenharmony_ci    }
300bae44755Sopenharmony_ci    for (i = 0; i < sysCapCount; i++) {
301bae44755Sopenharmony_ci        char *temp = sysCapBegin + i * SINGLE_FEAT_LEN;
302bae44755Sopenharmony_ci        if (strlen(temp) >= SINGLE_FEAT_LEN) {
303bae44755Sopenharmony_ci            PRINT_ERR("Get SysCap failed, string length too long.\n");
304bae44755Sopenharmony_ci            ret = -1;
305bae44755Sopenharmony_ci            goto FREE_SYSCAP_OUT;
306bae44755Sopenharmony_ci        }
307bae44755Sopenharmony_ci        char buffer[SINGLE_SYSCAP_LEN] = "SystemCapability.";
308bae44755Sopenharmony_ci
309bae44755Sopenharmony_ci        ret = strncat_s(buffer, sizeof(buffer), temp, SINGLE_FEAT_LEN);
310bae44755Sopenharmony_ci        if (ret != EOK) {
311bae44755Sopenharmony_ci            PRINT_ERR("strncat_s failed.\n");
312bae44755Sopenharmony_ci            goto FREE_SYSCAP_OUT;
313bae44755Sopenharmony_ci        }
314bae44755Sopenharmony_ci
315bae44755Sopenharmony_ci        if (!cJSON_AddItemToArray(sysCapJson, cJSON_CreateString(buffer))) {
316bae44755Sopenharmony_ci            PRINT_ERR("Add syscap string to json failed.\n");
317bae44755Sopenharmony_ci            ret = -1;
318bae44755Sopenharmony_ci            goto FREE_SYSCAP_OUT;
319bae44755Sopenharmony_ci        }
320bae44755Sopenharmony_ci    }
321bae44755Sopenharmony_ci
322bae44755Sopenharmony_ci    if (!cJSON_AddNumberToObject(rpcidJson, "api_version", NtohsInter(rpcidHeader->apiVersion))) {
323bae44755Sopenharmony_ci        PRINT_ERR("Add api_version to json failed.\n");
324bae44755Sopenharmony_ci        ret = -1;
325bae44755Sopenharmony_ci        goto FREE_SYSCAP_OUT;
326bae44755Sopenharmony_ci    }
327bae44755Sopenharmony_ci    if (!cJSON_AddItemToObject(rpcidJson, "syscap", sysCapJson)) {
328bae44755Sopenharmony_ci        PRINT_ERR("Add syscap to json failed.\n");
329bae44755Sopenharmony_ci        ret = -1;
330bae44755Sopenharmony_ci        goto FREE_SYSCAP_OUT;
331bae44755Sopenharmony_ci    }
332bae44755Sopenharmony_ciFREE_SYSCAP_OUT:
333bae44755Sopenharmony_ci    cJSON_Delete(sysCapJson);
334bae44755Sopenharmony_ci    return ret;
335bae44755Sopenharmony_ci}
336bae44755Sopenharmony_ci
337bae44755Sopenharmony_cistatic int32_t TransStringFormatAndSaveSyscap(struct FreeAfterDecodeRpcidInfo freeAfterDecodeRpcidInfo,
338bae44755Sopenharmony_ci    cJSON *sysCapArray, const char *inputFile)
339bae44755Sopenharmony_ci{
340bae44755Sopenharmony_ci    // trans to string format
341bae44755Sopenharmony_ci    sysCapArray = cJSON_GetObjectItem(freeAfterDecodeRpcidInfo.rpcidRoot, "syscap");
342bae44755Sopenharmony_ci    if (sysCapArray == NULL || !cJSON_IsArray(sysCapArray)) {
343bae44755Sopenharmony_ci        PRINT_ERR("Get syscap failed. Input file: %s\n", inputFile);
344bae44755Sopenharmony_ci        return -1;
345bae44755Sopenharmony_ci    }
346bae44755Sopenharmony_ci    freeAfterDecodeRpcidInfo.sysCapArraySize = cJSON_GetArraySize(sysCapArray);
347bae44755Sopenharmony_ci    if (freeAfterDecodeRpcidInfo.sysCapArraySize < 0) {
348bae44755Sopenharmony_ci        PRINT_ERR("Get syscap size failed. Input file: %s\n", inputFile);
349bae44755Sopenharmony_ci        return -1;
350bae44755Sopenharmony_ci    }
351bae44755Sopenharmony_ci    // malloc for save os syscap index
352bae44755Sopenharmony_ci    freeAfterDecodeRpcidInfo.osSysCapIndex = (uint16_t *)malloc(sizeof(uint16_t)
353bae44755Sopenharmony_ci        * freeAfterDecodeRpcidInfo.sysCapArraySize);
354bae44755Sopenharmony_ci    if (freeAfterDecodeRpcidInfo.osSysCapIndex == NULL) {
355bae44755Sopenharmony_ci        PRINT_ERR("malloc failed.\n");
356bae44755Sopenharmony_ci        return -1;
357bae44755Sopenharmony_ci    }
358bae44755Sopenharmony_ci    free(freeAfterDecodeRpcidInfo.osSysCapIndex);
359bae44755Sopenharmony_ci    return 0;
360bae44755Sopenharmony_ci}
361bae44755Sopenharmony_ci
362bae44755Sopenharmony_cistatic void PrintResultToOutBuffer(struct FreeAfterDecodeRpcidInfo freeAfterDecodeRpcidInfo, char *outBuffer,
363bae44755Sopenharmony_ci    char *priSyscapArray, uint16_t indexOs, uint16_t indexPri)
364bae44755Sopenharmony_ci{
365bae44755Sopenharmony_ci    int32_t ret = 0;
366bae44755Sopenharmony_ci    uint32_t i;
367bae44755Sopenharmony_ci    uint32_t outUint[RPCID_OUT_BUFFER] = {0};
368bae44755Sopenharmony_ci    outUint[0] = *(uint32_t *)freeAfterDecodeRpcidInfo.contextBuffer;
369bae44755Sopenharmony_ci    outUint[1] = *(uint32_t *)(freeAfterDecodeRpcidInfo.contextBuffer + sizeof(uint32_t));
370bae44755Sopenharmony_ci    uint8_t *osOutUint = (uint8_t *)(outUint + 2);
371bae44755Sopenharmony_ci    if (SetOsSysCapBitMap(osOutUint, 120, freeAfterDecodeRpcidInfo.osSysCapIndex, indexOs)) {  // 120, len of osOutUint
372bae44755Sopenharmony_ci        PRINT_ERR("Set os syscap bit map failed.\n");
373bae44755Sopenharmony_ci        return;
374bae44755Sopenharmony_ci    }
375bae44755Sopenharmony_ci
376bae44755Sopenharmony_ci    uint16_t outBufferLen = U32_TO_STR_MAX_LEN * RPCID_OUT_BUFFER + SINGLE_SYSCAP_LEN * indexPri;
377bae44755Sopenharmony_ci    outBuffer = (char *)malloc(outBufferLen);
378bae44755Sopenharmony_ci    if (outBuffer == NULL) {
379bae44755Sopenharmony_ci        PRINT_ERR("malloc(%u) failed.\n", outBufferLen);
380bae44755Sopenharmony_ci        return;
381bae44755Sopenharmony_ci    }
382bae44755Sopenharmony_ci    (void)memset_s(outBuffer, outBufferLen, 0, outBufferLen);
383bae44755Sopenharmony_ci
384bae44755Sopenharmony_ci    ret = sprintf_s(outBuffer, outBufferLen, "%u", outUint[0]);
385bae44755Sopenharmony_ci    if (ret == -1) {
386bae44755Sopenharmony_ci        PRINT_ERR("sprintf_s failed.\n");
387bae44755Sopenharmony_ci        free(outBuffer);
388bae44755Sopenharmony_ci        return;
389bae44755Sopenharmony_ci    }
390bae44755Sopenharmony_ci    for (i = 1; i < RPCID_OUT_BUFFER; i++) {
391bae44755Sopenharmony_ci        ret = sprintf_s(outBuffer, outBufferLen, "%s,%u", outBuffer, outUint[i]);
392bae44755Sopenharmony_ci        if (ret == -1) {
393bae44755Sopenharmony_ci            PRINT_ERR("sprintf_s failed.\n");
394bae44755Sopenharmony_ci            free(outBuffer);
395bae44755Sopenharmony_ci            return;
396bae44755Sopenharmony_ci        }
397bae44755Sopenharmony_ci    }
398bae44755Sopenharmony_ci
399bae44755Sopenharmony_ci    for (i = 0; i < indexPri; i++) {
400bae44755Sopenharmony_ci        ret = sprintf_s(outBuffer, outBufferLen, "%s,%s", outBuffer, priSyscapArray + i * SINGLE_SYSCAP_LEN);
401bae44755Sopenharmony_ci        if (ret == -1) {
402bae44755Sopenharmony_ci            PRINT_ERR("sprintf_s failed.\n");
403bae44755Sopenharmony_ci            free(outBuffer);
404bae44755Sopenharmony_ci            return;
405bae44755Sopenharmony_ci        }
406bae44755Sopenharmony_ci    }
407bae44755Sopenharmony_ci}
408bae44755Sopenharmony_ci
409bae44755Sopenharmony_cistatic void PartSysCapAndOutBuffer(struct FreeAfterDecodeRpcidInfo freeAfterDecodeRpcidInfo, char *outBuffer,
410bae44755Sopenharmony_ci    char *priSyscapArray, cJSON *sysCapArray)
411bae44755Sopenharmony_ci{
412bae44755Sopenharmony_ci    uint32_t i;
413bae44755Sopenharmony_ci    int32_t ret = 0;
414bae44755Sopenharmony_ci    uint16_t indexOs = 0;
415bae44755Sopenharmony_ci    uint16_t indexPri = 0;
416bae44755Sopenharmony_ci    cJSON *cJsonTemp = NULL;
417bae44755Sopenharmony_ci
418bae44755Sopenharmony_ci    freeAfterDecodeRpcidInfo.sysCapDefine = CreateWholeSyscapJsonObj();
419bae44755Sopenharmony_ci    (void)memset_s(priSyscapArray, freeAfterDecodeRpcidInfo.sysCapArraySize * SINGLE_SYSCAP_LEN,
420bae44755Sopenharmony_ci                   0, freeAfterDecodeRpcidInfo.sysCapArraySize * SINGLE_SYSCAP_LEN);
421bae44755Sopenharmony_ci    freeAfterDecodeRpcidInfo.priSyscap = priSyscapArray;
422bae44755Sopenharmony_ci    // part os syscap and ptivate syscap
423bae44755Sopenharmony_ci    for (i = 0; i < (uint32_t)freeAfterDecodeRpcidInfo.sysCapArraySize; i++) {
424bae44755Sopenharmony_ci        cJSON *cJsonItem = cJSON_GetArrayItem(sysCapArray, i);
425bae44755Sopenharmony_ci        if (cJsonItem->valuestring == NULL) {
426bae44755Sopenharmony_ci            cJSON_Delete(cJsonItem);
427bae44755Sopenharmony_ci            return;
428bae44755Sopenharmony_ci        }
429bae44755Sopenharmony_ci
430bae44755Sopenharmony_ci        cJsonTemp = cJSON_GetObjectItem(freeAfterDecodeRpcidInfo.sysCapDefine, cJsonItem->valuestring);
431bae44755Sopenharmony_ci        if (cJsonTemp != NULL && cJSON_IsNumber(cJsonTemp)) {
432bae44755Sopenharmony_ci            freeAfterDecodeRpcidInfo.osSysCapIndex[indexOs++] = (uint16_t)(cJsonTemp->valueint);
433bae44755Sopenharmony_ci        } else {
434bae44755Sopenharmony_ci            ret = strcpy_s(freeAfterDecodeRpcidInfo.priSyscap, SINGLE_SYSCAP_LEN, cJsonItem->valuestring);
435bae44755Sopenharmony_ci            if (ret != EOK) {
436bae44755Sopenharmony_ci                PRINT_ERR("strcpy_s failed.\n");
437bae44755Sopenharmony_ci                return;
438bae44755Sopenharmony_ci            }
439bae44755Sopenharmony_ci            priSyscapArray += SINGLE_SYSCAP_LEN;
440bae44755Sopenharmony_ci            indexPri++;
441bae44755Sopenharmony_ci        }
442bae44755Sopenharmony_ci    }
443bae44755Sopenharmony_ci    PrintResultToOutBuffer(freeAfterDecodeRpcidInfo, outBuffer, priSyscapArray, indexOs, indexPri);
444bae44755Sopenharmony_ci}
445bae44755Sopenharmony_ci
446bae44755Sopenharmony_cistatic char *FreeAfterDecodeRpcidToString(struct FreeAfterDecodeRpcidInfo freeAfterDecodeRpcidInfo, int32_t type,
447bae44755Sopenharmony_ci    char *outBuffer)
448bae44755Sopenharmony_ci{
449bae44755Sopenharmony_ci    switch (type) {
450bae44755Sopenharmony_ci        case FREE_MALLOC_PRISYSCAP_AFTER_DECODE_RPCID:
451bae44755Sopenharmony_ci            SafeFree(freeAfterDecodeRpcidInfo.priSyscap);
452bae44755Sopenharmony_ci            free(freeAfterDecodeRpcidInfo.osSysCapIndex);
453bae44755Sopenharmony_ci            cJSON_Delete(freeAfterDecodeRpcidInfo.sysCapDefine);
454bae44755Sopenharmony_ci            cJSON_Delete(freeAfterDecodeRpcidInfo.rpcidRoot);
455bae44755Sopenharmony_ci            FreeContextBuffer(freeAfterDecodeRpcidInfo.contextBuffer);
456bae44755Sopenharmony_ci            break;
457bae44755Sopenharmony_ci        case FREE_MALLOC_OSSYSCAP_AFTER_DECODE_RPCID:
458bae44755Sopenharmony_ci            free(freeAfterDecodeRpcidInfo.osSysCapIndex);
459bae44755Sopenharmony_ci            cJSON_Delete(freeAfterDecodeRpcidInfo.sysCapDefine);
460bae44755Sopenharmony_ci            cJSON_Delete(freeAfterDecodeRpcidInfo.rpcidRoot);
461bae44755Sopenharmony_ci            FreeContextBuffer(freeAfterDecodeRpcidInfo.contextBuffer);
462bae44755Sopenharmony_ci            break;
463bae44755Sopenharmony_ci        case FREE_WHOLE_SYSCAP_AFTER_DECODE_RPCID:
464bae44755Sopenharmony_ci            cJSON_Delete(freeAfterDecodeRpcidInfo.sysCapDefine);
465bae44755Sopenharmony_ci            cJSON_Delete(freeAfterDecodeRpcidInfo.rpcidRoot);
466bae44755Sopenharmony_ci            FreeContextBuffer(freeAfterDecodeRpcidInfo.contextBuffer);
467bae44755Sopenharmony_ci            break;
468bae44755Sopenharmony_ci        case FREE_RPCID_ROOT_AFTER_DECODE_RPCID:
469bae44755Sopenharmony_ci            cJSON_Delete(freeAfterDecodeRpcidInfo.rpcidRoot);
470bae44755Sopenharmony_ci            FreeContextBuffer(freeAfterDecodeRpcidInfo.contextBuffer);
471bae44755Sopenharmony_ci            break;
472bae44755Sopenharmony_ci        case FREE_CONTEXT_OUT_AFTER_DECODE_RPCID:
473bae44755Sopenharmony_ci        default:
474bae44755Sopenharmony_ci            FreeContextBuffer(freeAfterDecodeRpcidInfo.contextBuffer);
475bae44755Sopenharmony_ci    }
476bae44755Sopenharmony_ci    return outBuffer;
477bae44755Sopenharmony_ci}
478bae44755Sopenharmony_ci
479bae44755Sopenharmony_cichar *DecodeRpcidToStringFormat(const char *inputFile)
480bae44755Sopenharmony_ci{
481bae44755Sopenharmony_ci    int32_t ret = 0;
482bae44755Sopenharmony_ci    uint32_t bufferLen;
483bae44755Sopenharmony_ci    char *priSyscapArray = NULL;
484bae44755Sopenharmony_ci    char *outBuffer = NULL;
485bae44755Sopenharmony_ci    cJSON *sysCapArray = NULL;
486bae44755Sopenharmony_ci
487bae44755Sopenharmony_ci    struct FreeAfterDecodeRpcidInfo freeAfterDecodeRpcidInfo;
488bae44755Sopenharmony_ci    freeAfterDecodeRpcidInfo.priSyscap = NULL;
489bae44755Sopenharmony_ci    freeAfterDecodeRpcidInfo.osSysCapIndex = 0;
490bae44755Sopenharmony_ci    freeAfterDecodeRpcidInfo.sysCapDefine = NULL;
491bae44755Sopenharmony_ci    freeAfterDecodeRpcidInfo.rpcidRoot = NULL;
492bae44755Sopenharmony_ci    freeAfterDecodeRpcidInfo.contextBuffer = NULL;
493bae44755Sopenharmony_ci    freeAfterDecodeRpcidInfo.sysCapArraySize = 0;
494bae44755Sopenharmony_ci
495bae44755Sopenharmony_ci    // check rpcid.sc
496bae44755Sopenharmony_ci    if (CheckRpcidFormat(inputFile, &freeAfterDecodeRpcidInfo.contextBuffer, &bufferLen)) {
497bae44755Sopenharmony_ci        PRINT_ERR("Check rpcid.sc format failed. Input file: %s\n", inputFile);
498bae44755Sopenharmony_ci        return FreeAfterDecodeRpcidToString(freeAfterDecodeRpcidInfo, FREE_CONTEXT_OUT_AFTER_DECODE_RPCID, outBuffer);
499bae44755Sopenharmony_ci    }
500bae44755Sopenharmony_ci
501bae44755Sopenharmony_ci    // parse rpcid to json
502bae44755Sopenharmony_ci    freeAfterDecodeRpcidInfo.rpcidRoot = cJSON_CreateObject();
503bae44755Sopenharmony_ci    if (freeAfterDecodeRpcidInfo.rpcidRoot == NULL) {
504bae44755Sopenharmony_ci        PRINT_ERR("Failed to create cJSON object for rpcidRoot\n");
505bae44755Sopenharmony_ci        return FreeAfterDecodeRpcidToString(freeAfterDecodeRpcidInfo, FREE_CONTEXT_OUT_AFTER_DECODE_RPCID, outBuffer);
506bae44755Sopenharmony_ci    }
507bae44755Sopenharmony_ci
508bae44755Sopenharmony_ci    if (ParseRpcidToJson(freeAfterDecodeRpcidInfo.contextBuffer, bufferLen, freeAfterDecodeRpcidInfo.rpcidRoot)) {
509bae44755Sopenharmony_ci        PRINT_ERR("Prase rpcid to json failed. Input file: %s\n", inputFile);
510bae44755Sopenharmony_ci        return FreeAfterDecodeRpcidToString(freeAfterDecodeRpcidInfo, FREE_RPCID_ROOT_AFTER_DECODE_RPCID, outBuffer);
511bae44755Sopenharmony_ci    }
512bae44755Sopenharmony_ci    ret = TransStringFormatAndSaveSyscap(freeAfterDecodeRpcidInfo, sysCapArray, inputFile);
513bae44755Sopenharmony_ci    if (ret == -1) {
514bae44755Sopenharmony_ci        return FreeAfterDecodeRpcidToString(freeAfterDecodeRpcidInfo, FREE_WHOLE_SYSCAP_AFTER_DECODE_RPCID, outBuffer);
515bae44755Sopenharmony_ci    }
516bae44755Sopenharmony_ci
517bae44755Sopenharmony_ci    (void)memset_s(freeAfterDecodeRpcidInfo.osSysCapIndex, sizeof(uint16_t) * freeAfterDecodeRpcidInfo
518bae44755Sopenharmony_ci            .sysCapArraySize, 0, sizeof(uint16_t) * freeAfterDecodeRpcidInfo.sysCapArraySize);
519bae44755Sopenharmony_ci    // malloc for save private syscap string
520bae44755Sopenharmony_ci    priSyscapArray = (char *)malloc(freeAfterDecodeRpcidInfo.sysCapArraySize * SINGLE_SYSCAP_LEN);
521bae44755Sopenharmony_ci    if (priSyscapArray == NULL) {
522bae44755Sopenharmony_ci        PRINT_ERR("malloc(%u) failed.\n", (uint32_t)freeAfterDecodeRpcidInfo.sysCapArraySize * SINGLE_SYSCAP_LEN);
523bae44755Sopenharmony_ci        return FreeAfterDecodeRpcidToString(freeAfterDecodeRpcidInfo, FREE_MALLOC_OSSYSCAP_AFTER_DECODE_RPCID,
524bae44755Sopenharmony_ci                outBuffer);
525bae44755Sopenharmony_ci    }
526bae44755Sopenharmony_ci
527bae44755Sopenharmony_ci    PartSysCapAndOutBuffer(freeAfterDecodeRpcidInfo, outBuffer, priSyscapArray, sysCapArray);
528bae44755Sopenharmony_ci    return FreeAfterDecodeRpcidToString(freeAfterDecodeRpcidInfo, FREE_MALLOC_PRISYSCAP_AFTER_DECODE_RPCID, outBuffer);
529bae44755Sopenharmony_ci}
530bae44755Sopenharmony_ci
531bae44755Sopenharmony_cistatic int32_t CopySyscopToRet(struct PcidPriSyscapInfo *pcidPriSyscapInfo, const size_t allSyscapNum,
532bae44755Sopenharmony_ci    char *tempSyscap, uint32_t i, uint8_t k)
533bae44755Sopenharmony_ci{
534bae44755Sopenharmony_ci    uint32_t pos = (i - 2) * INT_BIT + k;
535bae44755Sopenharmony_ci    uint32_t t;
536bae44755Sopenharmony_ci    for (t = 0; t < allSyscapNum; t++) {
537bae44755Sopenharmony_ci        if (g_arraySyscap[t].num == pos) {
538bae44755Sopenharmony_ci            break;
539bae44755Sopenharmony_ci        }
540bae44755Sopenharmony_ci    }
541bae44755Sopenharmony_ci    if (t == allSyscapNum) {
542bae44755Sopenharmony_ci        return -1;
543bae44755Sopenharmony_ci    }
544bae44755Sopenharmony_ci    pcidPriSyscapInfo->ret = strcpy_s(tempSyscap, sizeof(char) * SINGLE_SYSCAP_LEN, g_arraySyscap[t].str);
545bae44755Sopenharmony_ci    // 2, header of pcid & rpcid
546bae44755Sopenharmony_ci    if (pcidPriSyscapInfo->ret != EOK) {
547bae44755Sopenharmony_ci        return -1;
548bae44755Sopenharmony_ci    }
549bae44755Sopenharmony_ci    return 0;
550bae44755Sopenharmony_ci}
551bae44755Sopenharmony_ci
552bae44755Sopenharmony_cistatic int32_t CheckPcidEachBit(struct PcidPriSyscapInfo *pcidPriSyscapInfo, CompareError *result,
553bae44755Sopenharmony_ci    const size_t allSyscapNum, uint32_t i, uint32_t blockBits)
554bae44755Sopenharmony_ci{
555bae44755Sopenharmony_ci    int32_t ret = 0;
556bae44755Sopenharmony_ci    for (uint8_t k = 0; k < INT_BIT; k++) {
557bae44755Sopenharmony_ci        if (blockBits & (1U << k)) {
558bae44755Sopenharmony_ci            char *tempSyscap = (char *)malloc(sizeof(char) * SINGLE_SYSCAP_LEN);
559bae44755Sopenharmony_ci            if (tempSyscap == NULL) {
560bae44755Sopenharmony_ci                PRINT_ERR("malloc failed.\n");
561bae44755Sopenharmony_ci                FreeCompareError(result);
562bae44755Sopenharmony_ci                return -1;
563bae44755Sopenharmony_ci            }
564bae44755Sopenharmony_ci            ret = CopySyscopToRet(pcidPriSyscapInfo, allSyscapNum, tempSyscap, i, k);
565bae44755Sopenharmony_ci            if (ret != EOK) {
566bae44755Sopenharmony_ci                PRINT_ERR("strcpy_s failed.\n");
567bae44755Sopenharmony_ci                FreeCompareError(result);
568bae44755Sopenharmony_ci                free(tempSyscap);
569bae44755Sopenharmony_ci                return -1;
570bae44755Sopenharmony_ci            }
571bae44755Sopenharmony_ci            result->syscap[pcidPriSyscapInfo->ossyscapFlag++] = tempSyscap;
572bae44755Sopenharmony_ci        }
573bae44755Sopenharmony_ci    }
574bae44755Sopenharmony_ci    return ret;
575bae44755Sopenharmony_ci}
576bae44755Sopenharmony_ci
577bae44755Sopenharmony_cistatic int32_t ComparePcidWithOsSyscap(struct PcidPriSyscapInfo *pcidPriSyscapInfo,
578bae44755Sopenharmony_ci    const uint32_t *pcidOsAarry, const uint32_t *rpcidOsAarry, CompareError *result,
579bae44755Sopenharmony_ci    const size_t allSyscapNum)
580bae44755Sopenharmony_ci{
581bae44755Sopenharmony_ci    uint32_t i;
582bae44755Sopenharmony_ci    int32_t ret = 0;
583bae44755Sopenharmony_ci
584bae44755Sopenharmony_ci    for (i = 2; i < PCID_OUT_BUFFER; i++) { // 2, header of pcid & rpcid
585bae44755Sopenharmony_ci        uint32_t blockBits = (pcidOsAarry[i] ^ rpcidOsAarry[i]) & rpcidOsAarry[i];
586bae44755Sopenharmony_ci        if (!blockBits) {
587bae44755Sopenharmony_ci            continue;
588bae44755Sopenharmony_ci        }
589bae44755Sopenharmony_ci        ret = CheckPcidEachBit(pcidPriSyscapInfo, result, allSyscapNum, i, blockBits);
590bae44755Sopenharmony_ci        if (ret == -1) {
591bae44755Sopenharmony_ci            return -1;
592bae44755Sopenharmony_ci        }
593bae44755Sopenharmony_ci    }
594bae44755Sopenharmony_ci    return 0;
595bae44755Sopenharmony_ci}
596bae44755Sopenharmony_ci
597bae44755Sopenharmony_cistatic int32_t ComparePcidWithPriSyscap(struct PcidPriSyscapInfo pcidPriSyscapInfo, CompareError *result,
598bae44755Sopenharmony_ci    uint16_t versionFlag)
599bae44755Sopenharmony_ci{
600bae44755Sopenharmony_ci    uint32_t i, j;
601bae44755Sopenharmony_ci    uint16_t prisyscapFlag = 0;
602bae44755Sopenharmony_ci    uint32_t retFlag = 0;
603bae44755Sopenharmony_ci    bool priSysFound = false;
604bae44755Sopenharmony_ci
605bae44755Sopenharmony_ci    for (i = 0; i < pcidPriSyscapInfo.rpcidPriSyscapLen; i++) {
606bae44755Sopenharmony_ci        for (j = 0; j < pcidPriSyscapInfo.pcidPriSyscapLen; j++) {
607bae44755Sopenharmony_ci            if (strcmp(pcidPriSyscapInfo.rpcidPriSyscap + SINGLE_SYSCAP_LEN * i,
608bae44755Sopenharmony_ci                       pcidPriSyscapInfo.pcidPriSyscap + SINGLE_SYSCAP_LEN * j) == 0) {
609bae44755Sopenharmony_ci                priSysFound = true;
610bae44755Sopenharmony_ci                break;
611bae44755Sopenharmony_ci            }
612bae44755Sopenharmony_ci        }
613bae44755Sopenharmony_ci        if (priSysFound != true) {
614bae44755Sopenharmony_ci            char *temp = (char *)malloc(sizeof(char) * SINGLE_SYSCAP_LEN);
615bae44755Sopenharmony_ci            if (temp == NULL) {
616bae44755Sopenharmony_ci                PRINT_ERR("malloc failed.\n");
617bae44755Sopenharmony_ci                FreeCompareError(result);
618bae44755Sopenharmony_ci                return -1;
619bae44755Sopenharmony_ci            }
620bae44755Sopenharmony_ci            pcidPriSyscapInfo.ret = strcpy_s(temp, sizeof(char) * SINGLE_SYSCAP_LEN,
621bae44755Sopenharmony_ci                pcidPriSyscapInfo.rpcidPriSyscap + SINGLE_SYSCAP_LEN * i);
622bae44755Sopenharmony_ci            if (pcidPriSyscapInfo.ret != EOK) {
623bae44755Sopenharmony_ci                FreeCompareError(result);
624bae44755Sopenharmony_ci                PRINT_ERR("strcpy_s failed.\n");
625bae44755Sopenharmony_ci                free(temp);
626bae44755Sopenharmony_ci                return -1;
627bae44755Sopenharmony_ci            }
628bae44755Sopenharmony_ci            if (pcidPriSyscapInfo.ossyscapFlag + prisyscapFlag >= MAX_MISS_SYSCAP) {
629bae44755Sopenharmony_ci                FreeCompareError(result);
630bae44755Sopenharmony_ci                PRINT_ERR("array index out of bounds.\n");
631bae44755Sopenharmony_ci                free(temp);
632bae44755Sopenharmony_ci                return -1;
633bae44755Sopenharmony_ci            }
634bae44755Sopenharmony_ci            result->syscap[pcidPriSyscapInfo.ossyscapFlag + prisyscapFlag] = temp;
635bae44755Sopenharmony_ci            ++prisyscapFlag;
636bae44755Sopenharmony_ci        }
637bae44755Sopenharmony_ci        priSysFound = false;
638bae44755Sopenharmony_ci    }
639bae44755Sopenharmony_ci
640bae44755Sopenharmony_ci    if (versionFlag > 0) {
641bae44755Sopenharmony_ci        retFlag |= 1U << 0;
642bae44755Sopenharmony_ci    }
643bae44755Sopenharmony_ci    if (pcidPriSyscapInfo.ossyscapFlag > 0 || prisyscapFlag > 0) {
644bae44755Sopenharmony_ci        retFlag |= 1U << 1;
645bae44755Sopenharmony_ci        result->missSyscapNum = pcidPriSyscapInfo.ossyscapFlag + prisyscapFlag;
646bae44755Sopenharmony_ci    }
647bae44755Sopenharmony_ci    return (int32_t)retFlag;
648bae44755Sopenharmony_ci}
649bae44755Sopenharmony_ci
650bae44755Sopenharmony_ciint32_t ComparePcidString(const char *pcidString, const char *rpcidString, CompareError *result)
651bae44755Sopenharmony_ci{
652bae44755Sopenharmony_ci    uint16_t versionFlag = 0;
653bae44755Sopenharmony_ci    int32_t errorFlag = 0;
654bae44755Sopenharmony_ci    struct PcidPriSyscapInfo pcidPriSyscapInfo;
655bae44755Sopenharmony_ci    pcidPriSyscapInfo.pcidPriSyscap = NULL;
656bae44755Sopenharmony_ci    pcidPriSyscapInfo.rpcidPriSyscap = NULL;
657bae44755Sopenharmony_ci    pcidPriSyscapInfo.pcidPriSyscapLen = 0;
658bae44755Sopenharmony_ci    pcidPriSyscapInfo.rpcidPriSyscapLen = 0;
659bae44755Sopenharmony_ci    pcidPriSyscapInfo.ossyscapFlag = 0;
660bae44755Sopenharmony_ci    pcidPriSyscapInfo.ret = 0;
661bae44755Sopenharmony_ci    uint32_t pcidOsAarry[PCID_OUT_BUFFER] = {0};
662bae44755Sopenharmony_ci    uint32_t rpcidOsAarry[PCID_OUT_BUFFER] = {0};
663bae44755Sopenharmony_ci    const size_t allSyscapNum = sizeof(g_arraySyscap) / sizeof(SyscapWithNum);
664bae44755Sopenharmony_ci
665bae44755Sopenharmony_ci    pcidPriSyscapInfo.ret = SeparateSyscapFromString(pcidString, pcidOsAarry, PCID_OUT_BUFFER,
666bae44755Sopenharmony_ci        &pcidPriSyscapInfo.pcidPriSyscap, &pcidPriSyscapInfo.pcidPriSyscapLen);
667bae44755Sopenharmony_ci    pcidPriSyscapInfo.ret += SeparateSyscapFromString(rpcidString, rpcidOsAarry, RPCID_OUT_BUFFER,
668bae44755Sopenharmony_ci        &pcidPriSyscapInfo.rpcidPriSyscap, &pcidPriSyscapInfo.rpcidPriSyscapLen);
669bae44755Sopenharmony_ci    if (pcidPriSyscapInfo.ret != 0) {
670bae44755Sopenharmony_ci        PRINT_ERR("Separate syscap from string failed. ret = %d\n", pcidPriSyscapInfo.ret);
671bae44755Sopenharmony_ci        return -1;
672bae44755Sopenharmony_ci    }
673bae44755Sopenharmony_ci    result->missSyscapNum = 0;
674bae44755Sopenharmony_ci    // compare version
675bae44755Sopenharmony_ci    uint16_t pcidVersion = NtohsInter(((PCIDMain *)pcidOsAarry)->apiVersion);
676bae44755Sopenharmony_ci    uint16_t rpcidVersion = NtohsInter(((RPCIDHead *)rpcidOsAarry)->apiVersion);
677bae44755Sopenharmony_ci    if (pcidVersion < rpcidVersion) {
678bae44755Sopenharmony_ci        result->targetApiVersion = rpcidVersion;
679bae44755Sopenharmony_ci        versionFlag = 1;
680bae44755Sopenharmony_ci    }
681bae44755Sopenharmony_ci
682bae44755Sopenharmony_ci    // compare os sysscap
683bae44755Sopenharmony_ci    errorFlag = ComparePcidWithOsSyscap(&pcidPriSyscapInfo, pcidOsAarry, rpcidOsAarry, result, allSyscapNum);
684bae44755Sopenharmony_ci    if (errorFlag == -1) {
685bae44755Sopenharmony_ci        return errorFlag;
686bae44755Sopenharmony_ci    }
687bae44755Sopenharmony_ci
688bae44755Sopenharmony_ci    // compare pri syscap
689bae44755Sopenharmony_ci    return ComparePcidWithPriSyscap(pcidPriSyscapInfo, result, versionFlag);
690bae44755Sopenharmony_ci}
691bae44755Sopenharmony_ci
692bae44755Sopenharmony_ciint32_t FreeCompareError(CompareError *result)
693bae44755Sopenharmony_ci{
694bae44755Sopenharmony_ci    if (result == NULL) {
695bae44755Sopenharmony_ci        return 0;
696bae44755Sopenharmony_ci    }
697bae44755Sopenharmony_ci    for (int i = 0; i < result->missSyscapNum; i++) {
698bae44755Sopenharmony_ci        free(result->syscap[i]);
699bae44755Sopenharmony_ci        result->syscap[i] = NULL;
700bae44755Sopenharmony_ci    }
701bae44755Sopenharmony_ci    result->missSyscapNum = 0;
702bae44755Sopenharmony_ci    result->targetApiVersion = 0;
703bae44755Sopenharmony_ci    return 0;
704bae44755Sopenharmony_ci}