canard.c 62 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960
  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 2000000U
  33. #define IFACE_SWITCH_DELAY_USEC 1000000U
  34. #define TRANSFER_ID_BIT_LEN 5U
  35. #define ANON_MSG_DATA_TYPE_ID_BIT_LEN 2U
  36. #define SOURCE_ID_FROM_ID(x) ((uint8_t) (((x) >> 0U) & 0x7FU))
  37. #define SERVICE_NOT_MSG_FROM_ID(x) ((bool) (((x) >> 7U) & 0x1U))
  38. #define REQUEST_NOT_RESPONSE_FROM_ID(x) ((bool) (((x) >> 15U) & 0x1U))
  39. #define DEST_ID_FROM_ID(x) ((uint8_t) (((x) >> 8U) & 0x7FU))
  40. #define PRIORITY_FROM_ID(x) ((uint8_t) (((x) >> 24U) & 0x1FU))
  41. #define MSG_TYPE_FROM_ID(x) ((uint16_t)(((x) >> 8U) & 0xFFFFU))
  42. #define SRV_TYPE_FROM_ID(x) ((uint8_t) (((x) >> 16U) & 0xFFU))
  43. #define MAKE_TRANSFER_DESCRIPTOR(data_type_id, transfer_type, src_node_id, dst_node_id) \
  44. (((uint32_t)(data_type_id)) | (((uint32_t)(transfer_type)) << 16U) | \
  45. (((uint32_t)(src_node_id)) << 18U) | (((uint32_t)(dst_node_id)) << 25U))
  46. #define TRANSFER_ID_FROM_TAIL_BYTE(x) ((uint8_t)((x) & 0x1FU))
  47. // The extra cast to unsigned is needed to squelch warnings from clang-tidy
  48. #define IS_START_OF_TRANSFER(x) ((bool)(((uint32_t)(x) >> 7U) & 0x1U))
  49. #define IS_END_OF_TRANSFER(x) ((bool)(((uint32_t)(x) >> 6U) & 0x1U))
  50. #define TOGGLE_BIT(x) ((bool)(((uint32_t)(x) >> 5U) & 0x1U))
  51. /*
  52. * API functions
  53. */
  54. void canardInit(CanardInstance* out_ins,
  55. void* mem_arena,
  56. size_t mem_arena_size,
  57. CanardOnTransferReception on_reception,
  58. CanardShouldAcceptTransfer should_accept,
  59. void* user_reference)
  60. {
  61. CANARD_ASSERT(out_ins != NULL);
  62. /*
  63. * Checking memory layout.
  64. * This condition is supposed to be true for all 32-bit and smaller platforms.
  65. * If your application fails here, make sure it's not built in 64-bit mode.
  66. * Refer to the design documentation for more info.
  67. */
  68. CANARD_ASSERT(CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE >= 5);
  69. memset(out_ins, 0, sizeof(*out_ins));
  70. out_ins->node_id = CANARD_BROADCAST_NODE_ID;
  71. out_ins->on_reception = on_reception;
  72. out_ins->should_accept = should_accept;
  73. out_ins->rx_states = NULL;
  74. out_ins->tx_queue = NULL;
  75. out_ins->user_reference = user_reference;
  76. #if CANARD_ENABLE_TAO_OPTION
  77. out_ins->tao_disabled = false;
  78. #endif
  79. size_t pool_capacity = mem_arena_size / CANARD_MEM_BLOCK_SIZE;
  80. if (pool_capacity > 0xFFFFU)
  81. {
  82. pool_capacity = 0xFFFFU;
  83. }
  84. initPoolAllocator(&out_ins->allocator, mem_arena, (uint16_t)pool_capacity);
  85. }
  86. void* canardGetUserReference(const CanardInstance* ins)
  87. {
  88. CANARD_ASSERT(ins != NULL);
  89. return ins->user_reference;
  90. }
  91. void canardSetLocalNodeID(CanardInstance* ins, uint8_t self_node_id)
  92. {
  93. CANARD_ASSERT(ins != NULL);
  94. if ((ins->node_id == CANARD_BROADCAST_NODE_ID) &&
  95. (self_node_id >= CANARD_MIN_NODE_ID) &&
  96. (self_node_id <= CANARD_MAX_NODE_ID))
  97. {
  98. ins->node_id = self_node_id;
  99. }
  100. else
  101. {
  102. CANARD_ASSERT(false);
  103. }
  104. }
  105. uint8_t canardGetLocalNodeID(const CanardInstance* ins)
  106. {
  107. return ins->node_id;
  108. }
  109. void canardForgetLocalNodeID(CanardInstance* ins) {
  110. ins->node_id = CANARD_BROADCAST_NODE_ID;
  111. }
  112. void canardInitTxTransfer(CanardTxTransfer* transfer)
  113. {
  114. CANARD_ASSERT(transfer != NULL);
  115. memset(transfer, 0, sizeof(*transfer));
  116. }
  117. int16_t canardBroadcast(CanardInstance* ins,
  118. uint64_t data_type_signature,
  119. uint16_t data_type_id,
  120. uint8_t* inout_transfer_id,
  121. uint8_t priority,
  122. const void* payload,
  123. uint16_t payload_len
  124. #if CANARD_ENABLE_DEADLINE
  125. ,uint64_t tx_deadline
  126. #endif
  127. #if CANARD_MULTI_IFACE
  128. ,uint8_t iface_mask
  129. #endif
  130. #if CANARD_ENABLE_CANFD
  131. ,bool canfd
  132. #endif
  133. )
  134. {
  135. // create transfer object
  136. CanardTxTransfer transfer_object = {
  137. .data_type_signature = data_type_signature,
  138. .data_type_id = data_type_id,
  139. .inout_transfer_id = inout_transfer_id,
  140. .priority = priority,
  141. .payload = (uint8_t*)payload,
  142. .payload_len = payload_len,
  143. #if CANARD_ENABLE_DEADLINE
  144. .deadline_usec = tx_deadline,
  145. #endif
  146. #if CANARD_MULTI_IFACE
  147. .iface_mask = iface_mask,
  148. #endif
  149. #if CANARD_ENABLE_CANFD
  150. .canfd = canfd,
  151. #endif
  152. };
  153. return canardBroadcastObj(ins, &transfer_object);
  154. }
  155. int16_t canardBroadcastObj(CanardInstance* ins, CanardTxTransfer* transfer_object)
  156. {
  157. if (transfer_object->payload == NULL && transfer_object->payload_len > 0)
  158. {
  159. return -CANARD_ERROR_INVALID_ARGUMENT;
  160. }
  161. if (transfer_object->priority > CANARD_TRANSFER_PRIORITY_LOWEST)
  162. {
  163. return -CANARD_ERROR_INVALID_ARGUMENT;
  164. }
  165. uint32_t can_id = 0;
  166. uint16_t crc = 0xFFFFU;
  167. if (canardGetLocalNodeID(ins) == 0)
  168. {
  169. if (transfer_object->payload_len > 7)
  170. {
  171. return -CANARD_ERROR_NODE_ID_NOT_SET;
  172. }
  173. static const uint16_t DTIDMask = (1U << ANON_MSG_DATA_TYPE_ID_BIT_LEN) - 1U;
  174. if ((transfer_object->data_type_id & DTIDMask) != transfer_object->data_type_id)
  175. {
  176. return -CANARD_ERROR_INVALID_ARGUMENT;
  177. }
  178. // anonymous transfer, random discriminator
  179. const uint16_t discriminator = (uint16_t)((crcAdd(0xFFFFU, transfer_object->payload, transfer_object->payload_len)) & 0x7FFEU);
  180. can_id = ((uint32_t) transfer_object->priority << 24U) | ((uint32_t) discriminator << 9U) |
  181. ((uint32_t) (transfer_object->data_type_id & DTIDMask) << 8U) | (uint32_t) canardGetLocalNodeID(ins);
  182. }
  183. else
  184. {
  185. can_id = ((uint32_t) transfer_object->priority << 24U) | ((uint32_t) transfer_object->data_type_id << 8U) | (uint32_t) canardGetLocalNodeID(ins);
  186. crc = calculateCRC(transfer_object);
  187. }
  188. const int16_t result = enqueueTxFrames(ins, can_id, crc, transfer_object);
  189. if (result > 0) {
  190. incrementTransferID(transfer_object->inout_transfer_id);
  191. }
  192. return result;
  193. }
  194. /*
  195. the following FromIdx and ToIdx functions allow for the
  196. CanardBufferBlock and CanartRxState structures to have the same size
  197. on 32 bit and 64 bit platforms, which allows for easier testing in
  198. simulator environments
  199. */
  200. CANARD_INTERNAL CanardBufferBlock *canardBufferFromIdx(CanardPoolAllocator* allocator, canard_buffer_idx_t idx)
  201. {
  202. #if CANARD_64_BIT
  203. if (idx == CANARD_BUFFER_IDX_NONE) {
  204. return NULL;
  205. }
  206. return (CanardBufferBlock *)(uintptr_t)&((uint8_t *)allocator->arena)[idx-1];
  207. #else
  208. (void)allocator;
  209. return (CanardBufferBlock *)idx;
  210. #endif
  211. }
  212. CANARD_INTERNAL canard_buffer_idx_t canardBufferToIdx(CanardPoolAllocator* allocator, const CanardBufferBlock *buf)
  213. {
  214. #if CANARD_64_BIT
  215. if (buf == NULL) {
  216. return CANARD_BUFFER_IDX_NONE;
  217. }
  218. return 1U+((canard_buffer_idx_t)((uint8_t *)buf - (uint8_t *)allocator->arena));
  219. #else
  220. (void)allocator;
  221. return (canard_buffer_idx_t)buf;
  222. #endif
  223. }
  224. CANARD_INTERNAL CanardRxState *canardRxFromIdx(CanardPoolAllocator* allocator, canard_buffer_idx_t idx)
  225. {
  226. #if CANARD_64_BIT
  227. if (idx == CANARD_BUFFER_IDX_NONE) {
  228. return NULL;
  229. }
  230. return (CanardRxState *)(uintptr_t)&((uint8_t *)allocator->arena)[idx-1];
  231. #else
  232. (void)allocator;
  233. return (CanardRxState *)idx;
  234. #endif
  235. }
  236. CANARD_INTERNAL canard_buffer_idx_t canardRxToIdx(CanardPoolAllocator* allocator, const CanardRxState *rx)
  237. {
  238. #if CANARD_64_BIT
  239. if (rx == NULL) {
  240. return CANARD_BUFFER_IDX_NONE;
  241. }
  242. return 1U+((canard_buffer_idx_t)((uint8_t *)rx - (uint8_t *)allocator->arena));
  243. #else
  244. (void)allocator;
  245. return (canard_buffer_idx_t)rx;
  246. #endif
  247. }
  248. CANARD_INTERNAL uint16_t calculateCRC(const CanardTxTransfer* transfer_object)
  249. {
  250. uint16_t crc = 0xFFFFU;
  251. #if CANARD_ENABLE_CANFD
  252. if ((transfer_object->payload_len > 7 && !transfer_object->canfd) ||
  253. (transfer_object->payload_len > 63 && transfer_object->canfd))
  254. #else
  255. if (transfer_object->payload_len > 7)
  256. #endif
  257. {
  258. crc = crcAddSignature(crc, transfer_object->data_type_signature);
  259. crc = crcAdd(crc, transfer_object->payload, transfer_object->payload_len);
  260. #if CANARD_ENABLE_CANFD
  261. if (transfer_object->payload_len > 63 && transfer_object->canfd) {
  262. uint8_t empty = 0;
  263. uint8_t padding = (uint8_t)dlcToDataLength(dataLengthToDlc((uint16_t)((transfer_object->payload_len+2) % 63)+1))-1;
  264. padding -= (uint8_t)((transfer_object->payload_len+2) % 63);
  265. for (uint8_t i=0; i<padding; i++) {
  266. crc = crcAddByte(crc, empty);
  267. }
  268. }
  269. #endif
  270. }
  271. return crc;
  272. }
  273. int16_t canardRequestOrRespond(CanardInstance* ins,
  274. uint8_t destination_node_id,
  275. uint64_t data_type_signature,
  276. uint8_t data_type_id,
  277. uint8_t* inout_transfer_id,
  278. uint8_t priority,
  279. CanardRequestResponse kind,
  280. const void* payload,
  281. uint16_t payload_len
  282. #if CANARD_ENABLE_DEADLINE
  283. ,uint64_t tx_deadline
  284. #endif
  285. #if CANARD_MULTI_IFACE
  286. ,uint8_t iface_mask
  287. #endif
  288. #if CANARD_ENABLE_CANFD
  289. ,bool canfd
  290. #endif
  291. )
  292. {
  293. CanardTxTransfer transfer_object = {
  294. .data_type_signature = data_type_signature,
  295. .data_type_id = data_type_id,
  296. .inout_transfer_id = inout_transfer_id,
  297. .priority = priority,
  298. .transfer_type = kind == CanardRequest ? CanardTransferTypeRequest : CanardTransferTypeResponse,
  299. .payload = payload,
  300. .payload_len = payload_len,
  301. #if CANARD_ENABLE_DEADLINE
  302. .deadline_usec = tx_deadline,
  303. #endif
  304. #if CANARD_MULTI_IFACE
  305. .iface_mask = iface_mask,
  306. #endif
  307. #if CANARD_ENABLE_CANFD
  308. .canfd = canfd,
  309. #endif
  310. };
  311. return canardRequestOrRespondObj(ins, destination_node_id, &transfer_object);
  312. }
  313. int16_t canardRequestOrRespondObj(CanardInstance* ins, uint8_t destination_node_id, CanardTxTransfer* transfer_object)
  314. {
  315. if (transfer_object->payload == NULL && transfer_object->payload_len > 0)
  316. {
  317. return -CANARD_ERROR_INVALID_ARGUMENT;
  318. }
  319. if (transfer_object->priority > CANARD_TRANSFER_PRIORITY_LOWEST)
  320. {
  321. return -CANARD_ERROR_INVALID_ARGUMENT;
  322. }
  323. if (canardGetLocalNodeID(ins) == 0)
  324. {
  325. return -CANARD_ERROR_NODE_ID_NOT_SET;
  326. }
  327. const uint32_t can_id = ((uint32_t) transfer_object->priority << 24U) | ((uint32_t) transfer_object->data_type_id << 16U) |
  328. ((uint32_t) transfer_object->transfer_type << 15U) | ((uint32_t) destination_node_id << 8U) |
  329. (1U << 7U) | (uint32_t) canardGetLocalNodeID(ins);
  330. uint16_t crc = calculateCRC(transfer_object);
  331. const int16_t result = enqueueTxFrames(ins, can_id, crc, transfer_object);
  332. if (result > 0 && transfer_object->transfer_type == CanardTransferTypeRequest) // Response Transfer ID must not be altered
  333. {
  334. incrementTransferID(transfer_object->inout_transfer_id);
  335. }
  336. return result;
  337. }
  338. CanardCANFrame* canardPeekTxQueue(const CanardInstance* ins)
  339. {
  340. if (ins->tx_queue == NULL)
  341. {
  342. return NULL;
  343. }
  344. return &ins->tx_queue->frame;
  345. }
  346. void canardPopTxQueue(CanardInstance* ins)
  347. {
  348. CanardTxQueueItem* item = ins->tx_queue;
  349. ins->tx_queue = item->next;
  350. freeBlock(&ins->allocator, item);
  351. }
  352. int16_t canardHandleRxFrame(CanardInstance* ins, const CanardCANFrame* frame, uint64_t timestamp_usec)
  353. {
  354. const CanardTransferType transfer_type = extractTransferType(frame->id);
  355. const uint8_t destination_node_id = (transfer_type == CanardTransferTypeBroadcast) ?
  356. (uint8_t)CANARD_BROADCAST_NODE_ID :
  357. DEST_ID_FROM_ID(frame->id);
  358. // TODO: This function should maintain statistics of transfer errors and such.
  359. if ((frame->id & CANARD_CAN_FRAME_EFF) == 0 ||
  360. (frame->id & CANARD_CAN_FRAME_RTR) != 0 ||
  361. (frame->id & CANARD_CAN_FRAME_ERR) != 0 ||
  362. (frame->data_len < 1))
  363. {
  364. return -CANARD_ERROR_RX_INCOMPATIBLE_PACKET;
  365. }
  366. if (transfer_type != CanardTransferTypeBroadcast &&
  367. destination_node_id != canardGetLocalNodeID(ins))
  368. {
  369. return -CANARD_ERROR_RX_WRONG_ADDRESS;
  370. }
  371. const uint8_t priority = PRIORITY_FROM_ID(frame->id);
  372. const uint8_t source_node_id = SOURCE_ID_FROM_ID(frame->id);
  373. const uint16_t data_type_id = extractDataType(frame->id);
  374. const uint32_t transfer_descriptor =
  375. MAKE_TRANSFER_DESCRIPTOR(data_type_id, transfer_type, source_node_id, destination_node_id);
  376. const uint8_t tail_byte = frame->data[frame->data_len - 1];
  377. uint64_t data_type_signature = 0;
  378. CanardRxState* rx_state = NULL;
  379. if (IS_START_OF_TRANSFER(tail_byte))
  380. {
  381. if (ins->should_accept(ins, &data_type_signature, data_type_id, transfer_type, source_node_id))
  382. {
  383. rx_state = traverseRxStates(ins, transfer_descriptor);
  384. if(rx_state == NULL)
  385. {
  386. return -CANARD_ERROR_OUT_OF_MEMORY;
  387. }
  388. }
  389. else
  390. {
  391. return -CANARD_ERROR_RX_NOT_WANTED;
  392. }
  393. }
  394. else
  395. {
  396. rx_state = findRxState(ins, transfer_descriptor);
  397. if (rx_state == NULL)
  398. {
  399. // we should return -CANARD_ERROR_RX_NOT_WANTED for
  400. // non-start frames where we have rejected the start of
  401. // transfer. doing it here avoids calling the potentially
  402. // expensive should_accept() on every frame in messages we
  403. // will be accepting
  404. if (!ins->should_accept(ins, &data_type_signature, data_type_id, transfer_type, source_node_id)) {
  405. return -CANARD_ERROR_RX_NOT_WANTED;
  406. }
  407. return -CANARD_ERROR_RX_MISSED_START;
  408. }
  409. }
  410. CANARD_ASSERT(rx_state != NULL); // All paths that lead to NULL should be terminated with return above
  411. // Resolving the state flags:
  412. const bool not_initialized = rx_state->timestamp_usec == 0;
  413. const bool tid_timed_out = (timestamp_usec - rx_state->timestamp_usec) > TRANSFER_TIMEOUT_USEC;
  414. const bool same_iface = frame->iface_id == rx_state->iface_id;
  415. const bool first_frame = IS_START_OF_TRANSFER(tail_byte);
  416. const bool not_previous_tid =
  417. computeTransferIDForwardDistance((uint8_t) rx_state->transfer_id, TRANSFER_ID_FROM_TAIL_BYTE(tail_byte)) > 1;
  418. const bool iface_switch_allowed = (timestamp_usec - rx_state->timestamp_usec) > IFACE_SWITCH_DELAY_USEC;
  419. const bool non_wrapped_tid = computeTransferIDForwardDistance(TRANSFER_ID_FROM_TAIL_BYTE(tail_byte), (uint8_t) rx_state->transfer_id) < (1 << (TRANSFER_ID_BIT_LEN-1));
  420. const bool incomplete_frame = rx_state->buffer_blocks != CANARD_BUFFER_IDX_NONE;
  421. const bool need_restart =
  422. (not_initialized) ||
  423. (tid_timed_out) ||
  424. (same_iface && first_frame && (not_previous_tid || incomplete_frame)) ||
  425. (iface_switch_allowed && first_frame && non_wrapped_tid);
  426. if (need_restart)
  427. {
  428. rx_state->transfer_id = TRANSFER_ID_FROM_TAIL_BYTE(tail_byte);
  429. rx_state->next_toggle = 0;
  430. releaseStatePayload(ins, rx_state);
  431. rx_state->iface_id = frame->iface_id;
  432. if (!IS_START_OF_TRANSFER(tail_byte))
  433. {
  434. rx_state->transfer_id++;
  435. return -CANARD_ERROR_RX_MISSED_START;
  436. }
  437. }
  438. if (frame->iface_id != rx_state->iface_id)
  439. {
  440. // drop frame if coming from unexpected interface
  441. return CANARD_OK;
  442. }
  443. if (IS_START_OF_TRANSFER(tail_byte) && IS_END_OF_TRANSFER(tail_byte)) // single frame transfer
  444. {
  445. rx_state->timestamp_usec = timestamp_usec;
  446. CanardRxTransfer rx_transfer = {
  447. .timestamp_usec = timestamp_usec,
  448. .payload_head = frame->data,
  449. .payload_len = (uint8_t)(frame->data_len - 1U),
  450. .data_type_id = data_type_id,
  451. .transfer_type = (uint8_t)transfer_type,
  452. .transfer_id = TRANSFER_ID_FROM_TAIL_BYTE(tail_byte),
  453. .priority = priority,
  454. .source_node_id = source_node_id,
  455. #if CANARD_ENABLE_CANFD
  456. .canfd = frame->canfd,
  457. .tao = !(frame->canfd || ins->tao_disabled)
  458. #elif CANARD_ENABLE_TAO_OPTION
  459. .tao = !ins->tao_disabled
  460. #endif
  461. };
  462. ins->on_reception(ins, &rx_transfer);
  463. prepareForNextTransfer(rx_state);
  464. return CANARD_OK;
  465. }
  466. if (TOGGLE_BIT(tail_byte) != rx_state->next_toggle)
  467. {
  468. return -CANARD_ERROR_RX_WRONG_TOGGLE;
  469. }
  470. if (TRANSFER_ID_FROM_TAIL_BYTE(tail_byte) != rx_state->transfer_id)
  471. {
  472. return -CANARD_ERROR_RX_UNEXPECTED_TID;
  473. }
  474. if (IS_START_OF_TRANSFER(tail_byte) && !IS_END_OF_TRANSFER(tail_byte)) // Beginning of multi frame transfer
  475. {
  476. if (frame->data_len <= 3)
  477. {
  478. return -CANARD_ERROR_RX_SHORT_FRAME;
  479. }
  480. // take off the crc and store the payload
  481. rx_state->timestamp_usec = timestamp_usec;
  482. rx_state->payload_len = 0;
  483. const int16_t ret = bufferBlockPushBytes(&ins->allocator, rx_state, frame->data + 2,
  484. (uint8_t) (frame->data_len - 3));
  485. if (ret < 0)
  486. {
  487. releaseStatePayload(ins, rx_state);
  488. prepareForNextTransfer(rx_state);
  489. return -CANARD_ERROR_OUT_OF_MEMORY;
  490. }
  491. rx_state->payload_crc = (uint16_t)(((uint16_t) frame->data[0]) | (uint16_t)((uint16_t) frame->data[1] << 8U));
  492. rx_state->calculated_crc = crcAddSignature(0xFFFFU, data_type_signature);
  493. rx_state->calculated_crc = crcAdd((uint16_t)rx_state->calculated_crc,
  494. frame->data + 2, (uint8_t)(frame->data_len - 3));
  495. }
  496. else if (!IS_START_OF_TRANSFER(tail_byte) && !IS_END_OF_TRANSFER(tail_byte)) // Middle of a multi-frame transfer
  497. {
  498. const int16_t ret = bufferBlockPushBytes(&ins->allocator, rx_state, frame->data,
  499. (uint8_t) (frame->data_len - 1));
  500. if (ret < 0)
  501. {
  502. releaseStatePayload(ins, rx_state);
  503. prepareForNextTransfer(rx_state);
  504. return -CANARD_ERROR_OUT_OF_MEMORY;
  505. }
  506. rx_state->calculated_crc = crcAdd((uint16_t)rx_state->calculated_crc,
  507. frame->data, (uint8_t)(frame->data_len - 1));
  508. }
  509. else // End of a multi-frame transfer
  510. {
  511. const uint8_t frame_payload_size = (uint8_t)(frame->data_len - 1);
  512. uint8_t tail_offset = 0;
  513. if (rx_state->payload_len < CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE)
  514. {
  515. // Copy the beginning of the frame into the head, point the tail pointer to the remainder
  516. for (size_t i = rx_state->payload_len;
  517. (i < CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE) && (tail_offset < frame_payload_size);
  518. i++, tail_offset++)
  519. {
  520. rx_state->buffer_head[i] = frame->data[tail_offset];
  521. }
  522. }
  523. else
  524. {
  525. // Like above, except that the beginning goes into the last block of the storage
  526. CanardBufferBlock* block = canardBufferFromIdx(&ins->allocator, rx_state->buffer_blocks);
  527. if (block != NULL)
  528. {
  529. size_t offset = CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE; // Payload offset of the first block
  530. while (block->next != NULL)
  531. {
  532. block = block->next;
  533. offset += CANARD_BUFFER_BLOCK_DATA_SIZE;
  534. }
  535. CANARD_ASSERT(block != NULL);
  536. const size_t offset_within_block = rx_state->payload_len - offset;
  537. CANARD_ASSERT(offset_within_block <= CANARD_BUFFER_BLOCK_DATA_SIZE);
  538. for (size_t i = offset_within_block;
  539. (i < CANARD_BUFFER_BLOCK_DATA_SIZE) && (tail_offset < frame_payload_size);
  540. i++, tail_offset++)
  541. {
  542. block->data[i] = frame->data[tail_offset];
  543. }
  544. }
  545. }
  546. CanardRxTransfer rx_transfer = {
  547. .timestamp_usec = timestamp_usec,
  548. .payload_head = rx_state->buffer_head,
  549. .payload_middle = canardBufferFromIdx(&ins->allocator, rx_state->buffer_blocks),
  550. .payload_tail = (tail_offset >= frame_payload_size) ? NULL : (&frame->data[tail_offset]),
  551. .payload_len = (uint16_t)(rx_state->payload_len + frame_payload_size),
  552. .data_type_id = data_type_id,
  553. .transfer_type = (uint8_t)transfer_type,
  554. .transfer_id = TRANSFER_ID_FROM_TAIL_BYTE(tail_byte),
  555. .priority = priority,
  556. .source_node_id = source_node_id,
  557. #if CANARD_ENABLE_CANFD
  558. .canfd = frame->canfd,
  559. .tao = !(frame->canfd || ins->tao_disabled)
  560. #elif CANARD_ENABLE_TAO_OPTION
  561. .tao = !ins->tao_disabled
  562. #endif
  563. };
  564. rx_state->buffer_blocks = CANARD_BUFFER_IDX_NONE; // Block list ownership has been transferred to rx_transfer!
  565. // CRC validation
  566. rx_state->calculated_crc = crcAdd((uint16_t)rx_state->calculated_crc, frame->data, frame->data_len - 1U);
  567. if (rx_state->calculated_crc == rx_state->payload_crc)
  568. {
  569. ins->on_reception(ins, &rx_transfer);
  570. }
  571. // Making sure the payload is released even if the application didn't bother with it
  572. canardReleaseRxTransferPayload(ins, &rx_transfer);
  573. prepareForNextTransfer(rx_state);
  574. if (rx_state->calculated_crc == rx_state->payload_crc)
  575. {
  576. return CANARD_OK;
  577. }
  578. else
  579. {
  580. return -CANARD_ERROR_RX_BAD_CRC;
  581. }
  582. }
  583. rx_state->next_toggle = rx_state->next_toggle ? 0 : 1;
  584. return CANARD_OK;
  585. }
  586. void canardCleanupStaleTransfers(CanardInstance* ins, uint64_t current_time_usec)
  587. {
  588. CanardRxState* prev = ins->rx_states, * state = ins->rx_states;
  589. while (state != NULL)
  590. {
  591. if ((current_time_usec - state->timestamp_usec) > TRANSFER_TIMEOUT_USEC)
  592. {
  593. if (state == ins->rx_states)
  594. {
  595. releaseStatePayload(ins, state);
  596. ins->rx_states = canardRxFromIdx(&ins->allocator, ins->rx_states->next);
  597. freeBlock(&ins->allocator, state);
  598. state = ins->rx_states;
  599. prev = state;
  600. }
  601. else
  602. {
  603. releaseStatePayload(ins, state);
  604. prev->next = state->next;
  605. freeBlock(&ins->allocator, state);
  606. state = canardRxFromIdx(&ins->allocator, prev->next);
  607. }
  608. }
  609. else
  610. {
  611. prev = state;
  612. state = canardRxFromIdx(&ins->allocator, state->next);
  613. }
  614. }
  615. #if CANARD_MULTI_IFACE || CANARD_ENABLE_DEADLINE
  616. // remove stale TX transfers
  617. CanardTxQueueItem* prev_item = ins->tx_queue, * item = ins->tx_queue;
  618. while (item != NULL)
  619. {
  620. #if CANARD_MULTI_IFACE && CANARD_ENABLE_DEADLINE
  621. if ((current_time_usec > item->frame.deadline_usec) || item->frame.iface_mask == 0)
  622. #elif CANARD_MULTI_IFACE
  623. if (item->frame.iface_mask == 0)
  624. #else
  625. if (current_time_usec > item->frame.deadline_usec)
  626. #endif
  627. {
  628. if (item == ins->tx_queue)
  629. {
  630. ins->tx_queue = ins->tx_queue->next;
  631. freeBlock(&ins->allocator, item);
  632. item = ins->tx_queue;
  633. prev_item = item;
  634. }
  635. else
  636. {
  637. prev_item->next = item->next;
  638. freeBlock(&ins->allocator, item);
  639. item = prev_item->next;
  640. }
  641. }
  642. else
  643. {
  644. prev_item = item;
  645. item = item->next;
  646. }
  647. }
  648. #endif
  649. }
  650. int16_t canardDecodeScalar(const CanardRxTransfer* transfer,
  651. uint32_t bit_offset,
  652. uint8_t bit_length,
  653. bool value_is_signed,
  654. void* out_value)
  655. {
  656. if (transfer == NULL || out_value == NULL)
  657. {
  658. return -CANARD_ERROR_INVALID_ARGUMENT;
  659. }
  660. if (bit_length < 1 || bit_length > 64)
  661. {
  662. return -CANARD_ERROR_INVALID_ARGUMENT;
  663. }
  664. if (bit_length == 1 && value_is_signed)
  665. {
  666. return -CANARD_ERROR_INVALID_ARGUMENT;
  667. }
  668. /*
  669. * Reading raw bytes into the temporary storage.
  670. * Luckily, C guarantees that every element is aligned at the beginning (lower address) of the union.
  671. */
  672. union
  673. {
  674. bool boolean; ///< sizeof(bool) is implementation-defined, so it has to be handled separately
  675. uint8_t u8; ///< Also char
  676. int8_t s8;
  677. uint16_t u16;
  678. int16_t s16;
  679. uint32_t u32;
  680. int32_t s32; ///< Also float, possibly double, possibly long double (depends on implementation)
  681. uint64_t u64;
  682. int64_t s64; ///< Also double, possibly float, possibly long double (depends on implementation)
  683. uint8_t bytes[8];
  684. } storage;
  685. memset(&storage, 0, sizeof(storage)); // This is important
  686. const int16_t result = descatterTransferPayload(transfer, bit_offset, bit_length, &storage.bytes[0]);
  687. if (result <= 0)
  688. {
  689. return result;
  690. }
  691. CANARD_ASSERT((result > 0) && (result <= 64) && (result <= bit_length));
  692. /*
  693. * The bit copy algorithm assumes that more significant bits have lower index, so we need to shift some.
  694. * Extra most significant bits will be filled with zeroes, which is fine.
  695. * Coverity Scan mistakenly believes that the array may be overrun if bit_length == 64; however, this branch will
  696. * not be taken if bit_length == 64, because 64 % 8 == 0.
  697. */
  698. if ((bit_length % 8) != 0)
  699. {
  700. // coverity[overrun-local]
  701. storage.bytes[bit_length / 8U] = (uint8_t)(storage.bytes[bit_length / 8U] >> ((8U - (bit_length % 8U)) & 7U));
  702. }
  703. /*
  704. * Determining the closest standard byte length - this will be needed for byte reordering and sign bit extension.
  705. */
  706. uint8_t std_byte_length = 0;
  707. if (bit_length == 1) { std_byte_length = sizeof(bool); }
  708. else if (bit_length <= 8) { std_byte_length = 1; }
  709. else if (bit_length <= 16) { std_byte_length = 2; }
  710. else if (bit_length <= 32) { std_byte_length = 4; }
  711. else if (bit_length <= 64) { std_byte_length = 8; }
  712. else
  713. {
  714. CANARD_ASSERT(false);
  715. return -CANARD_ERROR_INTERNAL;
  716. }
  717. CANARD_ASSERT((std_byte_length > 0) && (std_byte_length <= 8));
  718. /*
  719. * Flipping the byte order if needed.
  720. */
  721. if (isBigEndian())
  722. {
  723. swapByteOrder(&storage.bytes[0], std_byte_length);
  724. }
  725. #if WORD_ADDRESSING_IS_16BITS
  726. /*
  727. * Copying 8-bit array to 64-bit storage
  728. */
  729. {
  730. uint64_t temp = 0;
  731. for(uint16_t i=0; i<std_byte_length; i++)
  732. {
  733. temp |= (((uint64_t)storage.bytes[i] & 0xFFU) << (8*i));
  734. }
  735. storage.u64 = temp;
  736. }
  737. #endif
  738. /*
  739. * Extending the sign bit if needed. I miss templates.
  740. * Note that we operate on unsigned values in order to avoid undefined behaviors.
  741. */
  742. if (value_is_signed && (std_byte_length * 8 != bit_length))
  743. {
  744. if (bit_length <= 8)
  745. {
  746. if ((storage.u8 & (1U << (bit_length - 1U))) != 0) // If the sign bit is set...
  747. {
  748. storage.u8 |= (uint8_t) 0xFFU & (uint8_t) ~((1U << bit_length) - 1U); // ...set all bits above it.
  749. }
  750. }
  751. else if (bit_length <= 16)
  752. {
  753. if ((storage.u16 & (1U << (bit_length - 1U))) != 0)
  754. {
  755. storage.u16 |= (uint16_t) 0xFFFFU & (uint16_t) ~((1U << bit_length) - 1U);
  756. }
  757. }
  758. else if (bit_length <= 32)
  759. {
  760. if ((storage.u32 & (((uint32_t) 1) << (bit_length - 1U))) != 0)
  761. {
  762. storage.u32 |= (uint32_t) 0xFFFFFFFFUL & (uint32_t) ~((((uint32_t) 1) << bit_length) - 1U);
  763. }
  764. }
  765. else if (bit_length < 64) // Strictly less, this is not a typo
  766. {
  767. if ((storage.u64 & (((uint64_t) 1) << (bit_length - 1U))) != 0)
  768. {
  769. storage.u64 |= (uint64_t) 0xFFFFFFFFFFFFFFFFULL & (uint64_t) ~((((uint64_t) 1) << bit_length) - 1U);
  770. }
  771. }
  772. else
  773. {
  774. CANARD_ASSERT(false);
  775. return -CANARD_ERROR_INTERNAL;
  776. }
  777. }
  778. /*
  779. * Copying the result out.
  780. */
  781. if (value_is_signed)
  782. {
  783. if (bit_length <= 8) { *( (int8_t*) out_value) = storage.s8; }
  784. else if (bit_length <= 16) { *((int16_t*) out_value) = storage.s16; }
  785. else if (bit_length <= 32) { *((int32_t*) out_value) = storage.s32; }
  786. else if (bit_length <= 64) { *((int64_t*) out_value) = storage.s64; }
  787. else
  788. {
  789. CANARD_ASSERT(false);
  790. return -CANARD_ERROR_INTERNAL;
  791. }
  792. }
  793. else
  794. {
  795. if (bit_length == 1) { *( (bool*) out_value) = storage.boolean; }
  796. else if (bit_length <= 8) { *( (uint8_t*) out_value) = storage.u8; }
  797. else if (bit_length <= 16) { *((uint16_t*) out_value) = storage.u16; }
  798. else if (bit_length <= 32) { *((uint32_t*) out_value) = storage.u32; }
  799. else if (bit_length <= 64) { *((uint64_t*) out_value) = storage.u64; }
  800. else
  801. {
  802. CANARD_ASSERT(false);
  803. return -CANARD_ERROR_INTERNAL;
  804. }
  805. }
  806. CANARD_ASSERT(result <= bit_length);
  807. CANARD_ASSERT(result > 0);
  808. return result;
  809. }
  810. void canardEncodeScalar(void* destination,
  811. uint32_t bit_offset,
  812. uint8_t bit_length,
  813. const void* value)
  814. {
  815. /*
  816. * This function can only fail due to invalid arguments, so it was decided to make it return void,
  817. * and in the case of bad arguments try the best effort or just trigger an CANARD_ASSERTion failure.
  818. * Maybe not the best solution, but it simplifies the API.
  819. */
  820. CANARD_ASSERT(destination != NULL);
  821. CANARD_ASSERT(value != NULL);
  822. if (bit_length > 64)
  823. {
  824. CANARD_ASSERT(false);
  825. bit_length = 64;
  826. }
  827. if (bit_length < 1)
  828. {
  829. CANARD_ASSERT(false);
  830. bit_length = 1;
  831. }
  832. /*
  833. * Preparing the data in the temporary storage.
  834. */
  835. union
  836. {
  837. bool boolean;
  838. uint8_t u8;
  839. uint16_t u16;
  840. uint32_t u32;
  841. uint64_t u64;
  842. uint8_t bytes[8];
  843. } storage;
  844. memset(&storage, 0, sizeof(storage));
  845. uint8_t std_byte_length = 0;
  846. // Extra most significant bits can be safely ignored here.
  847. if (bit_length == 1) { std_byte_length = sizeof(bool); storage.boolean = (*((bool*) value) != 0); }
  848. else if (bit_length <= 8) { std_byte_length = 1; storage.u8 = *((uint8_t*) value); }
  849. else if (bit_length <= 16) { std_byte_length = 2; storage.u16 = *((uint16_t*) value); }
  850. else if (bit_length <= 32) { std_byte_length = 4; storage.u32 = *((uint32_t*) value); }
  851. else if (bit_length <= 64) { std_byte_length = 8; storage.u64 = *((uint64_t*) value); }
  852. else
  853. {
  854. CANARD_ASSERT(false);
  855. }
  856. CANARD_ASSERT(std_byte_length > 0);
  857. #if WORD_ADDRESSING_IS_16BITS
  858. /*
  859. * Copying 64-bit storage to 8-bit array
  860. */
  861. {
  862. uint64_t temp = storage.u64;
  863. for(uint16_t i=0; i<std_byte_length; i++)
  864. {
  865. storage.bytes[i] = (temp >> (8*i)) & 0xFFU;
  866. }
  867. }
  868. #endif
  869. if (isBigEndian())
  870. {
  871. swapByteOrder(&storage.bytes[0], std_byte_length);
  872. }
  873. /*
  874. * The bit copy algorithm assumes that more significant bits have lower index, so we need to shift some.
  875. * Extra least significant bits will be filled with zeroes, which is fine.
  876. * Extra most significant bits will be discarded here.
  877. * Coverity Scan mistakenly believes that the array may be overrun if bit_length == 64; however, this branch will
  878. * not be taken if bit_length == 64, because 64 % 8 == 0.
  879. */
  880. if ((bit_length % 8) != 0)
  881. {
  882. // coverity[overrun-local]
  883. storage.bytes[bit_length / 8U] = (uint8_t)(storage.bytes[bit_length / 8U] << ((8U - (bit_length % 8U)) & 7U));
  884. }
  885. /*
  886. * Now, the storage contains properly serialized scalar. Copying it out.
  887. */
  888. copyBitArray(&storage.bytes[0], 0, bit_length, (uint8_t*) destination, bit_offset);
  889. }
  890. void canardReleaseRxTransferPayload(CanardInstance* ins, CanardRxTransfer* transfer)
  891. {
  892. while (transfer->payload_middle != NULL)
  893. {
  894. CanardBufferBlock* const temp = transfer->payload_middle->next;
  895. freeBlock(&ins->allocator, transfer->payload_middle);
  896. transfer->payload_middle = temp;
  897. }
  898. transfer->payload_middle = NULL;
  899. transfer->payload_head = NULL;
  900. transfer->payload_tail = NULL;
  901. transfer->payload_len = 0;
  902. }
  903. CanardPoolAllocatorStatistics canardGetPoolAllocatorStatistics(CanardInstance* ins)
  904. {
  905. return ins->allocator.statistics;
  906. }
  907. uint16_t canardConvertNativeFloatToFloat16(float value)
  908. {
  909. CANARD_ASSERT(sizeof(float) == CANARD_SIZEOF_FLOAT);
  910. union FP32
  911. {
  912. uint32_t u;
  913. float f;
  914. };
  915. const union FP32 f32inf = { 255UL << 23U };
  916. const union FP32 f16inf = { 31UL << 23U };
  917. const union FP32 magic = { 15UL << 23U };
  918. const uint32_t sign_mask = 0x80000000UL;
  919. const uint32_t round_mask = 0xFFFFF000UL;
  920. union FP32 in;
  921. in.f = value;
  922. uint32_t sign = in.u & sign_mask;
  923. in.u ^= sign;
  924. uint16_t out = 0;
  925. if (in.u >= f32inf.u)
  926. {
  927. out = (in.u > f32inf.u) ? (uint16_t)0x7FFFU : (uint16_t)0x7C00U;
  928. }
  929. else
  930. {
  931. in.u &= round_mask;
  932. in.f *= magic.f;
  933. in.u -= round_mask;
  934. if (in.u > f16inf.u)
  935. {
  936. in.u = f16inf.u;
  937. }
  938. out = (uint16_t)(in.u >> 13U);
  939. }
  940. out |= (uint16_t)(sign >> 16U);
  941. return out;
  942. }
  943. float canardConvertFloat16ToNativeFloat(uint16_t value)
  944. {
  945. CANARD_ASSERT(sizeof(float) == CANARD_SIZEOF_FLOAT);
  946. union FP32
  947. {
  948. uint32_t u;
  949. float f;
  950. };
  951. const union FP32 magic = { (254UL - 15UL) << 23U };
  952. const union FP32 was_inf_nan = { (127UL + 16UL) << 23U };
  953. union FP32 out;
  954. out.u = (value & 0x7FFFU) << 13U;
  955. out.f *= magic.f;
  956. if (out.f >= was_inf_nan.f)
  957. {
  958. out.u |= 255UL << 23U;
  959. }
  960. out.u |= (value & 0x8000UL) << 16U;
  961. return out.f;
  962. }
  963. /*
  964. * Internal (static functions)
  965. */
  966. CANARD_INTERNAL int16_t computeTransferIDForwardDistance(uint8_t a, uint8_t b)
  967. {
  968. int16_t d = (int16_t)(a - b);
  969. if (d < 0)
  970. {
  971. d = (int16_t)(d + (int16_t)(1U << TRANSFER_ID_BIT_LEN));
  972. }
  973. return d;
  974. }
  975. CANARD_INTERNAL void incrementTransferID(uint8_t* transfer_id)
  976. {
  977. CANARD_ASSERT(transfer_id != NULL);
  978. (*transfer_id)++;
  979. if (*transfer_id >= 32)
  980. {
  981. *transfer_id = 0;
  982. }
  983. }
  984. CANARD_INTERNAL uint16_t dlcToDataLength(uint16_t dlc) {
  985. /*
  986. Data Length Code 9 10 11 12 13 14 15
  987. Number of data bytes 12 16 20 24 32 48 64
  988. */
  989. if (dlc <= 8) {
  990. return dlc;
  991. } else if (dlc == 9) {
  992. return 12;
  993. } else if (dlc == 10) {
  994. return 16;
  995. } else if (dlc == 11) {
  996. return 20;
  997. } else if (dlc == 12) {
  998. return 24;
  999. } else if (dlc == 13) {
  1000. return 32;
  1001. } else if (dlc == 14) {
  1002. return 48;
  1003. }
  1004. return 64;
  1005. }
  1006. CANARD_INTERNAL uint16_t dataLengthToDlc(uint16_t data_length) {
  1007. if (data_length <= 8) {
  1008. return data_length;
  1009. } else if (data_length <= 12) {
  1010. return 9;
  1011. } else if (data_length <= 16) {
  1012. return 10;
  1013. } else if (data_length <= 20) {
  1014. return 11;
  1015. } else if (data_length <= 24) {
  1016. return 12;
  1017. } else if (data_length <= 32) {
  1018. return 13;
  1019. } else if (data_length <= 48) {
  1020. return 14;
  1021. }
  1022. return 15;
  1023. }
  1024. CANARD_INTERNAL int16_t enqueueTxFrames(CanardInstance* ins,
  1025. uint32_t can_id,
  1026. uint16_t crc,
  1027. CanardTxTransfer* transfer
  1028. )
  1029. {
  1030. CANARD_ASSERT(ins != NULL);
  1031. CANARD_ASSERT((can_id & CANARD_CAN_EXT_ID_MASK) == can_id); // Flags must be cleared
  1032. if (transfer->inout_transfer_id == NULL)
  1033. {
  1034. return -CANARD_ERROR_INVALID_ARGUMENT;
  1035. }
  1036. if ((transfer->payload_len > 0) && (transfer->payload == NULL))
  1037. {
  1038. return -CANARD_ERROR_INVALID_ARGUMENT;
  1039. }
  1040. int16_t result = 0;
  1041. #if CANARD_ENABLE_CANFD
  1042. uint8_t frame_max_data_len = transfer->canfd ? CANARD_CANFD_FRAME_MAX_DATA_LEN:CANARD_CAN_FRAME_MAX_DATA_LEN;
  1043. #else
  1044. uint8_t frame_max_data_len = CANARD_CAN_FRAME_MAX_DATA_LEN;
  1045. #endif
  1046. if (transfer->payload_len < frame_max_data_len) // Single frame transfer
  1047. {
  1048. CanardTxQueueItem* queue_item = createTxItem(&ins->allocator);
  1049. if (queue_item == NULL)
  1050. {
  1051. return -CANARD_ERROR_OUT_OF_MEMORY;
  1052. }
  1053. memcpy(queue_item->frame.data, transfer->payload, transfer->payload_len);
  1054. transfer->payload_len = dlcToDataLength(dataLengthToDlc(transfer->payload_len+1))-1;
  1055. queue_item->frame.data_len = (uint8_t)(transfer->payload_len + 1);
  1056. queue_item->frame.data[transfer->payload_len] = (uint8_t)(0xC0U | (*transfer->inout_transfer_id & 31U));
  1057. queue_item->frame.id = can_id | CANARD_CAN_FRAME_EFF;
  1058. #if CANARD_ENABLE_DEADLINE
  1059. queue_item->frame.deadline_usec = transfer->deadline_usec;
  1060. #endif
  1061. #if CANARD_MULTI_IFACE
  1062. queue_item->frame.iface_mask = transfer->iface_mask;
  1063. #endif
  1064. #if CANARD_ENABLE_CANFD
  1065. queue_item->frame.canfd = transfer->canfd;
  1066. #endif
  1067. pushTxQueue(ins, queue_item);
  1068. result++;
  1069. }
  1070. else // Multi frame transfer
  1071. {
  1072. uint16_t data_index = 0;
  1073. uint8_t toggle = 0;
  1074. uint8_t sot_eot = 0x80;
  1075. /*
  1076. see if we are going to be able to allocate enough blocks for
  1077. this transfer. If not then stop now, otherwise we will end
  1078. up doing a partial (corrupt) transfer which will just make
  1079. the situation worse as it will waste bus bandwidth
  1080. */
  1081. const uint16_t total_bytes = transfer->payload_len + 2; // including CRC
  1082. const uint8_t bytes_per_frame = frame_max_data_len-1; // sot/eot byte consumes one byte
  1083. const uint16_t frames_needed = (total_bytes + (bytes_per_frame-1)) / bytes_per_frame;
  1084. const uint16_t blocks_available = ins->allocator.statistics.capacity_blocks - ins->allocator.statistics.current_usage_blocks;
  1085. if (blocks_available < frames_needed) {
  1086. return -CANARD_ERROR_OUT_OF_MEMORY;
  1087. }
  1088. CanardTxQueueItem* queue_item = NULL;
  1089. while (transfer->payload_len - data_index != 0)
  1090. {
  1091. queue_item = createTxItem(&ins->allocator);
  1092. if (queue_item == NULL)
  1093. {
  1094. CANARD_ASSERT(false);
  1095. return -CANARD_ERROR_OUT_OF_MEMORY;
  1096. }
  1097. uint16_t i = 0;
  1098. if (data_index == 0)
  1099. {
  1100. // add crc
  1101. queue_item->frame.data[0] = (uint8_t) (crc);
  1102. queue_item->frame.data[1] = (uint8_t) (crc >> 8U);
  1103. i = 2;
  1104. }
  1105. else
  1106. {
  1107. i = 0;
  1108. }
  1109. for (; i < (frame_max_data_len - 1) && data_index < transfer->payload_len; i++, data_index++)
  1110. {
  1111. queue_item->frame.data[i] = transfer->payload[data_index];
  1112. }
  1113. // tail byte
  1114. sot_eot = (data_index == transfer->payload_len) ? (uint8_t)0x40 : sot_eot;
  1115. i = dlcToDataLength(dataLengthToDlc(i+1))-1;
  1116. queue_item->frame.data[i] = (uint8_t)(sot_eot | ((uint32_t)toggle << 5U) | ((uint32_t)*transfer->inout_transfer_id & 31U));
  1117. queue_item->frame.id = can_id | CANARD_CAN_FRAME_EFF;
  1118. queue_item->frame.data_len = (uint8_t)(i + 1);
  1119. #if CANARD_ENABLE_DEADLINE
  1120. queue_item->frame.deadline_usec = transfer->deadline_usec;
  1121. #endif
  1122. #if CANARD_MULTI_IFACE
  1123. queue_item->frame.iface_mask = transfer->iface_mask;
  1124. #endif
  1125. #if CANARD_ENABLE_CANFD
  1126. queue_item->frame.canfd = transfer->canfd;
  1127. #endif
  1128. pushTxQueue(ins, queue_item);
  1129. result++;
  1130. toggle ^= 1;
  1131. sot_eot = 0;
  1132. }
  1133. }
  1134. return result;
  1135. }
  1136. /**
  1137. * Puts frame on on the TX queue. Higher priority placed first
  1138. */
  1139. CANARD_INTERNAL void pushTxQueue(CanardInstance* ins, CanardTxQueueItem* item)
  1140. {
  1141. CANARD_ASSERT(ins != NULL);
  1142. CANARD_ASSERT(item->frame.data_len > 0); // UAVCAN doesn't allow zero-payload frames
  1143. if (ins->tx_queue == NULL)
  1144. {
  1145. ins->tx_queue = item;
  1146. return;
  1147. }
  1148. CanardTxQueueItem* queue = ins->tx_queue;
  1149. CanardTxQueueItem* previous = ins->tx_queue;
  1150. while (queue != NULL)
  1151. {
  1152. if (isPriorityHigher(queue->frame.id, item->frame.id)) // lower number wins
  1153. {
  1154. if (queue == ins->tx_queue)
  1155. {
  1156. item->next = queue;
  1157. ins->tx_queue = item;
  1158. }
  1159. else
  1160. {
  1161. previous->next = item;
  1162. item->next = queue;
  1163. }
  1164. return;
  1165. }
  1166. else
  1167. {
  1168. if (queue->next == NULL)
  1169. {
  1170. queue->next = item;
  1171. return;
  1172. }
  1173. else
  1174. {
  1175. previous = queue;
  1176. queue = queue->next;
  1177. }
  1178. }
  1179. }
  1180. }
  1181. /**
  1182. * Creates new tx queue item from allocator
  1183. */
  1184. CANARD_INTERNAL CanardTxQueueItem* createTxItem(CanardPoolAllocator* allocator)
  1185. {
  1186. CanardTxQueueItem* item = (CanardTxQueueItem*) allocateBlock(allocator);
  1187. if (item == NULL)
  1188. {
  1189. return NULL;
  1190. }
  1191. memset(item, 0, sizeof(*item));
  1192. return item;
  1193. }
  1194. /**
  1195. * Returns true if priority of rhs is higher than id
  1196. */
  1197. CANARD_INTERNAL bool isPriorityHigher(uint32_t rhs, uint32_t id)
  1198. {
  1199. const uint32_t clean_id = id & CANARD_CAN_EXT_ID_MASK;
  1200. const uint32_t rhs_clean_id = rhs & CANARD_CAN_EXT_ID_MASK;
  1201. /*
  1202. * STD vs EXT - if 11 most significant bits are the same, EXT loses.
  1203. */
  1204. const bool ext = (id & CANARD_CAN_FRAME_EFF) != 0;
  1205. const bool rhs_ext = (rhs & CANARD_CAN_FRAME_EFF) != 0;
  1206. if (ext != rhs_ext)
  1207. {
  1208. uint32_t arb11 = ext ? (clean_id >> 18U) : clean_id;
  1209. uint32_t rhs_arb11 = rhs_ext ? (rhs_clean_id >> 18U) : rhs_clean_id;
  1210. if (arb11 != rhs_arb11)
  1211. {
  1212. return arb11 < rhs_arb11;
  1213. }
  1214. else
  1215. {
  1216. return rhs_ext;
  1217. }
  1218. }
  1219. /*
  1220. * RTR vs Data frame - if frame identifiers and frame types are the same, RTR loses.
  1221. */
  1222. const bool rtr = (id & CANARD_CAN_FRAME_RTR) != 0;
  1223. const bool rhs_rtr = (rhs & CANARD_CAN_FRAME_RTR) != 0;
  1224. if (clean_id == rhs_clean_id && rtr != rhs_rtr)
  1225. {
  1226. return rhs_rtr;
  1227. }
  1228. /*
  1229. * Plain ID arbitration - greater value loses.
  1230. */
  1231. return clean_id < rhs_clean_id;
  1232. }
  1233. /**
  1234. * preps the rx state for the next transfer. does not delete the state
  1235. */
  1236. CANARD_INTERNAL void prepareForNextTransfer(CanardRxState* state)
  1237. {
  1238. CANARD_ASSERT(state->buffer_blocks == CANARD_BUFFER_IDX_NONE);
  1239. state->transfer_id++;
  1240. state->payload_len = 0;
  1241. state->next_toggle = 0;
  1242. }
  1243. /**
  1244. * returns data type from id
  1245. */
  1246. uint16_t extractDataType(uint32_t id)
  1247. {
  1248. if (extractTransferType(id) == CanardTransferTypeBroadcast)
  1249. {
  1250. uint16_t dtid = MSG_TYPE_FROM_ID(id);
  1251. if (SOURCE_ID_FROM_ID(id) == CANARD_BROADCAST_NODE_ID)
  1252. {
  1253. dtid &= (1U << ANON_MSG_DATA_TYPE_ID_BIT_LEN) - 1U;
  1254. }
  1255. return dtid;
  1256. }
  1257. else
  1258. {
  1259. return (uint16_t) SRV_TYPE_FROM_ID(id);
  1260. }
  1261. }
  1262. /**
  1263. * returns transfer type from id
  1264. */
  1265. CanardTransferType extractTransferType(uint32_t id)
  1266. {
  1267. const bool is_service = SERVICE_NOT_MSG_FROM_ID(id);
  1268. if (!is_service)
  1269. {
  1270. return CanardTransferTypeBroadcast;
  1271. }
  1272. else if (REQUEST_NOT_RESPONSE_FROM_ID(id) == 1)
  1273. {
  1274. return CanardTransferTypeRequest;
  1275. }
  1276. else
  1277. {
  1278. return CanardTransferTypeResponse;
  1279. }
  1280. }
  1281. /*
  1282. * CanardRxState functions
  1283. */
  1284. /**
  1285. * Traverses the list of CanardRxState's and returns a pointer to the CanardRxState
  1286. * with either the Id or a new one at the end
  1287. */
  1288. CANARD_INTERNAL CanardRxState* traverseRxStates(CanardInstance* ins, uint32_t transfer_descriptor)
  1289. {
  1290. CanardRxState* states = ins->rx_states;
  1291. if (states == NULL) // initialize CanardRxStates
  1292. {
  1293. states = createRxState(&ins->allocator, transfer_descriptor);
  1294. if(states == NULL)
  1295. {
  1296. return NULL;
  1297. }
  1298. ins->rx_states = states;
  1299. return states;
  1300. }
  1301. states = findRxState(ins, transfer_descriptor);
  1302. if (states != NULL)
  1303. {
  1304. return states;
  1305. }
  1306. else
  1307. {
  1308. return prependRxState(ins, transfer_descriptor);
  1309. }
  1310. }
  1311. /**
  1312. * returns pointer to the rx state of transfer descriptor or null if not found
  1313. */
  1314. CANARD_INTERNAL CanardRxState* findRxState(CanardInstance *ins, uint32_t transfer_descriptor)
  1315. {
  1316. CanardRxState *state = ins->rx_states;
  1317. while (state != NULL)
  1318. {
  1319. if (state->dtid_tt_snid_dnid == transfer_descriptor)
  1320. {
  1321. return state;
  1322. }
  1323. state = canardRxFromIdx(&ins->allocator, state->next);
  1324. }
  1325. return NULL;
  1326. }
  1327. /**
  1328. * prepends rx state to the canard instance rx_states
  1329. */
  1330. CANARD_INTERNAL CanardRxState* prependRxState(CanardInstance* ins, uint32_t transfer_descriptor)
  1331. {
  1332. CanardRxState* state = createRxState(&ins->allocator, transfer_descriptor);
  1333. if(state == NULL)
  1334. {
  1335. return NULL;
  1336. }
  1337. state->next = canardRxToIdx(&ins->allocator, ins->rx_states);
  1338. ins->rx_states = state;
  1339. return state;
  1340. }
  1341. CANARD_INTERNAL CanardRxState* createRxState(CanardPoolAllocator* allocator, uint32_t transfer_descriptor)
  1342. {
  1343. CanardRxState init = {
  1344. .next = CANARD_BUFFER_IDX_NONE,
  1345. .buffer_blocks = CANARD_BUFFER_IDX_NONE,
  1346. .dtid_tt_snid_dnid = transfer_descriptor
  1347. };
  1348. CanardRxState* state = (CanardRxState*) allocateBlock(allocator);
  1349. if (state == NULL)
  1350. {
  1351. return NULL;
  1352. }
  1353. memcpy(state, &init, sizeof(*state));
  1354. return state;
  1355. }
  1356. CANARD_INTERNAL uint64_t releaseStatePayload(CanardInstance* ins, CanardRxState* rxstate)
  1357. {
  1358. while (rxstate->buffer_blocks != CANARD_BUFFER_IDX_NONE)
  1359. {
  1360. CanardBufferBlock* block = canardBufferFromIdx(&ins->allocator, rxstate->buffer_blocks);
  1361. CanardBufferBlock* const temp = block->next;
  1362. freeBlock(&ins->allocator, block);
  1363. rxstate->buffer_blocks = canardBufferToIdx(&ins->allocator, temp);
  1364. }
  1365. rxstate->payload_len = 0;
  1366. return CANARD_OK;
  1367. }
  1368. /*
  1369. * CanardBufferBlock functions
  1370. */
  1371. /**
  1372. * pushes data into the rx state. Fills the buffer head, then appends data to buffer blocks
  1373. */
  1374. CANARD_INTERNAL int16_t bufferBlockPushBytes(CanardPoolAllocator* allocator,
  1375. CanardRxState* state,
  1376. const uint8_t* data,
  1377. uint8_t data_len)
  1378. {
  1379. uint16_t data_index = 0;
  1380. // if head is not full, add data to head
  1381. if ((CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE - state->payload_len) > 0)
  1382. {
  1383. for (uint16_t i = (uint16_t)state->payload_len;
  1384. i < CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE && data_index < data_len;
  1385. i++, data_index++)
  1386. {
  1387. state->buffer_head[i] = data[data_index];
  1388. }
  1389. if (data_index >= data_len)
  1390. {
  1391. state->payload_len =
  1392. (uint16_t)(state->payload_len + data_len) & ((1U << CANARD_TRANSFER_PAYLOAD_LEN_BITS) - 1U);
  1393. return 1;
  1394. }
  1395. } // head is full.
  1396. uint16_t index_at_nth_block =
  1397. (uint16_t)(((state->payload_len) - CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE) % CANARD_BUFFER_BLOCK_DATA_SIZE);
  1398. // get to current block
  1399. CanardBufferBlock* block = NULL;
  1400. // buffer blocks uninitialized
  1401. if (state->buffer_blocks == CANARD_BUFFER_IDX_NONE)
  1402. {
  1403. block = createBufferBlock(allocator);
  1404. state->buffer_blocks = canardBufferToIdx(allocator, block);
  1405. if (block == NULL)
  1406. {
  1407. return -CANARD_ERROR_OUT_OF_MEMORY;
  1408. }
  1409. index_at_nth_block = 0;
  1410. }
  1411. else
  1412. {
  1413. uint16_t nth_block = 1;
  1414. // get to block
  1415. block = canardBufferFromIdx(allocator, state->buffer_blocks);
  1416. while (block->next != NULL)
  1417. {
  1418. nth_block++;
  1419. block = block->next;
  1420. }
  1421. const uint16_t num_buffer_blocks =
  1422. (uint16_t) (((((uint32_t)state->payload_len + data_len) - CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE) /
  1423. CANARD_BUFFER_BLOCK_DATA_SIZE) + 1U);
  1424. if (num_buffer_blocks > nth_block && index_at_nth_block == 0)
  1425. {
  1426. block->next = createBufferBlock(allocator);
  1427. if (block->next == NULL)
  1428. {
  1429. return -CANARD_ERROR_OUT_OF_MEMORY;
  1430. }
  1431. block = block->next;
  1432. }
  1433. }
  1434. // add data to current block until it becomes full, add new block if necessary
  1435. while (data_index < data_len)
  1436. {
  1437. for (uint16_t i = index_at_nth_block;
  1438. i < CANARD_BUFFER_BLOCK_DATA_SIZE && data_index < data_len;
  1439. i++, data_index++)
  1440. {
  1441. block->data[i] = data[data_index];
  1442. }
  1443. if (data_index < data_len)
  1444. {
  1445. block->next = createBufferBlock(allocator);
  1446. if (block->next == NULL)
  1447. {
  1448. return -CANARD_ERROR_OUT_OF_MEMORY;
  1449. }
  1450. block = block->next;
  1451. index_at_nth_block = 0;
  1452. }
  1453. }
  1454. state->payload_len = (uint16_t)(state->payload_len + data_len) & ((1U << CANARD_TRANSFER_PAYLOAD_LEN_BITS) - 1U);
  1455. return 1;
  1456. }
  1457. CANARD_INTERNAL CanardBufferBlock* createBufferBlock(CanardPoolAllocator* allocator)
  1458. {
  1459. CanardBufferBlock* block = (CanardBufferBlock*) allocateBlock(allocator);
  1460. if (block == NULL)
  1461. {
  1462. return NULL;
  1463. }
  1464. block->next = NULL;
  1465. return block;
  1466. }
  1467. /**
  1468. * Bit array copy routine, originally developed by Ben Dyer for Libuavcan. Thanks Ben.
  1469. */
  1470. void copyBitArray(const uint8_t* src, uint32_t src_offset, uint32_t src_len,
  1471. uint8_t* dst, uint32_t dst_offset)
  1472. {
  1473. CANARD_ASSERT(src_len > 0U);
  1474. // Normalizing inputs
  1475. src += src_offset / 8U;
  1476. dst += dst_offset / 8U;
  1477. src_offset %= 8U;
  1478. dst_offset %= 8U;
  1479. const size_t last_bit = src_offset + src_len;
  1480. while (last_bit - src_offset)
  1481. {
  1482. const uint8_t src_bit_offset = (uint8_t)(src_offset % 8U);
  1483. const uint8_t dst_bit_offset = (uint8_t)(dst_offset % 8U);
  1484. const uint8_t max_offset = MAX(src_bit_offset, dst_bit_offset);
  1485. const uint32_t copy_bits = (uint32_t)MIN(last_bit - src_offset, 8U - max_offset);
  1486. #if WORD_ADDRESSING_IS_16BITS
  1487. /*
  1488. * (uint8_t) same as (uint16_t)
  1489. * Mask 0xFF must be used
  1490. */
  1491. const uint8_t write_mask = (uint8_t)((uint8_t)((0xFF00U >> copy_bits)&0xFF) >> dst_bit_offset)&0xFF;
  1492. const uint8_t src_data = (uint8_t)(((uint32_t)src[src_offset / 8U] << src_bit_offset) >> dst_bit_offset)&0xFF;
  1493. dst[dst_offset / 8U] =
  1494. (uint8_t)(((uint32_t)dst[dst_offset / 8U] & (uint32_t)~write_mask) | (uint32_t)(src_data & write_mask))&0xFF;
  1495. #else
  1496. const uint8_t write_mask = (uint8_t)((uint8_t)(0xFF00U >> copy_bits) >> dst_bit_offset);
  1497. const uint8_t src_data = (uint8_t)(((uint32_t)src[src_offset / 8U] << src_bit_offset) >> dst_bit_offset);
  1498. dst[dst_offset / 8U] =
  1499. (uint8_t)(((uint32_t)dst[dst_offset / 8U] & (uint32_t)~write_mask) | (uint32_t)(src_data & write_mask));
  1500. #endif
  1501. src_offset += copy_bits;
  1502. dst_offset += copy_bits;
  1503. }
  1504. }
  1505. CANARD_INTERNAL int16_t descatterTransferPayload(const CanardRxTransfer* transfer,
  1506. uint32_t bit_offset,
  1507. uint8_t bit_length,
  1508. void* output)
  1509. {
  1510. CANARD_ASSERT(transfer != 0);
  1511. if (bit_offset >= transfer->payload_len * 8)
  1512. {
  1513. return 0; // Out of range, reading zero bits
  1514. }
  1515. if (bit_offset + bit_length > transfer->payload_len * 8)
  1516. {
  1517. bit_length = (uint8_t)(transfer->payload_len * 8U - bit_offset);
  1518. }
  1519. CANARD_ASSERT(bit_length > 0);
  1520. if ((transfer->payload_middle != NULL) || (transfer->payload_tail != NULL)) // Multi frame
  1521. {
  1522. /*
  1523. * This part is hideously complicated and probably should be redesigned.
  1524. * The objective here is to copy the requested number of bits from scattered storage into the temporary
  1525. * local storage. We go through great pains to ensure that all corner cases are handled correctly.
  1526. */
  1527. uint32_t input_bit_offset = bit_offset;
  1528. uint8_t output_bit_offset = 0;
  1529. uint8_t remaining_bit_length = bit_length;
  1530. // Reading head
  1531. if (input_bit_offset < CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE * 8)
  1532. {
  1533. const uint8_t amount = (uint8_t)MIN(remaining_bit_length,
  1534. CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE * 8U - input_bit_offset);
  1535. copyBitArray(&transfer->payload_head[0], input_bit_offset, amount, (uint8_t*) output, 0);
  1536. input_bit_offset += amount;
  1537. output_bit_offset = (uint8_t)(output_bit_offset + amount);
  1538. remaining_bit_length = (uint8_t)(remaining_bit_length - amount);
  1539. }
  1540. // Reading middle
  1541. uint32_t remaining_bits = (uint32_t)(transfer->payload_len * 8U - CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE * 8U);
  1542. uint32_t block_bit_offset = CANARD_MULTIFRAME_RX_PAYLOAD_HEAD_SIZE * 8U;
  1543. const CanardBufferBlock* block = transfer->payload_middle;
  1544. while ((block != NULL) && (remaining_bit_length > 0))
  1545. {
  1546. CANARD_ASSERT(remaining_bits > 0);
  1547. const uint32_t block_end_bit_offset = block_bit_offset + MIN(CANARD_BUFFER_BLOCK_DATA_SIZE * 8,
  1548. remaining_bits);
  1549. // Perform copy if we've reached the requested offset, otherwise jump over this block and try next
  1550. if (block_end_bit_offset > input_bit_offset)
  1551. {
  1552. const uint8_t amount = (uint8_t) MIN(remaining_bit_length, block_end_bit_offset - input_bit_offset);
  1553. CANARD_ASSERT(input_bit_offset >= block_bit_offset);
  1554. const uint32_t bit_offset_within_block = input_bit_offset - block_bit_offset;
  1555. copyBitArray(&block->data[0], bit_offset_within_block, amount, (uint8_t*) output, output_bit_offset);
  1556. input_bit_offset += amount;
  1557. output_bit_offset = (uint8_t)(output_bit_offset + amount);
  1558. remaining_bit_length = (uint8_t)(remaining_bit_length - amount);
  1559. }
  1560. CANARD_ASSERT(block_end_bit_offset > block_bit_offset);
  1561. remaining_bits -= block_end_bit_offset - block_bit_offset;
  1562. block_bit_offset = block_end_bit_offset;
  1563. block = block->next;
  1564. }
  1565. CANARD_ASSERT(remaining_bit_length <= remaining_bits);
  1566. // Reading tail
  1567. if ((transfer->payload_tail != NULL) && (remaining_bit_length > 0))
  1568. {
  1569. CANARD_ASSERT(input_bit_offset >= block_bit_offset);
  1570. const uint32_t offset = input_bit_offset - block_bit_offset;
  1571. copyBitArray(&transfer->payload_tail[0], offset, remaining_bit_length, (uint8_t*) output,
  1572. output_bit_offset);
  1573. input_bit_offset += remaining_bit_length;
  1574. output_bit_offset = (uint8_t)(output_bit_offset + remaining_bit_length);
  1575. remaining_bit_length = 0;
  1576. }
  1577. CANARD_ASSERT(input_bit_offset <= transfer->payload_len * 8);
  1578. CANARD_ASSERT(output_bit_offset <= 64);
  1579. CANARD_ASSERT(remaining_bit_length == 0);
  1580. }
  1581. else // Single frame
  1582. {
  1583. copyBitArray(&transfer->payload_head[0], bit_offset, bit_length, (uint8_t*) output, 0);
  1584. }
  1585. return bit_length;
  1586. }
  1587. CANARD_INTERNAL bool isBigEndian(void)
  1588. {
  1589. #if defined(BYTE_ORDER) && defined(BIG_ENDIAN)
  1590. return BYTE_ORDER == BIG_ENDIAN; // Some compilers offer this neat shortcut
  1591. #else
  1592. union
  1593. {
  1594. #if WORD_ADDRESSING_IS_16BITS
  1595. /*
  1596. * with 16-bit memory addressing u8b[0]=u16a, u8b[1]=NOTHING
  1597. */
  1598. uint32_t a;
  1599. uint16_t b[2];
  1600. #else
  1601. uint16_t a;
  1602. uint8_t b[2];
  1603. #endif
  1604. } u;
  1605. u.a = 1;
  1606. return u.b[1] == 1; // Some don't...
  1607. #endif
  1608. }
  1609. CANARD_INTERNAL void swapByteOrder(void* data, unsigned size)
  1610. {
  1611. CANARD_ASSERT(data != NULL);
  1612. uint8_t* const bytes = (uint8_t*) data;
  1613. size_t fwd = 0;
  1614. size_t rev = size - 1;
  1615. while (fwd < rev)
  1616. {
  1617. const uint8_t x = bytes[fwd];
  1618. bytes[fwd] = bytes[rev];
  1619. bytes[rev] = x;
  1620. fwd++;
  1621. rev--;
  1622. }
  1623. }
  1624. /*
  1625. * CRC functions
  1626. */
  1627. CANARD_INTERNAL uint16_t crcAddByte(uint16_t crc_val, uint8_t byte)
  1628. {
  1629. crc_val ^= (uint16_t) ((uint16_t) (byte) << 8U);
  1630. for (uint8_t j = 0; j < 8; j++)
  1631. {
  1632. if (crc_val & 0x8000U)
  1633. {
  1634. crc_val = (uint16_t) ((uint16_t) (crc_val << 1U) ^ 0x1021U);
  1635. }
  1636. else
  1637. {
  1638. crc_val = (uint16_t) (crc_val << 1U);
  1639. }
  1640. }
  1641. return crc_val;
  1642. }
  1643. CANARD_INTERNAL uint16_t crcAddSignature(uint16_t crc_val, uint64_t data_type_signature)
  1644. {
  1645. for (uint16_t shift_val = 0; shift_val < 64; shift_val = (uint16_t)(shift_val + 8U))
  1646. {
  1647. crc_val = crcAddByte(crc_val, (uint8_t) (data_type_signature >> shift_val));
  1648. }
  1649. return crc_val;
  1650. }
  1651. CANARD_INTERNAL uint16_t crcAdd(uint16_t crc_val, const uint8_t* bytes, size_t len)
  1652. {
  1653. while (len--)
  1654. {
  1655. crc_val = crcAddByte(crc_val, *bytes++);
  1656. }
  1657. return crc_val;
  1658. }
  1659. /*
  1660. * Pool Allocator functions
  1661. */
  1662. CANARD_INTERNAL void initPoolAllocator(CanardPoolAllocator* allocator,
  1663. void* buf,
  1664. uint16_t buf_len)
  1665. {
  1666. size_t current_index = 0;
  1667. CanardPoolAllocatorBlock *abuf = buf;
  1668. allocator->arena = buf;
  1669. CanardPoolAllocatorBlock** current_block = &(allocator->free_list);
  1670. while (current_index < buf_len)
  1671. {
  1672. *current_block = &abuf[current_index];
  1673. current_block = &((*current_block)->next);
  1674. current_index++;
  1675. }
  1676. *current_block = NULL;
  1677. allocator->statistics.capacity_blocks = buf_len;
  1678. allocator->statistics.current_usage_blocks = 0;
  1679. allocator->statistics.peak_usage_blocks = 0;
  1680. // user should initialize semaphore after the canardInit
  1681. // or at first call of canard_allocate_sem_take
  1682. allocator->semaphore = NULL;
  1683. }
  1684. CANARD_INTERNAL void* allocateBlock(CanardPoolAllocator* allocator)
  1685. {
  1686. #if CANARD_ALLOCATE_SEM
  1687. canard_allocate_sem_take(allocator);
  1688. #endif
  1689. // Check if there are any blocks available in the free list.
  1690. if (allocator->free_list == NULL)
  1691. {
  1692. #if CANARD_ALLOCATE_SEM
  1693. canard_allocate_sem_give(allocator);
  1694. #endif
  1695. return NULL;
  1696. }
  1697. // Take first available block and prepares next block for use.
  1698. void* result = allocator->free_list;
  1699. allocator->free_list = allocator->free_list->next;
  1700. // Update statistics
  1701. allocator->statistics.current_usage_blocks++;
  1702. if (allocator->statistics.peak_usage_blocks < allocator->statistics.current_usage_blocks)
  1703. {
  1704. allocator->statistics.peak_usage_blocks = allocator->statistics.current_usage_blocks;
  1705. }
  1706. #if CANARD_ALLOCATE_SEM
  1707. canard_allocate_sem_give(allocator);
  1708. #endif
  1709. return result;
  1710. }
  1711. CANARD_INTERNAL void freeBlock(CanardPoolAllocator* allocator, void* p)
  1712. {
  1713. #if CANARD_ALLOCATE_SEM
  1714. canard_allocate_sem_take(allocator);
  1715. #endif
  1716. CanardPoolAllocatorBlock* block = (CanardPoolAllocatorBlock*) p;
  1717. block->next = allocator->free_list;
  1718. allocator->free_list = block;
  1719. CANARD_ASSERT(allocator->statistics.current_usage_blocks > 0);
  1720. allocator->statistics.current_usage_blocks--;
  1721. #if CANARD_ALLOCATE_SEM
  1722. canard_allocate_sem_give(allocator);
  1723. #endif
  1724. }