1 /*
2  * Copyright (c) 2023 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 "message_handler.h"
17 
18 #include <endian.h>
19 #include <securec.h>
20 
21 #include "utils_log.h"
22 
23 namespace OHOS::FileManagement::CloudSync {
24 using namespace std;
25 constexpr uint8_t MSG_MAGIC = 0xF8;
26 constexpr uint8_t VERSION = 0x1;
27 constexpr int8_t ALIGN_WIDH = 8;
MessageHandler(MessageInputInfo & info)28 MessageHandler::MessageHandler(MessageInputInfo &info)
29     : srcNetworkId_(info.srcNetworkId),
30       dstNetworkId_(info.dstNetworkId),
31       uri_(info.uri),
32       userId_(info.userId),
33       taskId_(info.taskId)
34 {
35     msgHdr_.msgType = info.msgType;
36     msgHdr_.errorCode = info.errorCode;
37     auto totalSize = sizeof(MessageHeader) + sizeof(SessionDeviceInfo) + sizeof(UserData) + uri_.size();
38     dataSize_ = GET_ALIGNED_SIZE(totalSize, ALIGN_WIDH);
39 }
40 
PackData(uint8_t * data,uint32_t totalLen)41 bool MessageHandler::PackData(uint8_t *data, uint32_t totalLen)
42 {
43     if (!data || totalLen < dataSize_) {
44         LOGE("Invalid param, totalLen:%{public}d, dataSize:%{public}d", totalLen, dataSize_);
45         return false;
46     }
47 
48     uint8_t *ptr = data;
49     MessageHeader *head = reinterpret_cast<MessageHeader *>(ptr);
50     head->magic = MSG_MAGIC;
51     head->version = VERSION;
52     head->msgType = htole16(msgHdr_.msgType);
53     head->dataLen = htole32(totalLen - sizeof(MessageHeader));
54     head->errorCode = static_cast<int32_t>(htole32(msgHdr_.errorCode));
55 
56     ptr += sizeof(MessageHeader);
57     SessionDeviceInfo *deviceInfo = reinterpret_cast<SessionDeviceInfo *>(ptr);
58     auto ret = strcpy_s(deviceInfo->sourceNetworkId, NETWORK_ID_SIZE_MAX, srcNetworkId_.c_str());
59     if (ret != 0) {
60         LOGE("strcpy for source device id failed, ret is %{public}d", ret);
61         return false;
62     }
63 
64     ret = strcpy_s(deviceInfo->tartgeNetworkId, NETWORK_ID_SIZE_MAX, dstNetworkId_.c_str());
65     if (ret != 0) {
66         LOGE("strcpy for source device id failed, ret is %{public}d", ret);
67         return false;
68     }
69 
70     ptr += sizeof(SessionDeviceInfo);
71     UserData *userData = reinterpret_cast<UserData *>(ptr);
72     userData->taskId = htole64(taskId_);
73     userData->userId = htole32(userId_);
74     userData->uriLen = htole32(uri_.size()); // not include '\0'
75     ptr += sizeof(UserData);
76 
77     uint8_t *end = data + totalLen;
78     ret = memcpy_s(userData->uri, end - ptr, uri_.c_str(), uri_.size());
79     if (ret != 0) {
80         LOGE("memcpy failed, error:%{public}d", errno);
81         return false;
82     }
83     return true;
84 }
85 
UnPackData(uint8_t * data,uint32_t totalLen)86 bool MessageHandler::UnPackData(uint8_t *data, uint32_t totalLen)
87 {
88     if (!data || totalLen < sizeof(MessageHeader)) {
89         LOGE("invalid input data, totalLen:%{public}d", totalLen);
90         return false;
91     }
92 
93     uint8_t *ptr = data;
94     uint32_t leftSize = totalLen;
95     MessageHeader *head = reinterpret_cast<MessageHeader *>(ptr);
96     msgHdr_.magic = head->magic;
97     msgHdr_.version = head->version;
98     msgHdr_.msgType = le16toh(head->msgType);
99     msgHdr_.dataLen = le32toh(head->dataLen);
100     msgHdr_.errorCode = static_cast<int32_t>(le32toh(head->errorCode));
101     if (msgHdr_.magic != MSG_MAGIC) {
102         LOGE("not valid data");
103         return false;
104     }
105 
106     leftSize -= sizeof(MessageHeader);
107     if (leftSize < sizeof(SessionDeviceInfo)) {
108         LOGE("failed to parse sessionDeviceInfo, leftsize:%{public}d", leftSize);
109         return false;
110     }
111     ptr += sizeof(MessageHeader);
112     SessionDeviceInfo *deviceInfo = reinterpret_cast<SessionDeviceInfo *>(ptr);
113     srcNetworkId_ = string(deviceInfo->sourceNetworkId, strnlen(deviceInfo->sourceNetworkId, NETWORK_ID_SIZE_MAX));
114     dstNetworkId_ = string(deviceInfo->tartgeNetworkId, strnlen(deviceInfo->tartgeNetworkId, NETWORK_ID_SIZE_MAX));
115 
116     leftSize -= sizeof(SessionDeviceInfo);
117     if (leftSize < sizeof(UserData)) {
118         LOGE("failed to parse UserData, leftsize:%{public}d", leftSize);
119         return false;
120     }
121     ptr += sizeof(SessionDeviceInfo);
122     UserData *userData = reinterpret_cast<UserData *>(ptr);
123     taskId_ = le64toh(userData->taskId);
124     userId_ = static_cast<int32_t>(le32toh(userData->userId));
125     auto uriLen = userData->uriLen;
126     if (uriLen > PATH_MAX) {
127         LOGE("exception uriLen:%{public}d", uriLen);
128         return false;
129     }
130     uri_ = string(userData->uri, uriLen);
131     return true;
132 }
133 
GetDataSize()134 uint32_t MessageHandler::GetDataSize()
135 {
136     return dataSize_;
137 }
138 
GetMessageHeader(MessageHeader & header)139 void MessageHandler::GetMessageHeader(MessageHeader &header)
140 {
141     header = msgHdr_;
142 }
GetTaskId()143 uint64_t MessageHandler::GetTaskId()
144 {
145     return taskId_;
146 }
147 
GetUserId()148 int32_t MessageHandler::GetUserId()
149 {
150     return userId_;
151 }
152 
GetUri()153 std::string MessageHandler::GetUri()
154 {
155     return uri_;
156 }
157 
GetSrcNetworkId()158 std::string MessageHandler::GetSrcNetworkId()
159 {
160     return srcNetworkId_;
161 }
162 
GetDstNetworkId()163 std::string MessageHandler::GetDstNetworkId()
164 {
165     return dstNetworkId_;
166 }
167 
GetMsgType()168 uint16_t MessageHandler::GetMsgType()
169 {
170     return msgHdr_.msgType;
171 }
172 
GetErrorCode()173 int32_t MessageHandler::GetErrorCode()
174 {
175     return msgHdr_.errorCode;
176 }
177 } // namespace OHOS::FileManagement::CloudSync