OpenLcbCLib 1.0 Alpha
OpenSource C Library to create OpenLcb/Lcc Nodes
Loading...
Searching...
No Matches
can_utilities.c File Reference

Implementation of utility functions for CAN frame buffers. More...

Functions

void CanUtilities_clear_can_message (can_msg_t *can_msg)
 Clears identifier, payload_count, and all payload bytes in a can_msg_t.
 
void CanUtilities_load_can_message (can_msg_t *can_msg, uint32_t identifier, uint8_t payload_size, uint8_t byte1, uint8_t byte2, uint8_t byte3, uint8_t byte4, uint8_t byte5, uint8_t byte6, uint8_t byte7, uint8_t byte8)
 Loads identifier, payload size, and all 8 data bytes into a can_msg_t.
 
uint8_t CanUtilities_copy_node_id_to_payload (can_msg_t *can_msg, uint64_t node_id, uint8_t start_offset)
 Copies a 48-bit Node ID into CAN message payload starting at start_offset.
 
uint8_t CanUtilities_copy_openlcb_payload_to_can_payload (openlcb_msg_t *openlcb_msg, can_msg_t *can_msg, uint16_t openlcb_start_index, uint8_t can_start_index)
 Copies payload bytes from an openlcb_msg_t into a can_msg_t.
 
uint8_t CanUtilities_append_can_payload_to_openlcb_payload (openlcb_msg_t *openlcb_msg, can_msg_t *can_msg, uint8_t can_start_index)
 Appends CAN payload bytes to the end of an openlcb_msg_t payload.
 
uint8_t CanUtilities_copy_64_bit_to_can_message (can_msg_t *can_msg, uint64_t data)
 Copies a 64-bit value MSB-first into all 8 payload bytes and sets payload_count to 8.
 
uint8_t CanUtilities_copy_can_message (can_msg_t *can_msg_source, can_msg_t *can_msg_target)
 Copies identifier and valid payload bytes from source to target can_msg_t.
 
node_id_t CanUtilities_extract_can_payload_as_node_id (can_msg_t *can_msg)
 Reads payload bytes 0-5 and returns them as a 48-bit node_id_t (big-endian).
 
uint16_t CanUtilities_extract_source_alias_from_can_identifier (can_msg_t *can_msg)
 Returns the 12-bit source alias from bits 0-11 of the CAN identifier.
 
uint16_t CanUtilities_extract_dest_alias_from_can_message (can_msg_t *can_msg)
 Returns the 12-bit destination alias from the appropriate location in a can_msg_t.
 
uint16_t CanUtilities_convert_can_mti_to_openlcb_mti (can_msg_t *can_msg)
 Converts the CAN frame MTI bits to the corresponding 16-bit OpenLCB MTI.
 
uint8_t CanUtilities_count_nulls_in_payloads (openlcb_msg_t *openlcb_msg, can_msg_t *can_msg)
 Counts NULL bytes in both an openlcb_msg_t and a can_msg_t payload combined.
 
bool CanUtilities_is_openlcb_message (can_msg_t *can_msg)
 Returns true if the CAN frame carries an OpenLCB message (CAN_OPENLCB_MSG bit set).
 

Detailed Description

Implementation of utility functions for CAN frame buffers.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Stateless helper functions for clearing, loading, copying, and extracting data from can_msg_t frames. Also provides CAN identifier field extraction, MTI conversion, and NULL-counting for legacy SNIP detection.

Author
Jim Kueneman
Date
4 Mar 2026

Function Documentation

◆ CanUtilities_clear_can_message()

void CanUtilities_clear_can_message ( can_msg_t * can_msg)

Clears identifier, payload_count, and all payload bytes in a can_msg_t.

◆ CanUtilities_load_can_message()

void CanUtilities_load_can_message ( can_msg_t * can_msg,
uint32_t identifier,
uint8_t payload_size,
uint8_t byte1,
uint8_t byte2,
uint8_t byte3,
uint8_t byte4,
uint8_t byte5,
uint8_t byte6,
uint8_t byte7,
uint8_t byte8 )

Loads identifier, payload size, and all 8 data bytes into a can_msg_t.

* @param can_msg      Destination buffer.
* @param identifier   29-bit CAN extended identifier.
* @param payload_size Number of valid payload bytes (0-8).
* @param byte1..byte8 Payload bytes in order.
* 

◆ CanUtilities_copy_node_id_to_payload()

uint8_t CanUtilities_copy_node_id_to_payload ( can_msg_t * can_msg,
uint64_t node_id,
uint8_t start_offset )

Copies a 48-bit Node ID into CAN message payload starting at start_offset.

Copies a 48-bit node_id_t into 6 payload bytes starting at start_offset.

Algorithm:

  1. Validate start_offset <= 2; return 0 if invalid.
  2. Set payload_count to 6 + start_offset.
  3. Write 6 bytes MSB-first from node_id into payload[start_offset..start_offset+5].
  4. Return payload_count.
* @param can_msg      Destination buffer.
* @param node_id      48-bit @ref node_id_t to copy.
* @param start_offset Byte position in payload to begin writing (0-2).
* 
Returns
Bytes written (start_offset + 6), or 0 if start_offset is out of range.
See also
CanUtilities_extract_can_payload_as_node_id

◆ CanUtilities_copy_openlcb_payload_to_can_payload()

uint8_t CanUtilities_copy_openlcb_payload_to_can_payload ( openlcb_msg_t * openlcb_msg,
can_msg_t * can_msg,
uint16_t openlcb_start_index,
uint8_t can_start_index )

Copies payload bytes from an openlcb_msg_t into a can_msg_t.

