Skip to content

Commit

Permalink
implement utility functions, improve p04
Browse files Browse the repository at this point in the history
  • Loading branch information
zariiii9003 committed Nov 19, 2024
1 parent 607170f commit df36e44
Show file tree
Hide file tree
Showing 5 changed files with 201 additions and 41 deletions.
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,13 @@ python_add_library(p05

# Add libraries
add_library(crclib STATIC ${CMAKE_SOURCE_DIR}/src/e2e/crclib.c)
add_library(util STATIC ${CMAKE_SOURCE_DIR}/src/e2e/util.c)

# Link against util
target_link_libraries(crc PRIVATE crclib)
target_link_libraries(p01 PRIVATE crclib)
target_link_libraries(p02 PRIVATE crclib)
target_link_libraries(p04 PRIVATE crclib)
target_link_libraries(p04 PRIVATE crclib util)
target_link_libraries(p05 PRIVATE crclib)

install(TARGETS crc p01 p02 p04 p05 LIBRARY DESTINATION e2e)
4 changes: 2 additions & 2 deletions src/e2e/crclib.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
#
# SPDX-License-Identifier: MIT */

#ifndef CRC_H
#define CRC_H
#ifndef CRCLIB_H
#define CRCLIB_H

#include <stdbool.h>
#include <stdint.h>
Expand Down
71 changes: 33 additions & 38 deletions src/e2e/p04.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,33 @@
#include <stdint.h>

#include "crclib.h"

uint32_t compute_p04_crc(uint8_t *data_ptr,
#include "util.h"

#define P04LENGTH_POS 0
#define P04LENGTH_LEN 2
#define P04COUNTER_POS 2
#define P04COUNTER_LEN 2
#define P04DATAID_POS 4
#define P04DATAID_LEN 4
#define P04CRC_POS 8
#define P04CRC_LEN 4
#define P04HEADER_LEN (P04LENGTH_LEN+P04COUNTER_LEN+P04DATAID_LEN+P04CRC_LEN)

uint32_t compute_p04_crc(uint8_t *data_ptr,
uint16_t length,
uint16_t offset)
{
uint32_t crc;

// bytes before crc bytes
uint32_t crc_offset = (uint32_t)(offset + 8u);
uint32_t crc_offset = (uint32_t)(offset + P04CRC_POS);
crc = Crc_CalculateCRC32P4(data_ptr, crc_offset, CRC32P4_INITIAL_VALUE, true);

// bytes after crc bytes, if any
if (offset + 12u < length){
crc = Crc_CalculateCRC32P4(&data_ptr[crc_offset + 4u], (uint32_t)(length - (offset + 12u)), crc, false);
if (offset + P04HEADER_LEN < length){
uint8_t * second_part_ptr = data_ptr + offset + P04HEADER_LEN;
uint32_t second_part_length = length - offset - P04HEADER_LEN;
crc = Crc_CalculateCRC32P4(second_part_ptr, second_part_length, crc, false);
}
return crc;
}
Expand Down Expand Up @@ -72,17 +85,17 @@ py_e2e_p04_protect(PyObject *module,
PyErr_SetString(PyExc_ValueError, "\"data\" must be mutable. Use a bytearray or any object that implements the buffer protocol.");
goto error;
}
if (data.len < 12)
if (data.len < P04HEADER_LEN)
{
PyErr_SetString(PyExc_ValueError, "The length of bytearray \"data\" must be greater than or equal to 12.");
goto error;
}
if (length < 12 || length > data.len)
if (length < P04HEADER_LEN || length > data.len)
{
PyErr_SetString(PyExc_ValueError, "Parameter \"length\" must fulfill the following condition: 12 <= length <= len(data).");
goto error;
}
if (offset > data.len - 12)
if (offset > data.len - P04HEADER_LEN)
{
PyErr_SetString(PyExc_ValueError, "Argument \"offset\" invalid.");
goto error;
Expand All @@ -91,29 +104,21 @@ py_e2e_p04_protect(PyObject *module,
uint8_t *data_ptr = (uint8_t *)data.buf;

// write length
data_ptr[offset] = (uint8_t)(length >> 8u);
data_ptr[offset + 1u] = (uint8_t)(length);
uint16_to_bigendian(data_ptr + offset + P04LENGTH_POS, length);

// increment counter
if (increment) {
uint16_t counter = ((uint16_t)(data_ptr[offset + 2u]) << 8u) + (uint16_t)(data_ptr[offset + 3u]);
uint16_t counter = bigendian_to_uint16(data_ptr + offset + P04COUNTER_POS);
counter++;
data_ptr[offset + 2u] = (uint8_t)((counter >> 8u));
data_ptr[offset + 3u] = (uint8_t)(counter & 0xFF);
uint16_to_bigendian(data_ptr + offset + P04COUNTER_POS, counter);
}

// write data_id
data_ptr[offset + 4u] = (uint8_t)(data_id >> 24u);
data_ptr[offset + 5u] = (uint8_t)(data_id >> 16u);
data_ptr[offset + 6u] = (uint8_t)(data_id >> 8u);
data_ptr[offset + 7u] = (uint8_t)(data_id);
uint32_to_bigendian(data_ptr + offset + P04DATAID_POS, data_id);

// calculate CRC
uint32_t crc = compute_p04_crc(data_ptr, length, offset);
data_ptr[offset + 8u] = (uint8_t)(crc >> 24u);
data_ptr[offset + 9u] = (uint8_t)(crc >> 16u);
data_ptr[offset + 10u] = (uint8_t)(crc >> 8u);
data_ptr[offset + 11u] = (uint8_t)(crc);
uint32_to_bigendian(data_ptr + offset + P04CRC_POS, crc);

PyBuffer_Release(&data);

Expand Down Expand Up @@ -162,17 +167,17 @@ py_e2e_p04_check(PyObject *module,
{
return NULL;
}
if (data.len < 12)
if (data.len < P04HEADER_LEN)
{
PyErr_SetString(PyExc_ValueError, "The length of bytearray \"data\" must be greater orequal to 12.");
PyErr_SetString(PyExc_ValueError, "The length of bytearray \"data\" must be greater or equal to 12.");
goto error;
}
if (length < 12 || length > data.len)
if (length < P04HEADER_LEN || length > data.len)
{
PyErr_SetString(PyExc_ValueError, "Parameter \"length\" must fulfill the following condition: 12 <= length <= len(data).");
goto error;
}
if (offset > data.len - 12)
if (offset > data.len - P04HEADER_LEN)
{
PyErr_SetString(PyExc_ValueError, "Argument \"offset\" invalid.");
goto error;
Expand All @@ -181,23 +186,13 @@ py_e2e_p04_check(PyObject *module,
uint8_t *data_ptr = (uint8_t *)data.buf;

// read length
uint16_t length_actual = (
((uint16_t)(data_ptr[offset]) << 8u)
+ (uint16_t)(data_ptr[offset + 1u]));
uint16_t length_actual = bigendian_to_uint16(data_ptr + offset + P04LENGTH_POS);

// read data_id
uint32_t data_id_actual = (
((uint32_t)(data_ptr[offset + 4u]) << 24u)
+ ((uint32_t)(data_ptr[offset + 5u]) << 16u)
+ ((uint32_t)(data_ptr[offset + 6u]) << 8u)
+ (uint32_t)(data_ptr[offset + 7u]));
uint32_t data_id_actual = bigendian_to_uint32(data_ptr + offset + P04DATAID_POS);

// read crc
uint32_t crc_actual = (
((uint32_t)(data_ptr[offset + 8u]) << 24u)
+ ((uint32_t)(data_ptr[offset + 9u]) << 16u)
+ ((uint32_t)(data_ptr[offset + 10u]) << 8u)
+ (uint32_t)(data_ptr[offset + 11u]));
uint32_t crc_actual = bigendian_to_uint32(data_ptr + offset + P04CRC_POS);

// calculate CRC
uint32_t crc = compute_p04_crc(data_ptr, length, offset);
Expand Down
138 changes: 138 additions & 0 deletions src/e2e/util.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/* SPDX-FileCopyrightText: 2022-present Artur Drogunow <[email protected]>
#
# SPDX-License-Identifier: MIT */

#include <stdint.h>
#include <stddef.h>

// copy uint16_t into buffer in littleendian byte order
void uint16_to_littleendian(uint8_t *target, uint16_t value)
{
size_t len = sizeof(value);
for (size_t i = 0; i < len; ++i)
{
target[i] = (uint8_t)((value >> (i * 8)) & 0xffu);
}
}

// copy uint32_t into buffer in littleendian byte order
void uint32_to_littleendian(uint8_t *target, uint32_t value)
{
size_t len = sizeof(value);
for (size_t i = 0; i < len; ++i)
{
target[i] = (uint8_t)((value >> (i * 8)) & 0xffu);
}
}

// copy uint64_t into buffer in littleendian byte order
void uint64_to_littleendian(uint8_t *target, uint64_t value)
{
size_t len = sizeof(value);
for (size_t i = 0; i < len; ++i)
{
target[i] = (uint8_t)((value >> (i * 8)) & 0xffu);
}
}

// read uint16_t from littleendian byte order buffer
uint16_t littleendian_to_uint16(uint8_t *source)
{
uint16_t value = 0;
size_t len = sizeof(value);
for (size_t i = 0; i < len; ++i)
{
value += (uint16_t)source[i] << (i * 8);
}
return value;
}

// read uint32_t from littleendian byte order buffer
uint32_t littleendian_to_uint32(uint8_t *source)
{
uint32_t value = 0;
size_t len = sizeof(value);
for (size_t i = 0; i < len; ++i)
{
value += (uint32_t)source[i] << (i * 8);
}
return value;
}

// read uint64_t from littleendian byte order buffer
uint64_t littleendian_to_uint64(uint8_t *source)
{
uint64_t value = 0;
size_t len = sizeof(value);
for (size_t i = 0; i < len; ++i)
{
value += (uint64_t)source[i] << (i * 8);
}
return value;
}

// copy uint16_t into buffer in bigendian byte order
void uint16_to_bigendian(uint8_t *target, uint16_t value)
{
size_t len = sizeof(value);
for (size_t i = 0; i < len; ++i)
{
target[i] = (uint8_t)((value >> ((len - 1 - i) * 8)) & 0xffu);
}
}

// copy uint32_t into buffer in bigendian byte order
void uint32_to_bigendian(uint8_t *target, uint32_t value)
{
size_t len = sizeof(value);
for (size_t i = 0; i < len; ++i)
{
target[i] = (uint8_t)((value >> ((len - 1 - i) * 8)) & 0xffu);
}
}

// copy uint64_t into buffer in bigendian byte order
void uint64_to_bigendian(uint8_t *target, uint64_t value)
{
size_t len = sizeof(value);
for (size_t i = 0; i < len; ++i)
{
target[i] = (uint8_t)((value >> ((len - 1 - i) * 8)) & 0xffu);
}
}

// read uint16_t from bigendian byte order buffer
uint16_t bigendian_to_uint16(uint8_t *source)
{
uint16_t value = 0;
size_t len = sizeof(value);
for (size_t i = 0; i < len; ++i)
{
value += (uint16_t)source[i] << ((len - 1 - i) * 8);
}
return value;
}

// read uint32_t from bigendian byte order buffer
uint32_t bigendian_to_uint32(uint8_t *source)
{
uint32_t value = 0;
size_t len = sizeof(value);
for (size_t i = 0; i < len; ++i)
{
value += (uint32_t)source[i] << ((len - 1 - i) * 8);
}
return value;
}

// read uint64_t from bigendian byte order buffer
uint64_t bigendian_to_uint64(uint8_t *source)
{
uint64_t value = 0;
size_t len = sizeof(value);
for (size_t i = 0; i < len; ++i)
{
value += (uint64_t)source[i] << ((len - 1 - i) * 8);
}
return value;
}
26 changes: 26 additions & 0 deletions src/e2e/util.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* SPDX-FileCopyrightText: 2022-present Artur Drogunow <[email protected]>
#
# SPDX-License-Identifier: MIT */

#ifndef UTIL_H
#define UTIL_H

#include <stdint.h>

void uint16_to_littleendian(uint8_t *target, uint16_t value);
void uint32_to_littleendian(uint8_t *target, uint32_t value);
void uint64_to_littleendian(uint8_t *target, uint64_t value);

uint16_t littleendian_to_uint16(uint8_t *source);
uint32_t littleendian_to_uint32(uint8_t *source);
uint64_t littleendian_to_uint64(uint8_t *source);

void uint16_to_bigendian(uint8_t *target, uint16_t value);
void uint32_to_bigendian(uint8_t *target, uint32_t value);
void uint64_to_bigendian(uint8_t *target, uint64_t value);

uint16_t bigendian_to_uint16(uint8_t *source);
uint32_t bigendian_to_uint32(uint8_t *source);
uint64_t bigendian_to_uint64(uint8_t *source);

#endif

0 comments on commit df36e44

Please sign in to comment.