1 /*
2 * Copyright (c) 2021 Chipsea Technologies (Shenzhen) Corp., Ltd. All rights reserved.
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 #ifndef _BLE_COMMON_UTILS_H
16 #define _BLE_COMMON_UTILS_H
17
18 #include <stdint.h> // standard definitions
19 #include <stddef.h> // standard definitions
20 #include "bt_common.h" // common bt definitions
21 #include "ble_ip_config.h" // SW configuration
22 #include "ble_ip.h" // SW configuration
23 #include "compiler.h" // for inline functions
24
25 /// Number of '1' bits in a byte
26 #define NB_ONE_BITS(byte) (one_bits[byte & 0x0F] + one_bits[byte >> 4])
27
28 /// Get the number of elements within an array, give also number of rows in a 2-D array
29 #define ARRAY_LEN(array) (sizeof((array))/sizeof((array)[0]))
30
31 /// Get the number of columns within a 2-D array
32 #define ARRAY_NB_COLUMNS(array) (sizeof((array[0]))/sizeof((array)[0][0]))
33
34
35 /// Macro for LMP message handler function declaration or definition
36 #define LMP_MSG_HANDLER(msg_name) __STATIC int lmp_##msg_name##_handler(struct lmp_##msg_name const *param, \
37 ke_task_id_t const dest_id)
38 /// Macro for LMP message handler function declaration or definition
39 #define LLCP_MSG_HANDLER(msg_name) __STATIC int llcp_##msg_name##_handler(struct llcp_##msg_name const *param, \
40 ke_task_id_t const dest_id)
41
42 /// Macro for HCI message handler function declaration or definition (for multi-instantiated tasks)
43 #define HCI_CMD_HANDLER_C(cmd_name, param_struct) __STATIC int hci_##cmd_name##_cmd_handler(param_struct const *param, \
44 ke_task_id_t const dest_id, \
45 uint16_t opcode)
46
47 /// Macro for HCI message handler function declaration or definition (with parameters)
48 #define HCI_CMD_HANDLER(cmd_name, param_struct) __STATIC int hci_##cmd_name##_cmd_handler(param_struct const *param, \
49 uint16_t opcode)
50
51 /// Macro for HCI message handler function declaration or definition (with parameters)
52 #define HCI_CMD_HANDLER_TAB(task) __STATIC const struct task##_hci_cmd_handler task##_hci_command_handler_tab[] =
53
54
55 /// MACRO to build a subversion field from the Minor and Release fields
56 #define CO_SUBVERSION_BUILD(minor, release) (((minor) << 8) | (release))
57
58
59 /// Macro to get a structure from one of its structure field
60 #define CONTAINER_OF(ptr, type, member) ((type *)( (char *)ptr - offsetof(type,member) ))
61
62
63 /// Increment value and make sure it's never greater or equals max (else wrap to 0)
64 #define CO_VAL_INC(_val, _max) \
65 (_val) = (_val) + 1; \
66 if((_val) >= (_max)) (_val) = 0
67
68
69 /// Add value and make sure it's never greater or equals max (else wrap)
70 /// _add must be less that _max
71 #define CO_VAL_ADD(_val, _add, _max) \
72 (_val) = (_val) + (_add); \
73 if((_val) >= (_max)) (_val) -= (_max)
74
75 /// sub value and make sure it's never greater or equals max (else wrap)
76 /// _sub must be less that _max
77 #define CO_VAL_SUB(_val, _sub, _max) \
78 if((_val) < (_sub)) (_val) += _max; \
79 (_val) = (_val) - (_sub)
80
81 /*
82 * ENUMERATIONS DEFINITIONS
83 ****************************************************************************************
84 */
85
86 /// Status returned by generic packer-unpacker
87 enum CO_UTIL_PACK_STATUS
88 {
89 CO_UTIL_PACK_OK,
90 CO_UTIL_PACK_IN_BUF_OVFLW,
91 CO_UTIL_PACK_OUT_BUF_OVFLW,
92 CO_UTIL_PACK_WRONG_FORMAT,
93 CO_UTIL_PACK_ERROR,
94 };
95
96
97 /// Rate information
98 /*@TRACE*/
99 enum phy_rate
100 {
101 /// 1 Mbits/s Rate
102 CO_RATE_1MBPS = 0,
103 /// 2 Mbits/s Rate
104 CO_RATE_2MBPS = 1,
105 /// 125 Kbits/s Rate
106 CO_RATE_125KBPS = 2,
107 /// 500 Kbits/s Rate
108 CO_RATE_500KBPS = 3,
109 /// Undefined rate (used for reporting when no packet is received)
110 CO_RATE_UNDEF = 4,
111
112 CO_RATE_MAX = 4,
113 };
114
115
116 /*
117 * FUNCTION DECLARATIONS
118 ****************************************************************************************
119 */
120
121 /*
122 * TYPE DEFINITIONS
123 ****************************************************************************************
124 */
125
126
127 /*
128 * CONSTANT DECLARATIONS
129 ****************************************************************************************
130 */
131
132 /// Number of '1' bits in values from 0 to 15, used to fasten bit counting
133 extern const unsigned char one_bits[16];
134
135 /// Conversion table Sleep Clock Accuracy to PPM
136 extern const uint16_t co_sca2ppm[];
137
138 /// NULL BD address
139 extern const struct bd_addr co_null_bdaddr;
140
141 /// Default BD address
142 extern const struct bd_addr co_default_bdaddr;
143
144 /// Table for converting rate to PHY
145 extern const uint8_t co_rate_to_phy[];
146
147 /// Table for converting PHY to rate (Warning: the coded PHY is converted to 125K by default)
148 extern const uint8_t co_phy_to_rate[];
149
150 /// Convert PHY mask (with one single bit set) to a value
151 extern const uint8_t co_phy_mask_to_value[];
152
153 /// Convert PHY a value to the corresponding mask bit
154 extern const uint8_t co_phy_value_to_mask[];
155
156 /// Convert Rate value to the corresponding PHY mask bit
157 extern const uint8_t co_rate_to_phy_mask[];
158
159 /// Convert PHY mask bit to the corresponding Rate value
160 extern const uint8_t co_phy_mask_to_rate[];
161
162 /// Convert Rate value to byte duration in us
163 extern const uint8_t co_rate_to_byte_dur_us[];
164
165 /*
166 * OPERATIONS ON BT CLOCK
167 ****************************************************************************************
168 */
169
170 /**
171 ****************************************************************************************
172 * @brief Clocks addition with 2 operands
173 *
174 * @param[in] clock_a 1st operand value (in BT half-slots)
175 * @param[in] clock_b 2nd operand value (in BT half-slots)
176 * @return result operation result (in BT half-slots)
177 ****************************************************************************************
178 */
179 #define CLK_ADD_2(clock_a, clock_b) ((uint32_t)(((clock_a) + (clock_b)) & RWIP_MAX_CLOCK_TIME))
180
181 /**
182 ****************************************************************************************
183 * @brief Clocks addition with 3 operands
184 *
185 * @param[in] clock_a 1st operand value (in BT half-slots)
186 * @param[in] clock_b 2nd operand value (in BT half-slots)
187 * @param[in] clock_c 3rd operand value (in BT half-slots)
188 * @return result operation result (in BT half-slots)
189 ****************************************************************************************
190 */
191 #define CLK_ADD_3(clock_a, clock_b, clock_c) ((uint32_t)(((clock_a) + (clock_b) + (clock_c)) & RWIP_MAX_CLOCK_TIME))
192
193 /**
194 ****************************************************************************************
195 * @brief Clocks subtraction
196 *
197 * @param[in] clock_a 1st operand value (in BT half-slots)
198 * @param[in] clock_b 2nd operand value (in BT half-slots)
199 * @return result operation result (in BT half-slots)
200 ****************************************************************************************
201 */
202 #define CLK_SUB(clock_a, clock_b) ((uint32_t)(((clock_a) - (clock_b)) & RWIP_MAX_CLOCK_TIME))
203
204 /**
205 ****************************************************************************************
206 * @brief Clocks time difference
207 *
208 * @param[in] clock_a 1st operand value (in BT half-slots)
209 * @param[in] clock_b 2nd operand value (in BT half-slots)
210 * @return result return the time difference from clock A to clock B
211 * - result < 0 => clock_b is in the past
212 * - result == 0 => clock_a is equal to clock_b
213 * - result > 0 => clock_b is in the future
214 ****************************************************************************************
215 */
216 #define CLK_DIFF(clock_a, clock_b) ( (CLK_SUB((clock_b), (clock_a)) > ((RWIP_MAX_CLOCK_TIME+1) >> 1)) ? \
217 ((int32_t)((-CLK_SUB((clock_a), (clock_b))))) : ((int32_t)((CLK_SUB((clock_b), (clock_a))))) )
218
219
220
221 /// macro to extract a field from a value containing several fields
222 /// @param[in] __r bit field value
223 /// @param[in] __f field name
224 /// @return the value of the register masked and shifted
225 #define GETF(__r, __f) \
226 (( (__r) & (__f##_MASK) ) >> (__f##_LSB))
227
228 /// macro to set a field value into a value containing several fields.
229 /// @param[in] __r bit field value
230 /// @param[in] __f field name
231 /// @param[in] __v value to put in field
232 #define SETF(__r, __f, __v) \
233 do { \
234 ASSERT_INFO( ( ( ( (__v) << (__f##_LSB) ) & ( ~(__f##_MASK) ) ) ) == 0 ,(__f##_MASK), (__v)); \
235 __r = (((__r) & ~(__f##_MASK)) | (__v) << (__f##_LSB)); \
236 } while (0)
237
238
239
240 /// macro to extract a bit field from a value containing several fields
241 /// @param[in] __r bit field value
242 /// @param[in] __b bit field name
243 /// @return the value of the register masked and shifted
244 #define GETB(__r, __b) \
245 (( (__r) & (__b##_BIT) ) >> (__b##_POS))
246
247 /// macro to set a bit field value into a value containing several fields.
248 /// @param[in] __r bit field value
249 /// @param[in] __b bit field name
250 /// @param[in] __v value to put in field
251 #define SETB(__r, __b, __v) \
252 do { \
253 ASSERT_ERR( ( ( ( (__v) << (__b##_POS) ) & ( ~(__b##_BIT) ) ) ) == 0 ); \
254 __r = (((__r) & ~(__b##_BIT)) | (__v) << (__b##_POS)); \
255 } while (0)
256
257 /// macro to toggle a bit into a value containing several bits.
258 /// @param[in] __r bit field value
259 /// @param[in] __b bit field name
260 #define TOGB(__r, __b) \
261 do { \
262 __r = ((__r) ^ (__b##_BIT)); \
263 } while (0)
264
265 /**
266 ****************************************************************************************
267 * @brief Check if clock_a is equal to clock_b
268 *
269 * @param[in] clock_a Clock A value (in BT half-slots)
270 * @param[in] clock_b Clock B value (in BT half-slots)
271 * @return result True: clock_a lower than or equal to clock_b | False: else
272 ****************************************************************************************
273 */
274 #define CLK_EQ(clock_a, clock_b) (clock_b == clock_a)
275
276 /**
277 ****************************************************************************************
278 * @brief Check if clock_a is lower than or equal to clock_b
279 *
280 * @param[in] clock_a Clock A value (in BT half-slots)
281 * @param[in] clock_b Clock B value (in BT half-slots)
282 * @return result True: clock_a lower than or equal to clock_b | False: else
283 ****************************************************************************************
284 */
285 #define CLK_LOWER_EQ(clock_a, clock_b) (CLK_SUB(clock_b, clock_a) < (RWIP_MAX_CLOCK_TIME >> 1))
286
287 /**
288 ****************************************************************************************
289 * @brief Check if clock A is lower than or equal to clock B (with half-us precision)
290 *
291 * @param[in] int_a Integer part of clock A (in BT half-slots)
292 * @param[in] fract_a Fractional part of clock A (in half-us) (range: 0 to 624)
293 * @param[in] int_b Integer part of clock B (in BT half-slots)
294 * @param[in] fract_b Fractional part of clock B (in half-us) (range: 0 to 624)
295 * @return result True: clock A lower than or equal to clock B | False: else
296 ****************************************************************************************
297 */
298 #define CLK_LOWER_EQ_HUS(int_a, fract_a, int_b, fract_b) ( CLK_GREATER_THAN(int_b, int_a) \
299 || ( CLK_EQ(int_a, int_b) \
300 && (fract_a <= fract_b) ) ) \
301
302 /**
303 ****************************************************************************************
304 * @brief Check if clock_a is greater than clock_b
305 *
306 * @param[in] clock_a Clock A value (in BT half-slots)
307 * @param[in] clock_b Clock B value (in BT half-slots)
308 * @return result True: clock_a is greater than clock_b | False: else
309 ****************************************************************************************
310 */
311 #define CLK_GREATER_THAN(clock_a, clock_b) !(CLK_LOWER_EQ(clock_a, clock_b))
312
313 /**
314 ****************************************************************************************
315 * @brief Check if clock A is greater than clock B (with half-us precision)
316 *
317 * @param[in] int_a Integer part of clock A (in BT half-slots)
318 * @param[in] fract_a Fractional part of clock A (in half-us) (range: 0 to 624)
319 * @param[in] int_b Integer part of clock B (in BT half-slots)
320 * @param[in] fract_b Fractional part of clock B (in half-us) (range: 0 to 624)
321 * @return result True: clock A greater than clock B | False: else
322 ****************************************************************************************
323 */
324 #define CLK_GREATER_THAN_HUS(int_a, fract_a, int_b, fract_b) ( CLK_GREATER_THAN(int_a, int_b) \
325 || ( CLK_EQ(int_a, int_b) \
326 && (fract_a > fract_b) ) ) \
327
328 #if (BLE_EMB_PRESENT)
329 /**
330 ******************************************************************************
331 * @brief Compare 2 BLE instants (connection event counter)
332 * @param[in] instant_a 1st operand value (connection event counter)
333 * @param[in] instant_b 2nd operand value (connection event counter)
334 * @return result True: B is greater or equal to A | False: B is smaller than A
335 ******************************************************************************
336 */
337 #define CO_BLE_INSTANT_PASSED(instant_a, instant_b) ((uint16_t)(instant_b - instant_a) < 32767)
338
339 /**
340 ******************************************************************************
341 * @brief Compute difference between two event counter
342 * @param[in] evt_cnt_a 1st operand value (connection event counter)
343 * @param[in] evt_cnt_b 2nd operand value (connection event counter)
344 * @return result return the time difference from evt_cnt_a to evt_cnt_b
345 * - result < 0 => evt_cnt_b is in the past
346 * - result == 0 => evt_cnt_a is equal to evt_cnt_b
347 * - result > 0 => evt_cnt_b is in the future
348 ******************************************************************************
349 */
350 #define CO_BLE_EVT_CNT_DIFF(evt_cnt_a, evt_cnt_b) ((((uint16_t) (evt_cnt_b)) - ((uint16_t) (evt_cnt_a)) > 32768) \
351 ? ((int16_t)(-(((uint16_t) (evt_cnt_a)) - ((uint16_t) (evt_cnt_b))))) \
352 : ((int16_t)(-(((uint16_t) (evt_cnt_b)) - ((uint16_t) (evt_cnt_a))))))
353
354 #endif //BLE_EMB_PRESENT
355
356
357 /*
358 * FUNCTION DECLARATIONS
359 ****************************************************************************************
360 */
361
362 /**
363 ****************************************************************************************
364 * @brief Read a packed 16 bits word.
365 * @param[in] ptr16 The address of the first byte of the 16 bits word.
366 * @return The 16 bits value.
367 ****************************************************************************************
368 */
ble_read16p(void const * ptr16)369 __INLINE uint16_t ble_read16p(void const *ptr16)
370 {
371 uint16_t value = ((uint8_t *)ptr16)[0] | ((uint8_t *)ptr16)[1] << 8;
372 return value;
373 }
374
375 /**
376 ****************************************************************************************
377 * @brief Read a packed 24 bits word.
378 * @param[in] ptr24 The address of the first byte of the 24 bits word.
379 * @return The 24 bits value.
380 ****************************************************************************************
381 */
382
ble_read24p(void const * ptr24)383 __INLINE uint32_t ble_read24p(void const *ptr24)
384 {
385 uint16_t addr_l, addr_h;
386 addr_l = ble_read16p(ptr24);
387 addr_h = *((uint8_t *)ptr24 + 2) & 0x00FF;
388 return ((uint32_t)addr_l | (uint32_t)addr_h << 16);
389 }
390
391 /**
392 ****************************************************************************************
393 * @brief Write a packed 24 bits word.
394 * @param[in] ptr24 The address of the first byte of the 24 bits word.
395 * @param[in] value The value to write.
396 ****************************************************************************************
397 */
398
ble_write24p(void const * ptr24,uint32_t value)399 __INLINE void ble_write24p(void const *ptr24, uint32_t value)
400 {
401 uint8_t *ptr=(uint8_t*)ptr24;
402
403 *ptr++ = (uint8_t)(value&0xff);
404 *ptr++ = (uint8_t)((value&0xff00)>>8);
405 *ptr++ = (uint8_t)((value&0xff0000)>>16);
406 }
407
408 /**
409 ****************************************************************************************
410 * @brief Read a packed 32 bits word.
411 * @param[in] ptr32 The address of the first byte of the 32 bits word.
412 * @return The 32 bits value.
413 ****************************************************************************************
414 */
ble_read32p(void const * ptr32)415 __INLINE uint32_t ble_read32p(void const *ptr32)
416 {
417 uint16_t addr_l, addr_h;
418 addr_l = ble_read16p(ptr32);
419 addr_h = ble_read16p((uint8_t *)ptr32 + 2);
420 return ((uint32_t)addr_l | (uint32_t)addr_h << 16);
421 }
422 /**
423 ****************************************************************************************
424 * @brief Write a packed 32 bits word.
425 * @param[in] ptr32 The address of the first byte of the 32 bits word.
426 * @param[in] value The value to write.
427 ****************************************************************************************
428 */
ble_write32p(void const * ptr32,uint32_t value)429 __INLINE void ble_write32p(void const *ptr32, uint32_t value)
430 {
431 uint8_t *ptr=(uint8_t*)ptr32;
432
433 *ptr++ = (uint8_t)(value&0xff);
434 *ptr++ = (uint8_t)((value&0xff00)>>8);
435 *ptr++ = (uint8_t)((value&0xff0000)>>16);
436 *ptr = (uint8_t)((value&0xff000000)>>24);
437 }
438
439 /**
440 ****************************************************************************************
441 * @brief Write a packed 16 bits word.
442 * @param[in] ptr16 The address of the first byte of the 16 bits word.
443 * @param[in] value The value to write.
444 ****************************************************************************************
445 */
ble_write16p(void const * ptr16,uint16_t value)446 __INLINE void ble_write16p(void const *ptr16, uint16_t value)
447 {
448 uint8_t *ptr=(uint8_t*)ptr16;
449
450 *ptr++ = value&0xff;
451 *ptr = (value&0xff00)>>8;
452 }
453
454 #if (RW_DEBUG || DISPLAY_SUPPORT)
455
456 /**
457 ****************************************************************************************
458 * @brief Convert bytes to hexadecimal string
459 *
460 * @param[out] dest Pointer to the destination string (must be 2x longer than input table)
461 * @param[in] src Pointer to the bytes table
462 * @param[in] nb_bytes Number of bytes to display in the string
463 ****************************************************************************************
464 */
465 void co_bytes_to_string(char* dest, uint8_t* src, uint8_t nb_bytes);
466 #endif //(RW_DEBUG || DISPLAY_SUPPORT)
467
468 /**
469 ****************************************************************************************
470 * @brief Compares two Bluetooth device addresses
471 *
472 * This function checks if the two bd address are equal.
473 *
474 * @param[in] bd_address1 Pointer on the first bd address to be compared.
475 * @param[in] bd_address2 Pointer on the second bd address to be compared.
476 *
477 * @return result of the comparison (true: equal | false: different).
478 ****************************************************************************************
479 */
480 bool co_bdaddr_compare(struct bd_addr const *bd_address1, struct bd_addr const *bd_address2);
481
482 #if (BLE_EMB_PRESENT)
483 /**
484 ******************************************************************************
485 * @brief Count the number of good channels in a LE map
486 * @param[in] map Channel Map (bit fields for the 40 BT RF channels)
487 * @return Number of good channels
488 ******************************************************************************
489 */
490 uint8_t co_nb_good_le_channels(const struct le_chnl_map* map);
491 #endif //BLE_EMB_PRESENT
492
493 #if (BT_EMB_PRESENT)
494
495 /**
496 ******************************************************************************
497 * @brief Convert an duration in baseband slot to a duration in number of ticks.
498 * @param[in] slot_cnt Duration in number of baseband slot
499 * @return Duration (in number of ticks).
500 ******************************************************************************
501 */
502 uint32_t co_slot_to_duration(uint32_t slot_cnt);
503
504 /**
505 ******************************************************************************
506 * @brief Count the number of good channels in a map
507 * @param[in] map Channel Map (bit fields for the 79 BT RF channels)
508 * @return Number of good channels
509 ******************************************************************************
510 */
511 uint8_t co_nb_good_channels(const struct chnl_map* map);
512
513 #endif //BT_EMB_PRESENT
514
515 /**
516 ****************************************************************************************
517 * @brief Pack parameters from a C structure to a packed buffer
518 *
519 * This function packs parameters according to a specific format. It takes care of the
520 * endianess, padding, required by the compiler.
521 *
522 * By default output format is LSB but it can be changed with first character of format string
523 * - < : LSB output format
524 * - > : MSB output format
525 *
526 * Format strings are the mechanism used to specify the expected layout when packing and unpacking data. They are built
527 * up from Format Characters, which specify the type of data being packed/unpacked.
528 * - B : byte - 8bits value
529 * - H : word - 16bits value
530 * - L : long - 32-bits value
531 * - D : 24 bits value
532 * - XXB: table of several bytes, where XX is the byte number, in decimal
533 * - XXG: Number of several bytes, where XX is the byte number, in decimal - subject to be swapped according to endianess
534 * - nB : table size over 1 byte, followed by the table of bytes
535 * - NB : table size over 2 bytes, followed by the table of bytes
536 *
537 * Example: "BBLH12BLnB" => 1 byte | 1 byte | 1 long | 1 short | 12-bytes table | 1 long | table size over 1 byte | n-bytes table
538 *
539 * Note: the function works in the same buffer
540 *
541 * @param[out] out Output Data Buffer
542 * @param[in] in Input Data Buffer
543 * @param[out] out_len Output size of packed data (in bytes)
544 * @param[in] in_len Input buffer size (in bytes)
545 * @param[in] format Parameters format
546 *
547 * @return Status of the packing operation
548 *****************************************************************************************
549 */
550 uint8_t co_util_pack(uint8_t* out, uint8_t* in, uint16_t* out_len, uint16_t in_len, const char* format);
551
552 /**
553 ****************************************************************************************
554 * @brief Unpack parameters from an unpacked buffer to a C structure
555 *
556 * This function unpacks parameters according to a specific format. It takes care of the
557 * endianess, padding, required by the compiler.
558 *
559 * By default input format is LSB but it can be changed with first character of format string
560 * - < : LSB input format
561 * - > : MSB input format
562 *
563 * Format strings are the mechanism used to specify the expected layout when packing and unpacking data. They are built
564 * up from Format Characters, which specify the type of data being packed/unpacked.
565 * - B : byte - 8bits value
566 * - H : word - 16bits value
567 * - L : long - 32-bits value
568 * - D : 24 bits value
569 * - XXB: table of several bytes, where XX is the byte number, in decimal
570 * - XXG: Number of several bytes, where XX is the byte number, in decimal - subject to be swapped according to endianess
571 * - nB : table size over 1 byte, followed by the table of bytes
572 * - NB : table size over 2 bytes, followed by the table of bytes
573 *
574 * Example: "BBLH12BLnB" => 1 byte | 1 byte | 1 long | 1 short | 12-bytes table | 1 long | table size over 1 byte | n-bytes table
575 *
576 * Note: the output buffer provided must be large enough to contain the unpacked data.
577 * Note2: if a NULL output buffer is provided, the function does not copy the unpacked parameters. It still parses the
578 * format string and input buffer to return the number of unpacked bytes. Can be used to compute the expected unpacked
579 * buffer size.
580 *
581 * @param[out] out Unpacked parameters buffer
582 * @param[in] in Packed parameters buffer
583 * @param[inout] out_len Input: buffer size / Output: size of unpacked data (in bytes)
584 * @param[in] in_len Size of the packed data (in bytes)
585 * @param[in] format Parameters format
586 *
587 * @return Status of the unpacking operation
588 *****************************************************************************************
589 */
590 uint8_t co_util_unpack(uint8_t* out, uint8_t* in, uint16_t* out_len, uint16_t in_len, const char* format);
591
592
593 #if (BLE_EMB_PRESENT)
594
595 /**
596 *****************************************************************************************
597 * @brief Get BLE packet duration in us according to PHY and packet size
598 *
599 * @param[in] len PDU size in octets
600 * @param[in] rate PHY Rate (@see enum lld_phy)
601 *
602 * @return packet duration in us.
603 *****************************************************************************************
604 */
605 uint16_t co_ble_pkt_dur_in_us(uint8_t len, uint8_t rate);
606 #endif // (BLE_EMB_PRESENT)
607
608 #endif // _BLE_COMMON_UTILS_H
609