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