Files
templates/c/set-protocol/src/pcan_abi.c

204 lines
5.6 KiB
C

#include "pcan_abi.h"
#include <string.h>
#include "pcan_crc.h"
#include "pcan_frame.h"
#include "pcan_id.h"
#include "gui_frame.h"
uint32_t pcan_abi_version(void)
{
return PCAN_ABI_VERSION;
}
uint32_t pcan_abi_id_pack(uint8_t priority, uint8_t route,
uint8_t device_type, uint8_t device_id,
uint8_t message_type, uint16_t body)
{
pcan_id_t id;
id.msg_body = body;
id.msg_type = message_type;
id.device_id = device_id;
id.device_type = device_type;
id.route = route;
id.priority = priority;
return pcan_id_pack(&id);
}
void pcan_abi_id_unpack(uint32_t raw, uint8_t *priority, uint8_t *route,
uint8_t *device_type, uint8_t *device_id,
uint8_t *message_type, uint16_t *body)
{
pcan_id_t id;
pcan_id_unpack(raw, &id);
if (priority != NULL) {
*priority = id.priority;
}
if (route != NULL) {
*route = id.route;
}
if (device_type != NULL) {
*device_type = id.device_type;
}
if (device_id != NULL) {
*device_id = id.device_id;
}
if (message_type != NULL) {
*message_type = id.msg_type;
}
if (body != NULL) {
*body = id.msg_body;
}
}
uint16_t pcan_abi_crc16(const uint8_t *data, size_t size)
{
if ((data == NULL) && (size != 0U)) {
return 0U;
}
return pcan_crc16(data, size);
}
size_t pcan_abi_frame_encode(uint8_t sequence, uint8_t flags,
uint32_t can_id, const uint8_t *data, uint8_t dlc,
uint8_t *output, size_t output_size)
{
pcan_frame_t frame;
if ((output == NULL) || (dlc > PCAN_DATA_MAX) ||
((data == NULL) && (dlc != 0U))) {
return 0U;
}
memset(&frame, 0, sizeof frame);
frame.seq = sequence;
frame.flags = flags;
frame.id = can_id;
frame.dlc = dlc;
if (dlc != 0U) {
memcpy(frame.data, data, dlc);
}
return pcan_frame_encode(&frame, output, output_size);
}
size_t pcan_abi_parser_size(void)
{
return sizeof(pcan_parser_t);
}
int pcan_abi_parser_init(void *parser_storage, size_t storage_size)
{
if ((parser_storage == NULL) || (storage_size < sizeof(pcan_parser_t))) {
return 0;
}
pcan_parser_init((pcan_parser_t *)parser_storage);
return 1;
}
int pcan_abi_parser_push(void *parser_storage, uint8_t byte,
pcan_abi_frame_t *output)
{
pcan_frame_t frame;
if ((parser_storage == NULL) || (output == NULL)) {
return -1;
}
if (!pcan_parser_push((pcan_parser_t *)parser_storage, byte, &frame)) {
return 0;
}
output->can_id = frame.id;
output->sequence = frame.seq;
output->flags = frame.flags;
output->dlc = frame.dlc;
memset(output->data, 0, sizeof output->data);
memcpy(output->data, frame.data, frame.dlc);
return 1;
}
int pcan_abi_parser_stats(const void *parser_storage, uint32_t *frames,
uint32_t *crc_errors, uint32_t *bad_length,
uint32_t *stray_bytes)
{
const pcan_parser_t *parser = (const pcan_parser_t *)parser_storage;
if (parser == NULL) {
return 0;
}
if (frames != NULL) {
*frames = parser->stats.frames;
}
if (crc_errors != NULL) {
*crc_errors = parser->stats.crc_errors;
}
if (bad_length != NULL) {
*bad_length = parser->stats.bad_len;
}
if (stray_bytes != NULL) {
*stray_bytes = parser->stats.stray_bytes;
}
return 1;
}
uint32_t pcan_abi_gui_crc32(const uint8_t *data, size_t size)
{
if ((data == NULL) && (size != 0U)) {
return 0U;
}
return gui_crc32(data, size);
}
size_t pcan_abi_gui_frame_encode(uint8_t message_type, uint16_t sequence,
const uint8_t *payload,
uint16_t payload_size, uint8_t *output,
size_t output_size)
{
return gui_frame_encode(message_type, sequence, payload, payload_size,
output, output_size);
}
size_t pcan_abi_gui_parser_size(void)
{
return sizeof(gui_parser_t);
}
int pcan_abi_gui_parser_init(void *parser_storage, size_t storage_size)
{
if ((parser_storage == NULL) || (storage_size < sizeof(gui_parser_t))) {
return 0;
}
gui_parser_init((gui_parser_t *)parser_storage);
return 1;
}
int pcan_abi_gui_parser_push(void *parser_storage, uint8_t byte,
pcan_abi_gui_frame_t *output)
{
gui_frame_t frame;
if ((parser_storage == NULL) || (output == NULL)) {
return -1;
}
if (!gui_parser_push((gui_parser_t *)parser_storage, byte, &frame)) {
return 0;
}
output->message_type = frame.type;
output->sequence = frame.sequence;
output->size = frame.size;
if (frame.size != 0U) {
memcpy(output->payload, frame.payload, frame.size);
}
return 1;
}
int pcan_abi_gui_parser_stats(const void *parser_storage, uint32_t *frames,
uint32_t *crc_errors, uint32_t *version_errors,
uint32_t *length_errors, uint32_t *stray_bytes)
{
const gui_parser_t *parser = (const gui_parser_t *)parser_storage;
if (parser == NULL) {
return 0;
}
if (frames != NULL) *frames = parser->stats.frames;
if (crc_errors != NULL) *crc_errors = parser->stats.crc_errors;
if (version_errors != NULL) *version_errors = parser->stats.version_errors;
if (length_errors != NULL) *length_errors = parser->stats.length_errors;
if (stray_bytes != NULL) *stray_bytes = parser->stats.stray_bytes;
return 1;
}