v1.0.0
* Initial release for SX1302 CoreCell Reference Design.
This commit is contained in:
parent
c7a5171a47
commit
4c61c5d48e
79 changed files with 30157 additions and 0 deletions
307
libtools/src/base64.c
Normal file
307
libtools/src/base64.c
Normal file
|
|
@ -0,0 +1,307 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
Base64 encoding & decoding library
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "base64.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE MACROS ------------------------------------------------------- */
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
#define CRIT(a) fprintf(stderr, "\nCRITICAL file:%s line:%u msg:%s\n", __FILE__, __LINE__,a);exit(EXIT_FAILURE)
|
||||
|
||||
//#define DEBUG(args...) fprintf(stderr,"debug: " args) /* diagnostic message that is destined to the user */
|
||||
#define DEBUG(args...)
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE CONSTANTS ---------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE MODULE-WIDE VARIABLES ---------------------------------------- */
|
||||
|
||||
static char code_62 = '+'; /* RFC 1421 standard character for code 62 */
|
||||
static char code_63 = '/'; /* RFC 1421 standard character for code 63 */
|
||||
static char code_pad = '='; /* RFC 1421 padding character if padding */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE FUNCTIONS DECLARATION ---------------------------------------- */
|
||||
|
||||
/**
|
||||
@brief Convert a code in the range 0-63 to an ASCII character
|
||||
*/
|
||||
char code_to_char(uint8_t x);
|
||||
|
||||
/**
|
||||
@brief Convert an ASCII character to a code in the range 0-63
|
||||
*/
|
||||
uint8_t char_to_code(char x);
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE FUNCTIONS DEFINITION ----------------------------------------- */
|
||||
|
||||
char code_to_char(uint8_t x) {
|
||||
if (x <= 25) {
|
||||
return 'A' + x;
|
||||
} else if ((x >= 26) && (x <= 51)) {
|
||||
return 'a' + (x-26);
|
||||
} else if ((x >= 52) && (x <= 61)) {
|
||||
return '0' + (x-52);
|
||||
} else if (x == 62) {
|
||||
return code_62;
|
||||
} else if (x == 63) {
|
||||
return code_63;
|
||||
} else {
|
||||
DEBUG("ERROR: %i IS OUT OF RANGE 0-63 FOR BASE64 ENCODING\n", x);
|
||||
exit(EXIT_FAILURE);
|
||||
} //TODO: improve error management
|
||||
}
|
||||
|
||||
uint8_t char_to_code(char x) {
|
||||
if ((x >= 'A') && (x <= 'Z')) {
|
||||
return (uint8_t)x - (uint8_t)'A';
|
||||
} else if ((x >= 'a') && (x <= 'z')) {
|
||||
return (uint8_t)x - (uint8_t)'a' + 26;
|
||||
} else if ((x >= '0') && (x <= '9')) {
|
||||
return (uint8_t)x - (uint8_t)'0' + 52;
|
||||
} else if (x == code_62) {
|
||||
return 62;
|
||||
} else if (x == code_63) {
|
||||
return 63;
|
||||
} else {
|
||||
DEBUG("ERROR: %c (0x%x) IS INVALID CHARACTER FOR BASE64 DECODING\n", x, x);
|
||||
exit(EXIT_FAILURE);
|
||||
} //TODO: improve error management
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */
|
||||
|
||||
int bin_to_b64_nopad(const uint8_t * in, int size, char * out, int max_len) {
|
||||
int i;
|
||||
int result_len; /* size of the result */
|
||||
int full_blocks; /* number of 3 unsigned chars / 4 characters blocks */
|
||||
int last_bytes; /* number of unsigned chars <3 in the last block */
|
||||
int last_chars; /* number of characters <4 in the last block */
|
||||
uint32_t b;
|
||||
|
||||
/* check input values */
|
||||
if ((out == NULL) || (in == NULL)) {
|
||||
DEBUG("ERROR: NULL POINTER AS OUTPUT IN BIN_TO_B64\n");
|
||||
return -1;
|
||||
}
|
||||
if (size == 0) {
|
||||
*out = 0; /* null string */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* calculate the number of base64 'blocks' */
|
||||
full_blocks = size / 3;
|
||||
last_bytes = size % 3;
|
||||
switch (last_bytes) {
|
||||
case 0: /* no byte left to encode */
|
||||
last_chars = 0;
|
||||
break;
|
||||
case 1: /* 1 byte left to encode -> +2 chars */
|
||||
last_chars = 2;
|
||||
break;
|
||||
case 2: /* 2 bytes left to encode -> +3 chars */
|
||||
last_chars = 3;
|
||||
break;
|
||||
default:
|
||||
CRIT("switch default that should not be possible");
|
||||
}
|
||||
|
||||
/* check if output buffer is big enough */
|
||||
result_len = (4*full_blocks) + last_chars;
|
||||
if (max_len < (result_len + 1)) { /* 1 char added for string terminator */
|
||||
DEBUG("ERROR: OUTPUT BUFFER TOO SMALL IN BIN_TO_B64\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* process all the full blocks */
|
||||
for (i=0; i < full_blocks; ++i) {
|
||||
b = (0xFF & in[3*i] ) << 16;
|
||||
b |= (0xFF & in[3*i + 1]) << 8;
|
||||
b |= 0xFF & in[3*i + 2];
|
||||
out[4*i + 0] = code_to_char((b >> 18) & 0x3F);
|
||||
out[4*i + 1] = code_to_char((b >> 12) & 0x3F);
|
||||
out[4*i + 2] = code_to_char((b >> 6 ) & 0x3F);
|
||||
out[4*i + 3] = code_to_char( b & 0x3F);
|
||||
}
|
||||
|
||||
/* process the last 'partial' block and terminate string */
|
||||
i = full_blocks;
|
||||
if (last_chars == 0) {
|
||||
out[4*i] = 0; /* null character to terminate string */
|
||||
} else if (last_chars == 2) {
|
||||
b = (0xFF & in[3*i] ) << 16;
|
||||
out[4*i + 0] = code_to_char((b >> 18) & 0x3F);
|
||||
out[4*i + 1] = code_to_char((b >> 12) & 0x3F);
|
||||
out[4*i + 2] = 0; /* null character to terminate string */
|
||||
} else if (last_chars == 3) {
|
||||
b = (0xFF & in[3*i] ) << 16;
|
||||
b |= (0xFF & in[3*i + 1]) << 8;
|
||||
out[4*i + 0] = code_to_char((b >> 18) & 0x3F);
|
||||
out[4*i + 1] = code_to_char((b >> 12) & 0x3F);
|
||||
out[4*i + 2] = code_to_char((b >> 6 ) & 0x3F);
|
||||
out[4*i + 3] = 0; /* null character to terminate string */
|
||||
}
|
||||
|
||||
return result_len;
|
||||
}
|
||||
|
||||
int b64_to_bin_nopad(const char * in, int size, uint8_t * out, int max_len) {
|
||||
int i;
|
||||
int result_len; /* size of the result */
|
||||
int full_blocks; /* number of 3 unsigned chars / 4 characters blocks */
|
||||
int last_chars; /* number of characters <4 in the last block */
|
||||
int last_bytes; /* number of unsigned chars <3 in the last block */
|
||||
uint32_t b;
|
||||
;
|
||||
|
||||
/* check input values */
|
||||
if ((out == NULL) || (in == NULL)) {
|
||||
DEBUG("ERROR: NULL POINTER AS OUTPUT OR INPUT IN B64_TO_BIN\n");
|
||||
return -1;
|
||||
}
|
||||
if (size == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* calculate the number of base64 'blocks' */
|
||||
full_blocks = size / 4;
|
||||
last_chars = size % 4;
|
||||
switch (last_chars) {
|
||||
case 0: /* no char left to decode */
|
||||
last_bytes = 0;
|
||||
break;
|
||||
case 1: /* only 1 char left is an error */
|
||||
DEBUG("ERROR: ONLY ONE CHAR LEFT IN B64_TO_BIN\n");
|
||||
return -1;
|
||||
case 2: /* 2 chars left to decode -> +1 byte */
|
||||
last_bytes = 1;
|
||||
break;
|
||||
case 3: /* 3 chars left to decode -> +2 bytes */
|
||||
last_bytes = 2;
|
||||
break;
|
||||
default:
|
||||
CRIT("switch default that should not be possible");
|
||||
}
|
||||
|
||||
/* check if output buffer is big enough */
|
||||
result_len = (3*full_blocks) + last_bytes;
|
||||
if (max_len < result_len) {
|
||||
DEBUG("ERROR: OUTPUT BUFFER TOO SMALL IN B64_TO_BIN\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* process all the full blocks */
|
||||
for (i=0; i < full_blocks; ++i) {
|
||||
b = (0x3F & char_to_code(in[4*i] )) << 18;
|
||||
b |= (0x3F & char_to_code(in[4*i + 1])) << 12;
|
||||
b |= (0x3F & char_to_code(in[4*i + 2])) << 6;
|
||||
b |= 0x3F & char_to_code(in[4*i + 3]);
|
||||
out[3*i + 0] = (b >> 16) & 0xFF;
|
||||
out[3*i + 1] = (b >> 8 ) & 0xFF;
|
||||
out[3*i + 2] = b & 0xFF;
|
||||
}
|
||||
|
||||
/* process the last 'partial' block */
|
||||
i = full_blocks;
|
||||
if (last_bytes == 1) {
|
||||
b = (0x3F & char_to_code(in[4*i] )) << 18;
|
||||
b |= (0x3F & char_to_code(in[4*i + 1])) << 12;
|
||||
out[3*i + 0] = (b >> 16) & 0xFF;
|
||||
if (((b >> 12) & 0x0F) != 0) {
|
||||
DEBUG("WARNING: last character contains unusable bits\n");
|
||||
}
|
||||
} else if (last_bytes == 2) {
|
||||
b = (0x3F & char_to_code(in[4*i] )) << 18;
|
||||
b |= (0x3F & char_to_code(in[4*i + 1])) << 12;
|
||||
b |= (0x3F & char_to_code(in[4*i + 2])) << 6;
|
||||
out[3*i + 0] = (b >> 16) & 0xFF;
|
||||
out[3*i + 1] = (b >> 8 ) & 0xFF;
|
||||
if (((b >> 6) & 0x03) != 0) {
|
||||
DEBUG("WARNING: last character contains unusable bits\n");
|
||||
}
|
||||
}
|
||||
|
||||
return result_len;
|
||||
}
|
||||
|
||||
int bin_to_b64(const uint8_t * in, int size, char * out, int max_len) {
|
||||
int ret;
|
||||
|
||||
ret = bin_to_b64_nopad(in, size, out, max_len);
|
||||
|
||||
if (ret == -1) {
|
||||
return -1;
|
||||
}
|
||||
switch (ret%4) {
|
||||
case 0: /* nothing to do */
|
||||
return ret;
|
||||
case 1:
|
||||
DEBUG("ERROR: INVALID UNPADDED BASE64 STRING\n");
|
||||
return -1;
|
||||
case 2: /* 2 chars in last block, must add 2 padding char */
|
||||
if (max_len >= (ret + 2 + 1)) {
|
||||
out[ret] = code_pad;
|
||||
out[ret+1] = code_pad;
|
||||
out[ret+2] = 0;
|
||||
return ret+2;
|
||||
} else {
|
||||
DEBUG("ERROR: not enough room to add padding in bin_to_b64\n");
|
||||
return -1;
|
||||
}
|
||||
case 3: /* 3 chars in last block, must add 1 padding char */
|
||||
if (max_len >= (ret + 1 + 1)) {
|
||||
out[ret] = code_pad;
|
||||
out[ret+1] = 0;
|
||||
return ret+1;
|
||||
} else {
|
||||
DEBUG("ERROR: not enough room to add padding in bin_to_b64\n");
|
||||
return -1;
|
||||
}
|
||||
default:
|
||||
CRIT("switch default that should not be possible");
|
||||
}
|
||||
}
|
||||
|
||||
int b64_to_bin(const char * in, int size, uint8_t * out, int max_len) {
|
||||
if (in == NULL) {
|
||||
DEBUG("ERROR: NULL POINTER AS OUTPUT OR INPUT IN B64_TO_BIN\n");
|
||||
return -1;
|
||||
}
|
||||
if ((size%4 == 0) && (size >= 4)) { /* potentially padded Base64 */
|
||||
if (in[size-2] == code_pad) { /* 2 padding char to ignore */
|
||||
return b64_to_bin_nopad(in, size-2, out, max_len);
|
||||
} else if (in[size-1] == code_pad) { /* 1 padding char to ignore */
|
||||
return b64_to_bin_nopad(in, size-1, out, max_len);
|
||||
} else { /* no padding to ignore */
|
||||
return b64_to_bin_nopad(in, size, out, max_len);
|
||||
}
|
||||
} else { /* treat as unpadded Base64 */
|
||||
return b64_to_bin_nopad(in, size, out, max_len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
1765
libtools/src/parson.c
Normal file
1765
libtools/src/parson.c
Normal file
File diff suppressed because it is too large
Load diff
145
libtools/src/tinymt32.c
Normal file
145
libtools/src/tinymt32.c
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
/**
|
||||
* @file tinymt32.c
|
||||
*
|
||||
* @brief Tiny Mersenne Twister only 127 bit internal state
|
||||
*
|
||||
* @author Mutsuo Saito (Hiroshima University)
|
||||
* @author Makoto Matsumoto (The University of Tokyo)
|
||||
*
|
||||
* Copyright (C) 2011 Mutsuo Saito, Makoto Matsumoto,
|
||||
* Hiroshima University and The University of Tokyo.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The 3-clause BSD License is applied to this software, see
|
||||
* LICENSE.txt
|
||||
*/
|
||||
#include "tinymt32.h"
|
||||
#define MIN_LOOP 8
|
||||
#define PRE_LOOP 8
|
||||
|
||||
/**
|
||||
* This function represents a function used in the initialization
|
||||
* by init_by_array
|
||||
* @param x 32-bit integer
|
||||
* @return 32-bit integer
|
||||
*/
|
||||
static uint32_t ini_func1(uint32_t x) {
|
||||
return (x ^ (x >> 27)) * UINT32_C(1664525);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function represents a function used in the initialization
|
||||
* by init_by_array
|
||||
* @param x 32-bit integer
|
||||
* @return 32-bit integer
|
||||
*/
|
||||
static uint32_t ini_func2(uint32_t x) {
|
||||
return (x ^ (x >> 27)) * UINT32_C(1566083941);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function certificate the period of 2^127-1.
|
||||
* @param random tinymt state vector.
|
||||
*/
|
||||
static void period_certification(tinymt32_t * random) {
|
||||
if ((random->status[0] & TINYMT32_MASK) == 0 &&
|
||||
random->status[1] == 0 &&
|
||||
random->status[2] == 0 &&
|
||||
random->status[3] == 0) {
|
||||
random->status[0] = 'T';
|
||||
random->status[1] = 'I';
|
||||
random->status[2] = 'N';
|
||||
random->status[3] = 'Y';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function initializes the internal state array with a 32-bit
|
||||
* unsigned integer seed.
|
||||
* @param random tinymt state vector.
|
||||
* @param seed a 32-bit unsigned integer used as a seed.
|
||||
*/
|
||||
void tinymt32_init(tinymt32_t * random, uint32_t seed) {
|
||||
random->status[0] = seed;
|
||||
random->status[1] = random->mat1;
|
||||
random->status[2] = random->mat2;
|
||||
random->status[3] = random->tmat;
|
||||
for (int i = 1; i < MIN_LOOP; i++) {
|
||||
random->status[i & 3] ^= i + UINT32_C(1812433253)
|
||||
* (random->status[(i - 1) & 3]
|
||||
^ (random->status[(i - 1) & 3] >> 30));
|
||||
}
|
||||
period_certification(random);
|
||||
for (int i = 0; i < PRE_LOOP; i++) {
|
||||
tinymt32_next_state(random);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function initializes the internal state array,
|
||||
* with an array of 32-bit unsigned integers used as seeds
|
||||
* @param random tinymt state vector.
|
||||
* @param init_key the array of 32-bit integers, used as a seed.
|
||||
* @param key_length the length of init_key.
|
||||
*/
|
||||
void tinymt32_init_by_array(tinymt32_t * random, uint32_t init_key[],
|
||||
int key_length) {
|
||||
const int lag = 1;
|
||||
const int mid = 1;
|
||||
const int size = 4;
|
||||
int i, j;
|
||||
int count;
|
||||
uint32_t r;
|
||||
uint32_t * st = &random->status[0];
|
||||
|
||||
st[0] = 0;
|
||||
st[1] = random->mat1;
|
||||
st[2] = random->mat2;
|
||||
st[3] = random->tmat;
|
||||
if (key_length + 1 > MIN_LOOP) {
|
||||
count = key_length + 1;
|
||||
} else {
|
||||
count = MIN_LOOP;
|
||||
}
|
||||
r = ini_func1(st[0] ^ st[mid % size]
|
||||
^ st[(size - 1) % size]);
|
||||
st[mid % size] += r;
|
||||
r += key_length;
|
||||
st[(mid + lag) % size] += r;
|
||||
st[0] = r;
|
||||
count--;
|
||||
for (i = 1, j = 0; (j < count) && (j < key_length); j++) {
|
||||
r = ini_func1(st[i % size]
|
||||
^ st[(i + mid) % size]
|
||||
^ st[(i + size - 1) % size]);
|
||||
st[(i + mid) % size] += r;
|
||||
r += init_key[j] + i;
|
||||
st[(i + mid + lag) % size] += r;
|
||||
st[i % size] = r;
|
||||
i = (i + 1) % size;
|
||||
}
|
||||
for (; j < count; j++) {
|
||||
r = ini_func1(st[i % size]
|
||||
^ st[(i + mid) % size]
|
||||
^ st[(i + size - 1) % size]);
|
||||
st[(i + mid) % size] += r;
|
||||
r += i;
|
||||
st[(i + mid + lag) % size] += r;
|
||||
st[i % size] = r;
|
||||
i = (i + 1) % size;
|
||||
}
|
||||
for (j = 0; j < size; j++) {
|
||||
r = ini_func2(st[i % size]
|
||||
+ st[(i + mid) % size]
|
||||
+ st[(i + size - 1) % size]);
|
||||
st[(i + mid) % size] ^= r;
|
||||
r -= i;
|
||||
st[(i + mid + lag) % size] ^= r;
|
||||
st[i % size] = r;
|
||||
i = (i + 1) % size;
|
||||
}
|
||||
period_certification(random);
|
||||
for (i = 0; i < PRE_LOOP; i++) {
|
||||
tinymt32_next_state(random);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue