From b35d4afe8568a986f91409ff66e0670fac523cef Mon Sep 17 00:00:00 2001 From: joeycastillo Date: Sun, 27 Oct 2024 15:12:24 -0400 Subject: [PATCH] add command to dump binary file as base64 encoded data --- Makefile | 2 + filesystem/filesystem.c | 28 +++++ filesystem/filesystem.h | 1 + movement/lib/base64/.gitignore | 57 +++++++++ movement/lib/base64/LICENSE | 21 ++++ movement/lib/base64/README.md | 13 +++ movement/lib/base64/base64.c | 204 +++++++++++++++++++++++++++++++++ movement/lib/base64/base64.h | 44 +++++++ shell/shell_cmd_list.c | 7 ++ 9 files changed, 377 insertions(+) create mode 100644 movement/lib/base64/.gitignore create mode 100644 movement/lib/base64/LICENSE create mode 100644 movement/lib/base64/README.md create mode 100644 movement/lib/base64/base64.c create mode 100644 movement/lib/base64/base64.h diff --git a/Makefile b/Makefile index d37da38a..088e6b4e 100644 --- a/Makefile +++ b/Makefile @@ -45,6 +45,7 @@ INCLUDES += \ -I./shell \ -I./movement/lib/sunriset \ -I./movement/lib/chirpy_tx \ + -I./movement/lib/base64 \ -I./watch-library/shared/watch \ -I./watch-library/shared/driver \ -I./watch-faces/clock \ @@ -65,6 +66,7 @@ SRCS += \ ./shell/shell_cmd_list.c \ ./movement/lib/sunriset/sunriset.c \ ./movement/lib/chirpy_tx/chirpy_tx.c \ + ./movement/lib/base64/base64.c \ ./watch-library/shared/driver/thermistor_driver.c \ ./watch-library/shared/watch/watch_common_buzzer.c \ ./watch-library/shared/watch/watch_common_display.c \ diff --git a/filesystem/filesystem.c b/filesystem/filesystem.c index 3b476426..741430ec 100644 --- a/filesystem/filesystem.c +++ b/filesystem/filesystem.c @@ -28,6 +28,8 @@ #include "filesystem.h" #include "watch.h" #include "lfs.h" +#include "base64.h" +#include "delay.h" #ifndef min #define min(x, y) ((x) > (y) ? (y) : (x)) @@ -280,6 +282,32 @@ int filesystem_cmd_cat(int argc, char *argv[]) { return 0; } +int filesystem_cmd_b64encode(int argc, char *argv[]) { + (void) argc; + info.type = 0; + lfs_stat(&eeprom_filesystem, argv[1], &info); + if (filesystem_file_exists(argv[1])) { + if (info.size > 0) { + char *buf = malloc(info.size + 1); + filesystem_read_file(argv[1], buf, info.size); + // print a base 64 encoding of the file, 12 bytes at a time + for (lfs_size_t i = 0; i < info.size; i += 12) { + lfs_size_t len = min(12, info.size - i); + char base64_line[17]; + b64_encode((unsigned char *)buf + i, len, (unsigned char *)base64_line); + printf("%s\n", base64_line); + delay_ms(10); + } + free(buf); + } else { + printf("\r\n"); + } + } else { + printf("b64encode: %s: No such file\r\n", argv[1]); + } + return 0; +} + int filesystem_cmd_df(int argc, char *argv[]) { (void) argc; (void) argv; diff --git a/filesystem/filesystem.h b/filesystem/filesystem.h index a54650a0..111f3f3b 100644 --- a/filesystem/filesystem.h +++ b/filesystem/filesystem.h @@ -98,6 +98,7 @@ bool filesystem_append_file(char *filename, char *text, int32_t length); int filesystem_cmd_ls(int argc, char *argv[]); int filesystem_cmd_cat(int argc, char *argv[]); +int filesystem_cmd_b64encode(int argc, char *argv[]); int filesystem_cmd_df(int argc, char *argv[]); int filesystem_cmd_rm(int argc, char *argv[]); int filesystem_cmd_format(int argc, char *argv[]); diff --git a/movement/lib/base64/.gitignore b/movement/lib/base64/.gitignore new file mode 100644 index 00000000..6b5a4f3f --- /dev/null +++ b/movement/lib/base64/.gitignore @@ -0,0 +1,57 @@ +~* +debug.bat +compile.bat +*.exe +*.lnk +*.url +*.tmp + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp + +# ========================= +# Operating System Files +# ========================= + +# OSX +# ========================= + +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear on external disk +.Spotlight-V100 +.Trashes + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk +data.7z +data.7z.b64 +picture.og.png +data.7z.b64.deco +picture.b64.txt +picture.b64.png diff --git a/movement/lib/base64/LICENSE b/movement/lib/base64/LICENSE new file mode 100644 index 00000000..973d540a --- /dev/null +++ b/movement/lib/base64/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 Joe DF (joedf@ahkscript.org) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/movement/lib/base64/README.md b/movement/lib/base64/README.md new file mode 100644 index 00000000..58fba4ba --- /dev/null +++ b/movement/lib/base64/README.md @@ -0,0 +1,13 @@ +base64.c +======== + +Base64 Library in C + +by Joe DF (joedf@ahkscript.org) +Released under the MIT License + +Thank you for inspiration: +http://www.codeproject.com/Tips/813146/Fast-base-functions-for-encode-decode + +## Usage +Simply include `base64.c` and `base64.h` in your project and see `base64.h` for instructions. \ No newline at end of file diff --git a/movement/lib/base64/base64.c b/movement/lib/base64/base64.c new file mode 100644 index 00000000..8604b949 --- /dev/null +++ b/movement/lib/base64/base64.c @@ -0,0 +1,204 @@ +/* + base64.c - by Joe DF (joedf@ahkscript.org) + Released under the MIT License + + See "base64.h", for more information. + + Thank you for inspiration: + http://www.codeproject.com/Tips/813146/Fast-base-functions-for-encode-decode +*/ + +#include "base64.h" + +//Base64 char table - used internally for encoding +unsigned char b64_chr[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +unsigned int b64_int(unsigned int ch) { + + // ASCII to base64_int + // 65-90 Upper Case >> 0-25 + // 97-122 Lower Case >> 26-51 + // 48-57 Numbers >> 52-61 + // 43 Plus (+) >> 62 + // 47 Slash (/) >> 63 + // 61 Equal (=) >> 64~ + if (ch==43) + return 62; + if (ch==47) + return 63; + if (ch==61) + return 64; + if ((ch>47) && (ch<58)) + return ch + 4; + if ((ch>64) && (ch<91)) + return ch - 'A'; + if ((ch>96) && (ch<123)) + return (ch - 'a') + 26; + return 0; +} + +unsigned int b64e_size(unsigned int in_size) { + + // size equals 4*floor((1/3)*(in_size+2)); + unsigned int i, j = 0; + for (i=0;i>2 ]; + out[k+1] = b64_chr[ ((s[0]&0x03)<<4)+((s[1]&0xF0)>>4) ]; + out[k+2] = b64_chr[ ((s[1]&0x0F)<<2)+((s[2]&0xC0)>>6) ]; + out[k+3] = b64_chr[ s[2]&0x3F ]; + j=0; k+=4; + } + } + + if (j) { + if (j==1) + s[1] = 0; + out[k+0] = b64_chr[ (s[0]&255)>>2 ]; + out[k+1] = b64_chr[ ((s[0]&0x03)<<4)+((s[1]&0xF0)>>4) ]; + if (j==2) + out[k+2] = b64_chr[ ((s[1]&0x0F)<<2) ]; + else + out[k+2] = '='; + out[k+3] = '='; + k+=4; + } + + out[k] = '\0'; + + return k; +} + +unsigned int b64_decode(const unsigned char* in, unsigned int in_len, unsigned char* out) { + + unsigned int i=0, j=0, k=0, s[4]; + + for (i=0;i>4); + if (s[2]!=64) { + out[k+1] = ((s[1]&0x0F)<<4)+((s[2]&0x3C)>>2); + if ((s[3]!=64)) { + out[k+2] = ((s[2]&0x03)<<6)+(s[3]); k+=3; + } else { + k+=2; + } + } else { + k+=1; + } + j=0; + } + } + + return k; +} + +unsigned int b64_encodef(char *InFile, char *OutFile) { + + FILE *pInFile = fopen(InFile,"rb"); + FILE *pOutFile = fopen(OutFile,"wb"); + + int i=0; + int j=0; + int c=0; + int s[4]; + + if ((pInFile==NULL) || (pOutFile==NULL) ) { + if (pInFile!=NULL){fclose(pInFile);} + if (pOutFile!=NULL){fclose(pOutFile);} + return 0; + } + + while(c!=EOF) { + c=fgetc(pInFile); + if (c==EOF) + break; + s[j++]=c; + if (j==3) { + fputc(b64_chr[ (s[0]&255)>>2 ],pOutFile); + fputc(b64_chr[ ((s[0]&0x03)<<4)+((s[1]&0xF0)>>4) ],pOutFile); + fputc(b64_chr[ ((s[1]&0x0F)<<2)+((s[2]&0xC0)>>6) ],pOutFile); + fputc(b64_chr[ s[2]&0x3F ],pOutFile); + j=0; i+=4; + } + } + + if (j) { + if (j==1) + s[1] = 0; + fputc(b64_chr[ (s[0]&255)>>2 ],pOutFile); + fputc(b64_chr[ ((s[0]&0x03)<<4)+((s[1]&0xF0)>>4) ],pOutFile); + if (j==2) + fputc(b64_chr[ ((s[1]&0x0F)<<2) ],pOutFile); + else + fputc('=',pOutFile); + fputc('=',pOutFile); + i+=4; + } + + fclose(pInFile); + fclose(pOutFile); + + return i; +} + +unsigned int b64_decodef(char *InFile, char *OutFile) { + + FILE *pInFile = fopen(InFile,"rb"); + FILE *pOutFile = fopen(OutFile,"wb"); + + int c=0; + int j=0; + int k=0; + int s[4]; + + if ((pInFile==NULL) || (pOutFile==NULL) ) { + if (pInFile!=NULL){fclose(pInFile);} + if (pOutFile!=NULL){fclose(pOutFile);} + return 0; + } + + while(c!=EOF) { + c=fgetc(pInFile); + if (c==EOF) + break; + s[j++]=b64_int(c); + if (j==4) { + fputc(((s[0]&255)<<2)+((s[1]&0x30)>>4),pOutFile); + if (s[2]!=64) { + fputc(((s[1]&0x0F)<<4)+((s[2]&0x3C)>>2),pOutFile); + if ((s[3]!=64)) { + fputc(((s[2]&0x03)<<6)+(s[3]),pOutFile); k+=3; + } else { + k+=2; + } + } else { + k+=1; + } + j=0; + } + } + + fclose(pInFile); + fclose(pOutFile); + + return k; +} diff --git a/movement/lib/base64/base64.h b/movement/lib/base64/base64.h new file mode 100644 index 00000000..c700c7f6 --- /dev/null +++ b/movement/lib/base64/base64.h @@ -0,0 +1,44 @@ +/* + base64.c - by Joe DF (joedf@ahkscript.org) + Released under the MIT License + + Revision: 2015-06-12 01:26:51 + + Thank you for inspiration: + http://www.codeproject.com/Tips/813146/Fast-base-functions-for-encode-decode +*/ + +#include + +//Base64 char table function - used internally for decoding +unsigned int b64_int(unsigned int ch); + +// in_size : the number bytes to be encoded. +// Returns the recommended memory size to be allocated for the output buffer excluding the null byte +unsigned int b64e_size(unsigned int in_size); + +// in_size : the number bytes to be decoded. +// Returns the recommended memory size to be allocated for the output buffer +unsigned int b64d_size(unsigned int in_size); + +// in : buffer of "raw" binary to be encoded. +// in_len : number of bytes to be encoded. +// out : pointer to buffer with enough memory, user is responsible for memory allocation, receives null-terminated string +// returns size of output including null byte +unsigned int b64_encode(const unsigned char* in, unsigned int in_len, unsigned char* out); + +// in : buffer of base64 string to be decoded. +// in_len : number of bytes to be decoded. +// out : pointer to buffer with enough memory, user is responsible for memory allocation, receives "raw" binary +// returns size of output excluding null byte +unsigned int b64_decode(const unsigned char* in, unsigned int in_len, unsigned char* out); + +// file-version b64_encode +// Input : filenames +// returns size of output +unsigned int b64_encodef(char *InFile, char *OutFile); + +// file-version b64_decode +// Input : filenames +// returns size of output +unsigned int b64_decodef(char *InFile, char *OutFile); \ No newline at end of file diff --git a/shell/shell_cmd_list.c b/shell/shell_cmd_list.c index 1e49539e..b83460f4 100644 --- a/shell/shell_cmd_list.c +++ b/shell/shell_cmd_list.c @@ -72,6 +72,13 @@ shell_command_t g_shell_commands[] = { .max_args = 1, .cb = filesystem_cmd_cat, }, + { + .name = "b64encode", + .help = "usage: b64encode ", + .min_args = 1, + .max_args = 1, + .cb = filesystem_cmd_b64encode, + }, { .name = "df", .help = "print filesystem free space",