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 
20 namespace Hdc {
21 
StringToHeapPtr(const std::string &input)22 char *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 
SerializeSessionHandShake(const RustStruct::SessionHandShake &value)34 extern "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 
SerializePayloadProtect(const RustStruct::PayloadProtect &value)50 extern "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 
SerializeTransferConfig(const RustStruct::TransferConfig &value)64 extern "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 
SerializeFileMode(const RustStruct::FileMode &value)87 extern "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 
SerializeTransferPayload(const RustStruct::TransferPayload &value)102 extern "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 
SerializePayloadHead(RustStruct::PayloadHead &value)116 extern "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 
SerializeUsbHead(RustStruct::USBHead &value)127 extern "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 
SerializeUartHead(RustStruct::UartHead &value)138 extern "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 
ParseSessionHandShake(RustStruct::SessionHandShake &value, SerializedBuffer buf)149 extern "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 
ParsePayloadProtect(RustStruct::PayloadProtect &value, SerializedBuffer buf)166 extern "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 
ParseTransferConfig(RustStruct::TransferConfig &value, SerializedBuffer buf)181 extern "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 
ParseFileMode(RustStruct::FileMode &value, SerializedBuffer buf)205 extern "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 
ParseTransferPayload(RustStruct::TransferPayload &value, SerializedBuffer buf)221 extern "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 
ParsePayloadHead(RustStruct::PayloadHead &value, SerializedBuffer buf)236 extern "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 
ParseUsbHead(RustStruct::USBHead &value, SerializedBuffer buf)244 extern "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 
ParseUartHead(RustStruct::UartHead &value, SerializedBuffer buf)252 extern "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