1 /*
2 * Copyright (C) 2021 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 "version_util.h"
17 #include "hc_log.h"
18 #include "hc_types.h"
19 #include "protocol_common.h"
20 #include "string_util.h"
21
GetSlice(char * str,char delim,int * nextIdx)22 static const char *GetSlice(char *str, char delim, int *nextIdx)
23 {
24 uint32_t len = HcStrlen(str);
25 for (uint32_t i = 0; i < len; i++) {
26 if (str[i] == delim) {
27 *nextIdx = *nextIdx + i + 1;
28 str[i] = '\0';
29 return str;
30 }
31 }
32 return str;
33 }
34
StringToVersion(const char * verStr,VersionStruct * version)35 int32_t StringToVersion(const char* verStr, VersionStruct* version)
36 {
37 CHECK_PTR_RETURN_ERROR_CODE(version, "version");
38 CHECK_PTR_RETURN_ERROR_CODE(verStr, "verStr");
39
40 const char *subVer = NULL;
41 int nextIdx = 0;
42
43 uint32_t len = HcStrlen(verStr);
44 char *verStrTmp = (char *)HcMalloc(len + 1, 0);
45 if (verStrTmp == NULL) {
46 LOGE("Malloc for verStrTmp failed.");
47 return HC_ERR_ALLOC_MEMORY;
48 }
49 if (memcpy_s(verStrTmp, len + 1, verStr, len) != EOK) {
50 LOGE("Memcpy for verStrTmp failed.");
51 HcFree(verStrTmp);
52 return HC_ERR_MEMORY_COPY;
53 }
54
55 subVer = GetSlice(verStrTmp, '.', &nextIdx);
56 if (subVer == NULL) {
57 goto CLEAN_UP;
58 }
59 version->first = (uint32_t)strtoul(subVer, NULL, DEC);
60
61 subVer = GetSlice(verStrTmp + nextIdx, '.', &nextIdx);
62 if (subVer == NULL) {
63 goto CLEAN_UP;
64 }
65 version->second = (uint32_t)strtoul(subVer, NULL, DEC);
66
67 subVer = GetSlice(verStrTmp + nextIdx, '.', &nextIdx);
68 if (subVer == NULL) {
69 goto CLEAN_UP;
70 }
71 version->third = (uint32_t)strtoul(subVer, NULL, DEC);
72
73 HcFree(verStrTmp);
74 return HC_SUCCESS;
75 CLEAN_UP:
76 LOGE("GetSlice failed.");
77 HcFree(verStrTmp);
78 return HC_ERROR;
79 }
80
VersionToString(const VersionStruct * version,char * verStr,uint32_t len)81 int32_t VersionToString(const VersionStruct *version, char *verStr, uint32_t len)
82 {
83 CHECK_PTR_RETURN_ERROR_CODE(version, "version");
84 CHECK_PTR_RETURN_ERROR_CODE(verStr, "verStr");
85
86 char tmpStr[TMP_VERSION_STR_LEN] = { 0 };
87 if (sprintf_s(tmpStr, TMP_VERSION_STR_LEN, "%u.%u.%u", version->first, version->second, version->third) <= 0) {
88 LOGE("Convert version struct to string failed.");
89 return HC_ERR_CONVERT_FAILED;
90 }
91 uint32_t tmpStrLen = HcStrlen(tmpStr);
92 if (len < tmpStrLen + 1) {
93 LOGE("The length of verStr is too short, len: %u.", len);
94 return HC_ERR_INVALID_LEN;
95 }
96
97 if (memcpy_s(verStr, len, tmpStr, tmpStrLen + 1) != 0) {
98 LOGE("Memcpy for verStr failed.");
99 return HC_ERR_MEMORY_COPY;
100 }
101
102 return HC_SUCCESS;
103 }
104
AddSingleVersionToJson(CJson * jsonObj,const VersionStruct * version)105 int32_t AddSingleVersionToJson(CJson *jsonObj, const VersionStruct *version)
106 {
107 CHECK_PTR_RETURN_ERROR_CODE(jsonObj, "jsonObj");
108 CHECK_PTR_RETURN_ERROR_CODE(version, "version");
109
110 char versionStr[TMP_VERSION_STR_LEN] = { 0 };
111 int32_t ret = VersionToString(version, versionStr, TMP_VERSION_STR_LEN);
112 if (ret != HC_SUCCESS) {
113 LOGE("VersionToString failed, res: %x.", ret);
114 return ret;
115 }
116
117 CJson *sendToPeer = GetObjFromJson(jsonObj, FIELD_SEND_TO_PEER);
118 if (sendToPeer == NULL) {
119 LOGD("There is not sendToPeer in json.");
120 return HC_SUCCESS;
121 }
122 if (AddStringToJson(sendToPeer, FIELD_GROUP_AND_MODULE_VERSION, versionStr) != HC_SUCCESS) {
123 LOGE("Add group and module version to sendToPeer failed.");
124 return HC_ERR_JSON_ADD;
125 }
126 return HC_SUCCESS;
127 }
128
GetSingleVersionFromJson(const CJson * jsonObj,VersionStruct * version)129 int32_t GetSingleVersionFromJson(const CJson* jsonObj, VersionStruct *version)
130 {
131 CHECK_PTR_RETURN_ERROR_CODE(jsonObj, "jsonObj");
132 CHECK_PTR_RETURN_ERROR_CODE(version, "version");
133
134 const char *versionStr = GetStringFromJson(jsonObj, FIELD_GROUP_AND_MODULE_VERSION);
135 if (versionStr == NULL) {
136 LOGE("Get group and module version from json failed.");
137 return HC_ERR_JSON_GET;
138 }
139
140 int32_t ret = StringToVersion(versionStr, version);
141 if (ret != HC_SUCCESS) {
142 LOGE("StringToVersion failed, res: %x.", ret);
143 return ret;
144 }
145 return HC_SUCCESS;
146 }
147
InitGroupAndModuleVersion(VersionStruct * version)148 void InitGroupAndModuleVersion(VersionStruct *version)
149 {
150 if (version == NULL) {
151 LOGE("Version is null.");
152 return;
153 }
154 version->first = MAJOR_VERSION_NO;
155 version->second = 0;
156 version->third = 0;
157 }