From 2fcfff13a29abed823307c0d9eb253e6c314a162 Mon Sep 17 00:00:00 2001
From: schneider <schneider@blinkenlichts.net>
Date: Fri, 3 Apr 2020 20:00:42 +0200
Subject: [PATCH] feat(config): Add micropython interface the the config file

This allows to read and write strings to the config file.
---
 pycardium/meson.build            |  1 +
 pycardium/modules/py/config.py   |  9 ++++
 pycardium/modules/py/meson.build |  1 +
 pycardium/modules/qstrdefs.h     |  4 ++
 pycardium/modules/sys_config.c   | 74 ++++++++++++++++++++++++++++++++
 pycardium/mpconfigport.h         |  1 +
 6 files changed, 90 insertions(+)
 create mode 100644 pycardium/modules/py/config.py
 create mode 100644 pycardium/modules/sys_config.c

diff --git a/pycardium/meson.build b/pycardium/meson.build
index 931662c25..d12e62f5e 100644
--- a/pycardium/meson.build
+++ b/pycardium/meson.build
@@ -3,6 +3,7 @@ name = 'pycardium'
 modsrc = files(
   'modules/bhi160-sys.c',
   'modules/buttons.c',
+  'modules/sys_config.c',
   'modules/fat_file.c',
   'modules/fat_reader_import.c',
   'modules/gpio.c',
diff --git a/pycardium/modules/py/config.py b/pycardium/modules/py/config.py
new file mode 100644
index 000000000..1ac655296
--- /dev/null
+++ b/pycardium/modules/py/config.py
@@ -0,0 +1,9 @@
+import sys_config
+
+
+def set_string(key, value):
+    sys_config.set_string(key, str(value))
+
+
+def get_string(key):
+    return sys_config.get_string(key)
diff --git a/pycardium/modules/py/meson.build b/pycardium/modules/py/meson.build
index fe26c64e2..b8d3310f0 100644
--- a/pycardium/modules/py/meson.build
+++ b/pycardium/modules/py/meson.build
@@ -1,4 +1,5 @@
 python_modules = files(
+  'config.py',
   'bhi160.py',
   'bme680.py',
   'color.py',
diff --git a/pycardium/modules/qstrdefs.h b/pycardium/modules/qstrdefs.h
index c2c1fdace..3a6e9dfcf 100644
--- a/pycardium/modules/qstrdefs.h
+++ b/pycardium/modules/qstrdefs.h
@@ -188,3 +188,7 @@ Q(MAX86150)
 /* ws2812 */
 Q(ws2812)
 Q(set_all)
+
+Q(config)
+Q(set_string)
+Q(get_string)
diff --git a/pycardium/modules/sys_config.c b/pycardium/modules/sys_config.c
new file mode 100644
index 000000000..a46103279
--- /dev/null
+++ b/pycardium/modules/sys_config.c
@@ -0,0 +1,74 @@
+#include "epicardium.h"
+
+#include "py/obj.h"
+#include "py/runtime.h"
+
+#include <string.h>
+#include <strings.h>
+
+#include <stdbool.h>
+
+static void extract_string(mp_obj_t obj, char *buf, size_t buf_len, const char *error_message)
+{
+	size_t len;
+	const char *str_ptr = mp_obj_str_get_data(obj, &len);
+	/*
+	 * The string retrieved from MicroPython is not NULL-terminated so we
+	 * first need to copy it and add a NULL-byte.
+	 */
+	if (len > (buf_len - 1)) {
+		mp_raise_ValueError(error_message);
+	}
+	memcpy(buf, str_ptr, len);
+	buf[len] = '\0';
+}
+
+static mp_obj_t mp_config_set_string(mp_obj_t key_in, mp_obj_t value_in)
+{
+	char key_str[128], value_str[128];
+
+	extract_string(key_in, key_str, sizeof(key_str), "key too long");
+	extract_string(value_in, value_str, sizeof(value_str), "value too long");
+
+	int status = epic_config_set_string(key_str, value_str);
+	if (status < 0) {
+		mp_raise_OSError(-status);
+	}
+
+	return mp_const_none;
+}
+static MP_DEFINE_CONST_FUN_OBJ_2(set_string_obj, mp_config_set_string);
+
+static mp_obj_t mp_config_get_string(mp_obj_t key_in)
+{
+	char key_str[128], value_str[128];
+	extract_string(key_in, key_str, sizeof(key_str), "key too long");
+
+	int status =
+		epic_config_get_string(key_str, value_str, sizeof(value_str));
+	if (status < 0) {
+		mp_raise_OSError(-status);
+	}
+
+	mp_obj_t ret = mp_obj_new_str(value_str, strlen(value_str));
+	return ret;
+}
+static MP_DEFINE_CONST_FUN_OBJ_1(get_string_obj, mp_config_get_string);
+
+static const mp_rom_map_elem_t config_module_globals_table[] = {
+	{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_sys_config) },
+	{ MP_ROM_QSTR(MP_QSTR_set_string), MP_ROM_PTR(&set_string_obj) },
+	{ MP_ROM_QSTR(MP_QSTR_get_string), MP_ROM_PTR(&get_string_obj) },
+};
+
+static MP_DEFINE_CONST_DICT(config_module_globals, config_module_globals_table);
+
+// Define module object.
+const mp_obj_module_t config_module = {
+	.base    = { &mp_type_module },
+	.globals = (mp_obj_dict_t *)&config_module_globals,
+};
+
+/* This is a special macro that will make MicroPython aware of this module */
+/* clang-format off */
+MP_REGISTER_MODULE(MP_QSTR_sys_config, config_module, MODULE_CONFIG_ENABLED);
diff --git a/pycardium/mpconfigport.h b/pycardium/mpconfigport.h
index 3d6ae86af..2b7059c89 100644
--- a/pycardium/mpconfigport.h
+++ b/pycardium/mpconfigport.h
@@ -64,6 +64,7 @@ int mp_hal_trng_read_int(void);
 #define MODULE_UTIME_ENABLED                (1)
 #define MODULE_VIBRA_ENABLED                (1)
 #define MODULE_WS2812_ENABLED               (1)
+#define MODULE_CONFIG_ENABLED               (1)
 
 /*
  * This port is intended to be 32-bit, but unfortunately, int32_t for
-- 
GitLab