• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }