canard.c 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594
  1. /*
  2. * Copyright (c) 2016-2019 UAVCAN Team
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5. * of this software and associated documentation files (the "Software"), to deal
  6. * in the Software without restriction, including without limitation the rights
  7. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. * copies of the Software, and to permit persons to whom the Software is
  9. * furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in all
  12. * copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. * SOFTWARE.
  21. *
  22. * Contributors: https://github.com/UAVCAN/libcanard/contributors
  23. *
  24. * Documentation: http://uavcan.org/Implementations/Libcanard
  25. */
  26. #include "canard_internals.h"
  27. #include <string.h>
  28. #undef MIN
  29. #undef MAX
  30. #define MIN(a, b) (((a) < (b)) ? (a) : (b))
  31. #define MAX(a, b) (((a) > (b)) ? (a) : (b))
  32. #define TRANSFER_TIMEOUT_USEC 2000000
  33. #define TRANSFER_ID_BIT_LEN 5U
  34. #define ANON_MSG_DATA_TYPE_ID_BIT_LEN 2U
  35. #define SOURCE_ID_FROM_ID(x) ((uint8_t) (((x) >> 0U) & 0x7FU))
  36. #define SERVICE_NOT_MSG_FROM_ID(x) ((bool) (((x) >> 7U) & 0x1U))
  37. #define REQUEST_NOT_RESPONSE_FROM_ID(x) ((bool) (((x) >> 15U) & 0x1U))
  38. #define DEST_ID_FROM_ID(x) ((uint8_t) (((x) >> 8U) & 0x7FU))
  39. #define PRIORITY_FROM_ID(x) ((uint8_t) (((x) >> 24U) & 0x1FU))
  40. #define MSG_TYPE_FROM_ID(x) ((uint16_t)(((x) >> 8U) & 0xFFFFU))
  41. #define SRV_TYPE_FROM_ID(x) ((uint8_t) (((x) >> 16U) & 0xFFU))
  42. #define MAKE_TRANSFER_DESCRIPTOR(data_type_id, transfer_type, src_node_id, dst_node_id) \
  43. (((uint32_t)(data_type_id)) | (((uint32_t)(transfer_type)) << 16U) | \
  44. (((uint32_t)(src_node_id)) << 18U) | (((uint32_t)(dst_node_id)) << 25U))
  45. #define TRANSFER_ID_FROM_TAIL_BYTE(x) ((uint8_t)((x) & 0x1FU))
  46. // The extra cast to unsigned is needed to squelch warnings from clang-tidy
  47. #define IS_START_OF_TRANSFER(x) ((bool)(((uint32_t)(x) >> 7U) & 0x1U))
  48. #define IS_END_OF_TRANSFER(x) ((bool)(((uint32_t)(x) >> 6U) & 0x1U))
  49. #define TOGGLE_BIT(x) ((bool)(((uint32_t)(x) >> 5U) & 0x1U))
  50. struct CanardTxQueueItem
  51. {
  52. CanardTxQueueItem* next;
  53. CanardCANFrame frame;
  54. };
  55. /*
  56. * API functions
  57. */
  58. void canardInit(CanardInstance* out_ins,
  59. void* mem_arena,
  60. size_t mem_arena_size,
  61. CanardOnTransferReception on_reception,
  62. CanardShouldAcceptTransfer should_accept,
  63. void* user_reference)
  64. {
  65. CANARD_ASSERT(out_ins != NULL);
  66. /*
  67. * Checking memory layout.
  68. * This condition is supposed to be true for all 32-bit and smaller platforms.
  69. * If your application fails here, make sure it's not built in 64-bit mode.
  70. * Refer to the design documentation for more info.
  71. */
  72. CANARD_ASSERT(CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE >= 6);
  73. memset(out_ins, 0, sizeof(*out_ins));
  74. out_ins->node_id = CANARD_BROADCAST_NODE_ID;
  75. out_ins->on_reception = on_reception;
  76. out_ins->should_accept = should_accept;
  77. out_ins->rx_states = NULL;
  78. out_ins->tx_queue = NULL;
  79. out_ins->user_reference = user_reference;
  80. size_t pool_capacity = mem_arena_size / CANARD_MEM_BLOCK_SIZE;
  81. if (pool_capacity > 0xFFFFU)
  82. {
  83. pool_capacity = 0xFFFFU;
  84. }
  85. initPoolAllocator(&out_ins->allocator, mem_arena, (uint16_t)pool_capacity);
  86. }
  87. void* canardGetUserReference(CanardInstance* ins)
  88. {
  89. CANARD_ASSERT(ins != NULL);
  90. return ins->user_reference;
  91. }
  92. void canardSetLocalNodeID(CanardInstance* ins, uint8_t self_node_id)
  93. {
  94. CANARD_ASSERT(ins != NULL);
  95. if ((ins->node_id == CANARD_BROADCAST_NODE_ID) &&
  96. (self_node_id >= CANARD_MIN_NODE_ID) &&
  97. (self_node_id <= CANARD_MAX_NODE_ID))
  98. {
  99. ins->node_id = self_node_id;
  100. }
  101. else
  102. {
  103. CANARD_ASSERT(false);
  104. }
  105. }
  106. uint8_t canardGetLocalNodeID(const CanardInstance* ins)
  107. {
  108. return ins->node_id;
  109. }
  110. int16_t canardBroadcast(CanardInstance* ins,
  111. uint64_t data_type_signature,
  112. uint16_t data_type_id,
  113. uint8_t* inout_transfer_id,
  114. uint8_t priority,
  115. const void* payload,
  116. uint16_t payload_len)
  117. {
  118. if (payload == NULL && payload_len > 0)
  119. {
  120. return -CANARD_ERROR_INVALID_ARGUMENT;
  121. }
  122. if (priority > CANARD_TRANSFER_PRIORITY_LOWEST)
  123. {
  124. return -CANARD_ERROR_INVALID_ARGUMENT;
  125. }
  126. uint32_t can_id = 0;
  127. uint16_t crc = 0xFFFFU;
  128. if (canardGetLocalNodeID(ins) == 0)
  129. {
  130. if (payload_len > 7)
  131. {
  132. return -CANARD_ERROR_NODE_ID_NOT_SET;
  133. }
  134. static const uint16_t DTIDMask = (1U << ANON_MSG_DATA_TYPE_ID_BIT_LEN) - 1U;
  135. if ((data_type_id & DTIDMask) != data_type_id)
  136. {
  137. return -CANARD_ERROR_INVALID_ARGUMENT;
  138. }
  139. // anonymous transfer, random discriminator
  140. const uint16_t discriminator = (uint16_t)((crcAdd(0xFFFFU, payload, payload_len)) & 0x7FFEU);
  141. can_id = ((uint32_t) priority << 24U) | ((uint32_t) discriminator << 9U) |
  142. ((uint32_t) (data_type_id & DTIDMask) << 8U) | (uint32_t) canardGetLocalNodeID(ins);
  143. }
  144. else
  145. {
  146. can_id = ((uint32_t) priority << 24U) | ((uint32_t) data_type_id << 8U) | (uint32_t) canardGetLocalNodeID(ins);
  147. if (payload_len > 7)
  148. {
  149. crc = crcAddSignature(crc, data_type_signature);
  150. crc = crcAdd(crc, payload, payload_len);
  151. }
  152. }
  153. const int16_t result = enqueueTxFrames(ins, can_id, inout_transfer_id, crc, payload, payload_len);
  154. incrementTransferID(inout_transfer_id);
  155. return result;
  156. }
  157. int16_t canardRequestOrRespond(CanardInstance* ins,
  158. uint8_t destination_node_id,
  159. uint64_t data_type_signature,
  160. uint8_t data_type_id,
  161. uint8_t* inout_transfer_id,
  162. uint8_t priority,
  163. CanardRequestResponse kind,
  164. const void* payload,
  165. uint16_t payload_len)
  166. {
  167. if (payload == NULL && payload_len > 0)
  168. {
  169. return -CANARD_ERROR_INVALID_ARGUMENT;
  170. }
  171. if (priority > CANARD_TRANSFER_PRIORITY_LOWEST)
  172. {
  173. return -CANARD_ERROR_INVALID_ARGUMENT;
  174. }
  175. if (canardGetLocalNodeID(ins) == 0)
  176. {
  177. return -CANARD_ERROR_NODE_ID_NOT_SET;
  178. }
  179. const uint32_t can_id = ((uint32_t) priority << 24U) | ((uint32_t) data_type_id << 16U) |
  180. ((uint32_t) kind << 15U) | ((uint32_t) destination_node_id << 8U) |
  181. (1U << 7U) | (uint32_t) canardGetLocalNodeID(ins);
  182. uint16_t crc = 0xFFFFU;
  183. if (payload_len > 7)
  184. {
  185. crc = crcAddSignature(crc, data_type_signature);
  186. crc = crcAdd(crc, payload, payload_len);
  187. }
  188. const int16_t result = enqueueTxFrames(ins, can_id, inout_transfer_id, crc, payload, payload_len);
  189. if (kind == CanardRequest) // Response Transfer ID must not be altered
  190. {
  191. incrementTransferID(inout_transfer_id);
  192. }
  193. return result;
  194. }
  195. const CanardCANFrame* canardPeekTxQueue(const CanardInstance* ins)
  196. {
  197. if (ins->tx_queue == NULL)
  198. {
  199. return NULL;
  200. }
  201. return &ins->tx_queue->frame;
  202. }
  203. void canardPopTxQueue(CanardInstance* ins)
  204. {
  205. CanardTxQueueItem* item = ins->tx_queue;
  206. ins->tx_queue = item->next;
  207. freeBlock(&ins->allocator, item);
  208. }
  209. int16_t canardHandleRxFrame(CanardInstance* ins, const CanardCANFrame* frame, uint64_t timestamp_usec)
  210. {
  211. const CanardTransferType transfer_type = extractTransferType(frame->id);
  212. const uint8_t destination_node_id = (transfer_type == CanardTransferTypeBroadcast) ?
  213. (uint8_t)CANARD_BROADCAST_NODE_ID :
  214. DEST_ID_FROM_ID(frame->id);
  215. // TODO: This function should maintain statistics of transfer errors and such.
  216. if ((frame->id & CANARD_CAN_FRAME_EFF) == 0 ||
  217. (frame->id & CANARD_CAN_FRAME_RTR) != 0 ||
  218. (frame->id & CANARD_CAN_FRAME_ERR) != 0 ||
  219. (frame->data_len < 1))
  220. {
  221. return -CANARD_ERROR_RX_INCOMPATIBLE_PACKET;
  222. }
  223. if (transfer_type != CanardTransferTypeBroadcast &&
  224. destination_node_id != canardGetLocalNodeID(ins))
  225. {
  226. return -CANARD_ERROR_RX_WRONG_ADDRESS;
  227. }
  228. const uint8_t priority = PRIORITY_FROM_ID(frame->id);
  229. const uint8_t source_node_id = SOURCE_ID_FROM_ID(frame->id);
  230. const uint16_t data_type_id = extractDataType(frame->id);
  231. const uint32_t transfer_descriptor =
  232. MAKE_TRANSFER_DESCRIPTOR(data_type_id, transfer_type, source_node_id, destination_node_id);
  233. const uint8_t tail_byte = frame->data[frame->data_len - 1];
  234. CanardRxState* rx_state = NULL;
  235. if (IS_START_OF_TRANSFER(tail_byte))
  236. {
  237. uint64_t data_type_signature = 0;
  238. if (ins->should_accept(ins, &data_type_signature, data_type_id, transfer_type, source_node_id))
  239. {
  240. rx_state = traverseRxStates(ins, transfer_descriptor);
  241. if(rx_state == NULL)
  242. {
  243. return -CANARD_ERROR_OUT_OF_MEMORY;
  244. }
  245. rx_state->calculated_crc = crcAddSignature(0xFFFFU, data_type_signature);
  246. }
  247. else
  248. {
  249. return -CANARD_ERROR_RX_NOT_WANTED;
  250. }
  251. }
  252. else
  253. {
  254. rx_state = findRxState(ins->rx_states, transfer_descriptor);
  255. if (rx_state == NULL)
  256. {
  257. return -CANARD_ERROR_RX_MISSED_START;
  258. }
  259. }
  260. CANARD_ASSERT(rx_state != NULL); // All paths that lead to NULL should be terminated with return above
  261. // Resolving the state flags:
  262. const bool not_initialized = rx_state->timestamp_usec == 0;
  263. const bool tid_timed_out = (timestamp_usec - rx_state->timestamp_usec) > TRANSFER_TIMEOUT_USEC;
  264. const bool first_frame = IS_START_OF_TRANSFER(tail_byte);
  265. const bool not_previous_tid =
  266. computeTransferIDForwardDistance((uint8_t) rx_state->transfer_id, TRANSFER_ID_FROM_TAIL_BYTE(tail_byte)) > 1;
  267. const bool need_restart =
  268. (not_initialized) ||
  269. (tid_timed_out) ||
  270. (first_frame && not_previous_tid);
  271. if (need_restart)
  272. {
  273. rx_state->transfer_id = TRANSFER_ID_FROM_TAIL_BYTE(tail_byte);
  274. rx_state->next_toggle = 0;
  275. releaseStatePayload(ins, rx_state);
  276. if (!IS_START_OF_TRANSFER(tail_byte))
  277. {
  278. rx_state->transfer_id++;
  279. return -CANARD_ERROR_RX_MISSED_START;
  280. }
  281. }
  282. if (IS_START_OF_TRANSFER(tail_byte) && IS_END_OF_TRANSFER(tail_byte)) // single frame transfer
  283. {
  284. rx_state->timestamp_usec = timestamp_usec;
  285. CanardRxTransfer rx_transfer = {
  286. .timestamp_usec = timestamp_usec,
  287. .payload_head = frame->data,
  288. .payload_len = (uint8_t)(frame->data_len - 1U),
  289. .data_type_id = data_type_id,
  290. .transfer_type = (uint8_t)transfer_type,
  291. .transfer_id = TRANSFER_ID_FROM_TAIL_BYTE(tail_byte),
  292. .priority = priority,
  293. .source_node_id = source_node_id
  294. };
  295. ins->on_reception(ins, &rx_transfer);
  296. prepareForNextTransfer(rx_state);
  297. return CANARD_OK;
  298. }
  299. if (TOGGLE_BIT(tail_byte) != rx_state->next_toggle)
  300. {
  301. return -CANARD_ERROR_RX_WRONG_TOGGLE;
  302. }
  303. if (TRANSFER_ID_FROM_TAIL_BYTE(tail_byte) != rx_state->transfer_id)
  304. {
  305. return -CANARD_ERROR_RX_UNEXPECTED_TID;
  306. }
  307. if (IS_START_OF_TRANSFER(tail_byte) && !IS_END_OF_TRANSFER(tail_byte)) // Beginning of multi frame transfer
  308. {
  309. if (frame->data_len <= 3)
  310. {
  311. return -CANARD_ERROR_RX_SHORT_FRAME;
  312. }
  313. // take off the crc and store the payload
  314. rx_state->timestamp_usec = timestamp_usec;
  315. const int16_t ret = bufferBlockPushBytes(&ins->allocator, rx_state, frame->data + 2,
  316. (uint8_t) (frame->data_len - 3));
  317. if (ret < 0)
  318. {
  319. releaseStatePayload(ins, rx_state);
  320. prepareForNextTransfer(rx_state);
  321. return CANARD_ERROR_OUT_OF_MEMORY;
  322. }
  323. rx_state->payload_crc = (uint16_t)(((uint16_t) frame->data[0]) | (uint16_t)((uint16_t) frame->data[1] << 8U));
  324. rx_state->calculated_crc = crcAdd((uint16_t)rx_state->calculated_crc,
  325. frame->data + 2, (uint8_t)(frame->data_len - 3));
  326. }
  327. else if (!IS_START_OF_TRANSFER(tail_byte) && !IS_END_OF_TRANSFER(tail_byte)) // Middle of a multi-frame transfer
  328. {
  329. const int16_t ret = bufferBlockPushBytes(&ins->allocator, rx_state, frame->data,
  330. (uint8_t) (frame->data_len - 1));
  331. if (ret < 0)
  332. {
  333. releaseStatePayload(ins, rx_state);
  334. prepareForNextTransfer(rx_state);
  335. return CANARD_ERROR_OUT_OF_MEMORY;
  336. }
  337. rx_state->calculated_crc = crcAdd((uint16_t)rx_state->calculated_crc,
  338. frame->data, (uint8_t)(frame->data_len - 1));
  339. }
  340. else // End of a multi-frame transfer
  341. {
  342. const uint8_t frame_payload_size = (uint8_t)(frame->data_len - 1);
  343. uint8_t tail_offset = 0;
  344. if (rx_state->payload_len < CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE)
  345. {
  346. // Copy the beginning of the frame into the head, point the tail pointer to the remainder
  347. for (size_t i = rx_state->payload_len;
  348. (i < CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE) && (tail_offset < frame_payload_size);
  349. i++, tail_offset++)
  350. {
  351. rx_state->buffer_head[i] = frame->data[tail_offset];
  352. }
  353. }
  354. else
  355. {
  356. // Like above, except that the beginning goes into the last block of the storage
  357. CanardBufferBlock* block = rx_state->buffer_blocks;
  358. if (block != NULL) // If there's no middle, that's fine, we'll use only head and tail
  359. {
  360. size_t offset = CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE; // Payload offset of the first block
  361. while (block->next != NULL)
  362. {
  363. block = block->next;
  364. offset += CANARD_BUFFER_BLOCK_DATA_SIZE;
  365. }
  366. CANARD_ASSERT(block != NULL);
  367. const size_t offset_within_block = rx_state->payload_len - offset;
  368. CANARD_ASSERT(offset_within_block < CANARD_BUFFER_BLOCK_DATA_SIZE);
  369. for (size_t i = offset_within_block;
  370. (i < CANARD_BUFFER_BLOCK_DATA_SIZE) && (tail_offset < frame_payload_size);
  371. i++, tail_offset++)
  372. {
  373. block->data[i] = frame->data[tail_offset];
  374. }
  375. }
  376. }
  377. CanardRxTransfer rx_transfer = {
  378. .timestamp_usec = timestamp_usec,
  379. .payload_head = rx_state->buffer_head,
  380. .payload_middle = rx_state->buffer_blocks,
  381. .payload_tail = (tail_offset >= frame_payload_size) ? NULL : (&frame->data[tail_offset]),
  382. .payload_len = (uint16_t)(rx_state->payload_len + frame_payload_size),
  383. .data_type_id = data_type_id,
  384. .transfer_type = (uint8_t)transfer_type,
  385. .transfer_id = TRANSFER_ID_FROM_TAIL_BYTE(tail_byte),
  386. .priority = priority,
  387. .source_node_id = source_node_id
  388. };
  389. rx_state->buffer_blocks = NULL; // Block list ownership has been transferred to rx_transfer!
  390. // CRC validation
  391. rx_state->calculated_crc = crcAdd((uint16_t)rx_state->calculated_crc, frame->data, frame->data_len - 1U);
  392. if (rx_state->calculated_crc == rx_state->payload_crc)
  393. {
  394. ins->on_reception(ins, &rx_transfer);
  395. }
  396. // Making sure the payload is released even if the application didn't bother with it
  397. canardReleaseRxTransferPayload(ins, &rx_transfer);
  398. prepareForNextTransfer(rx_state);
  399. if (rx_state->calculated_crc == rx_state->payload_crc)
  400. {
  401. return CANARD_OK;
  402. }
  403. else
  404. {
  405. return CANARD_ERROR_RX_BAD_CRC;
  406. }
  407. }
  408. rx_state->next_toggle = rx_state->next_toggle ? 0 : 1;
  409. return CANARD_OK;
  410. }
  411. void canardCleanupStaleTransfers(CanardInstance* ins, uint64_t current_time_usec)
  412. {
  413. CanardRxState* prev = ins->rx_states, * state = ins->rx_states;
  414. while (state != NULL)
  415. {
  416. if ((current_time_usec - state->timestamp_usec) > TRANSFER_TIMEOUT_USEC)
  417. {
  418. if (state == ins->rx_states)
  419. {
  420. releaseStatePayload(ins, state);
  421. ins->rx_states = ins->rx_states->next;
  422. freeBlock(&ins->allocator, state);
  423. state = ins->rx_states;
  424. prev = state;
  425. }
  426. else
  427. {
  428. releaseStatePayload(ins, state);
  429. prev->next = state->next;
  430. freeBlock(&ins->allocator, state);
  431. state = prev->next;
  432. }
  433. }
  434. else
  435. {
  436. prev = state;
  437. state = state->next;
  438. }
  439. }
  440. }
  441. int16_t canardDecodeScalar(const CanardRxTransfer* transfer,
  442. uint32_t bit_offset,
  443. uint8_t bit_length,
  444. bool value_is_signed,
  445. void* out_value)
  446. {
  447. if (transfer == NULL || out_value == NULL)
  448. {
  449. return -CANARD_ERROR_INVALID_ARGUMENT;
  450. }
  451. if (bit_length < 1 || bit_length > 64)
  452. {
  453. return -CANARD_ERROR_INVALID_ARGUMENT;
  454. }
  455. if (bit_length == 1 && value_is_signed)
  456. {
  457. return -CANARD_ERROR_INVALID_ARGUMENT;
  458. }
  459. /*
  460. * Reading raw bytes into the temporary storage.
  461. * Luckily, C guarantees that every element is aligned at the beginning (lower address) of the union.
  462. */
  463. union
  464. {
  465. bool boolean; ///< sizeof(bool) is implementation-defined, so it has to be handled separately
  466. uint8_t u8; ///< Also char
  467. int8_t s8;
  468. uint16_t u16;
  469. int16_t s16;
  470. uint32_t u32;
  471. int32_t s32; ///< Also float, possibly double, possibly long double (depends on implementation)
  472. uint64_t u64;
  473. int64_t s64; ///< Also double, possibly float, possibly long double (depends on implementation)
  474. uint8_t bytes[8];
  475. } storage;
  476. memset(&storage, 0, sizeof(storage)); // This is important
  477. const int16_t result = descatterTransferPayload(transfer, bit_offset, bit_length, &storage.bytes[0]);
  478. if (result <= 0)
  479. {
  480. return result;
  481. }
  482. CANARD_ASSERT((result > 0) && (result <= 64) && (result <= bit_length));
  483. /*
  484. * The bit copy algorithm assumes that more significant bits have lower index, so we need to shift some.
  485. * Extra most significant bits will be filled with zeroes, which is fine.
  486. * Coverity Scan mistakenly believes that the array may be overrun if bit_length == 64; however, this branch will
  487. * not be taken if bit_length == 64, because 64 % 8 == 0.
  488. */
  489. if ((bit_length % 8) != 0)
  490. {
  491. // coverity[overrun-local]
  492. storage.bytes[bit_length / 8U] = (uint8_t)(storage.bytes[bit_length / 8U] >> ((8U - (bit_length % 8U)) & 7U));
  493. }
  494. /*
  495. * Determining the closest standard byte length - this will be needed for byte reordering and sign bit extension.
  496. */
  497. uint8_t std_byte_length = 0;
  498. if (bit_length == 1) { std_byte_length = sizeof(bool); }
  499. else if (bit_length <= 8) { std_byte_length = 1; }
  500. else if (bit_length <= 16) { std_byte_length = 2; }
  501. else if (bit_length <= 32) { std_byte_length = 4; }
  502. else if (bit_length <= 64) { std_byte_length = 8; }
  503. else
  504. {
  505. CANARD_ASSERT(false);
  506. return -CANARD_ERROR_INTERNAL;
  507. }
  508. CANARD_ASSERT((std_byte_length > 0) && (std_byte_length <= 8));
  509. /*
  510. * Flipping the byte order if needed.
  511. */
  512. if (isBigEndian())
  513. {
  514. swapByteOrder(&storage.bytes[0], std_byte_length);
  515. }
  516. /*
  517. * Extending the sign bit if needed. I miss templates.
  518. * Note that we operate on unsigned values in order to avoid undefined behaviors.
  519. */
  520. if (value_is_signed && (std_byte_length * 8 != bit_length))
  521. {
  522. if (bit_length <= 8)
  523. {
  524. if ((storage.u8 & (1U << (bit_length - 1U))) != 0) // If the sign bit is set...
  525. {
  526. storage.u8 |= (uint8_t) 0xFFU & (uint8_t) ~((1U << bit_length) - 1U); // ...set all bits above it.
  527. }
  528. }
  529. else if (bit_length <= 16)
  530. {
  531. if ((storage.u16 & (1U << (bit_length - 1U))) != 0)
  532. {
  533. storage.u16 |= (uint16_t) 0xFFFFU & (uint16_t) ~((1U << bit_length) - 1U);
  534. }
  535. }
  536. else if (bit_length <= 32)
  537. {
  538. if ((storage.u32 & (((uint32_t) 1) << (bit_length - 1U))) != 0)
  539. {
  540. storage.u32 |= (uint32_t) 0xFFFFFFFFUL & (uint32_t) ~((((uint32_t) 1) << bit_length) - 1U);
  541. }
  542. }
  543. else if (bit_length < 64) // Strictly less, this is not a typo
  544. {
  545. if ((storage.u64 & (((uint64_t) 1) << (bit_length - 1U))) != 0)
  546. {
  547. storage.u64 |= (uint64_t) 0xFFFFFFFFFFFFFFFFULL & (uint64_t) ~((((uint64_t) 1) << bit_length) - 1U);
  548. }
  549. }
  550. else
  551. {
  552. CANARD_ASSERT(false);
  553. return -CANARD_ERROR_INTERNAL;
  554. }
  555. }
  556. /*
  557. * Copying the result out.
  558. */
  559. if (value_is_signed)
  560. {
  561. if (bit_length <= 8) { *( (int8_t*) out_value) = storage.s8; }
  562. else if (bit_length <= 16) { *((int16_t*) out_value) = storage.s16; }
  563. else if (bit_length <= 32) { *((int32_t*) out_value) = storage.s32; }
  564. else if (bit_length <= 64) { *((int64_t*) out_value) = storage.s64; }
  565. else
  566. {
  567. CANARD_ASSERT(false);
  568. return -CANARD_ERROR_INTERNAL;
  569. }
  570. }
  571. else
  572. {
  573. if (bit_length == 1) { *( (bool*) out_value) = storage.boolean; }
  574. else if (bit_length <= 8) { *( (uint8_t*) out_value) = storage.u8; }
  575. else if (bit_length <= 16) { *((uint16_t*) out_value) = storage.u16; }
  576. else if (bit_length <= 32) { *((uint32_t*) out_value) = storage.u32; }
  577. else if (bit_length <= 64) { *((uint64_t*) out_value) = storage.u64; }
  578. else
  579. {
  580. CANARD_ASSERT(false);
  581. return -CANARD_ERROR_INTERNAL;
  582. }
  583. }
  584. CANARD_ASSERT(result <= bit_length);
  585. CANARD_ASSERT(result > 0);
  586. return result;
  587. }
  588. void canardEncodeScalar(void* destination,
  589. uint32_t bit_offset,
  590. uint8_t bit_length,
  591. const void* value)
  592. {
  593. /*
  594. * This function can only fail due to invalid arguments, so it was decided to make it return void,
  595. * and in the case of bad arguments try the best effort or just trigger an CANARD_ASSERTion failure.
  596. * Maybe not the best solution, but it simplifies the API.
  597. */
  598. CANARD_ASSERT(destination != NULL);
  599. CANARD_ASSERT(value != NULL);
  600. if (bit_length > 64)
  601. {
  602. CANARD_ASSERT(false);
  603. bit_length = 64;
  604. }
  605. if (bit_length < 1)
  606. {
  607. CANARD_ASSERT(false);
  608. bit_length = 1;
  609. }
  610. /*
  611. * Preparing the data in the temporary storage.
  612. */
  613. union
  614. {
  615. bool boolean;
  616. uint8_t u8;
  617. uint16_t u16;
  618. uint32_t u32;
  619. uint64_t u64;
  620. uint8_t bytes[8];
  621. } storage;
  622. memset(&storage, 0, sizeof(storage));
  623. uint8_t std_byte_length = 0;
  624. // Extra most significant bits can be safely ignored here.
  625. if (bit_length == 1) { std_byte_length = sizeof(bool); storage.boolean = (*((bool*) value) != 0); }
  626. else if (bit_length <= 8) { std_byte_length = 1; storage.u8 = *((uint8_t*) value); }
  627. else if (bit_length <= 16) { std_byte_length = 2; storage.u16 = *((uint16_t*) value); }
  628. else if (bit_length <= 32) { std_byte_length = 4; storage.u32 = *((uint32_t*) value); }
  629. else if (bit_length <= 64) { std_byte_length = 8; storage.u64 = *((uint64_t*) value); }
  630. else
  631. {
  632. CANARD_ASSERT(false);
  633. }
  634. CANARD_ASSERT(std_byte_length > 0);
  635. if (isBigEndian())
  636. {
  637. swapByteOrder(&storage.bytes[0], std_byte_length);
  638. }
  639. /*
  640. * The bit copy algorithm assumes that more significant bits have lower index, so we need to shift some.
  641. * Extra least significant bits will be filled with zeroes, which is fine.
  642. * Extra most significant bits will be discarded here.
  643. * Coverity Scan mistakenly believes that the array may be overrun if bit_length == 64; however, this branch will
  644. * not be taken if bit_length == 64, because 64 % 8 == 0.
  645. */
  646. if ((bit_length % 8) != 0)
  647. {
  648. // coverity[overrun-local]
  649. storage.bytes[bit_length / 8U] = (uint8_t)(storage.bytes[bit_length / 8U] << ((8U - (bit_length % 8U)) & 7U));
  650. }
  651. /*
  652. * Now, the storage contains properly serialized scalar. Copying it out.
  653. */
  654. copyBitArray(&storage.bytes[0], 0, bit_length, (uint8_t*) destination, bit_offset);
  655. }
  656. void canardReleaseRxTransferPayload(CanardInstance* ins, CanardRxTransfer* transfer)
  657. {
  658. while (transfer->payload_middle != NULL)
  659. {
  660. CanardBufferBlock* const temp = transfer->payload_middle->next;
  661. freeBlock(&ins->allocator, transfer->payload_middle);
  662. transfer->payload_middle = temp;
  663. }
  664. transfer->payload_middle = NULL;
  665. transfer->payload_head = NULL;
  666. transfer->payload_tail = NULL;
  667. transfer->payload_len = 0;
  668. }
  669. CanardPoolAllocatorStatistics canardGetPoolAllocatorStatistics(CanardInstance* ins)
  670. {
  671. return ins->allocator.statistics;
  672. }
  673. uint16_t canardConvertNativeFloatToFloat16(float value)
  674. {
  675. CANARD_ASSERT(sizeof(float) == 4);
  676. union FP32
  677. {
  678. uint32_t u;
  679. float f;
  680. };
  681. const union FP32 f32inf = { 255UL << 23U };
  682. const union FP32 f16inf = { 31UL << 23U };
  683. const union FP32 magic = { 15UL << 23U };
  684. const uint32_t sign_mask = 0x80000000UL;
  685. const uint32_t round_mask = ~0xFFFUL;
  686. union FP32 in;
  687. in.f = value;
  688. uint32_t sign = in.u & sign_mask;
  689. in.u ^= sign;
  690. uint16_t out = 0;
  691. if (in.u >= f32inf.u)
  692. {
  693. out = (in.u > f32inf.u) ? (uint16_t)0x7FFFU : (uint16_t)0x7C00U;
  694. }
  695. else
  696. {
  697. in.u &= round_mask;
  698. in.f *= magic.f;
  699. in.u -= round_mask;
  700. if (in.u > f16inf.u)
  701. {
  702. in.u = f16inf.u;
  703. }
  704. out = (uint16_t)(in.u >> 13U);
  705. }
  706. out |= (uint16_t)(sign >> 16U);
  707. return out;
  708. }
  709. float canardConvertFloat16ToNativeFloat(uint16_t value)
  710. {
  711. CANARD_ASSERT(sizeof(float) == 4);
  712. union FP32
  713. {
  714. uint32_t u;
  715. float f;
  716. };
  717. const union FP32 magic = { (254UL - 15UL) << 23U };
  718. const union FP32 was_inf_nan = { (127UL + 16UL) << 23U };
  719. union FP32 out;
  720. out.u = (value & 0x7FFFU) << 13U;
  721. out.f *= magic.f;
  722. if (out.f >= was_inf_nan.f)
  723. {
  724. out.u |= 255UL << 23U;
  725. }
  726. out.u |= (value & 0x8000UL) << 16U;
  727. return out.f;
  728. }
  729. /*
  730. * Internal (static functions)
  731. */
  732. CANARD_INTERNAL int16_t computeTransferIDForwardDistance(uint8_t a, uint8_t b)
  733. {
  734. int16_t d = (int16_t)(b - a);
  735. if (d < 0)
  736. {
  737. d = (int16_t)(d + (int16_t)(1U << TRANSFER_ID_BIT_LEN));
  738. }
  739. return d;
  740. }
  741. CANARD_INTERNAL void incrementTransferID(uint8_t* transfer_id)
  742. {
  743. CANARD_ASSERT(transfer_id != NULL);
  744. (*transfer_id)++;
  745. if (*transfer_id >= 32)
  746. {
  747. *transfer_id = 0;
  748. }
  749. }
  750. CANARD_INTERNAL int16_t enqueueTxFrames(CanardInstance* ins,
  751. uint32_t can_id,
  752. uint8_t* transfer_id,
  753. uint16_t crc,
  754. const uint8_t* payload,
  755. uint16_t payload_len)
  756. {
  757. CANARD_ASSERT(ins != NULL);
  758. CANARD_ASSERT((can_id & CANARD_CAN_EXT_ID_MASK) == can_id); // Flags must be cleared
  759. if (transfer_id == NULL)
  760. {
  761. return -CANARD_ERROR_INVALID_ARGUMENT;
  762. }
  763. if ((payload_len > 0) && (payload == NULL))
  764. {
  765. return -CANARD_ERROR_INVALID_ARGUMENT;
  766. }
  767. int16_t result = 0;
  768. if (payload_len < CANARD_CAN_FRAME_MAX_DATA_LEN) // Single frame transfer
  769. {
  770. CanardTxQueueItem* queue_item = createTxItem(&ins->allocator);
  771. if (queue_item == NULL)
  772. {
  773. return -CANARD_ERROR_OUT_OF_MEMORY;
  774. }
  775. memcpy(queue_item->frame.data, payload, payload_len);
  776. queue_item->frame.data_len = (uint8_t)(payload_len + 1);
  777. queue_item->frame.data[payload_len] = (uint8_t)(0xC0U | (*transfer_id & 31U));
  778. queue_item->frame.id = can_id | CANARD_CAN_FRAME_EFF;
  779. pushTxQueue(ins, queue_item);
  780. result++;
  781. }
  782. else // Multi frame transfer
  783. {
  784. uint16_t data_index = 0;
  785. uint8_t toggle = 0;
  786. uint8_t sot_eot = 0x80;
  787. CanardTxQueueItem* queue_item = NULL;
  788. while (payload_len - data_index != 0)
  789. {
  790. queue_item = createTxItem(&ins->allocator);
  791. if (queue_item == NULL)
  792. {
  793. return -CANARD_ERROR_OUT_OF_MEMORY; // TODO: Purge all frames enqueued so far
  794. }
  795. uint8_t i = 0;
  796. if (data_index == 0)
  797. {
  798. // add crc
  799. queue_item->frame.data[0] = (uint8_t) (crc);
  800. queue_item->frame.data[1] = (uint8_t) (crc >> 8U);
  801. i = 2;
  802. }
  803. else
  804. {
  805. i = 0;
  806. }
  807. for (; i < (CANARD_CAN_FRAME_MAX_DATA_LEN - 1) && data_index < payload_len; i++, data_index++)
  808. {
  809. queue_item->frame.data[i] = payload[data_index];
  810. }
  811. // tail byte
  812. sot_eot = (data_index == payload_len) ? (uint8_t)0x40 : sot_eot;
  813. queue_item->frame.data[i] = (uint8_t)(sot_eot | ((uint32_t)toggle << 5U) | ((uint32_t)*transfer_id & 31U));
  814. queue_item->frame.id = can_id | CANARD_CAN_FRAME_EFF;
  815. queue_item->frame.data_len = (uint8_t)(i + 1);
  816. pushTxQueue(ins, queue_item);
  817. result++;
  818. toggle ^= 1;
  819. sot_eot = 0;
  820. }
  821. }
  822. return result;
  823. }
  824. /**
  825. * Puts frame on on the TX queue. Higher priority placed first
  826. */
  827. CANARD_INTERNAL void pushTxQueue(CanardInstance* ins, CanardTxQueueItem* item)
  828. {
  829. CANARD_ASSERT(ins != NULL);
  830. CANARD_ASSERT(item->frame.data_len > 0); // UAVCAN doesn't allow zero-payload frames
  831. if (ins->tx_queue == NULL)
  832. {
  833. ins->tx_queue = item;
  834. return;
  835. }
  836. CanardTxQueueItem* queue = ins->tx_queue;
  837. CanardTxQueueItem* previous = ins->tx_queue;
  838. while (queue != NULL)
  839. {
  840. if (isPriorityHigher(queue->frame.id, item->frame.id)) // lower number wins
  841. {
  842. if (queue == ins->tx_queue)
  843. {
  844. item->next = queue;
  845. ins->tx_queue = item;
  846. }
  847. else
  848. {
  849. previous->next = item;
  850. item->next = queue;
  851. }
  852. return;
  853. }
  854. else
  855. {
  856. if (queue->next == NULL)
  857. {
  858. queue->next = item;
  859. return;
  860. }
  861. else
  862. {
  863. previous = queue;
  864. queue = queue->next;
  865. }
  866. }
  867. }
  868. }
  869. /**
  870. * Creates new tx queue item from allocator
  871. */
  872. CANARD_INTERNAL CanardTxQueueItem* createTxItem(CanardPoolAllocator* allocator)
  873. {
  874. CanardTxQueueItem* item = (CanardTxQueueItem*) allocateBlock(allocator);
  875. if (item == NULL)
  876. {
  877. return NULL;
  878. }
  879. memset(item, 0, sizeof(*item));
  880. return item;
  881. }
  882. /**
  883. * Returns true if priority of rhs is higher than id
  884. */
  885. CANARD_INTERNAL bool isPriorityHigher(uint32_t rhs, uint32_t id)
  886. {
  887. const uint32_t clean_id = id & CANARD_CAN_EXT_ID_MASK;
  888. const uint32_t rhs_clean_id = rhs & CANARD_CAN_EXT_ID_MASK;
  889. /*
  890. * STD vs EXT - if 11 most significant bits are the same, EXT loses.
  891. */
  892. const bool ext = (id & CANARD_CAN_FRAME_EFF) != 0;
  893. const bool rhs_ext = (rhs & CANARD_CAN_FRAME_EFF) != 0;
  894. if (ext != rhs_ext)
  895. {
  896. uint32_t arb11 = ext ? (clean_id >> 18U) : clean_id;
  897. uint32_t rhs_arb11 = rhs_ext ? (rhs_clean_id >> 18U) : rhs_clean_id;
  898. if (arb11 != rhs_arb11)
  899. {
  900. return arb11 < rhs_arb11;
  901. }
  902. else
  903. {
  904. return rhs_ext;
  905. }
  906. }
  907. /*
  908. * RTR vs Data frame - if frame identifiers and frame types are the same, RTR loses.
  909. */
  910. const bool rtr = (id & CANARD_CAN_FRAME_RTR) != 0;
  911. const bool rhs_rtr = (rhs & CANARD_CAN_FRAME_RTR) != 0;
  912. if (clean_id == rhs_clean_id && rtr != rhs_rtr)
  913. {
  914. return rhs_rtr;
  915. }
  916. /*
  917. * Plain ID arbitration - greater value loses.
  918. */
  919. return clean_id < rhs_clean_id;
  920. }
  921. /**
  922. * preps the rx state for the next transfer. does not delete the state
  923. */
  924. CANARD_INTERNAL void prepareForNextTransfer(CanardRxState* state)
  925. {
  926. CANARD_ASSERT(state->buffer_blocks == NULL);
  927. state->transfer_id++;
  928. state->payload_len = 0;
  929. state->next_toggle = 0;
  930. }
  931. /**
  932. * returns data type from id
  933. */
  934. CANARD_INTERNAL uint16_t extractDataType(uint32_t id)
  935. {
  936. if (extractTransferType(id) == CanardTransferTypeBroadcast)
  937. {
  938. uint16_t dtid = MSG_TYPE_FROM_ID(id);
  939. if (SOURCE_ID_FROM_ID(id) == CANARD_BROADCAST_NODE_ID)
  940. {
  941. dtid &= (1U << ANON_MSG_DATA_TYPE_ID_BIT_LEN) - 1U;
  942. }
  943. return dtid;
  944. }
  945. else
  946. {
  947. return (uint16_t) SRV_TYPE_FROM_ID(id);
  948. }
  949. }
  950. /**
  951. * returns transfer type from id
  952. */
  953. CANARD_INTERNAL CanardTransferType extractTransferType(uint32_t id)
  954. {
  955. const bool is_service = SERVICE_NOT_MSG_FROM_ID(id);
  956. if (!is_service)
  957. {
  958. return CanardTransferTypeBroadcast;
  959. }
  960. else if (REQUEST_NOT_RESPONSE_FROM_ID(id) == 1)
  961. {
  962. return CanardTransferTypeRequest;
  963. }
  964. else
  965. {
  966. return CanardTransferTypeResponse;
  967. }
  968. }
  969. /*
  970. * CanardRxState functions
  971. */
  972. /**
  973. * Traverses the list of CanardRxState's and returns a pointer to the CanardRxState
  974. * with either the Id or a new one at the end
  975. */
  976. CANARD_INTERNAL CanardRxState* traverseRxStates(CanardInstance* ins, uint32_t transfer_descriptor)
  977. {
  978. CanardRxState* states = ins->rx_states;
  979. if (states == NULL) // initialize CanardRxStates
  980. {
  981. states = createRxState(&ins->allocator, transfer_descriptor);
  982. if(states == NULL)
  983. {
  984. return NULL;
  985. }
  986. ins->rx_states = states;
  987. return states;
  988. }
  989. states = findRxState(states, transfer_descriptor);
  990. if (states != NULL)
  991. {
  992. return states;
  993. }
  994. else
  995. {
  996. return prependRxState(ins, transfer_descriptor);
  997. }
  998. }
  999. /**
  1000. * returns pointer to the rx state of transfer descriptor or null if not found
  1001. */
  1002. CANARD_INTERNAL CanardRxState* findRxState(CanardRxState* state, uint32_t transfer_descriptor)
  1003. {
  1004. while (state != NULL)
  1005. {
  1006. if (state->dtid_tt_snid_dnid == transfer_descriptor)
  1007. {
  1008. return state;
  1009. }
  1010. state = state->next;
  1011. }
  1012. return NULL;
  1013. }
  1014. /**
  1015. * prepends rx state to the canard instance rx_states
  1016. */
  1017. CANARD_INTERNAL CanardRxState* prependRxState(CanardInstance* ins, uint32_t transfer_descriptor)
  1018. {
  1019. CanardRxState* state = createRxState(&ins->allocator, transfer_descriptor);
  1020. if(state == NULL)
  1021. {
  1022. return NULL;
  1023. }
  1024. state->next = ins->rx_states;
  1025. ins->rx_states = state;
  1026. return state;
  1027. }
  1028. CANARD_INTERNAL CanardRxState* createRxState(CanardPoolAllocator* allocator, uint32_t transfer_descriptor)
  1029. {
  1030. CanardRxState init = {
  1031. .next = NULL,
  1032. .buffer_blocks = NULL,
  1033. .dtid_tt_snid_dnid = transfer_descriptor
  1034. };
  1035. CanardRxState* state = (CanardRxState*) allocateBlock(allocator);
  1036. if (state == NULL)
  1037. {
  1038. return NULL;
  1039. }
  1040. memcpy(state, &init, sizeof(*state));
  1041. return state;
  1042. }
  1043. CANARD_INTERNAL uint64_t releaseStatePayload(CanardInstance* ins, CanardRxState* rxstate)
  1044. {
  1045. while (rxstate->buffer_blocks != NULL)
  1046. {
  1047. CanardBufferBlock* const temp = rxstate->buffer_blocks->next;
  1048. freeBlock(&ins->allocator, rxstate->buffer_blocks);
  1049. rxstate->buffer_blocks = temp;
  1050. }
  1051. rxstate->payload_len = 0;
  1052. return CANARD_OK;
  1053. }
  1054. /*
  1055. * CanardBufferBlock functions
  1056. */
  1057. /**
  1058. * pushes data into the rx state. Fills the buffer head, then appends data to buffer blocks
  1059. */
  1060. CANARD_INTERNAL int16_t bufferBlockPushBytes(CanardPoolAllocator* allocator,
  1061. CanardRxState* state,
  1062. const uint8_t* data,
  1063. uint8_t data_len)
  1064. {
  1065. uint16_t data_index = 0;
  1066. // if head is not full, add data to head
  1067. if ((CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE - state->payload_len) > 0)
  1068. {
  1069. for (uint16_t i = (uint16_t)state->payload_len;
  1070. i < CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE && data_index < data_len;
  1071. i++, data_index++)
  1072. {
  1073. state->buffer_head[i] = data[data_index];
  1074. }
  1075. if (data_index >= data_len)
  1076. {
  1077. state->payload_len =
  1078. (uint16_t)(state->payload_len + data_len) & ((1U << CANARD_TRANSFER_PAYLOAD_LEN_BITS) - 1U);
  1079. return 1;
  1080. }
  1081. } // head is full.
  1082. uint16_t index_at_nth_block =
  1083. (uint16_t)(((state->payload_len) - CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE) % CANARD_BUFFER_BLOCK_DATA_SIZE);
  1084. // get to current block
  1085. CanardBufferBlock* block = NULL;
  1086. // buffer blocks uninitialized
  1087. if (state->buffer_blocks == NULL)
  1088. {
  1089. state->buffer_blocks = createBufferBlock(allocator);
  1090. if (state->buffer_blocks == NULL)
  1091. {
  1092. return -CANARD_ERROR_OUT_OF_MEMORY;
  1093. }
  1094. block = state->buffer_blocks;
  1095. index_at_nth_block = 0;
  1096. }
  1097. else
  1098. {
  1099. uint16_t nth_block = 1;
  1100. // get to block
  1101. block = state->buffer_blocks;
  1102. while (block->next != NULL)
  1103. {
  1104. nth_block++;
  1105. block = block->next;
  1106. }
  1107. const uint16_t num_buffer_blocks =
  1108. (uint16_t) (((((uint32_t)state->payload_len + data_len) - CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE) /
  1109. CANARD_BUFFER_BLOCK_DATA_SIZE) + 1U);
  1110. if (num_buffer_blocks > nth_block && index_at_nth_block == 0)
  1111. {
  1112. block->next = createBufferBlock(allocator);
  1113. if (block->next == NULL)
  1114. {
  1115. return -CANARD_ERROR_OUT_OF_MEMORY;
  1116. }
  1117. block = block->next;
  1118. }
  1119. }
  1120. // add data to current block until it becomes full, add new block if necessary
  1121. while (data_index < data_len)
  1122. {
  1123. for (uint16_t i = index_at_nth_block;
  1124. i < CANARD_BUFFER_BLOCK_DATA_SIZE && data_index < data_len;
  1125. i++, data_index++)
  1126. {
  1127. block->data[i] = data[data_index];
  1128. }
  1129. if (data_index < data_len)
  1130. {
  1131. block->next = createBufferBlock(allocator);
  1132. if (block->next == NULL)
  1133. {
  1134. return -CANARD_ERROR_OUT_OF_MEMORY;
  1135. }
  1136. block = block->next;
  1137. index_at_nth_block = 0;
  1138. }
  1139. }
  1140. state->payload_len = (uint16_t)(state->payload_len + data_len) & ((1U << CANARD_TRANSFER_PAYLOAD_LEN_BITS) - 1U);
  1141. return 1;
  1142. }
  1143. CANARD_INTERNAL CanardBufferBlock* createBufferBlock(CanardPoolAllocator* allocator)
  1144. {
  1145. CanardBufferBlock* block = (CanardBufferBlock*) allocateBlock(allocator);
  1146. if (block == NULL)
  1147. {
  1148. return NULL;
  1149. }
  1150. block->next = NULL;
  1151. return block;
  1152. }
  1153. /**
  1154. * Bit array copy routine, originally developed by Ben Dyer for Libuavcan. Thanks Ben.
  1155. */
  1156. void copyBitArray(const uint8_t* src, uint32_t src_offset, uint32_t src_len,
  1157. uint8_t* dst, uint32_t dst_offset)
  1158. {
  1159. CANARD_ASSERT(src_len > 0U);
  1160. // Normalizing inputs
  1161. src += src_offset / 8U;
  1162. dst += dst_offset / 8U;
  1163. src_offset %= 8U;
  1164. dst_offset %= 8U;
  1165. const size_t last_bit = src_offset + src_len;
  1166. while (last_bit - src_offset)
  1167. {
  1168. const uint8_t src_bit_offset = (uint8_t)(src_offset % 8U);
  1169. const uint8_t dst_bit_offset = (uint8_t)(dst_offset % 8U);
  1170. const uint8_t max_offset = MAX(src_bit_offset, dst_bit_offset);
  1171. const uint32_t copy_bits = MIN(last_bit - src_offset, 8U - max_offset);
  1172. const uint8_t write_mask = (uint8_t)((uint8_t)(0xFF00U >> copy_bits) >> dst_bit_offset);
  1173. const uint8_t src_data = (uint8_t)(((uint32_t)src[src_offset / 8U] << src_bit_offset) >> dst_bit_offset);
  1174. dst[dst_offset / 8U] =
  1175. (uint8_t)(((uint32_t)dst[dst_offset / 8U] & (uint32_t)~write_mask) | (uint32_t)(src_data & write_mask));
  1176. src_offset += copy_bits;
  1177. dst_offset += copy_bits;
  1178. }
  1179. }
  1180. CANARD_INTERNAL int16_t descatterTransferPayload(const CanardRxTransfer* transfer,
  1181. uint32_t bit_offset,
  1182. uint8_t bit_length,
  1183. void* output)
  1184. {
  1185. CANARD_ASSERT(transfer != 0);
  1186. if (bit_offset >= transfer->payload_len * 8)
  1187. {
  1188. return 0; // Out of range, reading zero bits
  1189. }
  1190. if (bit_offset + bit_length > transfer->payload_len * 8)
  1191. {
  1192. bit_length = (uint8_t)(transfer->payload_len * 8U - bit_offset);
  1193. }
  1194. CANARD_ASSERT(bit_length > 0);
  1195. if ((transfer->payload_middle != NULL) || (transfer->payload_tail != NULL)) // Multi frame
  1196. {
  1197. /*
  1198. * This part is hideously complicated and probably should be redesigned.
  1199. * The objective here is to copy the requested number of bits from scattered storage into the temporary
  1200. * local storage. We go through great pains to ensure that all corner cases are handled correctly.
  1201. */
  1202. uint32_t input_bit_offset = bit_offset;
  1203. uint8_t output_bit_offset = 0;
  1204. uint8_t remaining_bit_length = bit_length;
  1205. // Reading head
  1206. if (input_bit_offset < CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE * 8)
  1207. {
  1208. const uint8_t amount = (uint8_t)MIN(remaining_bit_length,
  1209. CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE * 8U - input_bit_offset);
  1210. copyBitArray(&transfer->payload_head[0], input_bit_offset, amount, (uint8_t*) output, 0);
  1211. input_bit_offset += amount;
  1212. output_bit_offset = (uint8_t)(output_bit_offset + amount);
  1213. remaining_bit_length = (uint8_t)(remaining_bit_length - amount);
  1214. }
  1215. // Reading middle
  1216. uint32_t remaining_bits = transfer->payload_len * 8U - CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE * 8U;
  1217. uint32_t block_bit_offset = CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE * 8U;
  1218. const CanardBufferBlock* block = transfer->payload_middle;
  1219. while ((block != NULL) && (remaining_bit_length > 0))
  1220. {
  1221. CANARD_ASSERT(remaining_bits > 0);
  1222. const uint32_t block_end_bit_offset = block_bit_offset + MIN(CANARD_BUFFER_BLOCK_DATA_SIZE * 8,
  1223. remaining_bits);
  1224. // Perform copy if we've reached the requested offset, otherwise jump over this block and try next
  1225. if (block_end_bit_offset > input_bit_offset)
  1226. {
  1227. const uint8_t amount = (uint8_t) MIN(remaining_bit_length, block_end_bit_offset - input_bit_offset);
  1228. CANARD_ASSERT(input_bit_offset >= block_bit_offset);
  1229. const uint32_t bit_offset_within_block = input_bit_offset - block_bit_offset;
  1230. copyBitArray(&block->data[0], bit_offset_within_block, amount, (uint8_t*) output, output_bit_offset);
  1231. input_bit_offset += amount;
  1232. output_bit_offset = (uint8_t)(output_bit_offset + amount);
  1233. remaining_bit_length = (uint8_t)(remaining_bit_length - amount);
  1234. }
  1235. CANARD_ASSERT(block_end_bit_offset > block_bit_offset);
  1236. remaining_bits -= block_end_bit_offset - block_bit_offset;
  1237. block_bit_offset = block_end_bit_offset;
  1238. block = block->next;
  1239. }
  1240. CANARD_ASSERT(remaining_bit_length <= remaining_bits);
  1241. // Reading tail
  1242. if ((transfer->payload_tail != NULL) && (remaining_bit_length > 0))
  1243. {
  1244. CANARD_ASSERT(input_bit_offset >= block_bit_offset);
  1245. const uint32_t offset = input_bit_offset - block_bit_offset;
  1246. copyBitArray(&transfer->payload_tail[0], offset, remaining_bit_length, (uint8_t*) output,
  1247. output_bit_offset);
  1248. input_bit_offset += remaining_bit_length;
  1249. output_bit_offset = (uint8_t)(output_bit_offset + remaining_bit_length);
  1250. remaining_bit_length = 0;
  1251. }
  1252. CANARD_ASSERT(input_bit_offset <= transfer->payload_len * 8);
  1253. CANARD_ASSERT(output_bit_offset <= 64);
  1254. CANARD_ASSERT(remaining_bit_length == 0);
  1255. }
  1256. else // Single frame
  1257. {
  1258. copyBitArray(&transfer->payload_head[0], bit_offset, bit_length, (uint8_t*) output, 0);
  1259. }
  1260. return bit_length;
  1261. }
  1262. CANARD_INTERNAL bool isBigEndian(void)
  1263. {
  1264. #if defined(BYTE_ORDER) && defined(BIG_ENDIAN)
  1265. return BYTE_ORDER == BIG_ENDIAN; // Some compilers offer this neat shortcut
  1266. #else
  1267. union
  1268. {
  1269. uint16_t a;
  1270. uint8_t b[2];
  1271. } u;
  1272. u.a = 1;
  1273. return u.b[1] == 1; // Some don't...
  1274. #endif
  1275. }
  1276. CANARD_INTERNAL void swapByteOrder(void* data, size_t size)
  1277. {
  1278. CANARD_ASSERT(data != NULL);
  1279. uint8_t* const bytes = (uint8_t*) data;
  1280. size_t fwd = 0;
  1281. size_t rev = size - 1;
  1282. while (fwd < rev)
  1283. {
  1284. const uint8_t x = bytes[fwd];
  1285. bytes[fwd] = bytes[rev];
  1286. bytes[rev] = x;
  1287. fwd++;
  1288. rev--;
  1289. }
  1290. }
  1291. /*
  1292. * CRC functions
  1293. */
  1294. CANARD_INTERNAL uint16_t crcAddByte(uint16_t crc_val, uint8_t byte)
  1295. {
  1296. crc_val ^= (uint16_t) ((uint16_t) (byte) << 8U);
  1297. for (uint8_t j = 0; j < 8; j++)
  1298. {
  1299. if (crc_val & 0x8000U)
  1300. {
  1301. crc_val = (uint16_t) ((uint16_t) (crc_val << 1U) ^ 0x1021U);
  1302. }
  1303. else
  1304. {
  1305. crc_val = (uint16_t) (crc_val << 1U);
  1306. }
  1307. }
  1308. return crc_val;
  1309. }
  1310. CANARD_INTERNAL uint16_t crcAddSignature(uint16_t crc_val, uint64_t data_type_signature)
  1311. {
  1312. for (uint16_t shift_val = 0; shift_val < 64; shift_val = (uint16_t)(shift_val + 8U))
  1313. {
  1314. crc_val = crcAddByte(crc_val, (uint8_t) (data_type_signature >> shift_val));
  1315. }
  1316. return crc_val;
  1317. }
  1318. CANARD_INTERNAL uint16_t crcAdd(uint16_t crc_val, const uint8_t* bytes, size_t len)
  1319. {
  1320. while (len--)
  1321. {
  1322. crc_val = crcAddByte(crc_val, *bytes++);
  1323. }
  1324. return crc_val;
  1325. }
  1326. /*
  1327. * Pool Allocator functions
  1328. */
  1329. CANARD_INTERNAL void initPoolAllocator(CanardPoolAllocator* allocator,
  1330. CanardPoolAllocatorBlock* buf,
  1331. uint16_t buf_len)
  1332. {
  1333. size_t current_index = 0;
  1334. CanardPoolAllocatorBlock** current_block = &(allocator->free_list);
  1335. while (current_index < buf_len)
  1336. {
  1337. *current_block = &buf[current_index];
  1338. current_block = &((*current_block)->next);
  1339. current_index++;
  1340. }
  1341. *current_block = NULL;
  1342. allocator->statistics.capacity_blocks = buf_len;
  1343. allocator->statistics.current_usage_blocks = 0;
  1344. allocator->statistics.peak_usage_blocks = 0;
  1345. }
  1346. CANARD_INTERNAL void* allocateBlock(CanardPoolAllocator* allocator)
  1347. {
  1348. // Check if there are any blocks available in the free list.
  1349. if (allocator->free_list == NULL)
  1350. {
  1351. return NULL;
  1352. }
  1353. // Take first available block and prepares next block for use.
  1354. void* result = allocator->free_list;
  1355. allocator->free_list = allocator->free_list->next;
  1356. // Update statistics
  1357. allocator->statistics.current_usage_blocks++;
  1358. if (allocator->statistics.peak_usage_blocks < allocator->statistics.current_usage_blocks)
  1359. {
  1360. allocator->statistics.peak_usage_blocks = allocator->statistics.current_usage_blocks;
  1361. }
  1362. return result;
  1363. }
  1364. CANARD_INTERNAL void freeBlock(CanardPoolAllocator* allocator, void* p)
  1365. {
  1366. CanardPoolAllocatorBlock* block = (CanardPoolAllocatorBlock*) p;
  1367. block->next = allocator->free_list;
  1368. allocator->free_list = block;
  1369. CANARD_ASSERT(allocator->statistics.current_usage_blocks > 0);
  1370. allocator->statistics.current_usage_blocks--;
  1371. }