mirror of
https://gitlab.com/mobian1/eg25-manager.git
synced 2025-08-29 15:22:20 +02:00
src: implement config file lookup and initial parsing
This commit prepares the use of device-specific configuration files. These files should be named after the device-tree `compatible` string with the `toml` extension. `eg25-manager` will search for config files in `<prefix>/etc/eg25-manager` first (or `/etc/eg25-manager` if prefix is `/usr`), then in `<prefix>/share/eg25-manager`.
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
project (
|
project (
|
||||||
'eg25manager',
|
'eg25-manager',
|
||||||
'c',
|
'c',
|
||||||
version : '0.1.2',
|
version : '0.1.2',
|
||||||
license : 'GPLv3+',
|
license : 'GPLv3+',
|
||||||
@@ -41,6 +41,12 @@ else
|
|||||||
full_sysconfdir = join_paths(prefix, sysconfdir)
|
full_sysconfdir = join_paths(prefix, sysconfdir)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
eg25_confdir = join_paths(full_sysconfdir, meson.project_name())
|
||||||
|
eg25_datadir = join_paths(full_datadir, meson.project_name())
|
||||||
|
|
||||||
|
add_global_arguments('-D@0@="@1@"'.format('EG25_CONFDIR', eg25_confdir), language : 'c')
|
||||||
|
add_global_arguments('-D@0@="@1@"'.format('EG25_DATADIR', eg25_datadir), language : 'c')
|
||||||
|
|
||||||
mgr_deps = [
|
mgr_deps = [
|
||||||
dependency('glib-2.0'),
|
dependency('glib-2.0'),
|
||||||
dependency('gio-unix-2.0'),
|
dependency('gio-unix-2.0'),
|
||||||
|
2
src/at.c
2
src/at.c
@@ -218,7 +218,7 @@ static gboolean modem_response(gint fd,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int at_init(struct EG25Manager *manager)
|
int at_init(struct EG25Manager *manager, toml_table_t *config)
|
||||||
{
|
{
|
||||||
manager->at_fd = configure_serial(MODEM_UART);
|
manager->at_fd = configure_serial(MODEM_UART);
|
||||||
if (manager->at_fd < 0) {
|
if (manager->at_fd < 0) {
|
||||||
|
2
src/at.h
2
src/at.h
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#include "manager.h"
|
#include "manager.h"
|
||||||
|
|
||||||
int at_init(struct EG25Manager *data);
|
int at_init(struct EG25Manager *data, toml_table_t *config);
|
||||||
void at_destroy(struct EG25Manager *data);
|
void at_destroy(struct EG25Manager *data);
|
||||||
|
|
||||||
void at_sequence_configure(struct EG25Manager *data);
|
void at_sequence_configure(struct EG25Manager *data);
|
||||||
|
@@ -92,7 +92,7 @@ int gpio_sequence_resume(struct EG25Manager *manager)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int gpio_init(struct EG25Manager *manager)
|
int gpio_init(struct EG25Manager *manager, toml_table_t *config)
|
||||||
{
|
{
|
||||||
int i, ret;
|
int i, ret;
|
||||||
unsigned *gpio_in_idx;
|
unsigned *gpio_in_idx;
|
||||||
|
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#include "manager.h"
|
#include "manager.h"
|
||||||
|
|
||||||
int gpio_init(struct EG25Manager *state);
|
int gpio_init(struct EG25Manager *state, toml_table_t *config);
|
||||||
void gpio_destroy(struct EG25Manager *state);
|
void gpio_destroy(struct EG25Manager *state);
|
||||||
|
|
||||||
int gpio_sequence_poweron(struct EG25Manager *state);
|
int gpio_sequence_poweron(struct EG25Manager *state);
|
||||||
|
@@ -21,6 +21,13 @@
|
|||||||
|
|
||||||
#define EG25_USB_VID 0x2c7c
|
#define EG25_USB_VID 0x2c7c
|
||||||
#define EG25_USB_PID 0x0125
|
#define EG25_USB_PID 0x0125
|
||||||
|
#ifndef EG25_CONFDIR
|
||||||
|
#define EG25_CONFDIR "/etc/eg25-manager"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef EG25_DATADIR
|
||||||
|
#define EG25_DATADIR "/usr/share/eg25-manager"
|
||||||
|
#endif
|
||||||
|
|
||||||
static gboolean quit_app(struct EG25Manager *manager)
|
static gboolean quit_app(struct EG25Manager *manager)
|
||||||
{
|
{
|
||||||
@@ -198,15 +205,71 @@ void modem_resume_post(struct EG25Manager *manager)
|
|||||||
at_sequence_resume(manager);
|
at_sequence_resume(manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static toml_table_t *parse_config_file(char *config_file)
|
||||||
|
{
|
||||||
|
toml_table_t *toml_config;
|
||||||
|
gchar *compatible;
|
||||||
|
gchar error[256];
|
||||||
|
gsize len;
|
||||||
|
FILE *f = NULL;
|
||||||
|
|
||||||
|
if (config_file) {
|
||||||
|
f = fopen(config_file, "r");
|
||||||
|
} else if (g_file_get_contents("/proc/device-tree/compatible", &compatible, &len, NULL)) {
|
||||||
|
g_autoptr (GPtrArray) compat = g_ptr_array_new();
|
||||||
|
gsize pos = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* `compatible` file is a list of NULL-terminated strings, convert it
|
||||||
|
* to an array
|
||||||
|
*/
|
||||||
|
do {
|
||||||
|
g_ptr_array_add(compat, &compatible[pos]);
|
||||||
|
pos += strlen(&compatible[pos]) + 1;
|
||||||
|
} while (pos < len);
|
||||||
|
|
||||||
|
for (pos = 0; pos < compat->len; pos++) {
|
||||||
|
g_autofree gchar *filename = g_strdup_printf(EG25_CONFDIR "/%s.toml", (gchar *)g_ptr_array_index(compat, pos));
|
||||||
|
if (access(filename, F_OK) == 0) {
|
||||||
|
g_message("Opening config file: %s", filename);
|
||||||
|
f = fopen(filename, "r");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!f) {
|
||||||
|
for (pos = 0; pos < compat->len; pos++) {
|
||||||
|
g_autofree gchar *filename = g_strdup_printf(EG25_DATADIR "/%s.toml", (gchar *)g_ptr_array_index(compat, pos));
|
||||||
|
if (access(filename, F_OK) == 0) {
|
||||||
|
g_message("Opening config file: %s", filename);
|
||||||
|
f = fopen(filename, "r");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!f)
|
||||||
|
g_error("unable to find a suitable config file!");
|
||||||
|
|
||||||
|
toml_config = toml_parse_file(f, error, sizeof(error));
|
||||||
|
if (!toml_config)
|
||||||
|
g_error("unable to parse config file: %s", error);
|
||||||
|
|
||||||
|
return toml_config;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
g_autoptr(GOptionContext) opt_context = NULL;
|
g_autoptr(GOptionContext) opt_context = NULL;
|
||||||
g_autoptr(GError) err = NULL;
|
g_autoptr(GError) err = NULL;
|
||||||
struct EG25Manager manager;
|
struct EG25Manager manager;
|
||||||
char compatible[32];
|
gchar *config_file = NULL;
|
||||||
int fd, ret;
|
toml_table_t *toml_config;
|
||||||
|
toml_datum_t toml_value;
|
||||||
const GOptionEntry options[] = {
|
const GOptionEntry options[] = {
|
||||||
{ "gnss", 'g', 0, G_OPTION_ARG_NONE, &manager.manage_gnss, "Manage the GNSS feature.", NULL },
|
{ "gnss", 'g', 0, G_OPTION_ARG_NONE, &manager.manage_gnss, "Manage the GNSS feature.", NULL },
|
||||||
|
{ "config", 'c', 0, G_OPTION_ARG_STRING, &config_file, "Config file to use.", NULL },
|
||||||
{ NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL }
|
{ NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -224,21 +287,13 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
manager.loop = g_main_loop_new(NULL, FALSE);
|
manager.loop = g_main_loop_new(NULL, FALSE);
|
||||||
|
|
||||||
fd = open("/proc/device-tree/compatible", O_RDONLY);
|
toml_config = parse_config_file(config_file);
|
||||||
if (fd < 0) {
|
|
||||||
g_critical("Unable to read 'compatible' string from device tree");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
ret = read(fd, compatible, sizeof(compatible));
|
|
||||||
if (ret > 0 && !strstr(compatible, "pine64,pinephone-1.2"))
|
|
||||||
manager.braveheart = TRUE;
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
at_init(&manager);
|
at_init(&manager, toml_table_in(toml_config, "at"));
|
||||||
gpio_init(&manager);
|
gpio_init(&manager, toml_table_in(toml_config, "gpio"));
|
||||||
mm_iface_init(&manager);
|
mm_iface_init(&manager, toml_table_in(toml_config, "mm-iface"));
|
||||||
suspend_init(&manager);
|
suspend_init(&manager, toml_table_in(toml_config, "suspend"));
|
||||||
udev_init(&manager);
|
udev_init(&manager, toml_table_in(toml_config, "udev"));
|
||||||
|
|
||||||
g_idle_add(G_SOURCE_FUNC(modem_start), &manager);
|
g_idle_add(G_SOURCE_FUNC(modem_start), &manager);
|
||||||
|
|
||||||
|
@@ -11,6 +11,8 @@
|
|||||||
#include <gudev/gudev.h>
|
#include <gudev/gudev.h>
|
||||||
#include <libmm-glib.h>
|
#include <libmm-glib.h>
|
||||||
|
|
||||||
|
#include "toml.h"
|
||||||
|
|
||||||
enum EG25State {
|
enum EG25State {
|
||||||
EG25_STATE_INIT = 0,
|
EG25_STATE_INIT = 0,
|
||||||
EG25_STATE_POWERED, // Power-on sequence has been executed, but the modem isn't on yet
|
EG25_STATE_POWERED, // Power-on sequence has been executed, but the modem isn't on yet
|
||||||
|
@@ -187,7 +187,7 @@ static void mm_vanished_cb(GDBusConnection *connection,
|
|||||||
mm_iface_clean(manager);
|
mm_iface_clean(manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mm_iface_init(struct EG25Manager *manager)
|
void mm_iface_init(struct EG25Manager *manager, toml_table_t *config)
|
||||||
{
|
{
|
||||||
manager->mm_watch = g_bus_watch_name(G_BUS_TYPE_SYSTEM, MM_DBUS_SERVICE,
|
manager->mm_watch = g_bus_watch_name(G_BUS_TYPE_SYSTEM, MM_DBUS_SERVICE,
|
||||||
G_BUS_NAME_WATCHER_FLAGS_AUTO_START,
|
G_BUS_NAME_WATCHER_FLAGS_AUTO_START,
|
||||||
|
@@ -8,5 +8,5 @@
|
|||||||
|
|
||||||
#include "manager.h"
|
#include "manager.h"
|
||||||
|
|
||||||
void mm_iface_init(struct EG25Manager *data);
|
void mm_iface_init(struct EG25Manager *data, toml_table_t *config);
|
||||||
void mm_iface_destroy(struct EG25Manager *data);
|
void mm_iface_destroy(struct EG25Manager *data);
|
||||||
|
@@ -232,7 +232,7 @@ static void on_proxy_acquired(GObject *object,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void suspend_init(struct EG25Manager *manager)
|
void suspend_init(struct EG25Manager *manager, toml_table_t *config)
|
||||||
{
|
{
|
||||||
g_dbus_proxy_new_for_bus(G_BUS_TYPE_SYSTEM,
|
g_dbus_proxy_new_for_bus(G_BUS_TYPE_SYSTEM,
|
||||||
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START |
|
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START |
|
||||||
|
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#include "manager.h"
|
#include "manager.h"
|
||||||
|
|
||||||
void suspend_init (struct EG25Manager *data);
|
void suspend_init (struct EG25Manager *data, toml_table_t *config);
|
||||||
void suspend_destroy (struct EG25Manager *data);
|
void suspend_destroy (struct EG25Manager *data);
|
||||||
|
|
||||||
void suspend_inhibit (struct EG25Manager *data, gboolean inhibit, gboolean block);
|
void suspend_inhibit (struct EG25Manager *data, gboolean inhibit, gboolean block);
|
||||||
|
@@ -25,7 +25,7 @@ static void udev_event_cb(GUdevClient *client, gchar *action, GUdevDevice *devic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void udev_init (struct EG25Manager *manager)
|
void udev_init (struct EG25Manager *manager, toml_table_t *config)
|
||||||
{
|
{
|
||||||
const char * const subsystems[] = { "usb", NULL };
|
const char * const subsystems[] = { "usb", NULL };
|
||||||
|
|
||||||
|
@@ -8,5 +8,5 @@
|
|||||||
|
|
||||||
#include "manager.h"
|
#include "manager.h"
|
||||||
|
|
||||||
void udev_init (struct EG25Manager *data);
|
void udev_init (struct EG25Manager *data, toml_table_t *config);
|
||||||
void udev_destroy (struct EG25Manager *data);
|
void udev_destroy (struct EG25Manager *data);
|
||||||
|
Reference in New Issue
Block a user