From d392b91fc8b11b6fef5e13cd8c12503f5d2f2b23 Mon Sep 17 00:00:00 2001 From: yudechen Date: Thu, 2 Jun 2022 17:05:24 +0800 Subject: [PATCH] add function to compare pcid with rpcid string format. Signed-off-by: yudechen Change-Id: Ia9d19e20f2856a89240fadc931626a931dcdf6cb --- include/create_pcid.h | 8 +++ include/syscap_tool.h | 2 + src/create_pcid.c | 9 +--- src/main.c | 37 ++++++++----- src/syscap_tool.c | 118 +++++++++++++++++++++++++++++++++++++++++- 5 files changed, 151 insertions(+), 23 deletions(-) diff --git a/include/create_pcid.h b/include/create_pcid.h index e3661dd..748e7f1 100644 --- a/include/create_pcid.h +++ b/include/create_pcid.h @@ -31,6 +31,14 @@ typedef struct ProductCompatibilityID { uint8_t osSyscap[MAX_OS_SYSCAP_NUM / 8]; } PCIDMain; +typedef struct pcidHeader { + uint16_t apiVersion : 15; + uint16_t apiVersionType : 1; + uint16_t systemType : 3; + uint16_t reserved : 13; + uint32_t manufacturerID; +} PCIDHeader; + int32_t CreatePCID(char *inputFile, char *outDirPath); int32_t DecodePCID(char *inputFile, char *outDirPath); int32_t DecodeStringPCID(char *input, char *outDirPath, int type); diff --git a/include/syscap_tool.h b/include/syscap_tool.h index 68850ec..1baa22d 100644 --- a/include/syscap_tool.h +++ b/include/syscap_tool.h @@ -34,6 +34,8 @@ int32_t RPCIDEncode(char *inputFile, char *outputPath); int32_t RPCIDDecode(char *inputFile, char *outputPath); /* in: inputFile, out: outputPath/rpcid.json */ int32_t DecodeRpcidToString(char *inputFile, char *outDirPath); +/* in: pcidFile, rpcidFile */ +int32_t ComparePcidWithRpcidString(char *pcidFile, char *rpcidFile); #ifdef __cplusplus #if __cplusplus diff --git a/src/create_pcid.c b/src/create_pcid.c index 35f20bc..7792911 100644 --- a/src/create_pcid.c +++ b/src/create_pcid.c @@ -548,13 +548,6 @@ static int32_t AddHeaderToJsonObj(uint32_t *pcidHeader, uint32_t pcidHeaderLen, PRINT_ERR("input pcidHeader(%u) error.\n", pcidHeaderLen); return -1; } - typedef struct pcidHeader { - uint16_t apiVersion : 15; - uint16_t apiVersionType : 1; - uint16_t systemType : 3; - uint16_t reserved : 13; - uint32_t manufacturerID; - } PCIDHeader; PCIDHeader *header = (PCIDHeader *)pcidHeader; // trans system type to string @@ -709,7 +702,7 @@ int32_t DecodeStringPCID(char *input, char *outDirPath, int type) } // save as json file char *jsonBuffer = cJSON_Print(rootObj); - const char outputFileName[] = "syscap.json"; + const char outputFileName[] = "PCID.json"; if (ConvertedContextSaveAsFile(outDirPath, outputFileName, jsonBuffer, strlen(jsonBuffer))) { PRINT_ERR("Save as json file failed.\n"); goto SAVE_FAILED; diff --git a/src/main.c b/src/main.c index beb9a8f..8c90f92 100644 --- a/src/main.c +++ b/src/main.c @@ -40,6 +40,8 @@ int main(int argc, char **argv) int32_t help = 0; char curpath[PATH_MAX] = {0}; char *inputfile = NULL; + char *pcidfile = NULL; + char *rpcidfile = NULL; char *outputpath = getcwd(curpath, sizeof(curpath)); while (1) { @@ -47,15 +49,16 @@ int main(int argc, char **argv) {"help", no_argument, 0, 'h' }, {"RPCID", no_argument, 0, 'R' }, {"PCID", no_argument, 0, 'P' }, + {"compare", required_argument, 0, 'C' }, {"encode", no_argument, 0, 'e' }, {"decode", no_argument, 0, 'd' }, - {"string-decode", no_argument, 0, 's' }, + {"string", no_argument, 0, 's' }, {"input", required_argument, 0, 'i' }, {"output", required_argument, 0, 'o' }, {0, 0, 0, 0 } }; - int32_t flag = getopt_long(argc, argv, "hRPedsi:o:", long_options, &optIndex); + int32_t flag = getopt_long(argc, argv, "hRPC:edsi:o:", long_options, &optIndex); if (flag == -1) { break; } @@ -75,6 +78,10 @@ int main(int argc, char **argv) case 'P': pcid = 1; break; + case 'C': + pcidfile = optarg; + rpcidfile = argv[optind]; + break; case 'i': inputfile = optarg; break; @@ -87,28 +94,30 @@ int main(int argc, char **argv) } } - if (rpcid && !pcid && encode && !decode && inputfile && !help) { + if (rpcid && !pcid && encode && !decode && inputfile && !stringDecode && !help) { ret = RPCIDEncode(inputfile, outputpath); } else if (rpcid && !pcid && !encode && decode && !stringDecode && inputfile && !help) { ret = RPCIDDecode(inputfile, outputpath); } else if (rpcid && !pcid && !encode && decode && stringDecode && inputfile && !help) { ret = DecodeRpcidToString(inputfile, outputpath); - } else if (!rpcid && pcid && encode && !decode && inputfile && !help) { + } else if (!rpcid && !pcid && !encode && !decode && !stringDecode && pcidfile && rpcidfile && !inputfile && !help) { + ret = ComparePcidWithRpcidString(pcidfile, rpcidfile); + } else if (!rpcid && pcid && encode && !decode && inputfile && !stringDecode && !help) { ret = CreatePCID(inputfile, outputpath); - } else if (!rpcid && pcid && !encode && decode && inputfile && !help) { + } else if (!rpcid && pcid && !encode && decode && inputfile && !stringDecode && !help) { ret = DecodePCID(inputfile, outputpath); - } else if (!rpcid && !pcid && !encode && !decode && stringDecode && inputfile && !help) { + } else if (!rpcid && pcid && !encode && decode && stringDecode && inputfile && !help) { ret = DecodeStringPCID(inputfile, outputpath, TYPE_FILE); } else { printf("syscap_tool -R/P -e/d -i filepath [-o outpath]\n"); - printf("-h, --help : how to use\n"); - printf("-R, --RPCID : encode or decode RPCID\n"); - printf("-P, --PCID : encode or decode PCID\n"); - printf("-e, --encode : to encode\n"); - printf("-d, --encode : to decode\n"); - printf("-s, --string-decode : decode string pcid to json\n"); - printf("-i filepath, --input filepath : input file\n"); - printf("-o outpath, --input outpath : output path\n"); + printf("-h, --help\t: how to use\n"); + printf("-R, --RPCID\t: encode or decode RPCID\n"); + printf("-P, --PCID\t: encode or decode PCID\n"); + printf("-C, --compare\t: compare pcid with rpcid string format.\n"); + printf("-e, --encode\t: decode to sc format.\n"); + printf("-d, --encode\t: decode to json format.\n\t-s, --string : decode (to) string format.\n"); + printf("-i filepath, --input filepath\t: input file\n"); + printf("-o outpath, --input outpath\t: output path\n"); exit(0); } diff --git a/src/syscap_tool.c b/src/syscap_tool.c index fc22955..f1f791b 100644 --- a/src/syscap_tool.c +++ b/src/syscap_tool.c @@ -27,6 +27,7 @@ #include "endian_internal.h" #include "cJSON.h" #include "syscap_define.h" +#include "create_pcid.h" #include "syscap_tool.h" typedef struct ProductCompatibilityIDHead { @@ -44,13 +45,15 @@ typedef struct RequiredProductCompatibilityIDHead { #define SINGLE_FEAT_LENGTH 128 #define UINT8_BIT 8 +#define INT_BIT 32 #define RPCID_OUT_BUFFER 32 +#define PCID_OUT_BUFFER RPCID_OUT_BUFFER #define BYTES_OF_OS_SYSCAP 120 #define U32_TO_STR_MAX_LEN 11 #define PRINT_ERR(...) \ do { \ - printf("ERROR: in file %s at line %d -> ", __FILE__, __LINE__); \ + printf("ERROR: [%s: %d] -> ", __FILE__, __LINE__); \ printf(__VA_ARGS__); \ } while (0) @@ -557,4 +560,117 @@ FREE_RPCID_ROOT: FREE_CONTEXT_OUT: FreeContextBuffer(contextBuffer); return ret; +} + +static int32_t SeparateSyscapFromString(char *input, uint32_t *osArray, uint32_t osArraySize, + char **priSyscap, uint32_t *priSyscapLen) +{ + int32_t ret = 0; + uint32_t i, inputLen; + uint32_t count = 0; + char *temp = NULL; + char *tok = NULL; + char *private = NULL; + + if (osArraySize != PCID_OUT_BUFFER) { + return -1; + } + + inputLen = strlen(input); + for (i = 0; i < PCID_OUT_BUFFER; i++) { + ret = sscanf_s(input, "%u,%s", &osArray[i], input, inputLen); + if (ret == -1) { + PRINT_ERR("sscanf_s failed.\n"); + return -1; + } + } + + // count private syscap + if (*input == '\0') { + *priSyscap = 0; + *priSyscapLen = 0; + goto SKIP_PRI_SYSCAP; + } + for (i = 0; *(input + i) != '\0'; i++) { + if (*(input + i) == ',') { + count++; + } + } + count++; + // get private syscap string + char *priSysCapOut = (char *)malloc(SINGLE_FEAT_LENGTH * count); + if (priSysCapOut == NULL) { + PRINT_ERR("sscanf_s failed.\n"); + return -1; + } + (void)memset_s(priSysCapOut, SINGLE_FEAT_LENGTH * count, 0, SINGLE_FEAT_LENGTH * count); + private = priSysCapOut; + + temp = strtok_r(input, ",", &tok); + while (temp) { + ret = strncpy_s(priSysCapOut, SINGLE_FEAT_LENGTH * count, + temp, SINGLE_FEAT_LENGTH - 1); + if (ret != EOK) { + PRINT_ERR("strncpy_s failed.\n"); + free(priSysCapOut); + return -1; + } + temp = strtok_r(NULL, ",", &tok); + priSysCapOut += SINGLE_FEAT_LENGTH; + } + + *priSyscap = private; + *priSyscapLen = count; + +SKIP_PRI_SYSCAP: + return ret; +} + +int32_t ComparePcidWithRpcidString(char *pcidFile, char *rpcidFile) +{ + int32_t ret = 0; + char *pcidContent = NULL; + char *rpcidContent = NULL; + char *pcidPriSyscap = NULL; + char *rpcidPriSyscap = NULL; + uint32_t pcidContentLen, rpcidContentLen, pcidPriSyscapLen, rpcidPriSyscapLen, i; + uint32_t pcidOsAarry[PCID_OUT_BUFFER] = {0}; + uint32_t rpcidOsAarry[PCID_OUT_BUFFER] = {0}; + + if (GetFileContext(pcidFile, &pcidContent, &pcidContentLen)) { + PRINT_ERR("Get pcid file context failed, input file : %s\n", pcidFile); + return -1; + } + + if (GetFileContext(rpcidFile, &rpcidContent, &rpcidContentLen)) { + PRINT_ERR("Get rpcid file context failed, input file : %s\n", rpcidFile); + free(pcidContent); + return -1; + } + + SeparateSyscapFromString(pcidContent, pcidOsAarry, PCID_OUT_BUFFER, + &pcidPriSyscap, &pcidPriSyscapLen); + SeparateSyscapFromString(rpcidContent, rpcidOsAarry, RPCID_OUT_BUFFER, + &rpcidPriSyscap, &rpcidPriSyscapLen); + // compare version + uint16_t pcidVersion = NtohsInter(((PCIDMain *)pcidOsAarry)->apiVersion); + uint16_t rpcidVersion = NtohsInter(((RPCIDHead *)rpcidOsAarry)->apiVersion); + if (pcidVersion < rpcidVersion) { + PRINT_ERR("Pcid version(%u) less than rpcid version(%u).\n", pcidVersion, rpcidVersion); + } + // compare os sysscap + for (i = 2; i < PCID_OUT_BUFFER; i++) { // 2, header of pcid & rpcid + uint32_t temp1 = pcidOsAarry[i] ^ rpcidOsAarry[i]; + uint32_t temp2 = temp1 & rpcidOsAarry[i]; + if (!temp2) { + continue; + } + for (uint8_t j = 0; j < INT_BIT; j++) { + if (temp2 & (0x1 << j)) { + // 2, header of pcid & rpcid + printf("Miss: %s\n", arraySyscap[(i - 2) * INT_BIT + j].syscapStr); + } + } + } + return ret; } \ No newline at end of file -- Gitee