mirror of
https://gitlab.com/mobian1/eg25-manager.git
synced 2025-08-30 07:42:23 +02:00
When going into firmware upgrade mode, the modem comes back with different IDs than in normal use. We should make sure we cancel the reset sequence when that happens, and not start a new one.
74 lines
2.1 KiB
C
74 lines
2.1 KiB
C
/*
|
|
* Copyright (C) 2020 Arnaud Ferraris <arnaud.ferraris@gmail.com>
|
|
*
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
*/
|
|
|
|
#include "udev.h"
|
|
|
|
#include <string.h>
|
|
|
|
static void udev_event_cb(GUdevClient *client, gchar *action, GUdevDevice *device, gpointer data)
|
|
{
|
|
struct EG25Manager *manager = data;
|
|
const gchar *prop;
|
|
long vid = 0, pid = 0;
|
|
|
|
/*
|
|
* Act only if the device is the one identified as a modem by MM/ofono
|
|
*/
|
|
if (!manager->modem_usb_id ||
|
|
strcmp(g_udev_device_get_name(device), manager->modem_usb_id) != 0) {
|
|
return;
|
|
}
|
|
|
|
prop = g_udev_device_get_property(device, "ID_VENDOR_ID");
|
|
if (prop)
|
|
vid = strtol(prop, NULL, 16);
|
|
|
|
prop = g_udev_device_get_property(device, "ID_MODEL_ID");
|
|
if (prop)
|
|
pid = strtol(prop, NULL, 16);
|
|
|
|
if (strcmp(action, "bind") == 0 && vid != manager->usb_vid && pid != manager->usb_pid) {
|
|
/*
|
|
* Modem is probably executing a FW upgrade, make sure we don't interrupt it
|
|
*/
|
|
if (manager->schedule_reset_timer != 0) {
|
|
g_message("Modem re-appeared with different VID/PID, cancel reset.");
|
|
g_source_remove(manager->schedule_reset_timer);
|
|
manager->schedule_reset_timer = 0;
|
|
}
|
|
manager->modem_state = EG25_STATE_UPDATING;
|
|
}
|
|
|
|
if (strcmp(action, "unbind") != 0 ||
|
|
manager->modem_state == EG25_STATE_UPDATING ||
|
|
manager->modem_state == EG25_STATE_RESETTING ||
|
|
manager->complete_reset_timer != 0 ||
|
|
manager->schedule_reset_timer != 0) {
|
|
return;
|
|
}
|
|
|
|
g_message("Lost modem, resetting...");
|
|
manager->schedule_reset_timer = g_timeout_add_seconds(3, G_SOURCE_FUNC(modem_reset), manager);
|
|
}
|
|
|
|
void udev_init (struct EG25Manager *manager, toml_table_t *config[])
|
|
{
|
|
const char * const subsystems[] = { "usb", NULL };
|
|
|
|
manager->udev = g_udev_client_new(subsystems);
|
|
g_signal_connect(manager->udev, "uevent", G_CALLBACK(udev_event_cb), manager);
|
|
|
|
return;
|
|
}
|
|
|
|
void udev_destroy (struct EG25Manager *manager)
|
|
{
|
|
if (manager->udev) {
|
|
g_object_unref(manager->udev);
|
|
manager->udev = NULL;
|
|
}
|
|
}
|