Skip to content

Commit 9eae8d1

Browse files
committed
Added initial test
Added header length calc code to compression core file
1 parent eea438b commit 9eae8d1

File tree

3 files changed

+157
-10
lines changed

3 files changed

+157
-10
lines changed

source/application/compression.c

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,45 @@
2525
#include <stdlib.h>
2626
#include "compression.h"
2727
#include "lz4.h"
28+
#include "nrfx_log.h"
29+
30+
#define LZ4F_MAGICNUMBER 0x184D2204U
31+
#define LZ4F_MAGIC_SKIPPABLE_START 0x184D2A50U
32+
#define LZ4F_MIN_SIZE_TO_KNOW_HEADER_LENGTH 5
33+
#define LZ4F_HEADER_SIZE_MIN 7
34+
35+
static uint32_t LZ4F_readLE32(const void *src)
36+
{
37+
const uint8_t *const srcPtr = (const uint8_t *)src;
38+
uint32_t value32 = srcPtr[0];
39+
value32 |= ((uint32_t)srcPtr[1]) << 8;
40+
value32 |= ((uint32_t)srcPtr[2]) << 16;
41+
value32 |= ((uint32_t)srcPtr[3]) << 24;
42+
return value32;
43+
}
44+
45+
size_t LZ4F_headerSize(const void *src, size_t srcSize)
46+
{
47+
/* minimal srcSize to determine header size */
48+
if (srcSize < LZ4F_MIN_SIZE_TO_KNOW_HEADER_LENGTH)
49+
return -20;
50+
51+
/* special case : skippable frames */
52+
if ((LZ4F_readLE32(src) & 0xFFFFFFF0U) == LZ4F_MAGIC_SKIPPABLE_START)
53+
return 8;
54+
55+
/* control magic number */
56+
if (LZ4F_readLE32(src) != LZ4F_MAGICNUMBER)
57+
return -21;
58+
59+
/* Frame Header Size */
60+
{
61+
uint8_t const FLG = ((const uint8_t *)src)[4];
62+
uint32_t const contentSizeFlag = (FLG >> 3) & 0x01;
63+
uint32_t const dictIDFlag = FLG & 0x01;
64+
return LZ4F_HEADER_SIZE_MIN + (contentSizeFlag ? 8 : 0) + (dictIDFlag ? 4 : 0);
65+
}
66+
}
2867

