1 /*
2 * Copyright (c) 2021-2022 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 <vector>
17 #include <string>
18 #include "hdf_sbuf_ipc.h"
19 #include "hdf_sbuf_impl.h"
20 #include "hdf_log.h"
21 #include "hdf_remote_adapter.h"
22
23 using namespace OHOS;
24
25 static void MParcelImplInterfaceAssign(struct HdfSBufImpl *inf);
26
27 struct SBufMParcelImpl {
SBufMParcelImplSBufMParcelImpl28 SBufMParcelImpl(OHOS::MessageParcel *parcel, bool owned = true): realParcel_(parcel), owned_(owned)
29 {
30 MParcelImplInterfaceAssign(&infImpl);
31 }
~SBufMParcelImplSBufMParcelImpl32 ~SBufMParcelImpl()
33 {
34 if (owned_ && realParcel_ != nullptr) {
35 delete realParcel_;
36 realParcel_ = nullptr;
37 }
38 }
39 struct HdfSBufImpl infImpl;
40 OHOS::MessageParcel *realParcel_;
41 std::vector<std::u16string> str16Pool_;
42 bool owned_;
43 };
44
MParcelCast(struct HdfSBufImpl * impl)45 static MessageParcel *MParcelCast(struct HdfSBufImpl *impl)
46 {
47 SBufMParcelImpl *sbufImpl = reinterpret_cast<SBufMParcelImpl *>(impl);
48 return sbufImpl->realParcel_;
49 }
50
SbufMParcelImplWriteBuffer(struct HdfSBufImpl * sbuf,const uint8_t * data,uint32_t writeSize)51 static bool SbufMParcelImplWriteBuffer(struct HdfSBufImpl *sbuf, const uint8_t *data, uint32_t writeSize)
52 {
53 if (sbuf == nullptr) {
54 return false;
55 }
56 auto parcel = MParcelCast(sbuf);
57 if (!parcel->WriteUint32(writeSize)) {
58 return false;
59 }
60 return parcel->WriteUnpadBuffer(static_cast<const void *>(data), writeSize);
61 }
62
SbufMParcelImplWriteUnpadBuffer(struct HdfSBufImpl * sbuf,const uint8_t * data,uint32_t writeSize)63 static bool SbufMParcelImplWriteUnpadBuffer(struct HdfSBufImpl *sbuf, const uint8_t *data, uint32_t writeSize)
64 {
65 if (sbuf == nullptr) {
66 return false;
67 }
68 return MParcelCast(sbuf)->WriteUnpadBuffer(static_cast<const void *>(data), writeSize);
69 }
70
SbufMParcelImplWriteUint64(struct HdfSBufImpl * sbuf,uint64_t value)71 static bool SbufMParcelImplWriteUint64(struct HdfSBufImpl *sbuf, uint64_t value)
72 {
73 if (sbuf == nullptr) {
74 return false;
75 }
76 return MParcelCast(sbuf)->WriteUint64(value);
77 }
78
SbufMParcelImplWriteUint32(struct HdfSBufImpl * sbuf,uint32_t value)79 static bool SbufMParcelImplWriteUint32(struct HdfSBufImpl *sbuf, uint32_t value)
80 {
81 if (sbuf == nullptr) {
82 return false;
83 }
84 return MParcelCast(sbuf)->WriteUint32(value);
85 }
86
SbufMParcelImplWriteUint16(struct HdfSBufImpl * sbuf,uint16_t value)87 static bool SbufMParcelImplWriteUint16(struct HdfSBufImpl *sbuf, uint16_t value)
88 {
89 if (sbuf == nullptr) {
90 return false;
91 }
92 return MParcelCast(sbuf)->WriteUint16(value);
93 }
94
SbufMParcelImplWriteUint8(struct HdfSBufImpl * sbuf,uint8_t value)95 static bool SbufMParcelImplWriteUint8(struct HdfSBufImpl *sbuf, uint8_t value)
96 {
97 if (sbuf == nullptr) {
98 return false;
99 }
100 return MParcelCast(sbuf)->WriteUint8(value);
101 }
102
SbufMParcelImplWriteInt64(struct HdfSBufImpl * sbuf,int64_t value)103 static bool SbufMParcelImplWriteInt64(struct HdfSBufImpl *sbuf, int64_t value)
104 {
105 if (sbuf == nullptr) {
106 return false;
107 }
108 return MParcelCast(sbuf)->WriteInt64(value);
109 }
110
SbufMParcelImplWriteInt32(struct HdfSBufImpl * sbuf,int32_t value)111 static bool SbufMParcelImplWriteInt32(struct HdfSBufImpl *sbuf, int32_t value)
112 {
113 if (sbuf == nullptr) {
114 return false;
115 }
116 return MParcelCast(sbuf)->WriteInt32(value);
117 }
118
SbufMParcelImplWriteInt16(struct HdfSBufImpl * sbuf,int16_t value)119 static bool SbufMParcelImplWriteInt16(struct HdfSBufImpl *sbuf, int16_t value)
120 {
121 if (sbuf == nullptr) {
122 return false;
123 }
124 return MParcelCast(sbuf)->WriteInt16(value);
125 }
126
SbufMParcelImplWriteInt8(struct HdfSBufImpl * sbuf,int8_t value)127 static bool SbufMParcelImplWriteInt8(struct HdfSBufImpl *sbuf, int8_t value)
128 {
129 if (sbuf == nullptr) {
130 return false;
131 }
132 return MParcelCast(sbuf)->WriteInt8(value);
133 }
134
SbufMParcelImplWriteString(struct HdfSBufImpl * sbuf,const char * value)135 static bool SbufMParcelImplWriteString(struct HdfSBufImpl *sbuf, const char *value)
136 {
137 if (sbuf == nullptr) {
138 return false;
139 }
140 return MParcelCast(sbuf)->WriteCString(value);
141 }
142
SbufMParcelImplWriteString16(struct HdfSBufImpl * sbuf,const char16_t * value,uint32_t size)143 static bool SbufMParcelImplWriteString16(struct HdfSBufImpl *sbuf, const char16_t *value, uint32_t size)
144 {
145 if (sbuf == nullptr) {
146 return false;
147 }
148 return MParcelCast(sbuf)->WriteString16WithLength(value, size);
149 }
150
SbufMParcelImplWriteFileDescriptor(struct HdfSBufImpl * sbuf,int fd)151 static bool SbufMParcelImplWriteFileDescriptor(struct HdfSBufImpl *sbuf, int fd)
152 {
153 if (sbuf == nullptr) {
154 return false;
155 }
156 return MParcelCast(sbuf)->WriteFileDescriptor(fd);
157 }
158
SbufMParcelImplWriteDouble(struct HdfSBufImpl * sbuf,double value)159 static bool SbufMParcelImplWriteDouble(struct HdfSBufImpl *sbuf, double value)
160 {
161 if (sbuf == nullptr) {
162 return false;
163 }
164 return MParcelCast(sbuf)->WriteDouble(value);
165 }
166
SbufMParcelImplWriteFloat(struct HdfSBufImpl * sbuf,float value)167 static bool SbufMParcelImplWriteFloat(struct HdfSBufImpl *sbuf, float value)
168 {
169 if (sbuf == nullptr) {
170 return false;
171 }
172 return MParcelCast(sbuf)->WriteFloat(value);
173 }
174
SbufMParcelImplReadFloat(struct HdfSBufImpl * sbuf,float * value)175 static bool SbufMParcelImplReadFloat(struct HdfSBufImpl *sbuf, float *value)
176 {
177 if (sbuf == nullptr || value == nullptr) {
178 return false;
179 }
180 float v = 0;
181 bool ret = MParcelCast(sbuf)->ReadFloat(v);
182 *value = v;
183 return ret;
184 }
185
SbufMParcelImplReadDouble(struct HdfSBufImpl * sbuf,double * value)186 static bool SbufMParcelImplReadDouble(struct HdfSBufImpl *sbuf, double *value)
187 {
188 if (sbuf == nullptr || value == nullptr) {
189 return false;
190 }
191 double v = 0;
192 bool ret = MParcelCast(sbuf)->ReadDouble(v);
193 *value = v;
194 return ret;
195 }
196
SbufMParcelImplReadFileDescriptor(struct HdfSBufImpl * sbuf)197 static int SbufMParcelImplReadFileDescriptor(struct HdfSBufImpl *sbuf)
198 {
199 if (sbuf == nullptr) {
200 return -1;
201 }
202 return MParcelCast(sbuf)->ReadFileDescriptor();
203 }
204
SbufMParcelImplReadBuffer(struct HdfSBufImpl * sbuf,const uint8_t ** data,uint32_t * readSize)205 static bool SbufMParcelImplReadBuffer(struct HdfSBufImpl *sbuf, const uint8_t **data, uint32_t *readSize)
206 {
207 if (sbuf == nullptr || data == nullptr || readSize == nullptr) {
208 return false;
209 }
210 MessageParcel *parcel = MParcelCast(sbuf);
211 *readSize = parcel->ReadUint32();
212 *data = parcel->ReadUnpadBuffer(*readSize);
213 return *data != nullptr;
214 }
215
SbufMParcelImplReadUnpadBuffer(struct HdfSBufImpl * sbuf,size_t length)216 static const uint8_t *SbufMParcelImplReadUnpadBuffer(struct HdfSBufImpl *sbuf, size_t length)
217 {
218 if (sbuf == nullptr) {
219 return nullptr;
220 }
221 return MParcelCast(sbuf)->ReadUnpadBuffer(length);
222 }
223
SbufMParcelImplReadUint64(struct HdfSBufImpl * sbuf,uint64_t * value)224 static bool SbufMParcelImplReadUint64(struct HdfSBufImpl *sbuf, uint64_t *value)
225 {
226 if (sbuf == nullptr || value == nullptr) {
227 return false;
228 }
229 uint64_t v = 0;
230 bool ret = MParcelCast(sbuf)->ReadUint64(v);
231 *value = v;
232 return ret;
233 }
234
SbufMParcelImplReadUint32(struct HdfSBufImpl * sbuf,uint32_t * value)235 static bool SbufMParcelImplReadUint32(struct HdfSBufImpl *sbuf, uint32_t *value)
236 {
237 if (sbuf == nullptr || value == nullptr) {
238 return false;
239 }
240 uint32_t v = 0;
241 bool ret = MParcelCast(sbuf)->ReadUint32(v);
242 *value = v;
243 return ret;
244 }
245
SbufMParcelImplReadUint16(struct HdfSBufImpl * sbuf,uint16_t * value)246 static bool SbufMParcelImplReadUint16(struct HdfSBufImpl *sbuf, uint16_t *value)
247 {
248 if (sbuf == nullptr || value == nullptr) {
249 return false;
250 }
251 uint16_t v = 0;
252 bool ret = MParcelCast(sbuf)->ReadUint16(v);
253 *value = v;
254 return ret;
255 }
256
SbufMParcelImplReadUint8(struct HdfSBufImpl * sbuf,uint8_t * value)257 static bool SbufMParcelImplReadUint8(struct HdfSBufImpl *sbuf, uint8_t *value)
258 {
259 if (sbuf == nullptr || value == nullptr) {
260 return false;
261 }
262 uint8_t v = 0;
263 bool ret = MParcelCast(sbuf)->ReadUint8(v);
264 *value = v;
265 return ret;
266 }
267
SbufMParcelImplReadInt64(struct HdfSBufImpl * sbuf,int64_t * value)268 static bool SbufMParcelImplReadInt64(struct HdfSBufImpl *sbuf, int64_t *value)
269 {
270 if (sbuf == nullptr || value == nullptr) {
271 return false;
272 }
273 int64_t v = 0;
274 bool ret = MParcelCast(sbuf)->ReadInt64(v);
275 *value = v;
276 return ret;
277 }
278
SbufMParcelImplReadInt32(struct HdfSBufImpl * sbuf,int32_t * value)279 static bool SbufMParcelImplReadInt32(struct HdfSBufImpl *sbuf, int32_t *value)
280 {
281 if (sbuf == nullptr || value == nullptr) {
282 return false;
283 }
284 int32_t v = 0;
285 bool ret = MParcelCast(sbuf)->ReadInt32(v);
286 *value = v;
287 return ret;
288 }
289
SbufMParcelImplReadInt16(struct HdfSBufImpl * sbuf,int16_t * value)290 static bool SbufMParcelImplReadInt16(struct HdfSBufImpl *sbuf, int16_t *value)
291 {
292 if (sbuf == nullptr || value == nullptr) {
293 return false;
294 }
295 int16_t v = 0;
296 bool ret = MParcelCast(sbuf)->ReadInt16(v);
297 *value = v;
298 return ret;
299 }
300
SbufMParcelImplReadInt8(struct HdfSBufImpl * sbuf,int8_t * value)301 static bool SbufMParcelImplReadInt8(struct HdfSBufImpl *sbuf, int8_t *value)
302 {
303 if (sbuf == nullptr || value == nullptr) {
304 return false;
305 }
306 int8_t v = 0;
307 bool ret = MParcelCast(sbuf)->ReadInt8(v);
308 *value = v;
309 return ret;
310 }
311
SbufMParcelImplReadString(struct HdfSBufImpl * sbuf)312 static const char *SbufMParcelImplReadString(struct HdfSBufImpl *sbuf)
313 {
314 if (sbuf == nullptr) {
315 return nullptr;
316 }
317 return MParcelCast(sbuf)->ReadCString();
318 }
319
SbufMParcelImplReadString16(struct HdfSBufImpl * sbuf)320 static const char16_t *SbufMParcelImplReadString16(struct HdfSBufImpl *sbuf)
321 {
322 if (sbuf == nullptr) {
323 return nullptr;
324 }
325 SBufMParcelImpl *sbufImpl = reinterpret_cast<SBufMParcelImpl *>(sbuf);
326 sbufImpl->str16Pool_.emplace_back(sbufImpl->realParcel_->ReadString16());
327 return sbufImpl->str16Pool_.rbegin()->c_str();
328 }
329
SbufMParcelImplWriteRemoteService(struct HdfSBufImpl * sbuf,const struct HdfRemoteService * service)330 static int32_t SbufMParcelImplWriteRemoteService(struct HdfSBufImpl *sbuf, const struct HdfRemoteService *service)
331 {
332 if (sbuf == nullptr || service == nullptr) {
333 return HDF_ERR_INVALID_PARAM;
334 }
335 MessageParcel *parcel = MParcelCast(sbuf);
336 const struct HdfRemoteServiceHolder *holder = reinterpret_cast<const struct HdfRemoteServiceHolder *>(service);
337 return parcel->WriteRemoteObject(holder->remote_) ? HDF_SUCCESS : HDF_FAILURE;
338 }
339
SbufMParcelImplReadRemoteService(struct HdfSBufImpl * sbuf)340 static struct HdfRemoteService *SbufMParcelImplReadRemoteService(struct HdfSBufImpl *sbuf)
341 {
342 if (sbuf == nullptr) {
343 return nullptr;
344 }
345 auto remote = MParcelCast(sbuf)->ReadRemoteObject();
346 if (remote == nullptr) {
347 HDF_LOGE("%{public}s: read remote object fail", __func__);
348 return nullptr;
349 }
350 return HdfRemoteAdapterBind(remote);
351 }
352
SbufMParcelImplGetData(const struct HdfSBufImpl * sbuf)353 static const uint8_t *SbufMParcelImplGetData(const struct HdfSBufImpl *sbuf)
354 {
355 if (sbuf == nullptr) {
356 return nullptr;
357 }
358 return reinterpret_cast<const uint8_t *>(MParcelCast(const_cast<struct HdfSBufImpl *>(sbuf))->GetData());
359 }
360
SbufMParcelImplFlush(struct HdfSBufImpl * sbuf)361 static void SbufMParcelImplFlush(struct HdfSBufImpl *sbuf)
362 {
363 if (sbuf == nullptr) {
364 return;
365 }
366 return MParcelCast(sbuf)->FlushBuffer();
367 }
368
SbufMParcelImplGetCapacity(const struct HdfSBufImpl * sbuf)369 static size_t SbufMParcelImplGetCapacity(const struct HdfSBufImpl *sbuf)
370 {
371 if (sbuf == nullptr) {
372 return HDF_FAILURE;
373 }
374
375 return MParcelCast(const_cast<struct HdfSBufImpl *>(sbuf))->GetDataCapacity();
376 }
377
SbufMParcelImplGetDataSize(const struct HdfSBufImpl * sbuf)378 static size_t SbufMParcelImplGetDataSize(const struct HdfSBufImpl *sbuf)
379 {
380 if (sbuf == nullptr) {
381 return HDF_FAILURE;
382 }
383 return MParcelCast(const_cast<struct HdfSBufImpl *>(sbuf))->GetDataSize();
384 }
385
SbufMParcelImplSetDataSize(struct HdfSBufImpl * sbuf,size_t size)386 static void SbufMParcelImplSetDataSize(struct HdfSBufImpl *sbuf, size_t size)
387 {
388 if (sbuf == nullptr) {
389 return;
390 }
391 MParcelCast(sbuf)->SetDataSize(size);
392 }
393
SbufMParcelImplRecycle(struct HdfSBufImpl * sbuf)394 static void SbufMParcelImplRecycle(struct HdfSBufImpl *sbuf)
395 {
396 if (sbuf == nullptr) {
397 return;
398 }
399 SBufMParcelImpl *sbufImpl = reinterpret_cast<SBufMParcelImpl *>(sbuf);
400 delete sbufImpl;
401 }
402
MParcelImplInterfaceAssign(struct HdfSBufImpl * inf)403 static void MParcelImplInterfaceAssign(struct HdfSBufImpl *inf)
404 {
405 inf->writeBuffer = SbufMParcelImplWriteBuffer;
406 inf->writeUnpadBuffer = SbufMParcelImplWriteUnpadBuffer;
407 inf->writeUint64 = SbufMParcelImplWriteUint64;
408 inf->writeUint32 = SbufMParcelImplWriteUint32;
409 inf->writeUint16 = SbufMParcelImplWriteUint16;
410 inf->writeUint8 = SbufMParcelImplWriteUint8;
411 inf->writeInt64 = SbufMParcelImplWriteInt64;
412 inf->writeInt32 = SbufMParcelImplWriteInt32;
413 inf->writeInt16 = SbufMParcelImplWriteInt16;
414 inf->writeInt8 = SbufMParcelImplWriteInt8;
415 inf->writeString = SbufMParcelImplWriteString;
416 inf->writeString16 = SbufMParcelImplWriteString16;
417 inf->writeFileDescriptor = SbufMParcelImplWriteFileDescriptor;
418 inf->writeFloat = SbufMParcelImplWriteFloat;
419 inf->writeDouble = SbufMParcelImplWriteDouble;
420 inf->readDouble = SbufMParcelImplReadDouble;
421 inf->readFloat = SbufMParcelImplReadFloat;
422 inf->readFileDescriptor = SbufMParcelImplReadFileDescriptor;
423 inf->readBuffer = SbufMParcelImplReadBuffer;
424 inf->readUnpadBuffer = SbufMParcelImplReadUnpadBuffer;
425 inf->readUint64 = SbufMParcelImplReadUint64;
426 inf->readUint32 = SbufMParcelImplReadUint32;
427 inf->readUint16 = SbufMParcelImplReadUint16;
428 inf->readUint8 = SbufMParcelImplReadUint8;
429 inf->readInt64 = SbufMParcelImplReadInt64;
430 inf->readInt32 = SbufMParcelImplReadInt32;
431 inf->readInt16 = SbufMParcelImplReadInt16;
432 inf->readInt8 = SbufMParcelImplReadInt8;
433 inf->readString = SbufMParcelImplReadString;
434 inf->readString16 = SbufMParcelImplReadString16;
435 inf->writeRemoteService = SbufMParcelImplWriteRemoteService;
436 inf->readRemoteService = SbufMParcelImplReadRemoteService;
437 inf->getData = SbufMParcelImplGetData;
438 inf->flush = SbufMParcelImplFlush;
439 inf->getCapacity = SbufMParcelImplGetCapacity;
440 inf->getDataSize = SbufMParcelImplGetDataSize;
441 inf->setDataSize = SbufMParcelImplSetDataSize;
442 inf->recycle = SbufMParcelImplRecycle;
443 inf->transDataOwnership = nullptr;
444 inf->copy = nullptr;
445 inf->move = nullptr;
446 }
447
SbufObtainIpc(size_t capacity)448 extern "C" struct HdfSBufImpl *SbufObtainIpc(size_t capacity)
449 {
450 (void)capacity;
451 struct SBufMParcelImpl *sbuf = new SBufMParcelImpl(new MessageParcel());
452 return &sbuf->infImpl;
453 }
454
455 class SbufAllocator : public Allocator {
456 public:
Realloc(void * data,size_t newSize)457 void *Realloc(void *data, size_t newSize) override
458 {
459 (void)data;
460 (void)newSize;
461 return nullptr;
462 }
463
Alloc(size_t size)464 void *Alloc(size_t size) override
465 {
466 (void)size;
467 return nullptr;
468 }
469
Dealloc(void * data)470 void Dealloc(void *data) override
471 {
472 (void)data;
473 }
474 };
475
SbufBindIpc(uintptr_t base,size_t size)476 extern "C" struct HdfSBufImpl *SbufBindIpc(uintptr_t base, size_t size)
477 {
478 struct SBufMParcelImpl *sbuf = new SBufMParcelImpl(new MessageParcel(new SbufAllocator()));
479 sbuf->realParcel_->ParseFrom(base, size);
480 return &sbuf->infImpl;
481 }
482
ParcelToSbuf(OHOS::MessageParcel * parcel)483 struct HdfSBuf *ParcelToSbuf(OHOS::MessageParcel *parcel)
484 {
485 struct SBufMParcelImpl *sbuf = new SBufMParcelImpl(parcel, false);
486 return HdfSbufTypedObtainInplace(SBUF_IPC, &sbuf->infImpl);
487 }
488
SbufToParcel(struct HdfSBuf * sbuf,OHOS::MessageParcel ** parcel)489 int32_t SbufToParcel(struct HdfSBuf *sbuf, OHOS::MessageParcel **parcel)
490 {
491 if (sbuf == nullptr || parcel == nullptr) {
492 return HDF_ERR_INVALID_PARAM;
493 }
494 struct SBufMParcelImpl *impl = reinterpret_cast<SBufMParcelImpl *>(HdfSbufGetImpl(sbuf));
495 if (impl == nullptr) {
496 return HDF_ERR_INVALID_OBJECT;
497 }
498
499 *parcel = impl->realParcel_;
500 return HDF_SUCCESS;
501 }