lib: crc: add `crc8_rohc` for CRC-8/ROHC variant calculation
This commit introduces the `crc8_rohc` function to the CRC library, implementing the CRC-8/ROHC (RObust Header Compression) variant. This algorithm is widely used in networking protocols, which is commonly found in modem subsystems. Signed-off-by: Pisit Sawangvonganan <pisit@ndrsolution.com>
This commit is contained in:
parent
339ba1a23d
commit
ec5354cd80
|
@ -29,6 +29,7 @@ extern "C" {
|
|||
* computation.
|
||||
*/
|
||||
#define CRC8_CCITT_INITIAL_VALUE 0xFF
|
||||
#define CRC8_ROHC_INITIAL_VALUE 0xFF
|
||||
|
||||
/* Initial value expected to be used at the beginning of the OpenPGP CRC-24 computation. */
|
||||
#define CRC24_PGP_INITIAL_VALUE 0x00B704CEU
|
||||
|
@ -58,9 +59,10 @@ enum crc_type {
|
|||
CRC4, /**< Use @ref crc4 */
|
||||
CRC4_TI, /**< Use @ref crc4_ti */
|
||||
CRC7_BE, /**< Use @ref crc7_be */
|
||||
CRC8, /**< Use @ref crc8 */
|
||||
CRC8, /**< Use @ref crc8 */
|
||||
CRC8_CCITT, /**< Use @ref crc8_ccitt */
|
||||
CRC16, /**< Use @ref crc16 */
|
||||
CRC8_ROHC, /**< Use @ref crc8_rohc */
|
||||
CRC16, /**< Use @ref crc16 */
|
||||
CRC16_ANSI, /**< Use @ref crc16_ansi */
|
||||
CRC16_CCITT, /**< Use @ref crc16_ccitt */
|
||||
CRC16_ITU_T, /**< Use @ref crc16_itu_t */
|
||||
|
@ -135,7 +137,7 @@ uint16_t crc16_reflect(uint16_t poly, uint16_t seed, const uint8_t *src, size_t
|
|||
* @return The computed CRC8 value
|
||||
*/
|
||||
uint8_t crc8(const uint8_t *src, size_t len, uint8_t polynomial, uint8_t initial_value,
|
||||
bool reversed);
|
||||
bool reversed);
|
||||
|
||||
/**
|
||||
* @brief Compute the checksum of a buffer with polynomial 0x1021, reflecting
|
||||
|
@ -274,6 +276,20 @@ uint32_t crc32_c(uint32_t crc, const uint8_t *data,
|
|||
*/
|
||||
uint8_t crc8_ccitt(uint8_t initial_value, const void *buf, size_t len);
|
||||
|
||||
/**
|
||||
* @brief Compute ROHC variant of CRC 8
|
||||
*
|
||||
* ROHC (Robust Header Compression) variant of CRC 8.
|
||||
* Uses 0x07 as the polynomial with reflection.
|
||||
*
|
||||
* @param initial_value Initial value for the CRC computation
|
||||
* @param buf Input bytes for the computation
|
||||
* @param len Length of the input in bytes
|
||||
*
|
||||
* @return The computed CRC8 value
|
||||
*/
|
||||
uint8_t crc8_rohc(uint8_t initial_value, const void *buf, size_t len);
|
||||
|
||||
/**
|
||||
* @brief Compute the CRC-7 checksum of a buffer.
|
||||
*
|
||||
|
@ -322,7 +338,7 @@ uint8_t crc4_ti(uint8_t seed, const uint8_t *src, size_t len);
|
|||
* @return The computed CRC4 value
|
||||
*/
|
||||
uint8_t crc4(const uint8_t *src, size_t len, uint8_t polynomial, uint8_t initial_value,
|
||||
bool reversed);
|
||||
bool reversed);
|
||||
|
||||
/**
|
||||
* @brief Generate an OpenPGP CRC-24 checksum as defined in RFC 4880 section 6.1.
|
||||
|
@ -384,6 +400,8 @@ static inline uint32_t crc_by_type(enum crc_type type, const uint8_t *src, size_
|
|||
return crc8(src, len, poly, seed, reflect);
|
||||
case CRC8_CCITT:
|
||||
return crc8_ccitt(seed, src, len);
|
||||
case CRC8_ROHC:
|
||||
return crc8_rohc(seed, src, len);
|
||||
case CRC16:
|
||||
if (reflect) {
|
||||
return crc16_reflect(poly, seed, src, len);
|
||||
|
|
|
@ -13,6 +13,11 @@ static const uint8_t crc8_ccitt_small_table[16] = {
|
|||
0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d
|
||||
};
|
||||
|
||||
static const uint8_t crc8_rohc_small_table[16] = {
|
||||
0x00, 0x1c, 0x38, 0x24, 0x70, 0x6c, 0x48, 0x54,
|
||||
0xe0, 0xfc, 0xd8, 0xc4, 0x90, 0x8c, 0xa8, 0xb4
|
||||
};
|
||||
|
||||
uint8_t crc8_ccitt(uint8_t val, const void *buf, size_t cnt)
|
||||
{
|
||||
size_t i;
|
||||
|
@ -26,6 +31,19 @@ uint8_t crc8_ccitt(uint8_t val, const void *buf, size_t cnt)
|
|||
return val;
|
||||
}
|
||||
|
||||
uint8_t crc8_rohc(uint8_t val, const void *buf, size_t cnt)
|
||||
{
|
||||
size_t i;
|
||||
const uint8_t *p = buf;
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
val ^= p[i];
|
||||
val = (val >> 4) ^ crc8_rohc_small_table[val & 0x0f];
|
||||
val = (val >> 4) ^ crc8_rohc_small_table[val & 0x0f];
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
uint8_t crc8(const uint8_t *src, size_t len, uint8_t polynomial, uint8_t initial_value,
|
||||
bool reversed)
|
||||
{
|
||||
|
|
|
@ -24,6 +24,7 @@ static const char *const crc_types[] = {
|
|||
[CRC7_BE] = "7_be",
|
||||
[CRC8] = "8",
|
||||
[CRC8_CCITT] = "8_ccitt",
|
||||
[CRC8_ROHC] = "8_rohc",
|
||||
[CRC16] = "16",
|
||||
[CRC16_ANSI] = "16_ansi",
|
||||
[CRC16_CCITT] = "16_ccitt",
|
||||
|
|
|
@ -187,6 +187,29 @@ ZTEST(crc, test_crc8_ccitt)
|
|||
sizeof(test2)) == 0xFB, "pass", "fail");
|
||||
}
|
||||
|
||||
ZTEST(crc, test_crc8_rohc)
|
||||
{
|
||||
uint8_t test0[] = { 0 };
|
||||
uint8_t test1[] = { 'A' };
|
||||
uint8_t test2[] = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
|
||||
uint8_t test3[] = { 0x07, 0x3F }; /* GSM 07.10 example */
|
||||
uint8_t test4[] = { 0x07, 0x3F, 0x89 }; /* GSM 07.10 example */
|
||||
uint8_t test5[] = { 0x03, 0x3f, 0x01, 0x1c }; /* Our GSM 07.10 calc */
|
||||
|
||||
zassert(crc8_rohc(CRC8_ROHC_INITIAL_VALUE, test0,
|
||||
sizeof(test0)) == 0xcf, "pass", "fail");
|
||||
zassert(crc8_rohc(CRC8_ROHC_INITIAL_VALUE, test1,
|
||||
sizeof(test1)) == 0x2e, "pass", "fail");
|
||||
zassert(crc8_rohc(CRC8_ROHC_INITIAL_VALUE, test2,
|
||||
sizeof(test2)) == 0xd0, "pass", "fail");
|
||||
zassert(crc8_rohc(CRC8_ROHC_INITIAL_VALUE, test3,
|
||||
sizeof(test3)) == 0x76, "pass", "fail");
|
||||
zassert(crc8_rohc(CRC8_ROHC_INITIAL_VALUE, test4,
|
||||
sizeof(test4)) == 0xcf, "pass", "fail");
|
||||
zassert(crc8_rohc(CRC8_ROHC_INITIAL_VALUE, test5,
|
||||
sizeof(test5)) == 0xcf, "pass", "fail");
|
||||
}
|
||||
|
||||
ZTEST(crc, test_crc7_be)
|
||||
{
|
||||
uint8_t test0[] = { 0 };
|
||||
|
|
Loading…
Reference in New Issue