1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "syscap_tool.h"
17
18 #include <arpa/inet.h>
19 #include <errno.h>
20 #include <securec.h>
21 #include <stdint.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <sys/stat.h>
25
26 #include "hilog/log_c.h"
27
28 const int32_t OK = 0;
29 const int32_t ERROR = -1;
30 const int32_t API_VERSION_TYPE = 1;
31 const int32_t APP_SYSCAP_TYPE = 2;
32 const int32_t SYSCAP_PREFIX_NAME_LEN = 18;
33 const char SYSCAP_PREFIX_NAME[] = "SystemCapability.";
34
35 typedef struct RequiredProductCompatibilityIDHead {
36 uint16_t apiVersion : 15;
37 uint16_t apiVersionType : 1;
38 } RPCIDHead;
39
RPCIDStreamDecodeToBuffer(char * contextBuffer,uint32_t bufferLen,char ** syscapSetBuf,uint32_t * syscapSetLength)40 int32_t RPCIDStreamDecodeToBuffer(
41 char *contextBuffer, uint32_t bufferLen, char **syscapSetBuf, uint32_t *syscapSetLength)
42 {
43 char *contextBufferTail = NULL;
44 char *syscapBuf = NULL;
45 uint32_t syscapBufLen;
46 uint16_t sysCaptype;
47 uint16_t sysCapLength;
48 RPCIDHead *headPtr = NULL;
49 char *sysCapArrayPtr = NULL;
50 *syscapSetBuf = NULL;
51 *syscapSetLength = 0;
52 if (contextBuffer == NULL) {
53 HILOG_ERROR(LOG_CORE, "input buffer is NULL\n");
54 return ERROR;
55 }
56
57 contextBufferTail = contextBuffer + bufferLen;
58 sysCapArrayPtr = contextBuffer + sizeof(RPCIDHead) + APP_SYSCAP_TYPE * sizeof(uint16_t);
59 if (contextBufferTail <= sysCapArrayPtr) {
60 HILOG_ERROR(LOG_CORE, "format error:sysCapArray head over to buffer\n");
61 return ERROR;
62 }
63
64 headPtr = (RPCIDHead *)contextBuffer;
65 if (headPtr->apiVersionType != API_VERSION_TYPE) {
66 HILOG_ERROR(LOG_CORE, "format error:apiVersionType is invaild\n");
67 return ERROR;
68 }
69
70 sysCaptype = ntohs(*(uint16_t *)(sysCapArrayPtr - APP_SYSCAP_TYPE * sizeof(uint16_t)));
71 if (sysCaptype != APP_SYSCAP_TYPE) {
72 HILOG_ERROR(LOG_CORE, "format error:sysCaptype is invaild\n");
73 return ERROR;
74 }
75
76 sysCapLength = ntohs(*(uint16_t *)(sysCapArrayPtr - sizeof(uint16_t)));
77 if (contextBufferTail < sysCapArrayPtr + sysCapLength) {
78 HILOG_ERROR(LOG_CORE, "format error:sysCapArray tail over to buffer\n");
79 return ERROR;
80 }
81
82 if ((sysCapLength % SINGLE_FEAT_LENGTH) != 0) {
83 HILOG_ERROR(LOG_CORE, "format error:sysCapLength is invalid\n");
84 return ERROR;
85 }
86
87 syscapBufLen = sysCapLength / SINGLE_FEAT_LENGTH * SINGLE_SYSCAP_LENGTH;
88 syscapBuf = (char *)malloc(syscapBufLen);
89 if (syscapBuf == NULL) {
90 HILOG_ERROR(LOG_CORE, "malloc syscapBuf failed, size = %u, errno = %d\n", syscapBufLen, errno);
91 return ERROR;
92 }
93
94 (void)memset_s(syscapBuf, syscapBufLen, 0, syscapBufLen);
95 char *bufferPtr = syscapBuf;
96 for (int32_t i = 0; i < ((int32_t)sysCapLength / SINGLE_FEAT_LENGTH); i++) {
97 if (*(sysCapArrayPtr + (i + 1) * SINGLE_FEAT_LENGTH - 1) != '\0') {
98 HILOG_ERROR(LOG_CORE, "prase failed, format is invaild, in line %d\n", __LINE__);
99 (void)free(syscapBuf);
100 return ERROR;
101 }
102
103 errno_t ret = memcpy_s(bufferPtr, SINGLE_SYSCAP_LENGTH, SYSCAP_PREFIX_NAME, SYSCAP_PREFIX_NAME_LEN);
104 if (ret != EOK) {
105 HILOG_ERROR(LOG_CORE, "context of \"os\" array is invaild\n");
106 (void)free(syscapBuf);
107 return ERROR;
108 }
109
110 ret = strncat_s(bufferPtr, SINGLE_SYSCAP_LENGTH, sysCapArrayPtr + i * SINGLE_FEAT_LENGTH, SINGLE_FEAT_LENGTH);
111 if (ret != EOK) {
112 HILOG_ERROR(LOG_CORE, "strncat_s failed, (%s, %d, %s, %d)\n", bufferPtr, SINGLE_SYSCAP_LENGTH,
113 sysCapArrayPtr + i * SINGLE_FEAT_LENGTH, SINGLE_FEAT_LENGTH);
114 (void)free(syscapBuf);
115 return ERROR;
116 }
117
118 bufferPtr += SINGLE_SYSCAP_LENGTH;
119 }
120
121 *syscapSetBuf = syscapBuf;
122 *syscapSetLength = syscapBufLen;
123 return OK;
124 }