Merge branch 'fix-config-crash' into 'master'

Don't crash on incomplete config files

Closes #23

See merge request mobian1/devices/eg25-manager!31
This commit is contained in:
Arnaud Ferraris
2021-10-05 20:34:28 +00:00
19 changed files with 275 additions and 158 deletions

View File

@@ -5,6 +5,7 @@
*/
#include "at.h"
#include "config.h"
#include "suspend.h"
#include "gpio.h"
#include "gnss.h"
@@ -314,67 +315,61 @@ static void parse_commands_list(toml_array_t *array, GArray **cmds)
continue;
value = toml_string_in(table, "cmd");
if (value.ok) {
cmd->cmd = g_strdup(value.u.s);
free(value.u.s);
}
if (value.ok)
cmd->cmd = value.u.s;
value = toml_string_in(table, "subcmd");
if (value.ok) {
cmd->subcmd = g_strdup(value.u.s);
free(value.u.s);
}
if (value.ok)
cmd->subcmd = value.u.s;
value = toml_string_in(table, "value");
if (value.ok) {
cmd->value = g_strdup(value.u.s);
free(value.u.s);
}
if (value.ok)
cmd->value = value.u.s;
value = toml_string_in(table, "expect");
if (value.ok) {
cmd->expected = g_strdup(value.u.s);
free(value.u.s);
}
if (value.ok)
cmd->expected = value.u.s;
}
}
int at_init(struct EG25Manager *manager, toml_table_t *config)
int at_init(struct EG25Manager *manager, toml_table_t *config[])
{
toml_array_t *commands;
toml_datum_t uart_port;
toml_array_t *commands = NULL;
gchar *uart_port = NULL;
toml_table_t *at_config[EG25_CONFIG_COUNT];
uart_port = toml_string_in(config, "uart");
if (!uart_port.ok)
for (int i = 0; i < EG25_CONFIG_COUNT; i++)
at_config[i] = config[i] ? toml_table_in(config[i], "at") : NULL;
if (!at_config[EG25_CONFIG_SYS])
g_error("Default config file lacks the 'at' section!");
if (!config_get_string(at_config, "uart", &uart_port))
g_error("Configuration file lacks UART port definition");
manager->at_fd = configure_serial(uart_port.u.s);
manager->at_fd = configure_serial(uart_port);
if (manager->at_fd < 0) {
g_critical("Unable to configure %s", uart_port.u.s);
free(uart_port.u.s);
g_critical("Unable to configure %s", uart_port);
g_free(uart_port);
return 1;
}
free(uart_port.u.s);
g_free(uart_port);
manager->at_source = g_unix_fd_add(manager->at_fd, G_IO_IN, modem_response, manager);
commands = toml_array_in(config, "configure");
if (!commands)
if (!config_get_array(at_config, "configure", &commands))
g_error("Configuration file lacks initial AT commands list");
parse_commands_list(commands, &configure_commands);
commands = toml_array_in(config, "suspend");
if (!commands)
if (!config_get_array(at_config, "suspend", &commands))
g_error("Configuration file lacks suspend AT commands list");
parse_commands_list(commands, &suspend_commands);
commands = toml_array_in(config, "resume");
if (!commands)
if (!config_get_array(at_config, "resume", &commands))
g_error("Configuration file lacks resume AT commands list");
parse_commands_list(commands, &resume_commands);
commands = toml_array_in(config, "reset");
if (!commands)
if (!config_get_array(at_config, "reset", &commands))
g_error("Configuration file lacks reset AT commands list");
parse_commands_list(commands, &reset_commands);

View File

@@ -17,7 +17,7 @@ typedef struct AtCommand {
int retries;
} AtCommand;
int at_init(struct EG25Manager *manager, toml_table_t *config);
int at_init(struct EG25Manager *manager, toml_table_t *config[]);
void at_destroy(struct EG25Manager *manager);
void at_process_result(struct EG25Manager *manager,

83
src/config.c Normal file
View File

@@ -0,0 +1,83 @@
/*
* Copyright (C) 2020 Arnaud Ferraris <arnaud.ferraris@gmail.com>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "config.h"
#include "toml.h"
gboolean config_get_bool(toml_table_t **config, const gchar *key, gboolean *result)
{
toml_datum_t value = { .ok = 0 };
if (config[EG25_CONFIG_USER])
value = toml_bool_in(config[EG25_CONFIG_USER], key);
if (!value.ok)
value = toml_bool_in(config[EG25_CONFIG_SYS], key);
if (value.ok && result)
*result = value.u.b;
return !!value.ok;
}
gboolean config_get_int(toml_table_t **config, const gchar *key, gint *result)
{
toml_datum_t value = { .ok = 0 };
if (config[EG25_CONFIG_USER])
value = toml_int_in(config[EG25_CONFIG_USER], key);
if (!value.ok)
value = toml_int_in(config[EG25_CONFIG_SYS], key);
if (value.ok && result)
*result = value.u.i;
return !!value.ok;
}
gboolean config_get_uint(toml_table_t **config, const gchar *key, guint *result)
{
gint value;
gboolean found;
found = config_get_int(config, key, &value);
if (found) {
if (value <= 0 || value >= G_MAXUINT) {
g_message("Value out of range for [%s], discarding", key);
found = FALSE;
}
}
if (found && result)
*result = (guint) value;
return found;
}
gboolean config_get_string(toml_table_t **config, const gchar *key, gchar **result)
{
toml_datum_t value = { .ok = 0 };
if (config[EG25_CONFIG_USER])
value = toml_string_in(config[EG25_CONFIG_USER], key);
if (!value.ok)
value = toml_string_in(config[EG25_CONFIG_SYS], key);
if (value.ok && result)
*result = value.u.s;
return !!value.ok;
}
gboolean config_get_array(toml_table_t **config, const gchar *key, toml_array_t **result)
{
toml_array_t *array = NULL;
if (config[EG25_CONFIG_USER])
array = toml_array_in(config[EG25_CONFIG_USER], key);
if (!array)
array = toml_array_in(config[EG25_CONFIG_SYS], key);
if (array && result)
*result = array;
return !!array;
}

26
src/config.h Normal file
View File

@@ -0,0 +1,26 @@
/*
* Copyright (C) 2020 Arnaud Ferraris <arnaud.ferraris@gmail.com>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#pragma once
#include <glib.h>
#include "manager.h"
#include "toml.h"
/*
* Helper functions for parsing config files: each function retrieves the
* value for key `key`, with the user config file having priority over the
* default config file. The values are stored in `result`.
*
* They all return TRUE if the value was found, FALSE otherwise.
*/
gboolean config_get_bool(toml_table_t **config, const gchar *key, gboolean *result);
gboolean config_get_int(toml_table_t **config, const gchar *key, gint *result);
gboolean config_get_uint(toml_table_t **config, const gchar *key, guint *result);
gboolean config_get_string(toml_table_t **config, const gchar *key, gchar **result);
gboolean config_get_array(toml_table_t **config, const gchar *key, toml_array_t **result);

View File

@@ -4,6 +4,7 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "config.h"
#include "gnss.h"
#include "manager.h"
#include "at.h"
@@ -58,38 +59,34 @@ gboolean gnss_upload_assistance_data(struct EG25Manager *manager)
return FALSE;
}
void gnss_init(struct EG25Manager *manager, toml_table_t *config)
void gnss_init(struct EG25Manager *manager, toml_table_t *config[])
{
toml_datum_t enabled;
toml_datum_t url;
toml_datum_t file;
toml_table_t *gnss_config[EG25_CONFIG_COUNT];
g_autoptr (GError) error = NULL;
for (int i = 0; i < EG25_CONFIG_COUNT; i++)
gnss_config[i] = config[i] ? toml_table_in(config[i], "gnss") : NULL;
if (!gnss_config[EG25_CONFIG_SYS])
g_error("Default config file lacks the 'gnss' section!");
/*
* GNSS assistance is an optional feature, you can disable it
* if you want in the configuration file.
* In case the configuration is missing, we assume GNSS assistance
* to be disabled.
*/
enabled = toml_bool_in(config, "enabled");
manager->gnss_assistance_enabled = FALSE;
if (enabled.ok)
manager->gnss_assistance_enabled = enabled.u.b;
config_get_bool(gnss_config, "enabled", &manager->gnss_assistance_enabled);
if (!manager->gnss_assistance_enabled) {
g_message("GNSS assistance is disabled!");
return;
}
url = toml_string_in(config, "url");
if (url.ok)
manager->gnss_assistance_url = url.u.s;
else
if (!config_get_string(gnss_config, "url", &manager->gnss_assistance_url))
g_error("GNSS assistance server URL is missing from config file");
file = toml_string_in(config, "file");
if (file.ok)
manager->gnss_assistance_file = file.u.s;
else
if (!config_get_string(gnss_config, "file", &manager->gnss_assistance_file))
g_error("GNSS assistance file name is missing from config file");
/* Create temporary file to store assistance data */
@@ -105,6 +102,8 @@ void gnss_init(struct EG25Manager *manager, toml_table_t *config)
void gnss_destroy(struct EG25Manager *manager)
{
g_free(manager->gnss_assistance_url);
g_free(manager->gnss_assistance_file);
close(manager->gnss_assistance_fd);
}
@@ -512,4 +511,3 @@ void gnss_step(struct EG25Manager *manager)
break;
}
}