2968
int compression_decompress(size_t destination_size,
3069
const void *source,
@@ -34,18 +73,24 @@ int compression_decompress(size_t destination_size,
3473
{
3574
int status = 0;
3675

76+
size_t header_size = LZ4F_headerSize(source, source_size);
77+
78+
if (header_size < 0)
79+
{
80+
return header_size;
81+
}
82+
3783
char *output_buffer = malloc(destination_size);
84+
3885
if (output_buffer == NULL)
3986
{
4087
return -1;
4188
}
4289

43-
// TODO the frame header might not be 7
44-
char *block_pointer = (char *)source + 7;
90+
char *block_pointer = (char *)source + header_size;
4591

4692
while (1)
4793
{
48-
4994
int current_block_size = ((uint8_t)block_pointer[0]) +
5095
((uint8_t)block_pointer[1] << 8) +
5196
((uint8_t)block_pointer[2] << 16) +

source/application/lua_libraries/compression.c

Lines changed: 89 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,82 @@
2222
* PERFORMANCE OF THIS SOFTWARE.
2323
*/
2424

25+
#include <string.h>
2526
#include "compression.h"
2627
#include "frame_lua_libraries.h"
2728
#include "lauxlib.h"
2829
#include "lua.h"
2930
#include "watchdog.h"
3031

32+
/*
33+
* Test steps:
34+
*
35+
* 1. Create a test file with some text
36+
*
37+
* 2. Compress the file
38+
*
39+
* lz4 -9 -B32 test.txt test.lz4
40+
*
41+
* 3. Convert to header data
42+
*
43+
* xxd -include test.lz4 test.h
44+
*
45+
* 4. Copy the header data to the test buffer below
46+
*/
47+
48+
const unsigned char test_data[] = {
49+
0x04, 0x22, 0x4d, 0x18, 0x64, 0x40, 0xa7, 0x24, 0x02, 0x00, 0x00, 0xf0,
50+
0x30, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20,
51+
0x69, 0x73, 0x20, 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x66, 0x69,
52+
0x6c, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x74,
53+
0x61, 0x69, 0x6e, 0x73, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x74, 0x65,
54+
0x78, 0x74, 0x2e, 0x0a, 0x0a, 0x4c, 0x6f, 0x72, 0x65, 0x6d, 0x20, 0x49,
55+
0x70, 0x73, 0x75, 0x6d, 0x35, 0x00, 0xc1, 0x73, 0x69, 0x6d, 0x70, 0x6c,
56+
0x79, 0x20, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x23, 0x00, 0xf1, 0x0d, 0x20,
57+
0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74,
58+
0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65,
59+
0x73, 0x65, 0x74, 0x10, 0x00, 0xa8, 0x69, 0x6e, 0x64, 0x75, 0x73, 0x74,
60+
0x72, 0x79, 0x2e, 0x20, 0x4b, 0x00, 0x81, 0x68, 0x61, 0x73, 0x20, 0x62,
61+
0x65, 0x65, 0x6e, 0x3c, 0x00, 0x04, 0x23, 0x00, 0xb8, 0x27, 0x73, 0x20,
62+
0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x62, 0x00, 0xa1, 0x65,
63+
0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x2e, 0x00, 0xf2,
64+
0x07, 0x31, 0x35, 0x30, 0x30, 0x73, 0x2c, 0x20, 0x77, 0x68, 0x65, 0x6e,
65+
0x20, 0x61, 0x6e, 0x20, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x81,
66+
0x00, 0xf1, 0x01, 0x65, 0x72, 0x20, 0x74, 0x6f, 0x6f, 0x6b, 0x20, 0x61,
67+
0x20, 0x67, 0x61, 0x6c, 0x6c, 0x65, 0x79, 0x9e, 0x00, 0x31, 0x79, 0x70,
68+
0x65, 0x96, 0x00, 0xf2, 0x07, 0x73, 0x63, 0x72, 0x61, 0x6d, 0x62, 0x6c,
69+
0x65, 0x64, 0x20, 0x69, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x6d, 0x61, 0x6b,
70+
0x65, 0x20, 0x61, 0x20, 0x00, 0xf1, 0x02, 0x73, 0x70, 0x65, 0x63, 0x69,
71+
0x6d, 0x65, 0x6e, 0x20, 0x62, 0x6f, 0x6f, 0x6b, 0x2e, 0x20, 0x49, 0x74,
72+
0xa2, 0x00, 0xf1, 0x1b, 0x73, 0x75, 0x72, 0x76, 0x69, 0x76, 0x65, 0x64,
73+
0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x66, 0x69,
74+
0x76, 0x65, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x75, 0x72, 0x69, 0x65, 0x73,
75+
0x2c, 0x20, 0x62, 0x75, 0x74, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x9a, 0x00,
76+
0xf8, 0x05, 0x6c, 0x65, 0x61, 0x70, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x20,
77+
0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x0c, 0x01,
78+
0x80, 0x2c, 0x20, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x17, 0x01, 0xf1,
79+
0x06, 0x65, 0x73, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x79,
80+
0x20, 0x75, 0x6e, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x79, 0x00,
81+
0xd0, 0x77, 0x61, 0x73, 0x20, 0x70, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x72,
82+
0x69, 0x73, 0xad, 0x00, 0x02, 0x25, 0x01, 0xa1, 0x31, 0x39, 0x36, 0x30,
83+
0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x0f, 0x00, 0x70, 0x72, 0x65, 0x6c,
84+
0x65, 0x61, 0x73, 0x65, 0xe1, 0x00, 0xf4, 0x00, 0x4c, 0x65, 0x74, 0x72,
85+
0x61, 0x73, 0x65, 0x74, 0x20, 0x73, 0x68, 0x65, 0x65, 0x74, 0x73, 0xc8,
86+
0x01, 0x00, 0x66, 0x00, 0x08, 0x73, 0x01, 0x60, 0x70, 0x61, 0x73, 0x73,
87+
0x61, 0x67, 0xb5, 0x00, 0x00, 0x0d, 0x01, 0x30, 0x6d, 0x6f, 0x72, 0x45,
88+
0x00, 0x00, 0xcb, 0x00, 0x22, 0x6c, 0x79, 0x57, 0x00, 0xf0, 0x00, 0x64,
89+
0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69,
90+
0x73, 0x68, 0x40, 0x00, 0xf0, 0x15, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61,
91+
0x72, 0x65, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x41, 0x6c, 0x64, 0x75,
92+
0x73, 0x20, 0x50, 0x61, 0x67, 0x65, 0x4d, 0x61, 0x6b, 0x65, 0x72, 0x20,
93+
0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x28, 0x00, 0x81, 0x76, 0x65, 0x72,
94+
0x73, 0x69, 0x6f, 0x6e, 0x73, 0x8f, 0x00, 0xb0, 0x6f, 0x72, 0x65, 0x6d,
95+
0x20, 0x49, 0x70, 0x73, 0x75, 0x6d, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x31,
96+
0xb8, 0x0d, 0xa8};
97+
3198
static int registered_function = 0;
99+
static uint8_t decompression_buffer[4096];
100+
static size_t decompression_buffer_size = 0;
32101

33102
static void decompression_lua_handler(lua_State *L, lua_Debug *ar)
34103
{
@@ -38,9 +107,11 @@ static void decompression_lua_handler(lua_State *L, lua_Debug *ar)
38107
{
39108
lua_rawgeti(L, LUA_REGISTRYINDEX, registered_function);
40109

41-
// TODO: Add the data to the function call if it's not already added
110+
lua_pushlstring(L,
111+
(char *)decompression_buffer,
112+
decompression_buffer_size);
42113

43-
if (lua_pcall(L, 0, 0, 0) != LUA_OK)
114+
if (lua_pcall(L, 1, 0, 0) != LUA_OK)
44115
{
45116
luaL_error(L, "%s", lua_tostring(L, -1));
46117
}
@@ -51,7 +122,10 @@ static void process_function_callback(void *context,
51122
void *data,
52123
size_t data_size)
53124
{
54-
// TODO copy the data to a buffer
125+
decompression_buffer_size = data_size;
126+
memcpy(decompression_buffer, data, data_size);
127+
128+
LOG("decompression_buffer_size: %d", decompression_buffer_size);
55129

56130
lua_sethook(L_global,
57131
decompression_lua_handler,
@@ -80,14 +154,22 @@ static int lua_compression_register_process_function(lua_State *L)
80154

81155
static int lua_compression_decompress(lua_State *L)
82156
{
83-
int status = compression_decompress(4096, // TODO figure out destination size
84-
NULL, // TODO pass the source data to the decompression function
85-
sizeof(0), // TODO set the source data size
157+
lua_Integer block_size = luaL_checkinteger(L, 1);
158+
159+
if (block_size <= 0)
160+
{
161+
luaL_error(L, "bytes must be greater than 0");
162+
}
163+
164+
int status = compression_decompress(block_size,
165+
test_data, // TODO pass the source data to the decompression function
166+
sizeof(test_data), // TODO set the source data size
86167
process_function_callback,
87168
NULL);
88169

89-
if (status != 0)
170+
if (status)
90171
{
172+
LOG("%d", status);
91173
luaL_error(L, "decompression failed");
92174
}
93175

tests/test_compression.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import asyncio
2+
from frameutils import Bluetooth
3+
4+
5+
async def main():
6+
b = Bluetooth()
7+
8+
await b.connect(print_response_handler=lambda s: print(s))
9+
10+
await b.send_lua("function process_function(data) print(data) end")
11+
await b.send_lua("frame.compression.process_function(process_function)")
12+
await b.send_lua("frame.compression.decompress(1024)")
13+
await b.send_lua("process_function(1)")
14+
15+
await asyncio.sleep(1)
16+
17+
await b.disconnect()
18+
19+
20+
asyncio.run(main())

0 commit comments

Comments
 (0)