CAEN Utility  2.0.2
Utilities for CAEN projects
CAENSerDes.c
Go to the documentation of this file.
1 /******************************************************************************
2 *
3 * CAEN SpA - Software Division
4 * Via Vetraia, 11 - 55049 - Viareggio ITALY
5 * +39 0594 388 398 - www.caen.it
6 *
7 *******************************************************************************
8 *
9 * Copyright (C) 2019-2022 CAEN SpA
10 *
11 * This file is part of the CAEN Utility.
12 *
13 * The CAEN Utility is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU Lesser General Public
15 * License as published by the Free Software Foundation; either
16 * version 3 of the License, or (at your option) any later version.
17 *
18 * The CAEN Utility is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * Lesser General Public License for more details.
22 *
23 * You should have received a copy of the GNU Lesser General Public
24 * License along with the CAEN Utility; if not, see
25 * https://www.gnu.org/licenses/.
26 *
27 * SPDX-License-Identifier: LGPL-3.0-or-later
28 *
29 ***************************************************************************/
37 #ifdef _WIN32
38 #include <WS2tcpip.h>
39 #endif
40 
41 #include <CAENSerDes.h>
42 
43 #include <CAENLogger.h>
44 #include <CAENMultiplatform.h>
45 #include <CAENThread.h>
46 #include <CAENSocket.h>
47 
48 INIT_C_LOGGER("CAENSerDesLog.log", "CAENSerDes.c");
49 
50 #define PKTHEAD_PROTOVERS_SIZE (sizeof(PKTHEAD_PROTOVERS_TYPE))
51 #define PKTHEAD_TOTLEN_SIZE (sizeof(PKTHEAD_TOTLEN_TYPE))
52 #define PKTHEAD_CMD_SIZE (sizeof(PKTHEAD_CMD_TYPE))
53 #define PKTHEAD_NPARAMS_SIZE (sizeof(PKTHEAD_NPARAMS_TYPE))
54 #define PKTHEAD_TOTALSIZE (PKTHEAD_PROTOVERS_SIZE + PKTHEAD_TOTLEN_SIZE + PKTHEAD_CMD_SIZE + PKTHEAD_NPARAMS_SIZE)
55 
56 static PKTHEAD_PROTOVERS_TYPE * getProtoVersPtr(uint8_t *header) {
57  uint8_t *datapointer = header;
58  return ((PKTHEAD_PROTOVERS_TYPE*)datapointer);
59 }
60 
61 static const PKTHEAD_PROTOVERS_TYPE* getProtoVersConstPtr(const uint8_t* header) {
62  const uint8_t* datapointer = header;
63  return ((const PKTHEAD_PROTOVERS_TYPE*)datapointer);
64 }
65 
66 static PKTHEAD_TOTLEN_TYPE * getSizePtr(uint8_t *header) {
67  uint8_t *datapointer = header + PKTHEAD_PROTOVERS_SIZE;
68  return ((PKTHEAD_TOTLEN_TYPE*)datapointer);
69 }
70 
71 static PKTHEAD_CMD_TYPE * getCmdPtr(uint8_t *header) {
72  uint8_t *datapointer = header + PKTHEAD_PROTOVERS_SIZE + PKTHEAD_TOTLEN_SIZE;
73  return ((PKTHEAD_CMD_TYPE*)datapointer);
74 }
75 
76 static const PKTHEAD_CMD_TYPE* getCmdConstPtr(const uint8_t* header) {
77  const uint8_t* datapointer = header + PKTHEAD_PROTOVERS_SIZE + PKTHEAD_TOTLEN_SIZE;
78  return ((const PKTHEAD_CMD_TYPE*)datapointer);
79 }
80 
81 static PKTHEAD_NPARAMS_TYPE * getParamsNumPtr(uint8_t *header) {
82  uint8_t *datapointer = header + PKTHEAD_PROTOVERS_SIZE + PKTHEAD_TOTLEN_SIZE + PKTHEAD_CMD_SIZE;
83  return ((PKTHEAD_NPARAMS_TYPE*)datapointer);
84 }
85 
86 static bool checkProtoVersPtr(const uint8_t *header, uint8_t version) {
87  const PKTHEAD_PROTOVERS_TYPE *datapointer = getProtoVersConstPtr(header);
88  PKTHEAD_PROTOVERS_TYPE packet_version = c_ntoh16(*datapointer);
89  return (packet_version == CAEN_PKT_VERSION(version));
90 }
91 
92 static PKTHEAD_TOTLEN_TYPE * setSizeToHeader(uint8_t *header, PKTHEAD_TOTLEN_TYPE size) {
93  PKTHEAD_TOTLEN_TYPE *datapointer = getSizePtr(header);
94  PKTHEAD_TOTLEN_TYPE s = c_hton32(size);
95  return c_memcpy(datapointer, &s, PKTHEAD_TOTLEN_SIZE);
96 }
97 
98 static PKTHEAD_NPARAMS_TYPE * incrHeaderParamsNum(uint8_t *header) {
99  PKTHEAD_NPARAMS_TYPE *datapointer = getParamsNumPtr(header);
100  PKTHEAD_NPARAMS_TYPE num = *datapointer;
101  num = c_ntoh16(num);
102  num++;
103  num = c_hton16(num);
104  return c_memcpy(datapointer, &num, PKTHEAD_NPARAMS_SIZE);
105 }
106 
107 static size_t getSizeOfType(c_type_t t) {
108  switch (t) {
109  case TYPE_INT8: return sizeof(int8_t);
110  case TYPE_UINT8: return sizeof(uint8_t);
111  case TYPE_INT16: return sizeof(int16_t);
112  case TYPE_UINT16: return sizeof(uint16_t);
113  case TYPE_INT32: return sizeof(int32_t);
114  case TYPE_UINT32: return sizeof(uint32_t);
115  case TYPE_INT64: return sizeof(int64_t);
116  case TYPE_UINT64: return sizeof(uint64_t);
117  case TYPE_LONG: return sizeof(int32_t);
118  case TYPE_DOUBLE: return sizeof(double);
119  case TYPE_CHAR: return sizeof(char);
120  case TYPE_SHORT: return sizeof(int16_t);
121  case TYPE_RESCODE:
122  case TYPE_STRING:
123  case TYPE_MEMORY:
124  case TYPE_NONE:
125  default: return 0;
126  }
127 }
128 
129 c_use_decl_annotations uint8_t* c_createheader(uint16_t version, PKTHEAD_CMD_TYPE cmd, size_t *allocatedSize) {
130  if (allocatedSize == NULL)
131  return NULL;
132  PKTHEAD_PROTOVERS_TYPE protovers = CAEN_PKT_VERSION(version);
133  PKTHEAD_NPARAMS_TYPE nparams = 0;
135  uint8_t *header = c_malloc(totlen);
136  if (header == NULL)
137  *allocatedSize = 0;
138  else {
139  protovers = c_hton16(protovers);
140  c_memcpy(getProtoVersPtr(header), &protovers, PKTHEAD_PROTOVERS_SIZE);
141 
142  *allocatedSize = (size_t)totlen;
143  setSizeToHeader(header, totlen);
144 
145  cmd = c_hton16(cmd);
146  c_memcpy(getCmdPtr(header), &cmd, PKTHEAD_CMD_SIZE);
147 
148  nparams = c_hton16(nparams);
149  c_memcpy(getParamsNumPtr(header), &nparams, PKTHEAD_NPARAMS_SIZE);
150  }
151  return header;
152 }
153 
156  if (buffer != NULL && checkProtoVersPtr(buffer, 0)) { // Check buffer starting with header
157  const PKTHEAD_CMD_TYPE *cmdAddr = getCmdConstPtr(buffer);
158  cmd = c_ntoh16(*cmdAddr);
159  }
160  return cmd;
161 }
162 
164  uint8_t header[PKTHEAD_TOTALSIZE];
165  uint8_t *buffer = NULL;
166  c_ssize_t recvsize;
167  PKTHEAD_TOTLEN_TYPE buffersize;
168  PKTHEAD_CMD_TYPE l_cmd;
169  PKTHEAD_TOTLEN_TYPE l_totSize;
170  PKTHEAD_NPARAMS_TYPE l_totParams;
171 
172  if (sckt == NULL) {
173  logMsg(c_logger_Severity_ERROR, "%s(): Invalid c_socket_t.", __func__);
174  return NULL;
175  }
176 
177  // Receive the header containing the size of the packet
178  recvsize = c_recv(sckt, header, PKTHEAD_TOTALSIZE);
179  if (recvsize != PKTHEAD_TOTALSIZE) {
180  logMsg(c_logger_Severity_ERROR, "%s(): recv() returned wrong header size.", __func__);
181  goto ErrFunc;
182  }
183 
184  l_cmd = *(getCmdPtr(header));
185  *cmd = c_ntoh16(l_cmd);
186  l_totSize = *(getSizePtr(header));
187  *totSize = c_ntoh32(l_totSize);
188  l_totParams = *(getParamsNumPtr(header));
189  *totParams = c_ntoh16(l_totParams);
190 
191  // Receive the rest of the packet, now that we know its size.
192  buffersize = *totSize - PKTHEAD_TOTALSIZE; // We already got the header
193 
194  if (buffersize > 0) {
195  buffer = c_malloc(buffersize);
196  if (buffer == NULL) {
197  goto ErrFunc;
198  }
199 
200  recvsize = c_recv(sckt, buffer, buffersize);
201  if (recvsize != (c_ssize_t)buffersize) {
202  logMsg(c_logger_Severity_ERROR, "%s(): recv() returned wrong packet size.", __func__);
203  goto ErrFunc;
204  }
205  }
206 
207  return buffer;
208 
209 ErrFunc:
210  *cmd = CMD_INVALID_LOCAL;
211  *totSize = 0;
212  *totParams = 0;
213  c_free(buffer);
214  return NULL;
215 }
216 
218  uint8_t *ret = c_recv_packet(sckt, cmd, totSize, totParams);
220  logMsg(c_logger_Severity_ERROR, "%s(): Error in c_mutex_unlock().", __func__);
221  c_free(ret);
222  return NULL;
223  }
224 
225  return ret;
226 }
227 
228 typedef uint16_t PARAMTYPE_TYPE;
229 typedef uint16_t PARAMNUM_TYPE;
230 
232  return c_hton16(type);
233 }
234 
236  return c_ntoh16(type);
237 }
238 
240  return c_hton16(type);
241 }
242 
244  return c_ntoh16(type);
245 }
246 
248  switch (type) {
249  case TYPE_INT8: return TYPE_UINT8;
250  case TYPE_UINT8: return TYPE_INT8;
251  case TYPE_INT16: return TYPE_UINT16;
252  case TYPE_UINT16: return TYPE_INT16;
253  case TYPE_INT32: return TYPE_UINT32;
254  case TYPE_UINT32: return TYPE_INT32;
255  case TYPE_INT64: return TYPE_UINT64;
256  case TYPE_UINT64: return TYPE_INT64;
257  default: return TYPE_NONE;
258  }
259 }
260 
261 // Serialize of base types
262 c_use_decl_annotations uint8_t* serialize_int8_t(const int8_t *src, uint32_t num, uint8_t *buffer, size_t *allocSize) {
263  const c_type_t type = TYPE_INT8;
264  size_t paramSize = getSizeOfType(type);
265  size_t sizeToAdd = sizeof(PARAMTYPE_TYPE) + sizeof(PARAMNUM_TYPE) + (num * paramSize);
266  if (buffer == NULL || *allocSize == 0) {
267  buffer = NULL; // TODO possible memleak
268  *allocSize = 0;
269  }
270  else {
271  if (!checkProtoVersPtr(buffer, 0)) // Check buffer starting with header
272  return NULL;
273  // realloc buffer to host new parameter
274  buffer = c_realloc(buffer, *allocSize + sizeToAdd);
275  if (buffer == NULL) // Check buffer allocation
276  return NULL;
277  else {
278  uint8_t *ptr = buffer + *allocSize; // Point to the new buffer's free space
279  PARAMTYPE_TYPE pType = ptypeton(type);
280  PARAMNUM_TYPE pNum = pnumton((PARAMNUM_TYPE)num);
281  // Copy ParamType to buffer
282  c_memcpy(ptr, &pType, sizeof(PARAMTYPE_TYPE));
283  ptr += sizeof(PARAMTYPE_TYPE);
284  // Copy ParamNum to buffer
285  c_memcpy(ptr, &pNum, sizeof(PARAMNUM_TYPE));
286  ptr += sizeof(PARAMNUM_TYPE);
287  // Copy parameters to buffer
288  // TODO we can also do a straight c_memcpy for 1byte sized types
289  for (uint32_t i = 0; i < num; i++) {
290  int8_t value = src[i];
291  c_memcpy(ptr, &value, paramSize);
292  ptr += paramSize;
293  }
294  *allocSize += sizeToAdd;
295  setSizeToHeader(buffer, (PKTHEAD_TOTLEN_TYPE)*allocSize);
296  incrHeaderParamsNum(buffer);
297  }
298  }
299  return buffer;
300 }
301 c_use_decl_annotations uint8_t* serialize_char(const char *src, uint32_t num, uint8_t *buffer, size_t *allocSize) {
302  uint32_t len = (uint32_t)strnlen(src, (size_t)num);
303  return serialize_int8_t((const int8_t*)src, len, buffer, allocSize);
304 }
305 c_use_decl_annotations uint8_t* serialize_uint8_t(const uint8_t *src, uint32_t num, uint8_t *buffer, size_t *allocSize) {
306  const c_type_t type = TYPE_UINT8;
307  size_t paramSize = getSizeOfType(type);
308  size_t sizeToAdd = sizeof(PARAMTYPE_TYPE) + sizeof(PARAMNUM_TYPE) + (num * paramSize);
309  if (buffer == NULL || *allocSize == 0) {
310  buffer = NULL; // TODO possible memleak
311  *allocSize = 0;
312  }
313  else {
314  if (!checkProtoVersPtr(buffer, 0)) // Check buffer starting with header
315  return NULL;
316  // realloc buffer to host new parameter
317  buffer = c_realloc(buffer, *allocSize + sizeToAdd);
318  if (buffer == NULL) // Check buffer allocation
319  return NULL;
320  else {
321  uint8_t *ptr = buffer + *allocSize; // Point to the new buffer's free space
322  PARAMTYPE_TYPE pType = ptypeton(type);
323  PARAMNUM_TYPE pNum = pnumton((PARAMNUM_TYPE)num);
324  // Copy ParamType to buffer
325  c_memcpy(ptr, &pType, sizeof(PARAMTYPE_TYPE));
326  ptr += sizeof(PARAMTYPE_TYPE);
327  // Copy ParamNum to buffer
328  c_memcpy(ptr, &pNum, sizeof(PARAMNUM_TYPE));
329  ptr += sizeof(PARAMNUM_TYPE);
330  // Copy parameters to buffer
331  for (uint32_t i = 0; i < num; i++) {
332  uint8_t value = src[i];
333  c_memcpy(ptr, &value, paramSize);
334  ptr += paramSize;
335  }
336  *allocSize += sizeToAdd;
337  setSizeToHeader(buffer, (PKTHEAD_TOTLEN_TYPE)*allocSize);
338  incrHeaderParamsNum(buffer);
339  }
340  }
341  return buffer;
342 }
343 c_use_decl_annotations uint8_t* serialize_int16_t(const int16_t *src, uint32_t num, uint8_t *buffer, size_t *allocSize) {
344  const c_type_t type = TYPE_INT16;
345  size_t paramSize = getSizeOfType(type);
346  size_t sizeToAdd = sizeof(PARAMTYPE_TYPE) + sizeof(PARAMNUM_TYPE) + (num * paramSize);
347  if (buffer == NULL || *allocSize == 0) {
348  buffer = NULL; // TODO possible memleak
349  *allocSize = 0;
350  }
351  else {
352  if (!checkProtoVersPtr(buffer, 0)) // Check buffer starting with header
353  return NULL;
354  // realloc buffer to host new parameter
355  buffer = c_realloc(buffer, *allocSize + sizeToAdd);
356  if (buffer == NULL) // Check buffer allocation
357  return NULL;
358  else {
359  uint8_t *ptr = buffer + *allocSize; // Point to the new buffer's free space
360  PARAMTYPE_TYPE pType = ptypeton(type);
361  PARAMNUM_TYPE pNum = pnumton((PARAMNUM_TYPE)num);
362  // Copy ParamType to buffer
363  c_memcpy(ptr, &pType, sizeof(PARAMTYPE_TYPE));
364  ptr += sizeof(PARAMTYPE_TYPE);
365  // Copy ParamNum to buffer
366  c_memcpy(ptr, &pNum, sizeof(PARAMNUM_TYPE));
367  ptr += sizeof(PARAMNUM_TYPE);
368  // Copy parameters to buffer
369  for (uint32_t i = 0; i < num; i++) {
370  int16_t value = c_hton16(src[i]);
371  c_memcpy(ptr, &value, paramSize);
372  ptr += paramSize;
373  }
374  *allocSize += sizeToAdd;
375  setSizeToHeader(buffer, (PKTHEAD_TOTLEN_TYPE)*allocSize);
376  incrHeaderParamsNum(buffer);
377  }
378  }
379  return buffer;
380 }
381 c_use_decl_annotations uint8_t* serialize_uint16_t(const uint16_t *src, uint32_t num, uint8_t *buffer, size_t *allocSize) {
382  const c_type_t type = TYPE_UINT16;
383  size_t paramSize = getSizeOfType(type);
384  size_t sizeToAdd = sizeof(PARAMTYPE_TYPE) + sizeof(PARAMNUM_TYPE) + (num * paramSize);
385  if (buffer == NULL || *allocSize == 0) {
386  buffer = NULL; // TODO possible memleak
387  *allocSize = 0;
388  }
389  else {
390  if (!checkProtoVersPtr(buffer, 0)) // Check buffer starting with header
391  return NULL;
392  // realloc buffer to host new parameter
393  buffer = c_realloc(buffer, *allocSize + sizeToAdd);
394  if (buffer == NULL) // Check buffer allocation
395  return NULL;
396  else {
397  uint8_t *ptr = buffer + *allocSize; // Point to the new buffer's free space
398  PARAMTYPE_TYPE pType = ptypeton(type);
399  PARAMNUM_TYPE pNum = pnumton((PARAMNUM_TYPE)num);
400  // Copy ParamType to buffer
401  c_memcpy(ptr, &pType, sizeof(PARAMTYPE_TYPE));
402  ptr += sizeof(PARAMTYPE_TYPE);
403  // Copy ParamNum to buffer
404  c_memcpy(ptr, &pNum, sizeof(PARAMNUM_TYPE));
405  ptr += sizeof(PARAMNUM_TYPE);
406  // Copy parameters to buffer
407  for (uint32_t i = 0; i < num; i++) {
408  uint16_t value = c_hton16(src[i]);
409  c_memcpy(ptr, &value, paramSize);
410  ptr += paramSize;
411  }
412  *allocSize += sizeToAdd;
413  setSizeToHeader(buffer, (PKTHEAD_TOTLEN_TYPE)*allocSize);
414  incrHeaderParamsNum(buffer);
415  }
416  }
417  return buffer;
418 }
419 c_use_decl_annotations uint8_t* serialize_int32_t(const int32_t *src, uint32_t num, uint8_t *buffer, size_t *allocSize) {
420  const c_type_t type = TYPE_INT32;
421  size_t paramSize = getSizeOfType(type);
422  size_t sizeToAdd = sizeof(PARAMTYPE_TYPE) + sizeof(PARAMNUM_TYPE) + (num * paramSize);
423  if (buffer == NULL || *allocSize == 0) {
424  buffer = NULL; // TODO possible memleak
425  *allocSize = 0;
426  }
427  else {
428  if (!checkProtoVersPtr(buffer, 0)) // Check buffer starting with header
429  return NULL;
430  // realloc buffer to host new parameter
431  buffer = c_realloc(buffer, *allocSize + sizeToAdd);
432  if (buffer == NULL) // Check buffer allocation
433  return NULL;
434  else {
435  uint8_t *ptr = buffer + *allocSize; // Point to the new buffer's free space
436  PARAMTYPE_TYPE pType = ptypeton(type);
437  PARAMNUM_TYPE pNum = pnumton((PARAMNUM_TYPE)num);
438  // Copy ParamType to buffer
439  c_memcpy(ptr, &pType, sizeof(PARAMTYPE_TYPE));
440  ptr += sizeof(PARAMTYPE_TYPE);
441  // Copy ParamNum to buffer
442  c_memcpy(ptr, &pNum, sizeof(PARAMNUM_TYPE));
443  ptr += sizeof(PARAMNUM_TYPE);
444  // Copy parameters to buffer
445  for (uint32_t i = 0; i < num; i++) {
446  int32_t value = c_hton32(src[i]);
447  c_memcpy(ptr, &value, paramSize);
448  ptr += paramSize;
449  }
450  *allocSize += sizeToAdd;
451  setSizeToHeader(buffer, (PKTHEAD_TOTLEN_TYPE)*allocSize);
452  incrHeaderParamsNum(buffer);
453  }
454  }
455  return buffer;
456 }
457 c_use_decl_annotations uint8_t* serialize_uint32_t(const uint32_t *src, uint32_t num, uint8_t *buffer, size_t *allocSize) {
458  const c_type_t type = TYPE_UINT32;
459  size_t paramSize = getSizeOfType(type);
460  size_t sizeToAdd = sizeof(PARAMTYPE_TYPE) + sizeof(PARAMNUM_TYPE) + (num * paramSize);
461  if (buffer == NULL || *allocSize == 0) {
462  buffer = NULL; // TODO possible memleak
463  *allocSize = 0;
464  }
465  else {
466  if (!checkProtoVersPtr(buffer, 0)) // Check buffer starting with header
467  return NULL;
468  // realloc buffer to host new parameter
469  buffer = c_realloc(buffer, *allocSize + sizeToAdd);
470  if (buffer == NULL) // Check buffer allocation
471  return NULL;
472  else {
473  uint8_t *ptr = buffer + *allocSize; // Point to the new buffer's free space
474  PARAMTYPE_TYPE pType = ptypeton(type);
475  PARAMNUM_TYPE pNum = pnumton((PARAMNUM_TYPE)num);
476  // Copy ParamType to buffer
477  c_memcpy(ptr, &pType, sizeof(PARAMTYPE_TYPE));
478  ptr += sizeof(PARAMTYPE_TYPE);
479  // Copy ParamNum to buffer
480  c_memcpy(ptr, &pNum, sizeof(PARAMNUM_TYPE));
481  ptr += sizeof(PARAMNUM_TYPE);
482  // Copy parameters to buffer
483  for (uint32_t i = 0; i < num; i++) {
484  uint32_t value = c_hton32(src[i]);
485  c_memcpy(ptr, &value, paramSize);
486  ptr += paramSize;
487  }
488  *allocSize += sizeToAdd;
489  setSizeToHeader(buffer, (PKTHEAD_TOTLEN_TYPE)*allocSize);
490  incrHeaderParamsNum(buffer);
491  }
492  }
493  return buffer;
494 }
495 c_use_decl_annotations uint8_t* serialize_int64_t(const int64_t *src, uint32_t num, uint8_t *buffer, size_t *allocSize) {
496  const c_type_t type = TYPE_INT64;
497  size_t paramSize = getSizeOfType(type);
498  size_t sizeToAdd = sizeof(PARAMTYPE_TYPE) + sizeof(PARAMNUM_TYPE) + (num * paramSize);
499  if (buffer == NULL || *allocSize == 0) {
500  buffer = NULL; // TODO possible memleak
501  *allocSize = 0;
502  }
503  else {
504  if (!checkProtoVersPtr(buffer, 0)) // Check buffer starting with header
505  return NULL;
506  // realloc buffer to host new parameter
507  buffer = c_realloc(buffer, *allocSize + sizeToAdd);
508  if (buffer == NULL) // Check buffer allocation
509  return NULL;
510  else {
511  uint8_t *ptr = buffer + *allocSize; // Point to the new buffer's free space
512  PARAMTYPE_TYPE pType = ptypeton(type);
513  PARAMNUM_TYPE pNum = pnumton((PARAMNUM_TYPE)num);
514  // Copy ParamType to buffer
515  c_memcpy(ptr, &pType, sizeof(PARAMTYPE_TYPE));
516  ptr += sizeof(PARAMTYPE_TYPE);
517  // Copy ParamNum to buffer
518  c_memcpy(ptr, &pNum, sizeof(PARAMNUM_TYPE));
519  ptr += sizeof(PARAMNUM_TYPE);
520  // Copy parameters to buffer
521  for (uint32_t i = 0; i < num; i++) {
522  int64_t value = c_hton64(src[i]);
523  c_memcpy(ptr, &value, paramSize);
524  ptr += paramSize;
525  }
526  *allocSize += sizeToAdd;
527  setSizeToHeader(buffer, (PKTHEAD_TOTLEN_TYPE)*allocSize);
528  incrHeaderParamsNum(buffer);
529  }
530  }
531  return buffer;
532 }
533 c_use_decl_annotations uint8_t* serialize_uint64_t(const uint64_t *src, uint32_t num, uint8_t *buffer, size_t *allocSize) {
534  const c_type_t type = TYPE_UINT64;
535  size_t paramSize = getSizeOfType(type);
536  size_t sizeToAdd = sizeof(PARAMTYPE_TYPE) + sizeof(PARAMNUM_TYPE) + (num * paramSize);
537  if (buffer == NULL || *allocSize == 0) {
538  buffer = NULL; // TODO possible memleak
539  *allocSize = 0;
540  }
541  else {
542  if (!checkProtoVersPtr(buffer, 0)) // Check buffer starting with header
543  return NULL;
544  // realloc buffer to host new parameter
545  buffer = c_realloc(buffer, *allocSize + sizeToAdd);
546  if (buffer == NULL) // Check buffer allocation
547  return NULL;
548  else {
549  uint8_t *ptr = buffer + *allocSize; // Point to the new buffer's free space
550  PARAMTYPE_TYPE pType = ptypeton(type);
551  PARAMNUM_TYPE pNum = pnumton((PARAMNUM_TYPE)num);
552  // Copy ParamType to buffer
553  c_memcpy(ptr, &pType, sizeof(PARAMTYPE_TYPE));
554  ptr += sizeof(PARAMTYPE_TYPE);
555  // Copy ParamNum to buffer
556  c_memcpy(ptr, &pNum, sizeof(PARAMNUM_TYPE));
557  ptr += sizeof(PARAMNUM_TYPE);
558  // Copy parameters to buffer
559  for (uint32_t i = 0; i < num; i++) {
560  uint64_t value = c_hton64(src[i]);
561  c_memcpy(ptr, &value, paramSize);
562  ptr += paramSize;
563  }
564  *allocSize += sizeToAdd;
565  setSizeToHeader(buffer, (PKTHEAD_TOTLEN_TYPE)*allocSize);
566  incrHeaderParamsNum(buffer);
567  }
568  }
569  return buffer;
570 }
571 c_use_decl_annotations uint8_t* serialize_float(const float *src, uint32_t num, uint8_t *buffer, size_t *allocSize) {
572  // cppcheck-suppress invalidPointerCast
573  return serialize_int32_t((const int32_t*)src, num, buffer, allocSize);
574 }
575 c_use_decl_annotations uint8_t* serialize_double(const double *src, uint32_t num, uint8_t *buffer, size_t *allocSize) {
576  int64_t *mantissa = c_malloc(num * sizeof(*mantissa));
577  int16_t *exponent = c_malloc(num * sizeof(*exponent));
578  int8_t *classification = c_malloc(num * sizeof(*classification));
579 
580  if (mantissa == NULL || exponent == NULL || classification == NULL) {
581  buffer = NULL;
582  goto exit;
583  }
584 
585  // Expand double values in mantissa, exponent and classification
586  for (uint32_t i = 0; i < num; i++)
587  mantissa[i] = c_frexp(src[i], &exponent[i], &classification[i]);
588 
589  // Serialize them separately
590  buffer = serialize_int64_t(mantissa, num, buffer, allocSize);
591  buffer = serialize_int16_t(exponent, num, buffer, allocSize);
592  buffer = serialize_int8_t(classification, num, buffer, allocSize);
593 
594 exit:
595 
596  c_free(mantissa);
597  c_free(exponent);
598  c_free(classification);
599 
600  return buffer;
601 }
602 
603 // Deserialize of base types
604 c_use_decl_annotations uint8_t* deserialize_int8_t(int8_t *dest, uint32_t num, uint8_t *buffer) {
605  PARAMTYPE_TYPE type;
606  PARAMNUM_TYPE gNum = 0;
607  const c_type_t expType = TYPE_INT8;
608  size_t pSize = getSizeOfType(expType);
609  if (buffer == NULL)
610  return NULL;
611 
612  // Get param type (accept identically signed and unsigned)
613  c_memcpy(&type, buffer, sizeof(PARAMTYPE_TYPE));
614  type = ntoptype(type);
615  if (type != expType && type != toggleSigned(expType)) // Invalid type.
616  return NULL;
617  buffer += sizeof(PARAMTYPE_TYPE);
618 
619  // Get param num
620  c_memcpy(&gNum, buffer, sizeof(PARAMNUM_TYPE));
621  gNum = ntopnum(gNum);
622  if (gNum != num) // Wrong parameters number.
623  return NULL;
624  buffer += sizeof(PARAMNUM_TYPE);
625 
626  // Get params
627  // NOTE: for byte-sized types we can simply memcopy
628  // since we don't have endianness problems.
629  c_memcpy(dest, buffer, num * pSize);
630  buffer += num * pSize;
631 
632  return buffer;
633 }
634 c_use_decl_annotations uint8_t* deserialize_int8_t_array(int8_t *dest, uint32_t maxnum, uint32_t *num, uint8_t *buffer) {
635  PARAMTYPE_TYPE type;
636  PARAMNUM_TYPE gNum = 0;
637  const c_type_t expType = TYPE_INT8;
638  size_t pSize = getSizeOfType(expType);
639  if (buffer == NULL)
640  return NULL;
641 
642  // Get param type (accept identically signed and unsigned)
643  c_memcpy(&type, buffer, sizeof(PARAMTYPE_TYPE));
644  type = ntoptype(type);
645  if (type != expType && type != toggleSigned(expType)) // Invalid type.
646  return NULL;
647  buffer += sizeof(PARAMTYPE_TYPE);
648 
649  // Get param num
650  c_memcpy(&gNum, buffer, sizeof(PARAMNUM_TYPE));
651  gNum = ntopnum(gNum);
652 
653  if (gNum > maxnum) // Error
654  return NULL;
655 
656  *num = gNum;
657  buffer += sizeof(PARAMNUM_TYPE);
658 
659  // Get params
660  // NOTE: for byte-sized types we can simply memcopy
661  // since we don't have endianness problems.
662  c_memcpy(dest, buffer, gNum * pSize);
663  buffer += gNum * pSize;
664 
665  return buffer;
666 }
667 c_use_decl_annotations uint8_t* deserialize_char(char *dest, uint32_t maxnum, uint8_t *buffer) {
668  //return deserialize_int8_t((int8_t*)dest, num, buffer);
669  uint32_t num;
670  buffer = deserialize_int8_t_array((int8_t*)dest, maxnum, &num, buffer);
671  // if the function succeded, memset the remaining string to 0
672  if (buffer != NULL)
673  c_zeromem(&dest[num], maxnum - num);
674  return buffer;
675 }
676 c_use_decl_annotations uint8_t* deserialize_uint8_t(uint8_t *dest, uint32_t num, uint8_t *buffer) {
677  PARAMTYPE_TYPE type;
678  PARAMNUM_TYPE gNum = 0;
679  const c_type_t expType = TYPE_UINT8;
680  size_t pSize = getSizeOfType(expType);
681  if (buffer == NULL)
682  return NULL;
683 
684  // Get param type (accept identically signed and unsigned)
685  c_memcpy(&type, buffer, sizeof(PARAMTYPE_TYPE));
686  type = ntoptype(type);
687  if (type != expType && type != toggleSigned(expType)) // Invalid type.
688  return NULL;
689  buffer += sizeof(PARAMTYPE_TYPE);
690 
691  // Get param num
692  c_memcpy(&gNum, buffer, sizeof(PARAMNUM_TYPE));
693  gNum = ntopnum(gNum);
694  if (gNum != num) // Wrong parameters number.
695  return NULL;
696  buffer += sizeof(PARAMNUM_TYPE);
697 
698  // Get params
699  // NOTE: for byte-sized types we can simply memcopy
700  // since we don't have endianness problems.
701  c_memcpy(dest, buffer, num * pSize);
702  buffer += num * pSize;
703 
704  return buffer;
705 }
706 c_use_decl_annotations uint8_t* deserialize_uint8_t_array(uint8_t *dest, uint32_t maxnum, uint32_t *num, uint8_t *buffer) {
707  PARAMTYPE_TYPE type;
708  PARAMNUM_TYPE gNum = 0;
709  const c_type_t expType = TYPE_UINT8;
710  size_t pSize = getSizeOfType(expType);
711  if (buffer == NULL)
712  return NULL;
713 
714  // Get param type (accept identically signed and unsigned)
715  c_memcpy(&type, buffer, sizeof(PARAMTYPE_TYPE));
716  type = ntoptype(type);
717  if (type != expType && type != toggleSigned(expType)) // Invalid type.
718  return NULL;
719  buffer += sizeof(PARAMTYPE_TYPE);
720 
721  // Get param num
722  c_memcpy(&gNum, buffer, sizeof(PARAMNUM_TYPE));
723  gNum = ntopnum(gNum);
724 
725  if (gNum > maxnum) // Error
726  return NULL;
727 
728  *num = gNum;
729  buffer += sizeof(PARAMNUM_TYPE);
730 
731  // Get params
732  // NOTE: for byte-sized types we can simply memcopy
733  // since we don't have endianness problems.
734  c_memcpy(dest, buffer, gNum * pSize);
735  buffer += gNum * pSize;
736 
737  return buffer;
738 }
739 c_use_decl_annotations uint8_t* deserialize_int16_t(int16_t *dest, uint32_t num, uint8_t *buffer) {
740  PARAMTYPE_TYPE type;
741  PARAMNUM_TYPE gNum = 0;
742  const c_type_t expType = TYPE_INT16;
743  size_t pSize = getSizeOfType(expType);
744  if (buffer == NULL)
745  return NULL;
746 
747  // Get param type (accept identically signed and unsigned)
748  c_memcpy(&type, buffer, sizeof(PARAMTYPE_TYPE));
749  type = ntoptype(type);
750  if (type != expType && type != toggleSigned(expType)) // Invalid type.
751  return NULL;
752  buffer += sizeof(PARAMTYPE_TYPE);
753 
754  // Get param num
755  c_memcpy(&gNum, buffer, sizeof(PARAMNUM_TYPE));
756  gNum = ntopnum(gNum);
757  if (gNum != num) // Wrong parameters number.
758  return NULL;
759  buffer += sizeof(PARAMNUM_TYPE);
760 
761  // Get params
762  for (uint32_t i = 0; i < num; i++) {
763  c_memcpy(&dest[i], buffer, pSize);
764  dest[i] = c_ntoh16(dest[i]);
765  buffer += pSize;
766  }
767 
768  return buffer;
769 }
770 c_use_decl_annotations uint8_t* deserialize_int16_t_array(int16_t *dest, uint32_t maxnum, uint32_t *num, uint8_t *buffer) {
771  PARAMTYPE_TYPE type;
772  PARAMNUM_TYPE gNum = 0;
773  const c_type_t expType = TYPE_INT16;
774  size_t pSize = getSizeOfType(expType);
775  if (buffer == NULL)
776  return NULL;
777 
778  // Get param type (accept identically signed and unsigned)
779  c_memcpy(&type, buffer, sizeof(PARAMTYPE_TYPE));
780  type = ntoptype(type);
781  if (type != expType && type != toggleSigned(expType)) // Invalid type.
782  return NULL;
783  buffer += sizeof(PARAMTYPE_TYPE);
784 
785  // Get param num
786  c_memcpy(&gNum, buffer, sizeof(PARAMNUM_TYPE));
787  gNum = ntopnum(gNum);
788  if (gNum > maxnum) // Too much parameters
789  return NULL;
790  *num = gNum;
791  buffer += sizeof(PARAMNUM_TYPE);
792 
793  // Get params
794  for (uint32_t i = 0; i < gNum; i++) {
795  c_memcpy(&dest[i], buffer, pSize);
796  dest[i] = c_ntoh16(dest[i]);
797  buffer += pSize;
798  }
799 
800  return buffer;
801 }
802 c_use_decl_annotations uint8_t* deserialize_uint16_t(uint16_t *dest, uint32_t num, uint8_t *buffer) {
803  PARAMTYPE_TYPE type;
804  PARAMNUM_TYPE gNum = 0;
805  const c_type_t expType = TYPE_UINT16;
806  size_t pSize = getSizeOfType(expType);
807  if (buffer == NULL)
808  return NULL;
809 
810  // Get param type (accept identically signed and unsigned)
811  c_memcpy(&type, buffer, sizeof(PARAMTYPE_TYPE));
812  type = ntoptype(type);
813  if (type != expType && type != toggleSigned(expType)) // Invalid type.
814  return NULL;
815  buffer += sizeof(PARAMTYPE_TYPE);
816 
817  // Get param num
818  c_memcpy(&gNum, buffer, sizeof(PARAMNUM_TYPE));
819  gNum = ntopnum(gNum);
820  if (gNum != num) // Wrong parameters number.
821  return NULL;
822  buffer += sizeof(PARAMNUM_TYPE);
823 
824  // Get params
825  for (uint32_t i = 0; i < num; i++) {
826  c_memcpy(&dest[i], buffer, pSize);
827  dest[i] = c_ntoh16(dest[i]);
828  buffer += pSize;
829  }
830 
831  return buffer;
832 }
833 c_use_decl_annotations uint8_t* deserialize_uint16_t_array(uint16_t *dest, uint32_t maxnum, uint32_t *num, uint8_t *buffer) {
834  PARAMTYPE_TYPE type;
835  PARAMNUM_TYPE gNum = 0;
836  const c_type_t expType = TYPE_UINT16;
837  size_t pSize = getSizeOfType(expType);
838  if (buffer == NULL)
839  return NULL;
840 
841  // Get param type (accept identically signed and unsigned)
842  c_memcpy(&type, buffer, sizeof(PARAMTYPE_TYPE));
843  type = ntoptype(type);
844  if (type != expType && type != toggleSigned(expType)) // Invalid type.
845  return NULL;
846  buffer += sizeof(PARAMTYPE_TYPE);
847 
848  // Get param num
849  c_memcpy(&gNum, buffer, sizeof(PARAMNUM_TYPE));
850  gNum = ntopnum(gNum);
851  if (gNum > maxnum) // Too much parameters
852  return NULL;
853  *num = gNum;
854  buffer += sizeof(PARAMNUM_TYPE);
855 
856  // Get params
857  for (uint32_t i = 0; i < gNum; i++) {
858  c_memcpy(&dest[i], buffer, pSize);
859  dest[i] = c_ntoh16(dest[i]);
860  buffer += pSize;
861  }
862 
863  return buffer;
864 }
865 c_use_decl_annotations uint8_t* deserialize_int32_t(int32_t *dest, uint32_t num, uint8_t *buffer) {
866  PARAMTYPE_TYPE type;
867  PARAMNUM_TYPE gNum = 0;
868  const c_type_t expType = TYPE_INT32;
869  size_t pSize = getSizeOfType(expType);
870  if (buffer == NULL)
871  return NULL;
872 
873  // Get param type (accept identically signed and unsigned)
874  c_memcpy(&type, buffer, sizeof(PARAMTYPE_TYPE));
875  type = ntoptype(type);
876  if (type != expType && type != toggleSigned(expType)) // Invalid type.
877  return NULL;
878  buffer += sizeof(PARAMTYPE_TYPE);
879 
880  // Get param num
881  c_memcpy(&gNum, buffer, sizeof(PARAMNUM_TYPE));
882  gNum = ntopnum(gNum);
883  if (gNum != num) // Wrong parameters number.
884  return NULL;
885  buffer += sizeof(PARAMNUM_TYPE);
886 
887  // Get params
888  for (uint32_t i = 0; i < num; i++) {
889  c_memcpy(&dest[i], buffer, pSize);
890  dest[i] = c_ntoh32(dest[i]);
891  buffer += pSize;
892  }
893 
894  return buffer;
895 }
896 c_use_decl_annotations uint8_t* deserialize_int32_t_array(int32_t *dest, uint32_t maxnum, uint32_t *num, uint8_t *buffer) {
897  PARAMTYPE_TYPE type;
898  PARAMNUM_TYPE gNum = 0;
899  const c_type_t expType = TYPE_INT32;
900  size_t pSize = getSizeOfType(expType);
901  if (buffer == NULL)
902  return NULL;
903 
904  // Get param type (accept identically signed and unsigned)
905  c_memcpy(&type, buffer, sizeof(PARAMTYPE_TYPE));
906  type = ntoptype(type);
907  if (type != expType && type != toggleSigned(expType)) // Invalid type.
908  return NULL;
909  buffer += sizeof(PARAMTYPE_TYPE);
910 
911  // Get param num
912  c_memcpy(&gNum, buffer, sizeof(PARAMNUM_TYPE));
913  gNum = ntopnum(gNum);
914  if (gNum > maxnum) // Too much parameters
915  return NULL;
916  *num = gNum;
917  buffer += sizeof(PARAMNUM_TYPE);
918 
919  // Get params
920  for (uint32_t i = 0; i < gNum; i++) {
921  c_memcpy(&dest[i], buffer, pSize);
922  dest[i] = c_ntoh32(dest[i]);
923  buffer += pSize;
924  }
925 
926  return buffer;
927 }
928 c_use_decl_annotations uint8_t* deserialize_uint32_t(uint32_t *dest, uint32_t num, uint8_t *buffer) {
929  PARAMTYPE_TYPE type;
930  PARAMNUM_TYPE gNum = 0;
931  const c_type_t expType = TYPE_UINT32;
932  size_t pSize = getSizeOfType(expType);
933  if (buffer == NULL)
934  return NULL;
935 
936  // Get param type (accept identically signed and unsigned)
937  c_memcpy(&type, buffer, sizeof(PARAMTYPE_TYPE));
938  type = ntoptype(type);
939  if (type != expType && type != toggleSigned(expType)) // Invalid type.
940  return NULL;
941  buffer += sizeof(PARAMTYPE_TYPE);
942 
943  // Get param num
944  c_memcpy(&gNum, buffer, sizeof(PARAMNUM_TYPE));
945  gNum = ntopnum(gNum);
946  if (gNum != num) // Wrong parameters number.
947  return NULL;
948  buffer += sizeof(PARAMNUM_TYPE);
949 
950  // Get params
951  for (uint32_t i = 0; i < num; i++) {
952  c_memcpy(&dest[i], buffer, pSize);
953  dest[i] = c_ntoh32(dest[i]);
954  buffer += pSize;
955  }
956 
957  return buffer;
958 }
959 c_use_decl_annotations uint8_t* deserialize_uint32_t_array(uint32_t *dest, uint32_t maxnum, uint32_t *num, uint8_t *buffer) {
960  PARAMTYPE_TYPE type;
961  PARAMNUM_TYPE gNum = 0;
962  const c_type_t expType = TYPE_UINT32;
963  size_t pSize = getSizeOfType(expType);
964  if (buffer == NULL)
965  return NULL;
966 
967  // Get param type (accept identically signed and unsigned)
968  c_memcpy(&type, buffer, sizeof(PARAMTYPE_TYPE));
969  type = ntoptype(type);
970  if (type != expType && type != toggleSigned(expType)) // Invalid type.
971  return NULL;
972  buffer += sizeof(PARAMTYPE_TYPE);
973 
974  // Get param num
975  c_memcpy(&gNum, buffer, sizeof(PARAMNUM_TYPE));
976  gNum = ntopnum(gNum);
977  if (gNum > maxnum) // Too much parameters
978  return NULL;
979  *num = gNum;
980  buffer += sizeof(PARAMNUM_TYPE);
981 
982  // Get params
983  for (uint32_t i = 0; i < gNum; i++) {
984  c_memcpy(&dest[i], buffer, pSize);
985  dest[i] = c_ntoh32(dest[i]);
986  buffer += pSize;
987  }
988 
989  return buffer;
990 }
991 c_use_decl_annotations uint8_t* deserialize_int64_t(int64_t *dest, uint32_t num, uint8_t *buffer) {
992  PARAMTYPE_TYPE type;
993  PARAMNUM_TYPE gNum = 0;
994  const c_type_t expType = TYPE_INT64;
995  size_t pSize = getSizeOfType(expType);
996  if (buffer == NULL)
997  return NULL;
998 
999  // Get param type (accept identically signed and unsigned)
1000  c_memcpy(&type, buffer, sizeof(PARAMTYPE_TYPE));
1001  type = ntoptype(type);
1002  if (type != expType && type != toggleSigned(expType)) // Invalid type.
1003  return NULL;
1004  buffer += sizeof(PARAMTYPE_TYPE);
1005 
1006  // Get param num
1007  c_memcpy(&gNum, buffer, sizeof(PARAMNUM_TYPE));
1008  gNum = ntopnum(gNum);
1009  if (gNum != num) // Wrong parameters number.
1010  return NULL;
1011  buffer += sizeof(PARAMNUM_TYPE);
1012 
1013  // Get params
1014  for (uint32_t i = 0; i < num; i++) {
1015  c_memcpy(&dest[i], buffer, pSize);
1016  dest[i] = c_ntoh64(dest[i]);
1017  buffer += pSize;
1018  }
1019 
1020  return buffer;
1021 }
1022 c_use_decl_annotations uint8_t* deserialize_int64_t_array(int64_t *dest, uint32_t maxnum, uint32_t *num, uint8_t *buffer) {
1023  PARAMTYPE_TYPE type;
1024  PARAMNUM_TYPE gNum = 0;
1025  const c_type_t expType = TYPE_INT64;
1026  size_t pSize = getSizeOfType(expType);
1027  if (buffer == NULL)
1028  return NULL;
1029 
1030  // Get param type (accept identically signed and unsigned)
1031  c_memcpy(&type, buffer, sizeof(PARAMTYPE_TYPE));
1032  type = ntoptype(type);
1033  if (type != expType && type != toggleSigned(expType)) // Invalid type.
1034  return NULL;
1035  buffer += sizeof(PARAMTYPE_TYPE);
1036 
1037  // Get param num
1038  c_memcpy(&gNum, buffer, sizeof(PARAMNUM_TYPE));
1039  gNum = ntopnum(gNum);
1040  if (gNum > maxnum) // Too much parameters
1041  return NULL;
1042  *num = gNum;
1043  buffer += sizeof(PARAMNUM_TYPE);
1044 
1045  // Get params
1046  for (uint32_t i = 0; i < gNum; i++) {
1047  c_memcpy(&dest[i], buffer, pSize);
1048  dest[i] = c_ntoh64(dest[i]);
1049  buffer += pSize;
1050  }
1051 
1052  return buffer;
1053 }
1054 c_use_decl_annotations uint8_t* deserialize_uint64_t(uint64_t *dest, uint32_t num, uint8_t *buffer) {
1055  PARAMTYPE_TYPE type;
1056  PARAMNUM_TYPE gNum = 0;
1057  const c_type_t expType = TYPE_UINT64;
1058  size_t pSize = getSizeOfType(expType);
1059  if (buffer == NULL)
1060  return NULL;
1061 
1062  // Get param type (accept identically signed and unsigned)
1063  c_memcpy(&type, buffer, sizeof(PARAMTYPE_TYPE));
1064  type = ntoptype(type);
1065  if (type != expType && type != toggleSigned(expType)) // Invalid type.
1066  return NULL;
1067  buffer += sizeof(PARAMTYPE_TYPE);
1068 
1069  // Get param num
1070  c_memcpy(&gNum, buffer, sizeof(PARAMNUM_TYPE));
1071  gNum = ntopnum(gNum);
1072  if (gNum != num) // Wrong parameters number.
1073  return NULL;
1074  buffer += sizeof(PARAMNUM_TYPE);
1075 
1076  // Get params
1077  for (uint32_t i = 0; i < num; i++) {
1078  c_memcpy(&dest[i], buffer, pSize);
1079  dest[i] = c_ntoh64(dest[i]);
1080  buffer += pSize;
1081  }
1082 
1083  return buffer;
1084 }
1085 c_use_decl_annotations uint8_t* deserialize_uint64_t_array(uint64_t *dest, uint32_t maxnum, uint32_t *num, uint8_t *buffer) {
1086  PARAMTYPE_TYPE type;
1087  PARAMNUM_TYPE gNum = 0;
1088  const c_type_t expType = TYPE_UINT64;
1089  size_t pSize = getSizeOfType(expType);
1090  if (buffer == NULL)
1091  return NULL;
1092 
1093  // Get param type (accept identically signed and unsigned)
1094  c_memcpy(&type, buffer, sizeof(PARAMTYPE_TYPE));
1095  type = ntoptype(type);
1096  if (type != expType && type != toggleSigned(expType)) // Invalid type.
1097  return NULL;
1098  buffer += sizeof(PARAMTYPE_TYPE);
1099 
1100  // Get param num
1101  c_memcpy(&gNum, buffer, sizeof(PARAMNUM_TYPE));
1102  gNum = ntopnum(gNum);
1103  if (gNum > maxnum) // Too much parameters
1104  return NULL;
1105  *num = gNum;
1106  buffer += sizeof(PARAMNUM_TYPE);
1107 
1108  // Get params
1109  for (uint32_t i = 0; i < gNum; i++) {
1110  c_memcpy(&dest[i], buffer, pSize);
1111  dest[i] = c_ntoh64(dest[i]);
1112  buffer += pSize;
1113  }
1114 
1115  return buffer;
1116 }
1117 c_use_decl_annotations uint8_t* deserialize_float(float *dest, uint32_t num, uint8_t *buffer) {
1118  // cppcheck-suppress invalidPointerCast
1119  return deserialize_int32_t((int32_t*)dest, num, buffer);
1120 }
1121 c_use_decl_annotations uint8_t* deserialize_float_array(float *dest, uint32_t maxnum, uint32_t *num, uint8_t *buffer) {
1122  // cppcheck-suppress invalidPointerCast
1123  return deserialize_int32_t_array((int32_t*)dest, maxnum, num, buffer);
1124 }
1125 c_use_decl_annotations uint8_t* deserialize_double(double *dest, uint32_t num, uint8_t *buffer) {
1126  int64_t *mantissa = c_malloc(num * sizeof(*mantissa));
1127  int16_t *exponent = c_malloc(num * sizeof(*exponent));
1128  int8_t *classification = c_malloc(num * sizeof(*classification));
1129 
1130  if (mantissa == NULL || exponent == NULL || classification == NULL) {
1131  buffer = NULL;
1132  goto exit;
1133  }
1134 
1135  // Serialize them separately
1136  buffer = deserialize_int64_t(mantissa, num, buffer);
1137  buffer = deserialize_int16_t(exponent, num, buffer);
1138  buffer = deserialize_int8_t(classification, num, buffer);
1139 
1140  // Expand double values in mantissa, exponent and classification
1141  for (uint32_t i = 0; i < num; i++)
1142  dest[i] = c_ldexp(mantissa[i], exponent[i], classification[i]);
1143 
1144 exit:
1145 
1146  c_free(mantissa);
1147  c_free(exponent);
1148  c_free(classification);
1149 
1150  return buffer;
1151 }
1152 c_use_decl_annotations uint8_t* deserialize_double_array(double *dest, uint32_t maxnum, uint32_t *num, uint8_t *buffer) {
1153  int64_t *mantissa = c_malloc(maxnum * sizeof(*mantissa));
1154  int16_t *exponent = c_malloc(maxnum * sizeof(*exponent));
1155  int8_t *classification = c_malloc(maxnum * sizeof(*classification));
1156 
1157  if (mantissa == NULL || exponent == NULL || classification == NULL) {
1158  buffer = NULL;
1159  goto exit;
1160  }
1161 
1162  // Serialize them separately
1163  buffer = deserialize_int64_t_array(mantissa, maxnum, num, buffer);
1164  buffer = deserialize_int16_t_array(exponent, maxnum, num, buffer);
1165  buffer = deserialize_int8_t_array(classification, maxnum, num, buffer);
1166 
1167  // Expand double values in mantissa, exponent and classification
1168  for (uint32_t i = 0; i < *num; i++)
1169  dest[i] = c_ldexp(mantissa[i], exponent[i], classification[i]);
1170 
1171 exit:
1172 
1173  c_free(mantissa);
1174  c_free(exponent);
1175  c_free(classification);
1176 
1177  return buffer;
1178 }
uint8_t * deserialize_float_array(float *dest, uint32_t maxnum, uint32_t *num, uint8_t *buffer)
Definition: CAENSerDes.c:1121
uint8_t * deserialize_double(double *dest, uint32_t num, uint8_t *buffer)
Definition: CAENSerDes.c:1125
uint8_t * deserialize_uint8_t_array(uint8_t *dest, uint32_t maxnum, uint32_t *num, uint8_t *buffer)
Definition: CAENSerDes.c:706
static PKTHEAD_NPARAMS_TYPE * getParamsNumPtr(uint8_t *header)
Definition: CAENSerDes.c:81
c_mutex_t mutex
A mutex, use by some functions.
static uint64_t c_hton64(uint64_t x)
uint8_t * deserialize_int8_t(int8_t *dest, uint32_t num, uint8_t *buffer)
Definition: CAENSerDes.c:604
static const PKTHEAD_PROTOVERS_TYPE * getProtoVersConstPtr(const uint8_t *header)
Definition: CAENSerDes.c:61
static void * c_memcpy(void *__restrict dest, const void *__restrict src, size_t size)
Wrapper to memcpy(dest, src, size), with check for NULL arguments.
PKTHEAD_CMD_TYPE c_getcmd(const uint8_t *buffer)
Definition: CAENSerDes.c:154
uint8_t * deserialize_double_array(double *dest, uint32_t maxnum, uint32_t *num, uint8_t *buffer)
Definition: CAENSerDes.c:1152
static PKTHEAD_PROTOVERS_TYPE * getProtoVersPtr(uint8_t *header)
Definition: CAENSerDes.c:56
static uint32_t c_ntoh32(uint32_t x)
uint8_t * deserialize_int64_t_array(int64_t *dest, uint32_t maxnum, uint32_t *num, uint8_t *buffer)
Definition: CAENSerDes.c:1022
uint8_t * deserialize_int8_t_array(int8_t *dest, uint32_t maxnum, uint32_t *num, uint8_t *buffer)
Definition: CAENSerDes.c:634
void c_free(void *ptr)
static size_t getSizeOfType(c_type_t t)
Definition: CAENSerDes.c:107
uint8_t * deserialize_uint64_t(uint64_t *dest, uint32_t num, uint8_t *buffer)
Definition: CAENSerDes.c:1054
static PKTHEAD_TOTLEN_TYPE * setSizeToHeader(uint8_t *header, PKTHEAD_TOTLEN_TYPE size)
Definition: CAENSerDes.c:92
uint8_t * deserialize_uint32_t(uint32_t *dest, uint32_t num, uint8_t *buffer)
Definition: CAENSerDes.c:928
#define PKTHEAD_PROTOVERS_SIZE
Definition: CAENSerDes.c:50
uint8_t * deserialize_uint16_t_array(uint16_t *dest, uint32_t maxnum, uint32_t *num, uint8_t *buffer)
Definition: CAENSerDes.c:833
#define PKTHEAD_CMD_SIZE
Definition: CAENSerDes.c:52
uint8_t * c_createheader(uint16_t version, PKTHEAD_CMD_TYPE cmd, size_t *allocatedSize)
Definition: CAENSerDes.c:129
uint8_t * deserialize_uint32_t_array(uint32_t *dest, uint32_t maxnum, uint32_t *num, uint8_t *buffer)
Definition: CAENSerDes.c:959
uint8_t * c_recv_packet(const c_socket_t *sckt, PKTHEAD_CMD_TYPE *cmd, PKTHEAD_TOTLEN_TYPE *totSize, PKTHEAD_NPARAMS_TYPE *totParams)
Definition: CAENSerDes.c:163
TCP/IP CAEN protocol.
uint8_t * serialize_int32_t(const int32_t *src, uint32_t num, uint8_t *buffer, size_t *allocSize)
Definition: CAENSerDes.c:419
uint8_t * deserialize_int32_t_array(int32_t *dest, uint32_t maxnum, uint32_t *num, uint8_t *buffer)
Definition: CAENSerDes.c:896
uint16_t PKTHEAD_NPARAMS_TYPE
uint8_t * serialize_uint64_t(const uint64_t *src, uint32_t num, uint8_t *buffer, size_t *allocSize)
Definition: CAENSerDes.c:533
uint8_t * deserialize_char(char *dest, uint32_t maxnum, uint8_t *buffer)
Definition: CAENSerDes.c:667
static c_type_t toggleSigned(c_type_t type)
Definition: CAENSerDes.c:247
static PARAMNUM_TYPE ntopnum(PARAMNUM_TYPE type)
Definition: CAENSerDes.c:243
c_type_t
Type of data.
Definition: CAENUtility.h:298
#define CMD_INVALID_LOCAL
The only commang code defined here, as used as return value in case of error. MUST be 0xFFFF...
uint8_t * deserialize_int16_t(int16_t *dest, uint32_t num, uint8_t *buffer)
Definition: CAENSerDes.c:739
uint16_t PKTHEAD_PROTOVERS_TYPE
TCP/IP functions.
uint8_t * deserialize_uint16_t(uint16_t *dest, uint32_t num, uint8_t *buffer)
Definition: CAENSerDes.c:802
uint8_t * deserialize_int16_t_array(int16_t *dest, uint32_t maxnum, uint32_t *num, uint8_t *buffer)
Definition: CAENSerDes.c:770
#define CAEN_PKT_VERSION(_VER)
static uint16_t c_hton16(uint16_t x)
Functions to handle threads, inspired to C11 threads.h.
void * c_malloc(size_t size)
static bool checkProtoVersPtr(const uint8_t *header, uint8_t version)
Definition: CAENSerDes.c:86
double c_ldexp(int64_t mantissa, int16_t exponent, int8_t classification)
Generic wrappers to platform-dependent functions.
#define INIT_C_LOGGER(fname, mname)
Definition: CAENLogger.h:139
uint8_t * deserialize_float(float *dest, uint32_t num, uint8_t *buffer)
Definition: CAENSerDes.c:1117
static uint32_t c_hton32(uint32_t x)
ssize_t c_ssize_t
Return type of send() and recv().
#define PKTHEAD_TOTLEN_SIZE
Definition: CAENSerDes.c:51
uint8_t * serialize_char(const char *src, uint32_t num, uint8_t *buffer, size_t *allocSize)
Definition: CAENSerDes.c:301
uint8_t * deserialize_uint8_t(uint8_t *dest, uint32_t num, uint8_t *buffer)
Definition: CAENSerDes.c:676
static PKTHEAD_TOTLEN_TYPE * getSizePtr(uint8_t *header)
Definition: CAENSerDes.c:66
uint8_t * serialize_uint16_t(const uint16_t *src, uint32_t num, uint8_t *buffer, size_t *allocSize)
Definition: CAENSerDes.c:381
static PARAMTYPE_TYPE ptypeton(PARAMTYPE_TYPE type)
Definition: CAENSerDes.c:231
uint8_t * serialize_int8_t(const int8_t *src, uint32_t num, uint8_t *buffer, size_t *allocSize)
Definition: CAENSerDes.c:262
static uint64_t c_ntoh64(uint64_t x)
Logger implemented in C.
uint8_t * deserialize_int64_t(int64_t *dest, uint32_t num, uint8_t *buffer)
Definition: CAENSerDes.c:991
#define logMsg(s,...)
Definition: CAENLogger.h:157
uint8_t * serialize_uint8_t(const uint8_t *src, uint32_t num, uint8_t *buffer, size_t *allocSize)
Definition: CAENSerDes.c:305
uint8_t * serialize_int64_t(const int64_t *src, uint32_t num, uint8_t *buffer, size_t *allocSize)
Definition: CAENSerDes.c:495
uint8_t * deserialize_uint64_t_array(uint64_t *dest, uint32_t maxnum, uint32_t *num, uint8_t *buffer)
Definition: CAENSerDes.c:1085
uint8_t * serialize_float(const float *src, uint32_t num, uint8_t *buffer, size_t *allocSize)
Definition: CAENSerDes.c:571
#define c_use_decl_annotations
Definition: CAENUtility.h:278
uint8_t * serialize_double(const double *src, uint32_t num, uint8_t *buffer, size_t *allocSize)
Definition: CAENSerDes.c:575
int64_t c_frexp(double value, int16_t *exponent, int8_t *classification)
uint16_t PARAMTYPE_TYPE
Definition: CAENSerDes.c:228
c_ssize_t c_recv(const c_socket_t *sckt, void *buffer, size_t totSize)
Definition: CAENSocket.c:165
uint8_t * deserialize_int32_t(int32_t *dest, uint32_t num, uint8_t *buffer)
Definition: CAENSerDes.c:865
static uint16_t c_ntoh16(uint16_t x)
static PKTHEAD_NPARAMS_TYPE * incrHeaderParamsNum(uint8_t *header)
Definition: CAENSerDes.c:98
int32_t c_mutex_unlock(c_mutex_t *m)
Definition: CAENThread.c:367
uint16_t PKTHEAD_CMD_TYPE
uint32_t PKTHEAD_TOTLEN_TYPE
void * c_realloc(void *ptr, size_t size)
static PKTHEAD_CMD_TYPE * getCmdPtr(uint8_t *header)
Definition: CAENSerDes.c:71
uint16_t PARAMNUM_TYPE
Definition: CAENSerDes.c:229
uint8_t * c_recv_packet_unlock(c_socket_t *sckt, PKTHEAD_CMD_TYPE *cmd, PKTHEAD_TOTLEN_TYPE *totSize, PKTHEAD_NPARAMS_TYPE *totParams)
Definition: CAENSerDes.c:217
static PARAMTYPE_TYPE ntoptype(PARAMTYPE_TYPE type)
Definition: CAENSerDes.c:235
uint8_t * serialize_uint32_t(const uint32_t *src, uint32_t num, uint8_t *buffer, size_t *allocSize)
Definition: CAENSerDes.c:457
static PARAMNUM_TYPE pnumton(PARAMNUM_TYPE type)
Definition: CAENSerDes.c:239
uint8_t * serialize_int16_t(const int16_t *src, uint32_t num, uint8_t *buffer, size_t *allocSize)
Definition: CAENSerDes.c:343
static const PKTHEAD_CMD_TYPE * getCmdConstPtr(const uint8_t *header)
Definition: CAENSerDes.c:76
#define PKTHEAD_TOTALSIZE
Definition: CAENSerDes.c:54
static void * c_zeromem(void *dest, size_t size)
Wrapper to memset(dest, 0, size), with check for NULL arguments.
#define PKTHEAD_NPARAMS_SIZE
Definition: CAENSerDes.c:53