View File

@@ -12,6 +12,6 @@
#include "manager.h"
void gnss_init(struct EG25Manager *manager, toml_table_t *config);
void gnss_init(struct EG25Manager *manager, toml_table_t *config[]);
void gnss_destroy(struct EG25Manager *manager);
gboolean gnss_upload_assistance_data(struct EG25Manager *manager);

View File

@@ -4,6 +4,7 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "config.h"
#include "gpio.h"
#include <unistd.h>
@@ -13,8 +14,6 @@
#define MAX_GPIOCHIP_LINES 352
#define GPIO_IDX_INVAL 0xffff
enum {
GPIO_OUT_DTR = 0,
GPIO_OUT_PWRKEY,
@@ -24,12 +23,23 @@ enum {
GPIO_OUT_COUNT
};
enum {
GPIO_IN_STATUS = 0,
GPIO_IN_COUNT
};
static char *gpio_out_names[] = {
"dtr",
"pwrkey",
"reset",
"apready",
"disable",
};
static char *gpio_in_names[] = {
"status",
};
int gpio_sequence_poweron(struct EG25Manager *manager)
{
gpiod_line_set_value(manager->gpio_out[GPIO_OUT_PWRKEY], 1);
@@ -91,24 +101,17 @@ int gpio_sequence_sleep(struct EG25Manager *manager)
return 0;
}
static guint get_config_gpio(toml_table_t *config, const char *id)
{
toml_datum_t value = toml_int_in(config, id);
guint gpio;
if (!value.ok)
return GPIO_IDX_INVAL;
gpio = (guint)value.u.i;
return gpio;
}
int gpio_init(struct EG25Manager *manager, toml_table_t *config)
int gpio_init(struct EG25Manager *manager, toml_table_t *config[])
{
int i, ret;
guint gpio_out_idx[GPIO_OUT_COUNT];
guint gpio_in_idx[GPIO_IN_COUNT];
guint offset, chipidx, gpio_idx;
toml_table_t *gpio_config[EG25_CONFIG_COUNT];
for (i = 0; i < EG25_CONFIG_COUNT; i++)
gpio_config[i] = config[i] ? toml_table_in(config[i], "gpio") : NULL;
if (!gpio_config[EG25_CONFIG_SYS])
g_error("Default config file lacks the 'gpio' section!");
manager->gpiochip[0] = gpiod_chip_open_by_label(GPIO_CHIP1_LABEL);
if (!manager->gpiochip[0]) {
@@ -122,21 +125,15 @@ int gpio_init(struct EG25Manager *manager, toml_table_t *config)
return 1;
}
gpio_out_idx[GPIO_OUT_DTR] = get_config_gpio(config, "dtr");
gpio_out_idx[GPIO_OUT_PWRKEY] = get_config_gpio(config, "pwrkey");
gpio_out_idx[GPIO_OUT_RESET] = get_config_gpio(config, "reset");
gpio_out_idx[GPIO_OUT_APREADY] = get_config_gpio(config, "apready");
gpio_out_idx[GPIO_OUT_DISABLE] = get_config_gpio(config, "disable");
gpio_in_idx[GPIO_IN_STATUS] = get_config_gpio(config, "status");
for (i = 0; i < GPIO_OUT_COUNT; i++) {
guint offset, chipidx;
if (!config_get_uint(gpio_config, gpio_out_names[i], &gpio_idx))
g_error("Unable to get config for output GPIO '%s'", gpio_out_names[i]);
if (gpio_out_idx[i] < MAX_GPIOCHIP_LINES) {
offset = gpio_out_idx[i];
if (gpio_idx < MAX_GPIOCHIP_LINES) {
offset = gpio_idx;
chipidx = 0;
} else {
offset = gpio_out_idx[i] - MAX_GPIOCHIP_LINES;
offset = gpio_idx - MAX_GPIOCHIP_LINES;
chipidx = 1;
}
@@ -154,16 +151,14 @@ int gpio_init(struct EG25Manager *manager, toml_table_t *config)
}
for (i = 0; i < GPIO_IN_COUNT; i++) {
guint offset, chipidx;
if (gpio_in_idx[i] == GPIO_IDX_INVAL)
if (!config_get_uint(gpio_config, gpio_in_names[i], &gpio_idx))
continue;
if (gpio_in_idx[i] < MAX_GPIOCHIP_LINES) {
offset = gpio_in_idx[i];
if (gpio_idx < MAX_GPIOCHIP_LINES) {
offset = gpio_idx;
chipidx = 0;
} else {
offset = gpio_in_idx[i] - MAX_GPIOCHIP_LINES;
offset = gpio_idx - MAX_GPIOCHIP_LINES;
chipidx = 1;
}

View File

@@ -8,7 +8,7 @@
#include "manager.h"
int gpio_init(struct EG25Manager *state, toml_table_t *config);
int gpio_init(struct EG25Manager *state, toml_table_t *config[]);
void gpio_destroy(struct EG25Manager *state);
int gpio_sequence_poweron(struct EG25Manager *state);

View File

@@ -5,6 +5,7 @@
*/
#include "at.h"
#include "config.h"
#include "gpio.h"
#include "manager.h"
@@ -33,6 +34,8 @@
#define EG25_DATADIR "/usr/share/eg25-manager"
#endif
#define POWERON_DELAY_US 100000UL
static gboolean quit_app(struct EG25Manager *manager)
{
int i;
@@ -151,7 +154,7 @@ void modem_reset(struct EG25Manager *manager)
* TODO: Improve ofono plugin and add support for fetching USB ID
*/
if (manager->modem_iface != MODEM_IFACE_MODEMMANAGER)
return;
return;
if (manager->modem_recovery_timer) {
g_source_remove(manager->modem_recovery_timer);
@@ -225,7 +228,7 @@ void modem_resume_post(struct EG25Manager *manager)
at_sequence_resume(manager);
}
static toml_table_t *parse_config_file(char *config_file)
static toml_table_t *parse_config_file(char *config_file, gboolean force_default)
{
toml_table_t *toml_config;
gchar *compatible;
@@ -249,28 +252,26 @@ static toml_table_t *parse_config_file(char *config_file)
} 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));
g_autofree gchar *filename = NULL;
if (force_default)
filename = g_strdup_printf(EG25_DATADIR "/%s.toml", (gchar *)g_ptr_array_index(compat, pos));
else
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!");
if (!f) {
if (force_default)
g_error("unable to find a suitable config file!");
else
return NULL;
}
toml_config = toml_parse_file(f, error, sizeof(error));
if (!toml_config)
@@ -285,9 +286,8 @@ int main(int argc, char *argv[])
g_autoptr(GError) err = NULL;
struct EG25Manager manager;
gchar *config_file = NULL;
toml_table_t *toml_config;
toml_table_t *toml_manager;
toml_datum_t toml_value;
toml_table_t *toml_config[EG25_CONFIG_COUNT];
toml_table_t *manager_config[EG25_CONFIG_COUNT];
const GOptionEntry options[] = {
{ "config", 'c', 0, G_OPTION_ARG_STRING, &config_file, "Config file to use.", NULL },
{ NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL }
@@ -295,6 +295,7 @@ int main(int argc, char *argv[])
memset(&manager, 0, sizeof(manager));
manager.at_fd = -1;
manager.poweron_delay = POWERON_DELAY_US;
manager.suspend_delay_fd = -1;
manager.suspend_block_fd = -1;
@@ -307,43 +308,46 @@ int main(int argc, char *argv[])
manager.loop = g_main_loop_new(NULL, FALSE);
toml_config = parse_config_file(config_file);
toml_config[EG25_CONFIG_SYS] = parse_config_file(NULL, TRUE);
toml_config[EG25_CONFIG_USER] = parse_config_file(config_file, FALSE);
toml_manager = toml_table_in(toml_config, "manager");
if (toml_manager) {
toml_value = toml_bool_in(toml_manager, "need_libusb");
if (toml_value.ok)
manager.use_libusb = toml_value.u.b;
toml_value = toml_int_in(toml_manager, "usb_vid");
if (toml_value.ok)
manager.usb_vid = toml_value.u.i;
toml_value = toml_int_in(toml_manager, "usb_pid");
if (toml_value.ok)
manager.usb_pid = toml_value.u.i;
toml_value = toml_int_in(toml_manager, "poweron_delay");
if (toml_value.ok) {
if (toml_value.u.i >= 0 && toml_value.u.i <= G_MAXULONG) {
// Safe to cast into gulong
manager.poweron_delay = (gulong) toml_value.u.i;
} else {
// Changed from initialized default value but not in range
g_message("Configured poweron_delay out of range, using default");
}
}
/*
* We need at least one valid config file, and assuming it's
* EG25_CONFIG_SYS will make the rest easier to implement
*/
if (!toml_config[EG25_CONFIG_SYS] && toml_config[EG25_CONFIG_USER]) {
toml_config[EG25_CONFIG_SYS] = toml_config[EG25_CONFIG_USER];
toml_config[EG25_CONFIG_USER] = NULL;
}
at_init(&manager, toml_table_in(toml_config, "at"));
gpio_init(&manager, toml_table_in(toml_config, "gpio"));
if (!toml_config[EG25_CONFIG_SYS])
g_error("Unable to parse config file!");
for (int i = 0; i < EG25_CONFIG_COUNT; i++)
manager_config[i] = toml_config[i] ? toml_table_in(toml_config[i], "manager") : NULL;
if (!manager_config[EG25_CONFIG_SYS])
g_error("Default config file lacks the 'manager' section!");
config_get_bool(manager_config, "need_libusb", &manager.use_libusb);
config_get_uint(manager_config, "usb_vid", &manager.usb_vid);
config_get_uint(manager_config, "usb_pid", &manager.usb_pid);
config_get_uint(manager_config, "poweron_delay", &manager.poweron_delay);
at_init(&manager, toml_config);
gpio_init(&manager, toml_config);
#ifdef HAVE_MMGLIB
mm_iface_init(&manager, toml_table_in(toml_config, "mm-iface"));
mm_iface_init(&manager, toml_config);
#endif
ofono_iface_init(&manager);
suspend_init(&manager, toml_table_in(toml_config, "suspend"));
udev_init(&manager, toml_table_in(toml_config, "udev"));
gnss_init(&manager, toml_table_in(toml_config, "gnss"));
ofono_iface_init(&manager, toml_config);
suspend_init(&manager, toml_config);
udev_init(&manager, toml_config);
gnss_init(&manager, toml_config);
for (int i = 0; i < EG25_CONFIG_COUNT; i++) {
if (toml_config[i])
toml_free(toml_config[i]);
}
g_idle_add(G_SOURCE_FUNC(modem_start), &manager);

View File

@@ -62,13 +62,19 @@ enum ModemIface {
MODEM_IFACE_OFONO
};
enum EG25Config {
EG25_CONFIG_SYS = 0,
EG25_CONFIG_USER,
EG25_CONFIG_COUNT
};
struct EG25Manager {
GMainLoop *loop;
guint reset_timer;
gboolean use_libusb;
guint usb_vid;
guint usb_pid;
gulong poweron_delay;
guint poweron_delay;
int at_fd;
guint at_source;

View File

@@ -9,6 +9,7 @@ subdir('libgdbofono')
src = [
'at.c', 'at.h',
'config.c', 'config.h',
'gpio.c', 'gpio.h',
'manager.c', 'manager.h',
'ofono-iface.c', 'ofono-iface.h',

View File

@@ -209,7 +209,7 @@ static void mm_vanished_cb(GDBusConnection *connection,
mm_iface_clean(manager);
}
void mm_iface_init(struct EG25Manager *manager, toml_table_t *config)
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,
G_BUS_NAME_WATCHER_FLAGS_AUTO_START,

View File

@@ -8,5 +8,5 @@
#include "manager.h"
void mm_iface_init(struct EG25Manager *data, toml_table_t *config);
void mm_iface_init(struct EG25Manager *data, toml_table_t *config[]);
void mm_iface_destroy(struct EG25Manager *data);

View File

@@ -128,7 +128,7 @@ static void ofono_vanished_cb(GDBusConnection *connection,
}
}
void ofono_iface_init(struct EG25Manager *manager)
void ofono_iface_init(struct EG25Manager *manager, toml_table_t *config[])
{
manager->ofono_watch = g_bus_watch_name(G_BUS_TYPE_SYSTEM, OFONO_SERVICE,
G_BUS_NAME_WATCHER_FLAGS_AUTO_START,

View File

@@ -8,5 +8,5 @@
#include "manager.h"
void ofono_iface_init(struct EG25Manager *data);
void ofono_iface_init(struct EG25Manager *data, toml_table_t *config[]);
void ofono_iface_destroy(struct EG25Manager *data);

View File

@@ -9,6 +9,7 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "config.h"
#include "manager.h"
#include <gio/gunixfdlist.h>
@@ -172,7 +173,7 @@ static void signal_cb(GDBusProxy *proxy,
modem_resume_pre(manager);
if (
#ifdef HAVE_MMGLIB
manager->mm_modem ||
manager->mm_modem ||
#endif
manager->modem_iface == MODEM_IFACE_OFONO) {
/*
@@ -238,18 +239,26 @@ static void on_proxy_acquired(GObject *object,
}
}
void suspend_init(struct EG25Manager *manager, toml_table_t *config)
void suspend_init(struct EG25Manager *manager, toml_table_t *config[])
{
toml_datum_t timeout_value;
toml_table_t *suspend_config[EG25_CONFIG_COUNT];
if (config) {
timeout_value = toml_int_in(config, "boot_timeout");
if (timeout_value.ok)
manager->modem_boot_timeout = (guint)timeout_value.u.i;
for (int i = 0; i < EG25_CONFIG_COUNT; i++)
suspend_config[i] = config[i] ? toml_table_in(config[i], "suspend") : NULL;
timeout_value = toml_int_in(config, "recovery_timeout");
if (timeout_value.ok)
manager->modem_recovery_timeout = (guint)timeout_value.u.i;
/*
* The `suspend` section is optional in both the user and system config files,
* so let's make sure suspend_config[EG25_CONFIG_SYS] is valid if one of the
* files has it.
*/
if (suspend_config[EG25_CONFIG_USER] && !suspend_config[EG25_CONFIG_SYS]) {
suspend_config[EG25_CONFIG_SYS] = suspend_config[EG25_CONFIG_USER];
suspend_config[EG25_CONFIG_USER] = NULL;
}
if (suspend_config[EG25_CONFIG_SYS]) {
config_get_uint(suspend_config, "boot_timeout", &manager->modem_boot_timeout);
config_get_uint(suspend_config, "recovery_timeout", &manager->modem_recovery_timeout);
}
if (manager->modem_boot_timeout == 0)

View File

@@ -8,7 +8,7 @@
#include "manager.h"
void suspend_init (struct EG25Manager *data, toml_table_t *config);
void suspend_init (struct EG25Manager *data, toml_table_t *config[]);
void suspend_destroy (struct EG25Manager *data);
void suspend_inhibit (struct EG25Manager *data, gboolean inhibit, gboolean block);

View File

@@ -25,7 +25,7 @@ static void udev_event_cb(GUdevClient *client, gchar *action, GUdevDevice *devic
}
}
void udev_init (struct EG25Manager *manager, toml_table_t *config)
void udev_init (struct EG25Manager *manager, toml_table_t *config[])
{
const char * const subsystems[] = { "usb", NULL };

View File

@@ -8,5 +8,5 @@
#include "manager.h"
void udev_init (struct EG25Manager *data, toml_table_t *config);
void udev_init (struct EG25Manager *data, toml_table_t *config[]);
void udev_destroy (struct EG25Manager *data);