1bae44755Sopenharmony_ci/* 2bae44755Sopenharmony_ci * Copyright (c) 2021-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 <stdio.h> 17bae44755Sopenharmony_ci#include <stdint.h> 18bae44755Sopenharmony_ci#include <stdlib.h> 19bae44755Sopenharmony_ci#include <errno.h> 20bae44755Sopenharmony_ci#include <string.h> 21bae44755Sopenharmony_ci#include <limits.h> 22bae44755Sopenharmony_ci#include <sys/stat.h> 23bae44755Sopenharmony_ci#include "securec.h" 24bae44755Sopenharmony_ci#include "cJSON.h" 25bae44755Sopenharmony_ci#include "endian_internal.h" 26bae44755Sopenharmony_ci#include "create_pcid.h" 27bae44755Sopenharmony_ci#include "context_tool.h" 28bae44755Sopenharmony_ci#include "common_method.h" 29bae44755Sopenharmony_ci 30bae44755Sopenharmony_ci#ifdef SYSCAP_DEFINE_EXTERN_ENABLE 31bae44755Sopenharmony_ci#include "syscap_define_custom.h" 32bae44755Sopenharmony_ci#else 33bae44755Sopenharmony_ci#include "syscap_define.h" 34bae44755Sopenharmony_ci#endif 35bae44755Sopenharmony_ci 36bae44755Sopenharmony_ci#define SYSCAP_PREFIX_LEN 17 37bae44755Sopenharmony_ci#define SINGLE_FEAT_LEN (SINGLE_SYSCAP_LEN - SYSCAP_PREFIX_LEN) 38bae44755Sopenharmony_ci#define PCID_OUT_BUFFER 32 39bae44755Sopenharmony_ci#define PRIVATE_SYSCAP_SIZE 1000 40bae44755Sopenharmony_ci#define UINT8_BIT 8 41bae44755Sopenharmony_ci 42bae44755Sopenharmony_ci#define U32_TO_STR_MAX_LEN 11 43bae44755Sopenharmony_ci#define FREE_CREATE_PCID_BUFFER_OUT 1 44bae44755Sopenharmony_ci 45bae44755Sopenharmony_ci#define FREE_DECODE_PCID_CONVERT_OUT 1 46bae44755Sopenharmony_ci#define FREE_DECODE_PCID_ROOT_OUT 2 47bae44755Sopenharmony_ci#define FREE_DECODE_PCID_SYSCAP_OUT 3 48bae44755Sopenharmony_ci#define FREE_DECODE_PCID_CONTEXT_OUT 4 49bae44755Sopenharmony_ci 50bae44755Sopenharmony_ci#define ENCODE_PCID_OUTPUT 1 51bae44755Sopenharmony_ci#define FREE_ENCODE_PCID_OUT 2 52bae44755Sopenharmony_ci#define FREE_ENCODE_PCID_PRISYSCAP_FULL_OUT 3 53bae44755Sopenharmony_ci#define FREE_ENCODE_PCID_CONTEXT_OUT 4 54bae44755Sopenharmony_ci 55bae44755Sopenharmony_cistruct FreeEncodePcidInfo { 56bae44755Sopenharmony_ci char *output; 57bae44755Sopenharmony_ci char *priSyscapFull; 58bae44755Sopenharmony_ci char *contextBuffer; 59bae44755Sopenharmony_ci char *outDirPathFinal; 60bae44755Sopenharmony_ci}; 61bae44755Sopenharmony_ci 62bae44755Sopenharmony_cistruct FreeDecodePcidJsonInfo { 63bae44755Sopenharmony_ci char *strJson; 64bae44755Sopenharmony_ci char *contextBuffer; 65bae44755Sopenharmony_ci cJSON *jsonRootObj; 66bae44755Sopenharmony_ci cJSON *sysCapObj; 67bae44755Sopenharmony_ci int32_t flag; 68bae44755Sopenharmony_ci}; 69bae44755Sopenharmony_ci 70bae44755Sopenharmony_ciint32_t SetOsSyscap(PCIDMain *pcidBuffer, uint32_t osCapSize, 71bae44755Sopenharmony_ci const cJSON *jsonOsSyscapObj, const cJSON *allOsSyscapObj) 72bae44755Sopenharmony_ci{ 73bae44755Sopenharmony_ci int32_t sectorOfBits, posOfBits; 74bae44755Sopenharmony_ci cJSON *jsonArrayItem = NULL; 75bae44755Sopenharmony_ci cJSON *osCapIndex = NULL; 76bae44755Sopenharmony_ci 77bae44755Sopenharmony_ci for (uint32_t i = 0; i < osCapSize; i++) { 78bae44755Sopenharmony_ci jsonArrayItem = cJSON_GetArrayItem(jsonOsSyscapObj, (int)i); 79bae44755Sopenharmony_ci if (jsonArrayItem == NULL || !cJSON_IsString(jsonArrayItem)) { 80bae44755Sopenharmony_ci PRINT_ERR("Get jsonArrayItem failed."); 81bae44755Sopenharmony_ci return -1; 82bae44755Sopenharmony_ci } 83bae44755Sopenharmony_ci osCapIndex = cJSON_GetObjectItem(allOsSyscapObj, jsonArrayItem->valuestring); 84bae44755Sopenharmony_ci if (osCapIndex == NULL) { 85bae44755Sopenharmony_ci PRINT_ERR("can't find the syscap: %s, please add it in syscap_define.h.\n", jsonArrayItem->valuestring); 86bae44755Sopenharmony_ci return -1; 87bae44755Sopenharmony_ci } 88bae44755Sopenharmony_ci if (!cJSON_IsNumber(osCapIndex)) { 89bae44755Sopenharmony_ci PRINT_ERR("Get osCapIndex failed."); 90bae44755Sopenharmony_ci return -1; 91bae44755Sopenharmony_ci } 92bae44755Sopenharmony_ci sectorOfBits = (osCapIndex->valueint) / UINT8_BIT; 93bae44755Sopenharmony_ci posOfBits = (osCapIndex->valueint) % UINT8_BIT; 94bae44755Sopenharmony_ci if (sectorOfBits >= OS_SYSCAP_BYTES) { 95bae44755Sopenharmony_ci PRINT_ERR("num of \"os syscap\" is out of 960\n"); 96bae44755Sopenharmony_ci return -1; 97bae44755Sopenharmony_ci } 98bae44755Sopenharmony_ci pcidBuffer->osSyscap[sectorOfBits] |= 1 << (posOfBits); 99bae44755Sopenharmony_ci } 100bae44755Sopenharmony_ci 101bae44755Sopenharmony_ci return 0; 102bae44755Sopenharmony_ci} 103bae44755Sopenharmony_ci 104bae44755Sopenharmony_ciint32_t SetPriSyscap(PCIDMain *pcidBuffer, cJSON *jsonPriSyscapObj, 105bae44755Sopenharmony_ci uint32_t privateCapSize, uint16_t allPriSyscapStrLen) 106bae44755Sopenharmony_ci{ 107bae44755Sopenharmony_ci char *priSyscapHead = (char *)(pcidBuffer + 1); 108bae44755Sopenharmony_ci char *priSyscapStr = NULL; 109bae44755Sopenharmony_ci for (uint32_t i = 0; i < privateCapSize; i++) { 110bae44755Sopenharmony_ci cJSON *jsonArrayItem = cJSON_GetArrayItem(jsonPriSyscapObj, (int)i); 111bae44755Sopenharmony_ci if (jsonArrayItem == NULL || !cJSON_IsString(jsonArrayItem)) { 112bae44755Sopenharmony_ci PRINT_ERR("get jsonArrayItem failed!"); 113bae44755Sopenharmony_ci return -1; 114bae44755Sopenharmony_ci } 115bae44755Sopenharmony_ci priSyscapStr = strchr(jsonArrayItem->valuestring, '.'); 116bae44755Sopenharmony_ci if (priSyscapStr == NULL) { 117bae44755Sopenharmony_ci PRINT_ERR("get priSyscapStr failed!"); 118bae44755Sopenharmony_ci return -1; 119bae44755Sopenharmony_ci } 120bae44755Sopenharmony_ci priSyscapStr += 1; 121bae44755Sopenharmony_ci errno_t nRet = strcat_s(priSyscapHead, allPriSyscapStrLen + 1, priSyscapStr); 122bae44755Sopenharmony_ci nRet += strcat_s(priSyscapHead, allPriSyscapStrLen + 1, ","); 123bae44755Sopenharmony_ci if (nRet != EOK) { 124bae44755Sopenharmony_ci PRINT_ERR("strcat_s \"pri\" string is failed\n"); 125bae44755Sopenharmony_ci return -1; 126bae44755Sopenharmony_ci } 127bae44755Sopenharmony_ci } 128bae44755Sopenharmony_ci return 0; 129bae44755Sopenharmony_ci} 130bae44755Sopenharmony_ci 131bae44755Sopenharmony_ciint32_t SetPCIDHeader(PCIDMain *pcidBuffer, const cJSON *jsonRootObj) 132bae44755Sopenharmony_ci{ 133bae44755Sopenharmony_ci cJSON *jsonSyscapObj = cJSON_GetObjectItem(jsonRootObj, "api_version"); 134bae44755Sopenharmony_ci if (jsonSyscapObj == NULL || !cJSON_IsNumber(jsonSyscapObj)) { 135bae44755Sopenharmony_ci PRINT_ERR("get \"api_version\" failed\n"); 136bae44755Sopenharmony_ci return -1; 137bae44755Sopenharmony_ci } 138bae44755Sopenharmony_ci pcidBuffer->apiVersion = HtonsInter((uint16_t)jsonSyscapObj->valueint); 139bae44755Sopenharmony_ci pcidBuffer->apiVersionType = 0; 140bae44755Sopenharmony_ci 141bae44755Sopenharmony_ci jsonSyscapObj = cJSON_GetObjectItem(jsonRootObj, "system_type"); 142bae44755Sopenharmony_ci if (jsonSyscapObj == NULL || !cJSON_IsString(jsonSyscapObj)) { 143bae44755Sopenharmony_ci PRINT_ERR("get \"system_type\" failed\n"); 144bae44755Sopenharmony_ci return -1; 145bae44755Sopenharmony_ci } 146bae44755Sopenharmony_ci char *systemType = jsonSyscapObj->valuestring; 147bae44755Sopenharmony_ci pcidBuffer->systemType = !strcmp(systemType, "mini") ? 0b001 : 148bae44755Sopenharmony_ci (!strcmp(systemType, "small") ? 0b010 : 149bae44755Sopenharmony_ci (!strcmp(systemType, "standard") ? 0b100 : 0)); 150bae44755Sopenharmony_ci if (pcidBuffer->systemType == 0) { 151bae44755Sopenharmony_ci PRINT_ERR("\"system_type\" is invaild, systemType = \"%s\"\n", systemType); 152bae44755Sopenharmony_ci return -1; 153bae44755Sopenharmony_ci } 154bae44755Sopenharmony_ci 155bae44755Sopenharmony_ci jsonSyscapObj = cJSON_GetObjectItem(jsonRootObj, "manufacturer_id"); 156bae44755Sopenharmony_ci if (jsonSyscapObj == NULL || !cJSON_IsNumber(jsonSyscapObj)) { 157bae44755Sopenharmony_ci PRINT_ERR("get \"manufacturer_id\" failed\n"); 158bae44755Sopenharmony_ci return -1; 159bae44755Sopenharmony_ci } 160bae44755Sopenharmony_ci pcidBuffer->manufacturerID = HtonlInter((uint32_t)jsonSyscapObj->valueint); 161bae44755Sopenharmony_ci 162bae44755Sopenharmony_ci return 0; 163bae44755Sopenharmony_ci} 164bae44755Sopenharmony_ci 165bae44755Sopenharmony_ciint32_t GetOsAndPriSyscapSize(const cJSON *osSyscap, const cJSON *priSyscap, 166bae44755Sopenharmony_ci uint32_t *osCapSize, uint32_t *privateCapSize) 167bae44755Sopenharmony_ci{ 168bae44755Sopenharmony_ci *osCapSize = 0; 169bae44755Sopenharmony_ci *privateCapSize = 0; 170bae44755Sopenharmony_ci 171bae44755Sopenharmony_ci // get os syscap size 172bae44755Sopenharmony_ci if (osSyscap == NULL || !cJSON_IsArray(osSyscap)) { 173bae44755Sopenharmony_ci PRINT_ERR("get \"os\" array failed\n"); 174bae44755Sopenharmony_ci return -1; 175bae44755Sopenharmony_ci } 176bae44755Sopenharmony_ci int32_t ret = cJSON_GetArraySize(osSyscap); 177bae44755Sopenharmony_ci if (ret < 0) { 178bae44755Sopenharmony_ci PRINT_ERR("get \"os\" array size failed\n"); 179bae44755Sopenharmony_ci return -1; 180bae44755Sopenharmony_ci } 181bae44755Sopenharmony_ci *osCapSize = (uint32_t)ret; 182bae44755Sopenharmony_ci 183bae44755Sopenharmony_ci // get private syscap size 184bae44755Sopenharmony_ci if (priSyscap != NULL && cJSON_IsArray(priSyscap)) { 185bae44755Sopenharmony_ci ret = cJSON_GetArraySize(priSyscap); 186bae44755Sopenharmony_ci if (ret < 0) { 187bae44755Sopenharmony_ci PRINT_ERR("get \"private syscap\" array size failed\n"); 188bae44755Sopenharmony_ci return -1; 189bae44755Sopenharmony_ci } 190bae44755Sopenharmony_ci *privateCapSize = (uint32_t)ret; 191bae44755Sopenharmony_ci } else if (priSyscap == NULL) { 192bae44755Sopenharmony_ci *privateCapSize = 0; 193bae44755Sopenharmony_ci } else { 194bae44755Sopenharmony_ci PRINT_ERR("get \"private\" array failed\n"); 195bae44755Sopenharmony_ci return -1; 196bae44755Sopenharmony_ci } 197bae44755Sopenharmony_ci 198bae44755Sopenharmony_ci return 0; 199bae44755Sopenharmony_ci} 200bae44755Sopenharmony_ci 201bae44755Sopenharmony_ciint32_t GetPriSyscapLen(uint32_t privateCapSize, cJSON *jsonPriSyscapObj, uint16_t *len) 202bae44755Sopenharmony_ci{ 203bae44755Sopenharmony_ci for (uint32_t i = 0; i < privateCapSize; i++) { 204bae44755Sopenharmony_ci cJSON *jsonArrayItem = cJSON_GetArrayItem(jsonPriSyscapObj, (int)i); 205bae44755Sopenharmony_ci if (jsonArrayItem == NULL || !cJSON_IsString(jsonArrayItem)) { 206bae44755Sopenharmony_ci PRINT_ERR("Get jsonArrayItem failed."); 207bae44755Sopenharmony_ci return -1; 208bae44755Sopenharmony_ci } 209bae44755Sopenharmony_ci *len += (uint16_t)strlen(strchr(jsonArrayItem->valuestring, '.') + 1); 210bae44755Sopenharmony_ci (*len)++; // for separator ',' 211bae44755Sopenharmony_ci } 212bae44755Sopenharmony_ci if ((*len + 1) > PRIVATE_SYSCAP_SIZE) { 213bae44755Sopenharmony_ci PRINT_ERR("context of \"pri\" array is too many.\n"); 214bae44755Sopenharmony_ci return -1; 215bae44755Sopenharmony_ci } 216bae44755Sopenharmony_ci return 0; 217bae44755Sopenharmony_ci} 218bae44755Sopenharmony_ci 219bae44755Sopenharmony_cistatic int32_t CheckConvertedContextSaveAsFile(char *outDirPath, PCIDMain *pcidBuffer, uint16_t pcidLength, int32_t ret) 220bae44755Sopenharmony_ci{ 221bae44755Sopenharmony_ci const char pcidFileName[] = "pcid.sc"; 222bae44755Sopenharmony_ci ret = ConvertedContextSaveAsFile(outDirPath, pcidFileName, (char *)pcidBuffer, pcidLength); 223bae44755Sopenharmony_ci if (ret != 0) { 224bae44755Sopenharmony_ci PRINT_ERR("Save as file failed, outDirPath:%s, filename:%s\n", outDirPath, pcidFileName); 225bae44755Sopenharmony_ci } 226bae44755Sopenharmony_ci return ret; 227bae44755Sopenharmony_ci} 228bae44755Sopenharmony_ci 229bae44755Sopenharmony_cistatic int32_t FreeAfterCreatePCID(PCIDMain *pcidBuffer, cJSON *allOsSyscapObj, char *contextBuffer, 230bae44755Sopenharmony_ci int32_t type, int32_t ret) 231bae44755Sopenharmony_ci{ 232bae44755Sopenharmony_ci if (type == FREE_CREATE_PCID_BUFFER_OUT) { 233bae44755Sopenharmony_ci free(pcidBuffer); 234bae44755Sopenharmony_ci } 235bae44755Sopenharmony_ci cJSON_Delete(allOsSyscapObj); 236bae44755Sopenharmony_ci FreeContextBuffer(contextBuffer); 237bae44755Sopenharmony_ci return ret; 238bae44755Sopenharmony_ci} 239bae44755Sopenharmony_ci 240bae44755Sopenharmony_cistatic int32_t PreFreeAfterCreatePCID(PCIDMain *pcidBuffer, cJSON *allOsSyscapObj, cJSON *jsonRootObj, 241bae44755Sopenharmony_ci char *contextBuffer, int32_t type) 242bae44755Sopenharmony_ci{ 243bae44755Sopenharmony_ci cJSON_Delete(jsonRootObj); 244bae44755Sopenharmony_ci return FreeAfterCreatePCID(pcidBuffer, allOsSyscapObj, contextBuffer, type, -1); 245bae44755Sopenharmony_ci} 246bae44755Sopenharmony_ci 247bae44755Sopenharmony_ciint32_t CreatePCID(char *inputFile, char *outDirPath) 248bae44755Sopenharmony_ci{ 249bae44755Sopenharmony_ci uint32_t privateCapSize, osCapSize; 250bae44755Sopenharmony_ci uint32_t contextBufLen; 251bae44755Sopenharmony_ci char *contextBuffer = NULL; 252bae44755Sopenharmony_ci 253bae44755Sopenharmony_ci cJSON *allOsSyscapObj = CreateWholeSyscapJsonObj(); 254bae44755Sopenharmony_ci int32_t ret = CheckFileAndGetFileContext(inputFile, &contextBuffer, (uint32_t *)&contextBufLen); 255bae44755Sopenharmony_ci if (ret != 0) { 256bae44755Sopenharmony_ci return FreeAfterCreatePCID(NULL, allOsSyscapObj, contextBuffer, 0, -1); 257bae44755Sopenharmony_ci } 258bae44755Sopenharmony_ci 259bae44755Sopenharmony_ci cJSON *jsonRootObj = cJSON_ParseWithLength(contextBuffer, contextBufLen); 260bae44755Sopenharmony_ci if (jsonRootObj == NULL) { 261bae44755Sopenharmony_ci PRINT_ERR("cJSON_Parse failed, context buffer is:\n%s\n", contextBuffer); 262bae44755Sopenharmony_ci return PreFreeAfterCreatePCID(NULL, allOsSyscapObj, jsonRootObj, contextBuffer, 0); 263bae44755Sopenharmony_ci } 264bae44755Sopenharmony_ci 265bae44755Sopenharmony_ci cJSON *jsonSyscapObj = cJSON_GetObjectItem(jsonRootObj, "syscap"); 266bae44755Sopenharmony_ci if (jsonSyscapObj == NULL || !cJSON_IsObject(jsonSyscapObj)) { 267bae44755Sopenharmony_ci PRINT_ERR("get \"syscap\" object failed\n"); 268bae44755Sopenharmony_ci return PreFreeAfterCreatePCID(NULL, allOsSyscapObj, jsonRootObj, contextBuffer, 0); 269bae44755Sopenharmony_ci } 270bae44755Sopenharmony_ci 271bae44755Sopenharmony_ci cJSON *jsonOsSyscapObj = cJSON_GetObjectItem(jsonSyscapObj, "os"); 272bae44755Sopenharmony_ci cJSON *jsonPriSyscapObj = cJSON_GetObjectItem(jsonSyscapObj, "private"); 273bae44755Sopenharmony_ci 274bae44755Sopenharmony_ci ret = GetOsAndPriSyscapSize(jsonOsSyscapObj, jsonPriSyscapObj, &osCapSize, &privateCapSize); 275bae44755Sopenharmony_ci if (ret != 0) { 276bae44755Sopenharmony_ci return PreFreeAfterCreatePCID(NULL, allOsSyscapObj, jsonRootObj, contextBuffer, 0); 277bae44755Sopenharmony_ci } 278bae44755Sopenharmony_ci 279bae44755Sopenharmony_ci uint16_t allPriSyscapStrLen = 0; 280bae44755Sopenharmony_ci ret = GetPriSyscapLen(privateCapSize, jsonPriSyscapObj, &allPriSyscapStrLen); 281bae44755Sopenharmony_ci if (ret != 0) { 282bae44755Sopenharmony_ci return PreFreeAfterCreatePCID(NULL, allOsSyscapObj, jsonRootObj, contextBuffer, 0); 283bae44755Sopenharmony_ci } 284bae44755Sopenharmony_ci 285bae44755Sopenharmony_ci uint16_t pcidLength = sizeof(PCIDMain) + allPriSyscapStrLen + 1; 286bae44755Sopenharmony_ci PCIDMain *pcidBuffer = (PCIDMain *)malloc(pcidLength); 287bae44755Sopenharmony_ci if (pcidBuffer == NULL) { 288bae44755Sopenharmony_ci PRINT_ERR("malloc for pcid buffer failed\n"); 289bae44755Sopenharmony_ci return PreFreeAfterCreatePCID(NULL, allOsSyscapObj, jsonRootObj, contextBuffer, 0); 290bae44755Sopenharmony_ci } 291bae44755Sopenharmony_ci (void)memset_s(pcidBuffer, pcidLength, 0, pcidLength); 292bae44755Sopenharmony_ci 293bae44755Sopenharmony_ci ret = SetOsSyscap(pcidBuffer, osCapSize, jsonOsSyscapObj, allOsSyscapObj); 294bae44755Sopenharmony_ci ret += SetPriSyscap(pcidBuffer, jsonPriSyscapObj, privateCapSize, allPriSyscapStrLen); 295bae44755Sopenharmony_ci ret += SetPCIDHeader(pcidBuffer, jsonRootObj); 296bae44755Sopenharmony_ci if (ret != 0) { 297bae44755Sopenharmony_ci return PreFreeAfterCreatePCID(pcidBuffer, allOsSyscapObj, jsonRootObj, contextBuffer, 298bae44755Sopenharmony_ci FREE_CREATE_PCID_BUFFER_OUT); 299bae44755Sopenharmony_ci } 300bae44755Sopenharmony_ci 301bae44755Sopenharmony_ci ret = CheckConvertedContextSaveAsFile(outDirPath, pcidBuffer, pcidLength, ret); 302bae44755Sopenharmony_ci cJSON_Delete(jsonRootObj); 303bae44755Sopenharmony_ci return FreeAfterCreatePCID(pcidBuffer, allOsSyscapObj, contextBuffer, FREE_CREATE_PCID_BUFFER_OUT, ret); 304bae44755Sopenharmony_ci} 305bae44755Sopenharmony_ci 306bae44755Sopenharmony_ciint32_t GetOsSyscap(PCIDMain *pcidMain, cJSON *sysCapObject) 307bae44755Sopenharmony_ci{ 308bae44755Sopenharmony_ci uint32_t i, j, countOfSyscap = 0; 309bae44755Sopenharmony_ci uint8_t osSyscap[OS_SYSCAP_BYTES] = {0}; 310bae44755Sopenharmony_ci uint16_t indexOfSyscap[OS_SYSCAP_BYTES * UINT8_BIT] = {0}; 311bae44755Sopenharmony_ci 312bae44755Sopenharmony_ci cJSON *capVectorPtr = cJSON_CreateArray(); 313bae44755Sopenharmony_ci if (capVectorPtr == NULL) { 314bae44755Sopenharmony_ci PRINT_ERR("cJSON_CreateArray failed\n"); 315bae44755Sopenharmony_ci return -1; 316bae44755Sopenharmony_ci } 317bae44755Sopenharmony_ci 318bae44755Sopenharmony_ci // 8, bytes of pcid header 319bae44755Sopenharmony_ci errno_t nRet = memcpy_s(osSyscap, OS_SYSCAP_BYTES, (uint8_t *)pcidMain + 8, OS_SYSCAP_BYTES); 320bae44755Sopenharmony_ci if (nRet != EOK) { 321bae44755Sopenharmony_ci PRINT_ERR("memcpy_s failed."); 322bae44755Sopenharmony_ci cJSON_Delete(capVectorPtr); 323bae44755Sopenharmony_ci return -1; 324bae44755Sopenharmony_ci } 325bae44755Sopenharmony_ci 326bae44755Sopenharmony_ci for (i = 0; i < OS_SYSCAP_BYTES; i++) { 327bae44755Sopenharmony_ci for (j = 0; j < UINT8_BIT; j++) { 328bae44755Sopenharmony_ci if (osSyscap[i] & (0x01 << j)) { 329bae44755Sopenharmony_ci indexOfSyscap[countOfSyscap++] = i * UINT8_BIT + j; 330bae44755Sopenharmony_ci } 331bae44755Sopenharmony_ci } 332bae44755Sopenharmony_ci } 333bae44755Sopenharmony_ci for (i = 0; i < countOfSyscap; i++) { 334bae44755Sopenharmony_ci for (j = 0; j < sizeof(g_arraySyscap) / sizeof(SyscapWithNum); j++) { 335bae44755Sopenharmony_ci if (g_arraySyscap[j].num != indexOfSyscap[i]) { 336bae44755Sopenharmony_ci continue; 337bae44755Sopenharmony_ci } 338bae44755Sopenharmony_ci if (!cJSON_AddItemToArray(capVectorPtr, cJSON_CreateString(g_arraySyscap[j].str))) { 339bae44755Sopenharmony_ci printf("cJSON_AddItemToArray or cJSON_CreateString failed\n"); 340bae44755Sopenharmony_ci cJSON_Delete(capVectorPtr); 341bae44755Sopenharmony_ci return -1; 342bae44755Sopenharmony_ci } 343bae44755Sopenharmony_ci } 344bae44755Sopenharmony_ci } 345bae44755Sopenharmony_ci 346bae44755Sopenharmony_ci if (!cJSON_AddItemToObject(sysCapObject, "os", capVectorPtr)) { 347bae44755Sopenharmony_ci PRINT_ERR("cJSON_AddItemToObject failed\n"); 348bae44755Sopenharmony_ci cJSON_Delete(capVectorPtr); 349bae44755Sopenharmony_ci return -1; 350bae44755Sopenharmony_ci } 351bae44755Sopenharmony_ci 352bae44755Sopenharmony_ci return 0; 353bae44755Sopenharmony_ci} 354bae44755Sopenharmony_ci 355bae44755Sopenharmony_cistatic int32_t GetPriSyscapResult(cJSON *capVectorPtr, int32_t ret) 356bae44755Sopenharmony_ci{ 357bae44755Sopenharmony_ci cJSON_Delete(capVectorPtr); 358bae44755Sopenharmony_ci return ret; 359bae44755Sopenharmony_ci} 360bae44755Sopenharmony_ci 361bae44755Sopenharmony_cistatic int32_t GetPriSyscap(PCIDMain *pcidMain, cJSON *sysCapObject, int32_t contextBufLen) 362bae44755Sopenharmony_ci{ 363bae44755Sopenharmony_ci cJSON *capVectorPtr = cJSON_CreateArray(); 364bae44755Sopenharmony_ci if (capVectorPtr == NULL) { 365bae44755Sopenharmony_ci PRINT_ERR("cJSON_CreateArray failed\n"); 366bae44755Sopenharmony_ci return -1; 367bae44755Sopenharmony_ci } 368bae44755Sopenharmony_ci 369bae44755Sopenharmony_ci int32_t privateSyscapLen = contextBufLen - sizeof(PCIDMain) - 1; 370bae44755Sopenharmony_ci if (privateSyscapLen < 0 || privateSyscapLen > INT32_MAX) { 371bae44755Sopenharmony_ci PRINT_ERR("parse private syscap failed."); 372bae44755Sopenharmony_ci return GetPriSyscapResult(capVectorPtr, -1); 373bae44755Sopenharmony_ci } else if (privateSyscapLen == 0) { 374bae44755Sopenharmony_ci return GetPriSyscapResult(capVectorPtr, 0); 375bae44755Sopenharmony_ci } 376bae44755Sopenharmony_ci 377bae44755Sopenharmony_ci char fullCapStr[SINGLE_SYSCAP_LEN] = {0}; 378bae44755Sopenharmony_ci char priSyscapStr[SINGLE_SYSCAP_LEN] = {0}; 379bae44755Sopenharmony_ci char *tempPriSyscapStr = priSyscapStr; 380bae44755Sopenharmony_ci char *ptrPrivateSyscap = (char *)(pcidMain + 1); 381bae44755Sopenharmony_ci while (*ptrPrivateSyscap != '\0') { 382bae44755Sopenharmony_ci if (*ptrPrivateSyscap == ',') { 383bae44755Sopenharmony_ci *tempPriSyscapStr = '\0'; 384bae44755Sopenharmony_ci int32_t ret = sprintf_s(fullCapStr, SINGLE_SYSCAP_LEN, "SystemCapability.%s", priSyscapStr); 385bae44755Sopenharmony_ci if (ret == -1) { 386bae44755Sopenharmony_ci printf("sprintf_s failed\n"); 387bae44755Sopenharmony_ci return GetPriSyscapResult(capVectorPtr, -1); 388bae44755Sopenharmony_ci } 389bae44755Sopenharmony_ci if (!cJSON_AddItemToArray(capVectorPtr, cJSON_CreateString(fullCapStr))) { 390bae44755Sopenharmony_ci printf("cJSON_AddItemToArray or cJSON_CreateString failed\n"); 391bae44755Sopenharmony_ci return GetPriSyscapResult(capVectorPtr, -1); 392bae44755Sopenharmony_ci } 393bae44755Sopenharmony_ci tempPriSyscapStr = priSyscapStr; 394bae44755Sopenharmony_ci ptrPrivateSyscap++; 395bae44755Sopenharmony_ci continue; 396bae44755Sopenharmony_ci } 397bae44755Sopenharmony_ci *tempPriSyscapStr++ = *ptrPrivateSyscap++; 398bae44755Sopenharmony_ci } 399bae44755Sopenharmony_ci if (!cJSON_AddItemToObject(sysCapObject, "private", capVectorPtr)) { 400bae44755Sopenharmony_ci PRINT_ERR("cJSON_AddItemToObject failed\n"); 401bae44755Sopenharmony_ci return GetPriSyscapResult(capVectorPtr, -1); 402bae44755Sopenharmony_ci } 403bae44755Sopenharmony_ci return 0; 404bae44755Sopenharmony_ci} 405bae44755Sopenharmony_ci 406bae44755Sopenharmony_cistatic int32_t CheckSysCapObj(struct FreeDecodePcidJsonInfo freePcidJsonInfo, PCIDMain *pcidMain, 407bae44755Sopenharmony_ci uint32_t contextBufLen, int32_t ret) 408bae44755Sopenharmony_ci{ 409bae44755Sopenharmony_ci if (freePcidJsonInfo.sysCapObj == NULL) { 410bae44755Sopenharmony_ci PRINT_ERR("cJSON_CreateObject failed\n"); 411bae44755Sopenharmony_ci freePcidJsonInfo.flag = -1; 412bae44755Sopenharmony_ci return -1; 413bae44755Sopenharmony_ci } 414bae44755Sopenharmony_ci if (GetOsSyscap(pcidMain, freePcidJsonInfo.sysCapObj) != 0) { 415bae44755Sopenharmony_ci freePcidJsonInfo.flag = -1; 416bae44755Sopenharmony_ci return ret; 417bae44755Sopenharmony_ci } 418bae44755Sopenharmony_ci if (GetPriSyscap(pcidMain, freePcidJsonInfo.sysCapObj, contextBufLen) != 0) { 419bae44755Sopenharmony_ci freePcidJsonInfo.flag = -1; 420bae44755Sopenharmony_ci } 421bae44755Sopenharmony_ci return ret; 422bae44755Sopenharmony_ci} 423bae44755Sopenharmony_ci 424bae44755Sopenharmony_cistatic int32_t CheckJsonRootObj(struct FreeDecodePcidJsonInfo freePcidJsonInfo, PCIDMain *pcidMain, char *systemType) 425bae44755Sopenharmony_ci{ 426bae44755Sopenharmony_ci if (!cJSON_AddNumberToObject(freePcidJsonInfo.jsonRootObj, "api_version", NtohsInter(pcidMain->apiVersion))) { 427bae44755Sopenharmony_ci PRINT_ERR("cJSON_AddNumberToObject failed\n"); 428bae44755Sopenharmony_ci return -1; 429bae44755Sopenharmony_ci } 430bae44755Sopenharmony_ci if (!cJSON_AddNumberToObject(freePcidJsonInfo.jsonRootObj, "manufacturer_id", 431bae44755Sopenharmony_ci NtohlInter(pcidMain->manufacturerID))) { 432bae44755Sopenharmony_ci PRINT_ERR("cJSON_AddNumberToObject failed\n"); 433bae44755Sopenharmony_ci return -1; 434bae44755Sopenharmony_ci } 435bae44755Sopenharmony_ci if (!cJSON_AddStringToObject(freePcidJsonInfo.jsonRootObj, "system_type", systemType)) { 436bae44755Sopenharmony_ci PRINT_ERR("cJSON_AddStringToObject failed\n"); 437bae44755Sopenharmony_ci return -1; 438bae44755Sopenharmony_ci } 439bae44755Sopenharmony_ci if (!cJSON_AddItemToObject(freePcidJsonInfo.jsonRootObj, "syscap", freePcidJsonInfo.sysCapObj)) { 440bae44755Sopenharmony_ci PRINT_ERR("cJSON_AddItemToObject failed\n"); 441bae44755Sopenharmony_ci return -1; 442bae44755Sopenharmony_ci } 443bae44755Sopenharmony_ci return 0; 444bae44755Sopenharmony_ci} 445bae44755Sopenharmony_ci 446bae44755Sopenharmony_cistatic int32_t FreeAfterDecodePCID(struct FreeDecodePcidJsonInfo freePcidJsonInfo, int32_t type, int32_t ret) 447bae44755Sopenharmony_ci{ 448bae44755Sopenharmony_ci switch (type) { 449bae44755Sopenharmony_ci case FREE_DECODE_PCID_CONVERT_OUT: 450bae44755Sopenharmony_ci cJSON_free(freePcidJsonInfo.strJson); 451bae44755Sopenharmony_ci cJSON_Delete(freePcidJsonInfo.jsonRootObj); 452bae44755Sopenharmony_ci FreeContextBuffer(freePcidJsonInfo.contextBuffer); 453bae44755Sopenharmony_ci break; 454bae44755Sopenharmony_ci case FREE_DECODE_PCID_ROOT_OUT: 455bae44755Sopenharmony_ci cJSON_Delete(freePcidJsonInfo.jsonRootObj); 456bae44755Sopenharmony_ci cJSON_Delete(freePcidJsonInfo.sysCapObj); 457bae44755Sopenharmony_ci FreeContextBuffer(freePcidJsonInfo.contextBuffer); 458bae44755Sopenharmony_ci break; 459bae44755Sopenharmony_ci case FREE_DECODE_PCID_SYSCAP_OUT: 460bae44755Sopenharmony_ci cJSON_Delete(freePcidJsonInfo.sysCapObj); 461bae44755Sopenharmony_ci FreeContextBuffer(freePcidJsonInfo.contextBuffer); 462bae44755Sopenharmony_ci break; 463bae44755Sopenharmony_ci case FREE_DECODE_PCID_CONTEXT_OUT: 464bae44755Sopenharmony_ci cJSON_Delete(freePcidJsonInfo.sysCapObj); 465bae44755Sopenharmony_ci FreeContextBuffer(freePcidJsonInfo.contextBuffer); 466bae44755Sopenharmony_ci break; 467bae44755Sopenharmony_ci default: 468bae44755Sopenharmony_ci FreeContextBuffer(freePcidJsonInfo.contextBuffer); 469bae44755Sopenharmony_ci } 470bae44755Sopenharmony_ci return ret; 471bae44755Sopenharmony_ci} 472bae44755Sopenharmony_ci 473bae44755Sopenharmony_ciint32_t DecodePCID(char *inputFile, char *outDirPath) 474bae44755Sopenharmony_ci{ 475bae44755Sopenharmony_ci int32_t ret = 0; 476bae44755Sopenharmony_ci uint32_t contextBufLen; 477bae44755Sopenharmony_ci struct FreeDecodePcidJsonInfo freePcidJsonInfo; 478bae44755Sopenharmony_ci freePcidJsonInfo.strJson = NULL; 479bae44755Sopenharmony_ci freePcidJsonInfo.contextBuffer = NULL; 480bae44755Sopenharmony_ci freePcidJsonInfo.jsonRootObj = NULL; 481bae44755Sopenharmony_ci freePcidJsonInfo.sysCapObj = NULL; 482bae44755Sopenharmony_ci freePcidJsonInfo.flag = 0; 483bae44755Sopenharmony_ci 484bae44755Sopenharmony_ci ret = CheckFileAndGetFileContext(inputFile, &freePcidJsonInfo.contextBuffer, (uint32_t *)&contextBufLen); 485bae44755Sopenharmony_ci if (ret != 0) { 486bae44755Sopenharmony_ci return -1; 487bae44755Sopenharmony_ci } 488bae44755Sopenharmony_ci 489bae44755Sopenharmony_ci PCIDMain *pcidMain = (PCIDMain *)freePcidJsonInfo.contextBuffer; 490bae44755Sopenharmony_ci 491bae44755Sopenharmony_ci /* api version */ 492bae44755Sopenharmony_ci if (pcidMain->apiVersionType != 0) { 493bae44755Sopenharmony_ci PRINT_ERR("Prase file failed, apiVersionType is invaild, input file : %s\n", inputFile); 494bae44755Sopenharmony_ci return FreeAfterDecodePCID(freePcidJsonInfo, FREE_DECODE_PCID_CONTEXT_OUT, -1); 495bae44755Sopenharmony_ci } 496bae44755Sopenharmony_ci 497bae44755Sopenharmony_ci /* system type */ 498bae44755Sopenharmony_ci char *systemType = pcidMain->systemType == 0b001 ? "mini" : 499bae44755Sopenharmony_ci (pcidMain->systemType == 0b010 ? "small" : 500bae44755Sopenharmony_ci (pcidMain->systemType == 0b100 ? "standard" : NULL)); 501bae44755Sopenharmony_ci if (systemType == NULL) { 502bae44755Sopenharmony_ci PRINT_ERR("prase file failed, systemType is invaild, %u\n", pcidMain->systemType); 503bae44755Sopenharmony_ci return FreeAfterDecodePCID(freePcidJsonInfo, FREE_DECODE_PCID_CONTEXT_OUT, -1); 504bae44755Sopenharmony_ci } 505bae44755Sopenharmony_ci 506bae44755Sopenharmony_ci /* syscap */ 507bae44755Sopenharmony_ci freePcidJsonInfo.sysCapObj = cJSON_CreateObject(); 508bae44755Sopenharmony_ci ret = CheckSysCapObj(freePcidJsonInfo, pcidMain, contextBufLen, ret); 509bae44755Sopenharmony_ci if (freePcidJsonInfo.flag == -1) { 510bae44755Sopenharmony_ci return FreeAfterDecodePCID(freePcidJsonInfo, FREE_DECODE_PCID_CONTEXT_OUT, ret); 511bae44755Sopenharmony_ci } 512bae44755Sopenharmony_ci 513bae44755Sopenharmony_ci // create json root 514bae44755Sopenharmony_ci freePcidJsonInfo.jsonRootObj = cJSON_CreateObject(); 515bae44755Sopenharmony_ci if (freePcidJsonInfo.jsonRootObj == NULL) { 516bae44755Sopenharmony_ci PRINT_ERR("cJSON_CreateObject failed\n"); 517bae44755Sopenharmony_ci return FreeAfterDecodePCID(freePcidJsonInfo, FREE_DECODE_PCID_SYSCAP_OUT, -1); 518bae44755Sopenharmony_ci } 519bae44755Sopenharmony_ci 520bae44755Sopenharmony_ci ret = CheckJsonRootObj(freePcidJsonInfo, pcidMain, systemType); 521bae44755Sopenharmony_ci if (ret == -1) { 522bae44755Sopenharmony_ci return FreeAfterDecodePCID(freePcidJsonInfo, FREE_DECODE_PCID_ROOT_OUT, ret); 523bae44755Sopenharmony_ci } 524bae44755Sopenharmony_ci 525bae44755Sopenharmony_ci freePcidJsonInfo.strJson = cJSON_Print(freePcidJsonInfo.jsonRootObj); 526bae44755Sopenharmony_ci 527bae44755Sopenharmony_ci const char outputFileName[] = "pcid.json"; 528bae44755Sopenharmony_ci ret = ConvertedContextSaveAsFile(outDirPath, outputFileName, freePcidJsonInfo.strJson, 529bae44755Sopenharmony_ci strlen(freePcidJsonInfo.strJson)); 530bae44755Sopenharmony_ci if (ret != 0) { 531bae44755Sopenharmony_ci PRINT_ERR("ConvertedContextSaveAsFile failed, outDirPath:%s, filename:%s\n", outDirPath, outputFileName); 532bae44755Sopenharmony_ci } 533bae44755Sopenharmony_ci return FreeAfterDecodePCID(freePcidJsonInfo, FREE_DECODE_PCID_CONVERT_OUT, ret); 534bae44755Sopenharmony_ci} 535bae44755Sopenharmony_ci 536bae44755Sopenharmony_ci#define U32_TO_STR_MAX_LEN 11 537bae44755Sopenharmony_ci#define OS_SYSCAP_NUM 30 538bae44755Sopenharmony_ci#define PCID_HEADER 2 539bae44755Sopenharmony_cistatic int32_t ParseStringSyscap(char *input, uint32_t *osSyscap, uint32_t osSyscapNum, 540bae44755Sopenharmony_ci uint32_t *header, uint32_t headerLen) 541bae44755Sopenharmony_ci{ 542bae44755Sopenharmony_ci int32_t ret; 543bae44755Sopenharmony_ci uint32_t tempNum; 544bae44755Sopenharmony_ci uint32_t i = 0; 545bae44755Sopenharmony_ci size_t inputLen = strlen(input); 546bae44755Sopenharmony_ci 547bae44755Sopenharmony_ci if (osSyscapNum != OS_SYSCAP_NUM || headerLen != PCID_HEADER) { 548bae44755Sopenharmony_ci PRINT_ERR("Input osSyscapNum(%u) or headerLen(%u) error.\n", osSyscapNum, headerLen); 549bae44755Sopenharmony_ci return -1; 550bae44755Sopenharmony_ci } 551bae44755Sopenharmony_ci 552bae44755Sopenharmony_ci if (sscanf_s(input, "%u,%u,%s", &header[0], &header[1], input, inputLen) != 3) { // 3, return val of "%u,%u,%s" 553bae44755Sopenharmony_ci PRINT_ERR("Get pcid header failed.\n"); 554bae44755Sopenharmony_ci return -1; 555bae44755Sopenharmony_ci } 556bae44755Sopenharmony_ci 557bae44755Sopenharmony_ci while ((ret = sscanf_s(input, "%u,%s", &tempNum, input, inputLen)) > 0) { 558bae44755Sopenharmony_ci osSyscap[i++] = tempNum; 559bae44755Sopenharmony_ci if (i >= OS_SYSCAP_NUM) { 560bae44755Sopenharmony_ci break; 561bae44755Sopenharmony_ci } 562bae44755Sopenharmony_ci } 563bae44755Sopenharmony_ci if (ret == -1) { 564bae44755Sopenharmony_ci PRINT_ERR("sscanf_s failed, i = %u.\n", i); 565bae44755Sopenharmony_ci return -1; 566bae44755Sopenharmony_ci } 567bae44755Sopenharmony_ci 568bae44755Sopenharmony_ci if (strlen(input) <= 1) { 569bae44755Sopenharmony_ci *input = '\0'; 570bae44755Sopenharmony_ci } 571bae44755Sopenharmony_ci 572bae44755Sopenharmony_ci return 0; 573bae44755Sopenharmony_ci} 574bae44755Sopenharmony_ci 575bae44755Sopenharmony_cistatic int32_t AddHeaderToJsonObj(uint32_t *pcidHeader, uint32_t pcidHeaderLen, cJSON *rootObj) 576bae44755Sopenharmony_ci{ 577bae44755Sopenharmony_ci if (pcidHeaderLen != PCID_HEADER) { 578bae44755Sopenharmony_ci PRINT_ERR("input pcidHeader(%u) error.\n", pcidHeaderLen); 579bae44755Sopenharmony_ci return -1; 580bae44755Sopenharmony_ci } 581bae44755Sopenharmony_ci 582bae44755Sopenharmony_ci PCIDHeader *header = (PCIDHeader *)pcidHeader; 583bae44755Sopenharmony_ci // trans system type to string 584bae44755Sopenharmony_ci char *systemType = header->systemType == 0b001 ? "mini" : 585bae44755Sopenharmony_ci (header->systemType == 0b010 ? "small" : 586bae44755Sopenharmony_ci (header->systemType == 0b100 ? "standard" : NULL)); 587bae44755Sopenharmony_ci if (systemType == NULL) { 588bae44755Sopenharmony_ci PRINT_ERR("prase system type failed.\n"); 589bae44755Sopenharmony_ci return -1; 590bae44755Sopenharmony_ci } 591bae44755Sopenharmony_ci 592bae44755Sopenharmony_ci // add to json 593bae44755Sopenharmony_ci if (!cJSON_AddNumberToObject(rootObj, "api_version", NtohsInter(header->apiVersion))) { 594bae44755Sopenharmony_ci PRINT_ERR("add api_version(%u) to json object failed.\n", NtohsInter(header->apiVersion)); 595bae44755Sopenharmony_ci return -1; 596bae44755Sopenharmony_ci } 597bae44755Sopenharmony_ci if (!cJSON_AddNumberToObject(rootObj, "manufacturer_id", NtohlInter(header->manufacturerID))) { 598bae44755Sopenharmony_ci PRINT_ERR("add manufacturer_id(%u) to json object failed\n", NtohlInter(header->manufacturerID)); 599bae44755Sopenharmony_ci return -1; 600bae44755Sopenharmony_ci } 601bae44755Sopenharmony_ci if (!cJSON_AddStringToObject(rootObj, "system_type", systemType)) { 602bae44755Sopenharmony_ci PRINT_ERR("add system_type(%s) to json object failed\n", systemType); 603bae44755Sopenharmony_ci return -1; 604bae44755Sopenharmony_ci } 605bae44755Sopenharmony_ci return 0; 606bae44755Sopenharmony_ci} 607bae44755Sopenharmony_ci 608bae44755Sopenharmony_cistatic int32_t AddOsSyscapToJsonObj(uint32_t *osSyscapArray, uint32_t osSyscapArrayLen, cJSON *sysCapObj) 609bae44755Sopenharmony_ci{ 610bae44755Sopenharmony_ci cJSON *sysCapArray = cJSON_CreateArray(); 611bae44755Sopenharmony_ci if (sysCapArray == NULL) { 612bae44755Sopenharmony_ci PRINT_ERR("Create cJSON array failed.\n"); 613bae44755Sopenharmony_ci return -1; 614bae44755Sopenharmony_ci } 615bae44755Sopenharmony_ci 616bae44755Sopenharmony_ci if (osSyscapArrayLen != OS_SYSCAP_NUM) { 617bae44755Sopenharmony_ci PRINT_ERR("Input os syscap array len error.\n"); 618bae44755Sopenharmony_ci free(sysCapArray); 619bae44755Sopenharmony_ci return -1; 620bae44755Sopenharmony_ci } 621bae44755Sopenharmony_ci uint8_t *osSysCapArrayUint8 = (uint8_t *)osSyscapArray; 622bae44755Sopenharmony_ci 623bae44755Sopenharmony_ci uint32_t i, j; 624bae44755Sopenharmony_ci uint32_t osSyscapCount = 0; 625bae44755Sopenharmony_ci uint16_t index[OS_SYSCAP_BYTES * UINT8_BIT] = {0}; 626bae44755Sopenharmony_ci for (i = 0; i < OS_SYSCAP_BYTES; i++) { 627bae44755Sopenharmony_ci for (j = 0; j < UINT8_BIT; j++) { 628bae44755Sopenharmony_ci if (osSysCapArrayUint8[i] & (0x01 << j)) { 629bae44755Sopenharmony_ci index[osSyscapCount++] = i * UINT8_BIT + j; 630bae44755Sopenharmony_ci } 631bae44755Sopenharmony_ci } 632bae44755Sopenharmony_ci } 633bae44755Sopenharmony_ci 634bae44755Sopenharmony_ci for (i = 0; i < osSyscapCount; i++) { 635bae44755Sopenharmony_ci for (j = 0; j < sizeof(g_arraySyscap) / sizeof(SyscapWithNum); j++) { 636bae44755Sopenharmony_ci if (index[i] != g_arraySyscap[j].num) { 637bae44755Sopenharmony_ci continue; 638bae44755Sopenharmony_ci } 639bae44755Sopenharmony_ci if (!cJSON_AddItemToArray(sysCapArray, cJSON_CreateString(g_arraySyscap[j].str))) { 640bae44755Sopenharmony_ci PRINT_ERR("Add os syscap string to json failed.\n"); 641bae44755Sopenharmony_ci free(sysCapArray); 642bae44755Sopenharmony_ci return -1; 643bae44755Sopenharmony_ci } 644bae44755Sopenharmony_ci break; 645bae44755Sopenharmony_ci } 646bae44755Sopenharmony_ci } 647bae44755Sopenharmony_ci 648bae44755Sopenharmony_ci if (!cJSON_AddItemToObject(sysCapObj, "os", sysCapArray)) { 649bae44755Sopenharmony_ci PRINT_ERR("Add os syscap item to json object failed.\n"); 650bae44755Sopenharmony_ci free(sysCapArray); 651bae44755Sopenharmony_ci return -1; 652bae44755Sopenharmony_ci } 653bae44755Sopenharmony_ci return 0; 654bae44755Sopenharmony_ci} 655bae44755Sopenharmony_ci 656bae44755Sopenharmony_cistatic int32_t AddPriSyscapToJsonObj(char *priSyscapString, uint32_t priSyscapStringLen, cJSON *sysCapObj) 657bae44755Sopenharmony_ci{ 658bae44755Sopenharmony_ci char *token = NULL; 659bae44755Sopenharmony_ci 660bae44755Sopenharmony_ci cJSON *sysCapArray = cJSON_CreateArray(); 661bae44755Sopenharmony_ci if (sysCapArray == NULL) { 662bae44755Sopenharmony_ci PRINT_ERR("Create cJSON array failed.\n"); 663bae44755Sopenharmony_ci return -1; 664bae44755Sopenharmony_ci } 665bae44755Sopenharmony_ci if (priSyscapStringLen == 0) { 666bae44755Sopenharmony_ci if (!cJSON_AddItemToObject(sysCapObj, "private", sysCapArray)) { 667bae44755Sopenharmony_ci PRINT_ERR("Add private syscap array to json failed.\n"); 668bae44755Sopenharmony_ci cJSON_Delete(sysCapArray); 669bae44755Sopenharmony_ci return -1; 670bae44755Sopenharmony_ci } 671bae44755Sopenharmony_ci cJSON_Delete(sysCapArray); 672bae44755Sopenharmony_ci return 0; 673bae44755Sopenharmony_ci } 674bae44755Sopenharmony_ci 675bae44755Sopenharmony_ci token = strtok(priSyscapString, ","); 676bae44755Sopenharmony_ci while (token != NULL) { 677bae44755Sopenharmony_ci if (!cJSON_AddItemToArray(sysCapArray, cJSON_CreateString(token))) { 678bae44755Sopenharmony_ci PRINT_ERR("Add private syscap string to json failed.\n"); 679bae44755Sopenharmony_ci cJSON_Delete(sysCapArray); 680bae44755Sopenharmony_ci return -1; 681bae44755Sopenharmony_ci } 682bae44755Sopenharmony_ci token = strtok(NULL, ","); 683bae44755Sopenharmony_ci } 684bae44755Sopenharmony_ci if (!cJSON_AddItemToObject(sysCapObj, "private", sysCapArray)) { 685bae44755Sopenharmony_ci PRINT_ERR("Add private syscap array to json failed.\n"); 686bae44755Sopenharmony_ci cJSON_Delete(sysCapArray); 687bae44755Sopenharmony_ci return -1; 688bae44755Sopenharmony_ci } 689bae44755Sopenharmony_ci return 0; 690bae44755Sopenharmony_ci} 691bae44755Sopenharmony_ci 692bae44755Sopenharmony_cistatic int32_t GetSyscapStr(char *input, char const *priSyscapStr, uint32_t* osSyscap, uint32_t *pcidHeader) 693bae44755Sopenharmony_ci{ 694bae44755Sopenharmony_ci if (input == NULL) { 695bae44755Sopenharmony_ci PRINT_ERR("inputFile is null.\n"); 696bae44755Sopenharmony_ci return -1; 697bae44755Sopenharmony_ci } 698bae44755Sopenharmony_ci char *ctx = NULL; 699bae44755Sopenharmony_ci uint32_t fileContextLen; 700bae44755Sopenharmony_ci if (GetFileContext(input, &ctx, (uint32_t *)&fileContextLen) != 0) { 701bae44755Sopenharmony_ci PRINT_ERR("GetFileContext failed, input file : %s\n", input); 702bae44755Sopenharmony_ci return -1; 703bae44755Sopenharmony_ci } 704bae44755Sopenharmony_ci if (ParseStringSyscap(ctx, osSyscap, OS_SYSCAP_NUM, pcidHeader, PCID_HEADER) != 0) { 705bae44755Sopenharmony_ci PRINT_ERR("Parse string syscap failed.\n"); 706bae44755Sopenharmony_ci free(ctx); 707bae44755Sopenharmony_ci return -1; 708bae44755Sopenharmony_ci } 709bae44755Sopenharmony_ci priSyscapStr = ctx; 710bae44755Sopenharmony_ci return 0; 711bae44755Sopenharmony_ci} 712bae44755Sopenharmony_ci 713bae44755Sopenharmony_ciint32_t DecodeStringPCIDToJson(char *input, char *outDirPath) 714bae44755Sopenharmony_ci{ 715bae44755Sopenharmony_ci int32_t ret = -1; 716bae44755Sopenharmony_ci uint32_t osSyscap[OS_SYSCAP_NUM] = {0}; 717bae44755Sopenharmony_ci uint32_t pcidHeader[PCID_HEADER]; 718bae44755Sopenharmony_ci char *priSyscapStr = NULL; 719bae44755Sopenharmony_ci char *jsonBuffer = NULL; 720bae44755Sopenharmony_ci 721bae44755Sopenharmony_ci ret = GetSyscapStr(input, priSyscapStr, osSyscap, pcidHeader); 722bae44755Sopenharmony_ci if (ret == -1) { 723bae44755Sopenharmony_ci return ret; 724bae44755Sopenharmony_ci } 725bae44755Sopenharmony_ci 726bae44755Sopenharmony_ci // add to json object 727bae44755Sopenharmony_ci cJSON *sysCapObj = cJSON_CreateObject(); 728bae44755Sopenharmony_ci cJSON *rootObj = cJSON_CreateObject(); 729bae44755Sopenharmony_ci if (sysCapObj == NULL || rootObj == NULL) { 730bae44755Sopenharmony_ci PRINT_ERR("Failed to create cJSON objects.\n"); 731bae44755Sopenharmony_ci goto FAILED; 732bae44755Sopenharmony_ci } 733bae44755Sopenharmony_ci 734bae44755Sopenharmony_ci if (!cJSON_AddItemToObject(rootObj, "syscap", sysCapObj)) { 735bae44755Sopenharmony_ci PRINT_ERR("Add syscap to json failed.\n"); 736bae44755Sopenharmony_ci goto FAILED; 737bae44755Sopenharmony_ci } 738bae44755Sopenharmony_ci if (AddHeaderToJsonObj(pcidHeader, PCID_HEADER, rootObj) != 0) { 739bae44755Sopenharmony_ci PRINT_ERR("Add header to json object failed.\n"); 740bae44755Sopenharmony_ci goto FAILED; 741bae44755Sopenharmony_ci } 742bae44755Sopenharmony_ci if (AddOsSyscapToJsonObj(osSyscap, OS_SYSCAP_NUM, sysCapObj) != 0) { 743bae44755Sopenharmony_ci PRINT_ERR("Add os syscap json object failed.\n"); 744bae44755Sopenharmony_ci goto FAILED; 745bae44755Sopenharmony_ci } 746bae44755Sopenharmony_ci 747bae44755Sopenharmony_ci if (AddPriSyscapToJsonObj(priSyscapStr, (uint32_t) strlen(priSyscapStr), sysCapObj) != 0) { 748bae44755Sopenharmony_ci PRINT_ERR("Add private syscap json object failed.\n"); 749bae44755Sopenharmony_ci goto FAILED; 750bae44755Sopenharmony_ci } 751bae44755Sopenharmony_ci // save as json file 752bae44755Sopenharmony_ci jsonBuffer = cJSON_Print(rootObj); 753bae44755Sopenharmony_ci if (jsonBuffer == NULL) { 754bae44755Sopenharmony_ci PRINT_ERR("json buffer is null.\n"); 755bae44755Sopenharmony_ci goto FAILED; 756bae44755Sopenharmony_ci } 757bae44755Sopenharmony_ci const char outputFileName[] = "pcid.json"; 758bae44755Sopenharmony_ci if (ConvertedContextSaveAsFile(outDirPath, outputFileName, jsonBuffer, strlen(jsonBuffer)) != 0) { 759bae44755Sopenharmony_ci PRINT_ERR("Save as json file failed.\n"); 760bae44755Sopenharmony_ci goto FAILED; 761bae44755Sopenharmony_ci } 762bae44755Sopenharmony_ci ret = 0; 763bae44755Sopenharmony_ci 764bae44755Sopenharmony_ciFAILED: 765bae44755Sopenharmony_ci cJSON_free(jsonBuffer); 766bae44755Sopenharmony_ci SafeFree(priSyscapStr); 767bae44755Sopenharmony_ci cJSON_Delete(sysCapObj); 768bae44755Sopenharmony_ci cJSON_Delete(rootObj); 769bae44755Sopenharmony_ci return ret; 770bae44755Sopenharmony_ci} 771bae44755Sopenharmony_ci 772bae44755Sopenharmony_cistatic int32_t FreeAfterEncodePCID(struct FreeEncodePcidInfo freePcidInfo, int32_t type, int32_t ret) 773bae44755Sopenharmony_ci{ 774bae44755Sopenharmony_ci switch (type) { 775bae44755Sopenharmony_ci case FREE_ENCODE_PCID_OUT: 776bae44755Sopenharmony_ci free(freePcidInfo.output); 777bae44755Sopenharmony_ci free(freePcidInfo.priSyscapFull); 778bae44755Sopenharmony_ci free(freePcidInfo.contextBuffer); 779bae44755Sopenharmony_ci break; 780bae44755Sopenharmony_ci case FREE_ENCODE_PCID_PRISYSCAP_FULL_OUT: 781bae44755Sopenharmony_ci free(freePcidInfo.priSyscapFull); 782bae44755Sopenharmony_ci free(freePcidInfo.contextBuffer); 783bae44755Sopenharmony_ci break; 784bae44755Sopenharmony_ci case FREE_ENCODE_PCID_CONTEXT_OUT: 785bae44755Sopenharmony_ci default: 786bae44755Sopenharmony_ci free(freePcidInfo.contextBuffer); 787bae44755Sopenharmony_ci } 788bae44755Sopenharmony_ci return ret; 789bae44755Sopenharmony_ci} 790bae44755Sopenharmony_ci 791bae44755Sopenharmony_cistatic int32_t GetEncodePCIDOut(uint16_t priSyscapCount, uint32_t privateSyscapLen, uint32_t *mainSyscap, 792bae44755Sopenharmony_ci struct FreeEncodePcidInfo freePcidInfo, int32_t ret) 793bae44755Sopenharmony_ci{ 794bae44755Sopenharmony_ci // 17, size of "SystemCapability." 795bae44755Sopenharmony_ci uint32_t outputLen = U32_TO_STR_MAX_LEN * PCID_OUT_BUFFER + 17 * priSyscapCount + privateSyscapLen + 1; 796bae44755Sopenharmony_ci char *output = NULL; 797bae44755Sopenharmony_ci uint32_t i; 798bae44755Sopenharmony_ci output = (char *)malloc(outputLen); 799bae44755Sopenharmony_ci if (output == NULL) { 800bae44755Sopenharmony_ci PRINT_ERR("malloc failed\n"); 801bae44755Sopenharmony_ci return FreeAfterEncodePCID(freePcidInfo, FREE_ENCODE_PCID_PRISYSCAP_FULL_OUT, ret); 802bae44755Sopenharmony_ci } 803bae44755Sopenharmony_ci (void)memset_s(output, outputLen, 0, outputLen); 804bae44755Sopenharmony_ci ret = sprintf_s(output, outputLen, "%u", mainSyscap[0]); 805bae44755Sopenharmony_ci if (ret == -1) { 806bae44755Sopenharmony_ci PRINT_ERR("sprintf_s failed\n"); 807bae44755Sopenharmony_ci free(output); 808bae44755Sopenharmony_ci return FreeAfterEncodePCID(freePcidInfo, FREE_ENCODE_PCID_OUT, ret); 809bae44755Sopenharmony_ci } 810bae44755Sopenharmony_ci for (i = 1; i < PCID_OUT_BUFFER; i++) { 811bae44755Sopenharmony_ci ret = sprintf_s(output, outputLen, "%s,%u", output, mainSyscap[i]); 812bae44755Sopenharmony_ci if (ret == -1) { 813bae44755Sopenharmony_ci PRINT_ERR("sprintf_s failed\n"); 814bae44755Sopenharmony_ci free(output); 815bae44755Sopenharmony_ci return FreeAfterEncodePCID(freePcidInfo, FREE_ENCODE_PCID_OUT, ret); 816bae44755Sopenharmony_ci } 817bae44755Sopenharmony_ci } 818bae44755Sopenharmony_ci for (i = 0; i < priSyscapCount; i++) { 819bae44755Sopenharmony_ci ret = sprintf_s(output, outputLen, "%s,%s", output, freePcidInfo.priSyscapFull + i * SINGLE_SYSCAP_LEN); 820bae44755Sopenharmony_ci if (ret == -1) { 821bae44755Sopenharmony_ci PRINT_ERR("sprintf_s failed\n"); 822bae44755Sopenharmony_ci free(output); 823bae44755Sopenharmony_ci return FreeAfterEncodePCID(freePcidInfo, FREE_ENCODE_PCID_OUT, ret); 824bae44755Sopenharmony_ci } 825bae44755Sopenharmony_ci } 826bae44755Sopenharmony_ci // save as file 827bae44755Sopenharmony_ci const char outputFileName[] = "pcid.txt"; 828bae44755Sopenharmony_ci ret = ConvertedContextSaveAsFile(freePcidInfo.outDirPathFinal, outputFileName, output, strlen(output)); 829bae44755Sopenharmony_ci if (ret != 0) { 830bae44755Sopenharmony_ci PRINT_ERR("ConvertedContextSaveAsFile failed, outDirPath:%s, filename:%s\n", 831bae44755Sopenharmony_ci freePcidInfo.outDirPathFinal, outputFileName); 832bae44755Sopenharmony_ci } 833bae44755Sopenharmony_ci free(output); 834bae44755Sopenharmony_ci return FreeAfterEncodePCID(freePcidInfo, FREE_ENCODE_PCID_OUT, ret); 835bae44755Sopenharmony_ci} 836bae44755Sopenharmony_ci 837bae44755Sopenharmony_cistatic int32_t CheckPrivateSyCap(struct FreeEncodePcidInfo freePcidInfo, uint32_t privateSyscapLen, 838bae44755Sopenharmony_ci char *privateSyscap, int32_t ret) 839bae44755Sopenharmony_ci{ 840bae44755Sopenharmony_ci uint32_t i, j; 841bae44755Sopenharmony_ci char tempSyscap[SINGLE_SYSCAP_LEN] = {0}; 842bae44755Sopenharmony_ci char *temp = tempSyscap; 843bae44755Sopenharmony_ci for (i = 0, j = 0; i < privateSyscapLen; i++) { 844bae44755Sopenharmony_ci if (*privateSyscap == ',') { 845bae44755Sopenharmony_ci *temp = '\0'; 846bae44755Sopenharmony_ci ret = sprintf_s(freePcidInfo.priSyscapFull + j * SINGLE_SYSCAP_LEN, SINGLE_SYSCAP_LEN, 847bae44755Sopenharmony_ci "SystemCapability.%s", tempSyscap); 848bae44755Sopenharmony_ci if (ret == -1) { 849bae44755Sopenharmony_ci PRINT_ERR("sprintf_s failed\n"); 850bae44755Sopenharmony_ci return ret; 851bae44755Sopenharmony_ci } 852bae44755Sopenharmony_ci temp = tempSyscap; 853bae44755Sopenharmony_ci privateSyscap++; 854bae44755Sopenharmony_ci j++; 855bae44755Sopenharmony_ci continue; 856bae44755Sopenharmony_ci } 857bae44755Sopenharmony_ci *temp++ = *privateSyscap++; 858bae44755Sopenharmony_ci } 859bae44755Sopenharmony_ci return ret; 860bae44755Sopenharmony_ci} 861bae44755Sopenharmony_ci 862bae44755Sopenharmony_ciint32_t EncodePcidscToString(char *inputFile, char *outDirPath) 863bae44755Sopenharmony_ci{ 864bae44755Sopenharmony_ci int32_t ret = 0; 865bae44755Sopenharmony_ci uint32_t bufferLen, privateSyscapLen; 866bae44755Sopenharmony_ci uint32_t i; 867bae44755Sopenharmony_ci uint32_t *mainSyscap = NULL; 868bae44755Sopenharmony_ci uint16_t priSyscapCount = 0; 869bae44755Sopenharmony_ci 870bae44755Sopenharmony_ci char *privateSyscap = NULL; 871bae44755Sopenharmony_ci struct FreeEncodePcidInfo freePcidInfo; 872bae44755Sopenharmony_ci freePcidInfo.contextBuffer = NULL; 873bae44755Sopenharmony_ci freePcidInfo.priSyscapFull = NULL; 874bae44755Sopenharmony_ci freePcidInfo.output = NULL; 875bae44755Sopenharmony_ci freePcidInfo.outDirPathFinal = outDirPath; 876bae44755Sopenharmony_ci PCIDMain *pcidMain = NULL; 877bae44755Sopenharmony_ci 878bae44755Sopenharmony_ci ret = CheckFileAndGetFileContext(inputFile, &freePcidInfo.contextBuffer, (uint32_t *)&bufferLen); 879bae44755Sopenharmony_ci if (ret != 0) { 880bae44755Sopenharmony_ci return -1; 881bae44755Sopenharmony_ci } 882bae44755Sopenharmony_ci 883bae44755Sopenharmony_ci if (bufferLen > 1128) { // 1128, max size of pcid.sc 884bae44755Sopenharmony_ci PRINT_ERR("Input pcid file too large, pcid file size: %u\n", bufferLen); 885bae44755Sopenharmony_ci return FreeAfterEncodePCID(freePcidInfo, FREE_ENCODE_PCID_CONTEXT_OUT, ret); 886bae44755Sopenharmony_ci } 887bae44755Sopenharmony_ci 888bae44755Sopenharmony_ci pcidMain = (PCIDMain *)freePcidInfo.contextBuffer; 889bae44755Sopenharmony_ci privateSyscap = (char *)(pcidMain + 1); 890bae44755Sopenharmony_ci privateSyscapLen = strlen(privateSyscap); 891bae44755Sopenharmony_ci 892bae44755Sopenharmony_ci // process os syscap 893bae44755Sopenharmony_ci mainSyscap = (uint32_t *)pcidMain; 894bae44755Sopenharmony_ci 895bae44755Sopenharmony_ci // process private syscap 896bae44755Sopenharmony_ci for (i = 0; i < privateSyscapLen; i++) { 897bae44755Sopenharmony_ci if (privateSyscap[i] == ',') { 898bae44755Sopenharmony_ci priSyscapCount++; 899bae44755Sopenharmony_ci } 900bae44755Sopenharmony_ci } 901bae44755Sopenharmony_ci if (priSyscapCount == 0) { 902bae44755Sopenharmony_ci return GetEncodePCIDOut(priSyscapCount, privateSyscapLen, mainSyscap, freePcidInfo, ret); 903bae44755Sopenharmony_ci } 904bae44755Sopenharmony_ci freePcidInfo.priSyscapFull = (char *)malloc(priSyscapCount * SINGLE_SYSCAP_LEN); 905bae44755Sopenharmony_ci if (freePcidInfo.priSyscapFull == NULL) { 906bae44755Sopenharmony_ci PRINT_ERR("malloc failed\n"); 907bae44755Sopenharmony_ci return FreeAfterEncodePCID(freePcidInfo, FREE_ENCODE_PCID_CONTEXT_OUT, ret); 908bae44755Sopenharmony_ci } 909bae44755Sopenharmony_ci (void)memset_s(freePcidInfo.priSyscapFull, priSyscapCount * SINGLE_SYSCAP_LEN, 910bae44755Sopenharmony_ci 0, priSyscapCount * SINGLE_SYSCAP_LEN); 911bae44755Sopenharmony_ci 912bae44755Sopenharmony_ci ret = CheckPrivateSyCap(freePcidInfo, privateSyscapLen, privateSyscap, ret); 913bae44755Sopenharmony_ci if (ret == -1) { 914bae44755Sopenharmony_ci return FreeAfterEncodePCID(freePcidInfo, FREE_ENCODE_PCID_PRISYSCAP_FULL_OUT, ret); 915bae44755Sopenharmony_ci } 916bae44755Sopenharmony_ci 917bae44755Sopenharmony_ci // output 918bae44755Sopenharmony_ci return GetEncodePCIDOut(priSyscapCount, privateSyscapLen, mainSyscap, freePcidInfo, ret); 919bae44755Sopenharmony_ci}