Algorithm:

  1. Return 0 if openlcb_msg payload_count is 0.
  2. Copy from openlcb_msg->payload[openlcb_start_index] into can_msg->payload[can_start_index..7].
  3. Stop when either buffer is exhausted.
  4. Set can_msg->payload_count to can_start_index + bytes copied.
  5. Return bytes copied.
* @param openlcb_msg         Source OpenLCB message.
* @param can_msg             Destination CAN frame buffer.
* @param openlcb_start_index Starting index in the OpenLCB payload.
* @param can_start_index     Starting index in the CAN payload (0 or 2).
* 
Returns
Number of bytes copied.
See also
CanUtilities_append_can_payload_to_openlcb_payload

◆ CanUtilities_append_can_payload_to_openlcb_payload()

uint8_t CanUtilities_append_can_payload_to_openlcb_payload ( openlcb_msg_t * openlcb_msg,
can_msg_t * can_msg,
uint8_t can_start_index )

Appends CAN payload bytes to the end of an openlcb_msg_t payload.

Algorithm:

  1. Get OpenLCB buffer capacity from payload_type.
  2. Copy can_msg->payload[can_start_index..payload_count-1] into openlcb_msg payload.
  3. Stop when openlcb_msg is full.
  4. Return number of bytes copied.
* @param openlcb_msg     Destination OpenLCB message.
* @param can_msg         Source CAN frame.
* @param can_start_index Starting index in the CAN payload.
* 
Returns
Number of bytes copied.
Warning
Overflow is silently truncated when the OpenLCB buffer is full.
See also
CanUtilities_copy_openlcb_payload_to_can_payload

◆ CanUtilities_copy_64_bit_to_can_message()

uint8_t CanUtilities_copy_64_bit_to_can_message ( can_msg_t * can_msg,
uint64_t data )

Copies a 64-bit value MSB-first into all 8 payload bytes and sets payload_count to 8.

Copies a 64-bit value into all 8 payload bytes of a can_msg_t (big-endian).

* @param can_msg Destination buffer.
* @param data    64-bit value (e.g. Event ID).
* 
Returns
Always 8.

◆ CanUtilities_copy_can_message()

uint8_t CanUtilities_copy_can_message ( can_msg_t * can_msg_source,
can_msg_t * can_msg_target )

Copies identifier and valid payload bytes from source to target can_msg_t.

Does not copy state flags. Target payload_count is set to match source.

* @param can_msg_source Source buffer.
* @param can_msg_target Destination buffer.
* 
Returns
Number of payload bytes copied.

◆ CanUtilities_extract_can_payload_as_node_id()

node_id_t CanUtilities_extract_can_payload_as_node_id ( can_msg_t * can_msg)

Reads payload bytes 0-5 and returns them as a 48-bit node_id_t (big-endian).

* @param can_msg Source buffer. Must have at least 6 valid payload bytes.
* 
Returns
48-bit node_id_t.
See also
CanUtilities_copy_node_id_to_payload

◆ CanUtilities_extract_source_alias_from_can_identifier()

uint16_t CanUtilities_extract_source_alias_from_can_identifier ( can_msg_t * can_msg)

Returns the 12-bit source alias from bits 0-11 of the CAN identifier.

* @param can_msg Source buffer.
* 
Returns
Source alias (0x000-0xFFF).
See also
CanUtilities_extract_dest_alias_from_can_message

◆ CanUtilities_extract_dest_alias_from_can_message()

uint16_t CanUtilities_extract_dest_alias_from_can_message ( can_msg_t * can_msg)

Returns the 12-bit destination alias from the appropriate location in a can_msg_t.

Algorithm:

  1. For standard/stream frames: if MASK_CAN_DEST_ADDRESS_PRESENT is set, read alias from payload[0-1].
  2. For datagram frames: extract alias from identifier bits 12-23.
  3. Otherwise return 0 (global/broadcast frame).
* @param can_msg Source buffer.
* 
Returns
Destination alias (0x001-0xFFF), or 0 if the frame is global.
See also
CanUtilities_extract_source_alias_from_can_identifier

◆ CanUtilities_convert_can_mti_to_openlcb_mti()

uint16_t CanUtilities_convert_can_mti_to_openlcb_mti ( can_msg_t * can_msg)

Converts the CAN frame MTI bits to the corresponding 16-bit OpenLCB MTI.

Algorithm:

  1. For standard/stream frames: extract bits 12-23 as MTI; map PCER first/middle/last to MTI_PC_EVENT_REPORT_WITH_PAYLOAD.
  2. For any datagram frame type: return MTI_DATAGRAM.
  3. Otherwise return 0 (CAN control frames have no OpenLCB MTI).
* @param can_msg Source buffer.
* 
Returns
16-bit OpenLCB MTI, or 0 for control frames.
See also
CanUtilities_is_openlcb_message

◆ CanUtilities_count_nulls_in_payloads()

uint8_t CanUtilities_count_nulls_in_payloads ( openlcb_msg_t * openlcb_msg,
can_msg_t * can_msg )

Counts NULL bytes in both an openlcb_msg_t and a can_msg_t payload combined.

Counts NULL (0x00) bytes across both an openlcb_msg_t and a can_msg_t payload.

Used to detect SNIP message completion (exactly 6 NULLs required).

* @param openlcb_msg OpenLCB message with accumulated SNIP data.
* @param can_msg     Current CAN frame being appended.
* 
Returns
Total NULL byte count across both payloads.

◆ CanUtilities_is_openlcb_message()

bool CanUtilities_is_openlcb_message ( can_msg_t * can_msg)

Returns true if the CAN frame carries an OpenLCB message (CAN_OPENLCB_MSG bit set).

Returns true if the CAN frame carries an OpenLCB message (bit 27 set).


Copyright (c) 2026 Jim Kueneman all rights reserved. See the License