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#include <iostream>
16#include <cstring>
17#include "ffi_utils.h"
18#include "serial_struct.h"
19
20namespace Hdc {
21
22char *StringToHeapPtr(const std::string &input)
23{
24    size_t buf_size = input.length() + 1;
25    char *bufRet = (char *)malloc(buf_size);
26    if (bufRet == nullptr) {
27        return bufRet;
28    }
29    (void)memset_s(bufRet, buf_size, 0, buf_size);
30    (void)memcpy_s(bufRet, buf_size, input.c_str(), buf_size);
31    return bufRet;
32}
33
34extern "C" SerializedBuffer SerializeSessionHandShake(const RustStruct::SessionHandShake &value)
35{
36    BaseStruct::SessionHandShake shs = {
37        .banner = string(value.banner),
38        .authType = value.authType,
39        .sessionId = value.sessionId,
40        .connectKey = string(value.connectKey),
41        .buf = string(value.buf),
42        .version = string(value.version)
43    };
44    string serialized = Hdc::SerialStruct::SerializeToString(shs);
45    size_t len = serialized.length();
46    char *ptr = StringToHeapPtr(serialized);
47    return SerializedBuffer{ptr, len};
48}
49
50extern "C" SerializedBuffer SerializePayloadProtect(const RustStruct::PayloadProtect &value)
51{
52    BaseStruct::PayloadProtect pp = {
53        .channelId = value.channelId,
54        .commandFlag = value.commandFlag,
55        .checkSum = value.checkSum,
56        .vCode = value.vCode
57    };
58    string serialized = Hdc::SerialStruct::SerializeToString(pp);
59    size_t len = serialized.length();
60    char *ptr = StringToHeapPtr(serialized);
61    return SerializedBuffer{ptr, len};
62}
63
64extern "C" SerializedBuffer SerializeTransferConfig(const RustStruct::TransferConfig &value)
65{
66    BaseStruct::TransferConfig tc = {
67        .fileSize = value.fileSize,
68        .atime = value.atime,
69        .mtime = value.mtime,
70        .options = string(value.options),
71        .path = string(value.path),
72        .optionalName = string(value.optionalName),
73        .updateIfNew = static_cast<bool>(value.updateIfNew),
74        .compressType = value.compressType,
75        .holdTimestamp = static_cast<bool>(value.holdTimestamp),
76        .functionName = string(value.functionName),
77        .clientCwd = string(value.clientCwd),
78        .reserve1 = string(value.reserve1),
79        .reserve2 = string(value.reserve2)
80    };
81    string serialized = Hdc::SerialStruct::SerializeToString(tc);
82    size_t len = serialized.length();
83    char *ptr = StringToHeapPtr(serialized);
84    return SerializedBuffer{ptr, len};
85}
86
87extern "C" SerializedBuffer SerializeFileMode(const RustStruct::FileMode &value)
88{
89    BaseStruct::FileMode fm = {
90        .perm = value.perm,
91        .u_id = value.u_id,
92        .g_id = value.g_id,
93        .context = string(value.context),
94        .fullName = string(value.context)
95    };
96    string serialized = Hdc::SerialStruct::SerializeToString(fm);
97    size_t len = serialized.length();
98    char *ptr = StringToHeapPtr(serialized);
99    return SerializedBuffer{ptr, len};
100}
101
102extern "C" SerializedBuffer SerializeTransferPayload(const RustStruct::TransferPayload &value)
103{
104    BaseStruct::TransferPayload tp = {
105        .index = value.index,
106        .compressType = value.compressType,
107        .compressSize = value.compressSize,
108        .uncompressSize = value.uncompressSize
109    };
110    string serialized = Hdc::SerialStruct::SerializeToString(tp);
111    size_t len = serialized.length();
112    char *ptr = StringToHeapPtr(serialized);
113    return SerializedBuffer{ptr, len};
114}
115
116extern "C" SerializedBuffer SerializePayloadHead(RustStruct::PayloadHead &value)
117{
118    size_t len = sizeof(value);
119    char *ptr = (char *)malloc(len);
120    if (ptr == nullptr) {
121        return SerializedBuffer{ptr, len};
122    }
123    (void)memcpy_s(ptr, len, reinterpret_cast<char *>(&value), len);
124    return SerializedBuffer{ptr, len};
125}
126
127extern "C" SerializedBuffer SerializeUsbHead(RustStruct::USBHead &value)
128{
129    size_t len = sizeof(value);
130    char *ptr = (char *)malloc(len);
131    if (ptr == nullptr) {
132        return SerializedBuffer{ptr, len};
133    }
134    (void)memcpy_s(ptr, len, reinterpret_cast<char *>(&value), len);
135    return SerializedBuffer{ptr, len};
136}
137
138extern "C" SerializedBuffer SerializeUartHead(RustStruct::UartHead &value)
139{
140    size_t len = sizeof(value);
141    char *ptr = (char *)malloc(len);
142    if (ptr == nullptr) {
143        return SerializedBuffer{ptr, len};
144    }
145    (void)memcpy_s(ptr, len, reinterpret_cast<char *>(&value), len);
146    return SerializedBuffer{ptr, len};
147}
148
149extern "C" uint8_t ParseSessionHandShake(RustStruct::SessionHandShake &value, SerializedBuffer buf)
150{
151    BaseStruct::SessionHandShake shs = {};
152    if (!SerialStruct::ParseFromString(shs, string(buf.ptr, buf.size))) {
153        return 0;
154    }
155    value = {
156        .banner = StringToHeapPtr(shs.banner),
157        .authType = shs.authType,
158        .sessionId = shs.sessionId,
159        .connectKey = StringToHeapPtr(shs.connectKey),
160        .buf = StringToHeapPtr(shs.buf),
161        .version = StringToHeapPtr(shs.version)
162    };
163    return 1;
164}
165
166extern "C" uint8_t ParsePayloadProtect(RustStruct::PayloadProtect &value, SerializedBuffer buf)
167{
168    BaseStruct::PayloadProtect pp = {};
169    if (!SerialStruct::ParseFromString(pp, string(buf.ptr, buf.size))) {
170        return 0;
171    }
172    value = {
173        .channelId = pp.channelId,
174        .commandFlag = pp.commandFlag,
175        .checkSum = pp.checkSum,
176        .vCode = pp.vCode
177    };
178    return 1;
179}
180
181extern "C" uint8_t ParseTransferConfig(RustStruct::TransferConfig &value, SerializedBuffer buf)
182{
183    BaseStruct::TransferConfig tc = {};
184    if (!SerialStruct::ParseFromString(tc, string(buf.ptr, buf.size))) {
185        return 0;
186    }
187    value = {
188        .fileSize = tc.fileSize,
189        .atime = tc.atime,
190        .mtime = tc.mtime,
191        .options = StringToHeapPtr(tc.options),
192        .path = StringToHeapPtr(tc.path),
193        .optionalName = StringToHeapPtr(tc.optionalName),
194        .updateIfNew = tc.updateIfNew > 0,
195        .compressType = tc.compressType,
196        .holdTimestamp = tc.holdTimestamp > 0,
197        .functionName = StringToHeapPtr(tc.functionName), // must first index
198        .clientCwd = StringToHeapPtr(tc.clientCwd),
199        .reserve1 = StringToHeapPtr(tc.reserve1),
200        .reserve2 = StringToHeapPtr(tc.reserve2)
201    };
202    return 1;
203}
204
205extern "C" uint8_t ParseFileMode(RustStruct::FileMode &value, SerializedBuffer buf)
206{
207    BaseStruct::FileMode fm = {};
208    if (!SerialStruct::ParseFromString(fm, string(buf.ptr, buf.size))) {
209        return 0;
210    }
211    value = {
212        .perm = fm.perm,
213        .u_id = fm.u_id,
214        .g_id = fm.g_id,
215        .context = StringToHeapPtr(fm.context),
216        .fullName = StringToHeapPtr(fm.fullName)
217    };
218    return 1;
219}
220
221extern "C" uint8_t ParseTransferPayload(RustStruct::TransferPayload &value, SerializedBuffer buf)
222{
223    BaseStruct::TransferPayload tp = {};
224    if (!SerialStruct::ParseFromString(tp, string(buf.ptr, buf.size))) {
225        return 0;
226    }
227    value = {
228        .index = tp.index,
229        .compressType = tp.compressType,
230        .compressSize = tp.compressSize,
231        .uncompressSize = tp.uncompressSize
232    };
233    return 1;
234}
235
236extern "C" uint8_t ParsePayloadHead(RustStruct::PayloadHead &value, SerializedBuffer buf)
237{
238    if (memcpy_s(&value, buf.size, reinterpret_cast<struct PayloadHead *>(buf.ptr), buf.size) != EOK) {
239        return 0;
240    }
241    return 1;
242}
243
244extern "C" uint8_t ParseUsbHead(RustStruct::USBHead &value, SerializedBuffer buf)
245{
246    if (memcpy_s(&value, sizeof(RustStruct::USBHead), reinterpret_cast<struct USBHead *>(buf.ptr), buf.size) != EOK) {
247        return 0;
248    }
249    return 1;
250}
251
252extern "C" uint8_t ParseUartHead(RustStruct::UartHead &value, SerializedBuffer buf)
253{
254    if (memcpy_s(&value, sizeof(RustStruct::UartHead), reinterpret_cast<struct UartHead *>(buf.ptr), buf.size) != EOK) {
255        return 0;
256    }
257    return 1;
258}
259
260}; // Hdc
261