1 /*
2 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "hdf_sbuf.h"
10 #include "hdf_log.h"
11 #include "hdf_sbuf_impl.h"
12 #include "osal_mem.h"
13
14 #define HDF_SBUF_DEFAULT_SIZE 256
15 #define HDF_SBUF_IMPL_CHECK_RETURN(sbuf, api, retCode) \
16 do { \
17 if ((sbuf) == NULL || (sbuf)->impl == NULL) { \
18 HDF_LOGE("%s: invalid sbuf object", __func__); \
19 return retCode; \
20 } \
21 if ((sbuf)->impl->api == NULL) { \
22 HDF_LOGE(#api " is not support on %d sbuf", (sbuf)->type); \
23 return retCode; \
24 } \
25 } while (0)
26
27 #define HDF_SBUF_IMPL_CHECK_RETURN_VOID(sbuf, api) \
28 do { \
29 if ((sbuf) == NULL || (sbuf)->impl == NULL) { \
30 HDF_LOGE("%s: invalid sbuf object", __func__); \
31 return; \
32 } \
33 if ((sbuf)->impl->api == NULL) { \
34 HDF_LOGE(#api " is not support on %d sbuf", (sbuf)->type); \
35 return; \
36 } \
37 } while (0)
38
39 struct HdfSBuf {
40 struct HdfSBufImpl *impl;
41 uint32_t type;
42 };
43
44 struct HdfSBufImpl *SbufObtainRaw(size_t capacity);
45 struct HdfSBufImpl *SbufBindRaw(uintptr_t base, size_t size);
46 struct HdfSBufImpl *SbufObtainIpc(size_t capacity) __attribute__((weak));
47 struct HdfSBufImpl *SbufBindIpc(uintptr_t base, size_t size) __attribute__((weak));
48 struct HdfSBufImpl *SbufObtainIpcHw(size_t capacity) __attribute__((weak));
49 struct HdfSBufImpl *SbufBindRawIpcHw(uintptr_t base, size_t size) __attribute__((weak));
50
51 static const struct HdfSbufConstructor g_sbufConstructorMap[SBUF_TYPE_MAX] = {
52 [SBUF_RAW] = {
53 .obtain = SbufObtainRaw,
54 .bind = SbufBindRaw,
55 },
56 [SBUF_IPC] = {
57 .obtain = SbufObtainIpc,
58 .bind = SbufBindIpc,
59 },
60 [SBUF_IPC_HW] = {
61 .obtain = SbufObtainIpcHw,
62 .bind = SbufBindRawIpcHw,
63 },
64 };
65
HdfSbufConstructorGet(uint32_t type)66 static const struct HdfSbufConstructor *HdfSbufConstructorGet(uint32_t type)
67 {
68 if (type >= SBUF_TYPE_MAX) {
69 return NULL;
70 }
71
72 return &g_sbufConstructorMap[type];
73 }
74
HdfSbufGetData(const struct HdfSBuf * sbuf)75 uint8_t *HdfSbufGetData(const struct HdfSBuf *sbuf)
76 {
77 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, getData, NULL);
78 return (uint8_t *)sbuf->impl->getData(sbuf->impl);
79 }
80
HdfSbufFlush(struct HdfSBuf * sbuf)81 void HdfSbufFlush(struct HdfSBuf *sbuf)
82 {
83 HDF_SBUF_IMPL_CHECK_RETURN_VOID(sbuf, getData);
84 sbuf->impl->flush(sbuf->impl);
85 }
86
HdfSbufGetCapacity(const struct HdfSBuf * sbuf)87 size_t HdfSbufGetCapacity(const struct HdfSBuf *sbuf)
88 {
89 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, getCapacity, HDF_FAILURE);
90 return (sbuf != NULL && sbuf->impl != NULL) ? sbuf->impl->getCapacity(sbuf->impl) : 0;
91 }
92
HdfSbufGetDataSize(const struct HdfSBuf * sbuf)93 size_t HdfSbufGetDataSize(const struct HdfSBuf *sbuf)
94 {
95 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, getDataSize, HDF_FAILURE);
96 return sbuf->impl->getDataSize(sbuf->impl);
97 }
98
HdfSbufSetDataSize(struct HdfSBuf * sbuf,size_t size)99 void HdfSbufSetDataSize(struct HdfSBuf *sbuf, size_t size)
100 {
101 HDF_SBUF_IMPL_CHECK_RETURN_VOID(sbuf, setDataSize);
102 sbuf->impl->setDataSize(sbuf->impl, size);
103 }
104
HdfSbufWriteBuffer(struct HdfSBuf * sbuf,const void * data,uint32_t writeSize)105 bool HdfSbufWriteBuffer(struct HdfSBuf *sbuf, const void *data, uint32_t writeSize)
106 {
107 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, getCapacity, false);
108 return sbuf->impl->writeBuffer(sbuf->impl, (const uint8_t *)data, writeSize);
109 }
110
HdfSbufWriteUnpadBuffer(struct HdfSBuf * sbuf,const uint8_t * data,uint32_t writeSize)111 bool HdfSbufWriteUnpadBuffer(struct HdfSBuf *sbuf, const uint8_t *data, uint32_t writeSize)
112 {
113 if (data == NULL) {
114 return false;
115 }
116
117 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeUnpadBuffer, false);
118 return sbuf->impl->writeUnpadBuffer(sbuf->impl, data, writeSize);
119 }
120
HdfSbufReadUnpadBuffer(struct HdfSBuf * sbuf,size_t length)121 const uint8_t *HdfSbufReadUnpadBuffer(struct HdfSBuf *sbuf, size_t length)
122 {
123 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readUnpadBuffer, NULL);
124 return sbuf->impl->readUnpadBuffer(sbuf->impl, length);
125 }
126
HdfSbufReadBuffer(struct HdfSBuf * sbuf,const void ** data,uint32_t * readSize)127 bool HdfSbufReadBuffer(struct HdfSBuf *sbuf, const void **data, uint32_t *readSize)
128 {
129 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readBuffer, false);
130 return sbuf->impl->readBuffer(sbuf->impl, (const uint8_t **)data, readSize);
131 }
132
HdfSbufWriteUint64(struct HdfSBuf * sbuf,uint64_t value)133 bool HdfSbufWriteUint64(struct HdfSBuf *sbuf, uint64_t value)
134 {
135 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeUint64, false);
136 return sbuf->impl->writeUint64(sbuf->impl, value);
137 }
138
HdfSbufWriteUint32(struct HdfSBuf * sbuf,uint32_t value)139 bool HdfSbufWriteUint32(struct HdfSBuf *sbuf, uint32_t value)
140 {
141 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeUint32, false);
142 return sbuf->impl->writeUint32(sbuf->impl, value);
143 }
144
HdfSbufWriteUint16(struct HdfSBuf * sbuf,uint16_t value)145 bool HdfSbufWriteUint16(struct HdfSBuf *sbuf, uint16_t value)
146 {
147 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeUint16, false);
148 return sbuf->impl->writeUint16(sbuf->impl, value);
149 }
150
HdfSbufWriteUint8(struct HdfSBuf * sbuf,uint8_t value)151 bool HdfSbufWriteUint8(struct HdfSBuf *sbuf, uint8_t value)
152 {
153 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeUint8, false);
154 return sbuf->impl->writeUint8(sbuf->impl, value);
155 }
156
HdfSbufWriteInt64(struct HdfSBuf * sbuf,int64_t value)157 bool HdfSbufWriteInt64(struct HdfSBuf *sbuf, int64_t value)
158 {
159 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeInt64, false);
160 return sbuf->impl->writeInt64(sbuf->impl, value);
161 }
162
HdfSbufWriteInt32(struct HdfSBuf * sbuf,int32_t value)163 bool HdfSbufWriteInt32(struct HdfSBuf *sbuf, int32_t value)
164 {
165 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeInt32, false);
166 return sbuf->impl->writeInt32(sbuf->impl, value);
167 }
168
HdfSbufWriteInt16(struct HdfSBuf * sbuf,int16_t value)169 bool HdfSbufWriteInt16(struct HdfSBuf *sbuf, int16_t value)
170 {
171 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeInt16, false);
172 return sbuf->impl->writeInt16(sbuf->impl, value);
173 }
174
HdfSbufWriteInt8(struct HdfSBuf * sbuf,int8_t value)175 bool HdfSbufWriteInt8(struct HdfSBuf *sbuf, int8_t value)
176 {
177 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeInt8, false);
178 return sbuf->impl->writeInt8(sbuf->impl, value);
179 }
180
HdfSbufWriteString(struct HdfSBuf * sbuf,const char * value)181 bool HdfSbufWriteString(struct HdfSBuf *sbuf, const char *value)
182 {
183 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeString, false);
184 return sbuf->impl->writeString(sbuf->impl, value);
185 }
186
HdfSbufWriteString16(struct HdfSBuf * sbuf,const char16_t * value,uint32_t size)187 bool HdfSbufWriteString16(struct HdfSBuf *sbuf, const char16_t *value, uint32_t size)
188 {
189 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeString16, false);
190 return sbuf->impl->writeString16(sbuf->impl, value, size);
191 }
192
HdfSbufReadUint64(struct HdfSBuf * sbuf,uint64_t * value)193 bool HdfSbufReadUint64(struct HdfSBuf *sbuf, uint64_t *value)
194 {
195 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readUint64, false);
196 return sbuf->impl->readUint64(sbuf->impl, value);
197 }
198
HdfSbufReadUint32(struct HdfSBuf * sbuf,uint32_t * value)199 bool HdfSbufReadUint32(struct HdfSBuf *sbuf, uint32_t *value)
200 {
201 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readUint32, false);
202 return sbuf->impl->readUint32(sbuf->impl, value);
203 }
204
HdfSbufReadUint16(struct HdfSBuf * sbuf,uint16_t * value)205 bool HdfSbufReadUint16(struct HdfSBuf *sbuf, uint16_t *value)
206 {
207 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readUint16, false);
208 return sbuf->impl->readUint16(sbuf->impl, value);
209 }
210
HdfSbufReadUint8(struct HdfSBuf * sbuf,uint8_t * value)211 bool HdfSbufReadUint8(struct HdfSBuf *sbuf, uint8_t *value)
212 {
213 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readUint8, false);
214 return sbuf->impl->readUint8(sbuf->impl, value);
215 }
216
HdfSbufReadInt64(struct HdfSBuf * sbuf,int64_t * value)217 bool HdfSbufReadInt64(struct HdfSBuf *sbuf, int64_t *value)
218 {
219 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readInt64, false);
220 return sbuf->impl->readInt64(sbuf->impl, value);
221 }
222
HdfSbufReadInt32(struct HdfSBuf * sbuf,int32_t * value)223 bool HdfSbufReadInt32(struct HdfSBuf *sbuf, int32_t *value)
224 {
225 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readInt32, false);
226 return sbuf->impl->readInt32(sbuf->impl, value);
227 }
228
HdfSbufReadInt16(struct HdfSBuf * sbuf,int16_t * value)229 bool HdfSbufReadInt16(struct HdfSBuf *sbuf, int16_t *value)
230 {
231 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readInt16, false);
232 return sbuf->impl->readInt16(sbuf->impl, value);
233 }
234
HdfSbufReadInt8(struct HdfSBuf * sbuf,int8_t * value)235 bool HdfSbufReadInt8(struct HdfSBuf *sbuf, int8_t *value)
236 {
237 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readInt8, false);
238 return sbuf->impl->readInt8(sbuf->impl, value);
239 }
240
HdfSbufReadString(struct HdfSBuf * sbuf)241 const char *HdfSbufReadString(struct HdfSBuf *sbuf)
242 {
243 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readString, NULL);
244 return sbuf->impl->readString(sbuf->impl);
245 }
246
HdfSBufWriteString16(struct HdfSBuf * sbuf,const char16_t * value,uint32_t size)247 bool HdfSBufWriteString16(struct HdfSBuf *sbuf, const char16_t *value, uint32_t size)
248 {
249 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeString16, false);
250 return sbuf->impl->writeString16(sbuf->impl, value, size);
251 }
252
HdfSbufReadString16(struct HdfSBuf * sbuf)253 const char16_t *HdfSbufReadString16(struct HdfSBuf *sbuf)
254 {
255 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readString16, NULL);
256 return sbuf->impl->readString16(sbuf->impl);
257 }
258
HdfSbufWriteRemoteService(struct HdfSBuf * sbuf,const struct HdfRemoteService * service)259 int32_t HdfSbufWriteRemoteService(struct HdfSBuf *sbuf, const struct HdfRemoteService *service)
260 {
261 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeRemoteService, false);
262 return sbuf->impl->writeRemoteService(sbuf->impl, service);
263 }
264
HdfSbufReadRemoteService(struct HdfSBuf * sbuf)265 struct HdfRemoteService *HdfSbufReadRemoteService(struct HdfSBuf *sbuf)
266 {
267 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readRemoteService, NULL);
268 return sbuf->impl->readRemoteService(sbuf->impl);
269 }
270
HdfSbufWriteFloat(struct HdfSBuf * sbuf,float data)271 bool HdfSbufWriteFloat(struct HdfSBuf *sbuf, float data)
272 {
273 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeFloat, false);
274 return sbuf->impl->writeFloat(sbuf->impl, data);
275 }
276
HdfSbufWriteDouble(struct HdfSBuf * sbuf,double data)277 bool HdfSbufWriteDouble(struct HdfSBuf *sbuf, double data)
278 {
279 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeDouble, false);
280 return sbuf->impl->writeDouble(sbuf->impl, data);
281 }
282
HdfSbufWriteFileDescriptor(struct HdfSBuf * sbuf,int fd)283 bool HdfSbufWriteFileDescriptor(struct HdfSBuf *sbuf, int fd)
284 {
285 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, writeFileDescriptor, false);
286 return sbuf->impl->writeFileDescriptor(sbuf->impl, fd);
287 }
288
HdfSbufReadFileDescriptor(struct HdfSBuf * sbuf)289 int HdfSbufReadFileDescriptor(struct HdfSBuf *sbuf)
290 {
291 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readFileDescriptor, false);
292 return sbuf->impl->readFileDescriptor(sbuf->impl);
293 }
294
HdfSbufReadDouble(struct HdfSBuf * sbuf,double * data)295 bool HdfSbufReadDouble(struct HdfSBuf *sbuf, double *data)
296 {
297 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readDouble, false);
298 return sbuf->impl->readDouble(sbuf->impl, data);
299 }
300
HdfSbufReadFloat(struct HdfSBuf * sbuf,float * data)301 bool HdfSbufReadFloat(struct HdfSBuf *sbuf, float *data)
302 {
303 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readFloat, false);
304 return sbuf->impl->readFloat(sbuf->impl, data);
305 }
306
HdfSbufTypedObtainCapacity(uint32_t type,size_t capacity)307 struct HdfSBuf *HdfSbufTypedObtainCapacity(uint32_t type, size_t capacity)
308 {
309 struct HdfSBuf *sbuf = NULL;
310 const struct HdfSbufConstructor *constructor = HdfSbufConstructorGet(type);
311 if (constructor == NULL) {
312 HDF_LOGE("sbuf constructor %d not implement", type);
313 return NULL;
314 }
315 if (constructor->obtain == NULL) {
316 HDF_LOGE("sbuf constructor %d obtain method not implement", type);
317 return NULL;
318 }
319
320 sbuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf));
321 if (sbuf == NULL) {
322 HDF_LOGE("instance sbuf failure");
323 return NULL;
324 }
325
326 sbuf->impl = constructor->obtain(capacity);
327 if (sbuf->impl == NULL) {
328 OsalMemFree(sbuf);
329 HDF_LOGE("sbuf obtain fail, size=%u", (uint32_t)capacity);
330 return NULL;
331 }
332 sbuf->type = type;
333 return sbuf;
334 }
335
HdfSbufTypedObtainInplace(uint32_t type,struct HdfSBufImpl * impl)336 struct HdfSBuf *HdfSbufTypedObtainInplace(uint32_t type, struct HdfSBufImpl *impl)
337 {
338 struct HdfSBuf *sbuf = NULL;
339 if (type >= SBUF_TYPE_MAX || impl == NULL) {
340 return NULL;
341 }
342
343 sbuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf));
344 if (sbuf == NULL) {
345 HDF_LOGE("obtain in-place sbuf failure");
346 return NULL;
347 }
348
349 sbuf->impl = impl;
350 sbuf->type = type;
351 return sbuf;
352 }
353
HdfSbufTypedObtain(uint32_t type)354 struct HdfSBuf *HdfSbufTypedObtain(uint32_t type)
355 {
356 return HdfSbufTypedObtainCapacity(type, HDF_SBUF_DEFAULT_SIZE);
357 }
358
HdfSbufTypedBind(uint32_t type,uintptr_t base,size_t size)359 struct HdfSBuf *HdfSbufTypedBind(uint32_t type, uintptr_t base, size_t size)
360 {
361 struct HdfSBuf *sbuf = NULL;
362 const struct HdfSbufConstructor *constructor = HdfSbufConstructorGet(type);
363 if (constructor == NULL) {
364 HDF_LOGE("sbuf constructor %d not implement", type);
365 return NULL;
366 }
367
368 if (constructor->bind == NULL) {
369 HDF_LOGE("sbuf constructor %d bind method not implement", type);
370 return NULL;
371 }
372
373 sbuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf));
374 if (sbuf == NULL) {
375 HDF_LOGE("instance sbuf failure");
376 return NULL;
377 }
378
379 sbuf->impl = constructor->bind(base, size);
380 if (sbuf->impl == NULL) {
381 OsalMemFree(sbuf);
382 HDF_LOGE("sbuf bind fail");
383 return NULL;
384 }
385 sbuf->type = type;
386 return sbuf;
387 }
388
HdfSbufObtain(size_t capacity)389 struct HdfSBuf *HdfSbufObtain(size_t capacity)
390 {
391 return HdfSbufTypedObtainCapacity(SBUF_RAW, capacity);
392 }
393
HdfSbufObtainDefaultSize(void)394 struct HdfSBuf *HdfSbufObtainDefaultSize(void)
395 {
396 return HdfSbufObtain(HDF_SBUF_DEFAULT_SIZE);
397 }
398
HdfSBufObtainDefaultSize(void)399 struct HdfSBuf *HdfSBufObtainDefaultSize(void)
400 {
401 return HdfSbufObtain(HDF_SBUF_DEFAULT_SIZE);
402 }
403
HdfSbufBind(uintptr_t base,size_t size)404 struct HdfSBuf *HdfSbufBind(uintptr_t base, size_t size)
405 {
406 return HdfSbufTypedBind(SBUF_RAW, base, size);
407 }
408
HdfSbufCopy(const struct HdfSBuf * sbuf)409 struct HdfSBuf *HdfSbufCopy(const struct HdfSBuf *sbuf)
410 {
411 struct HdfSBuf *newBuf = NULL;
412 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, copy, NULL);
413 newBuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf));
414 if (newBuf == NULL) {
415 return NULL;
416 }
417 newBuf->impl = sbuf->impl->copy(sbuf->impl);
418 if (newBuf->impl == NULL) {
419 OsalMemFree(newBuf);
420 return NULL;
421 }
422 newBuf->type = sbuf->type;
423 return newBuf;
424 }
425
HdfSbufMove(struct HdfSBuf * sbuf)426 struct HdfSBuf *HdfSbufMove(struct HdfSBuf *sbuf)
427 {
428 struct HdfSBuf *newBuf = NULL;
429 HDF_SBUF_IMPL_CHECK_RETURN(sbuf, move, NULL);
430 newBuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf));
431 if (newBuf == NULL) {
432 return NULL;
433 }
434 newBuf->impl = sbuf->impl->move(sbuf->impl);
435 if (newBuf->impl == NULL) {
436 OsalMemFree(newBuf);
437 return NULL;
438 }
439 return newBuf;
440 }
441
HdfSbufTransDataOwnership(struct HdfSBuf * sbuf)442 void HdfSbufTransDataOwnership(struct HdfSBuf *sbuf)
443 {
444 HDF_SBUF_IMPL_CHECK_RETURN_VOID(sbuf, transDataOwnership);
445 sbuf->impl->transDataOwnership(sbuf->impl);
446 }
447
HdfSbufRecycle(struct HdfSBuf * sbuf)448 void HdfSbufRecycle(struct HdfSBuf *sbuf)
449 {
450 if (sbuf != NULL) {
451 if (sbuf->impl != NULL && sbuf->impl->recycle != NULL) {
452 sbuf->impl->recycle(sbuf->impl);
453 sbuf->impl = NULL;
454 }
455 OsalMemFree(sbuf);
456 }
457 }
458
HdfSBufRecycle(struct HdfSBuf * sbuf)459 void HdfSBufRecycle(struct HdfSBuf *sbuf)
460 {
461 if (sbuf != NULL) {
462 if (sbuf->impl != NULL && sbuf->impl->recycle != NULL) {
463 sbuf->impl->recycle(sbuf->impl);
464 sbuf->impl = NULL;
465 }
466 OsalMemFree(sbuf);
467 }
468 }
469
HdfSbufGetImpl(struct HdfSBuf * sbuf)470 struct HdfSBufImpl *HdfSbufGetImpl(struct HdfSBuf *sbuf)
471 {
472 if (sbuf != NULL) {
473 return sbuf->impl;
474 }
475
476 return NULL;
477 }