dispatcher-fcc-unlock: inherit from the base dispatcher object
This commit is contained in:
@@ -315,8 +315,8 @@ ModemManager_SOURCES = \
|
||||
mm-auth-provider.c \
|
||||
mm-dispatcher.h \
|
||||
mm-dispatcher.c \
|
||||
mm-fcc-unlock-dispatcher.h \
|
||||
mm-fcc-unlock-dispatcher.c \
|
||||
mm-dispatcher-fcc-unlock.h \
|
||||
mm-dispatcher-fcc-unlock.c \
|
||||
mm-filter.h \
|
||||
mm-filter.c \
|
||||
mm-base-manager.c \
|
||||
|
@@ -201,7 +201,7 @@ sources = files(
|
||||
'mm-context.c',
|
||||
'mm-device.c',
|
||||
'mm-dispatcher.c',
|
||||
'mm-fcc-unlock-dispatcher.c',
|
||||
'mm-dispatcher-fcc-unlock.c',
|
||||
'mm-filter.c',
|
||||
'mm-iface-modem-3gpp.c',
|
||||
'mm-iface-modem-3gpp-profile-manager.c',
|
||||
|
149
src/mm-dispatcher-fcc-unlock.c
Normal file
149
src/mm-dispatcher-fcc-unlock.c
Normal file
@@ -0,0 +1,149 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details:
|
||||
*
|
||||
* Copyright (C) 2021-2022 Aleksander Morgado <aleksander@aleksander.es>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <ModemManager.h>
|
||||
#include "mm-errors-types.h"
|
||||
#include "mm-utils.h"
|
||||
#include "mm-log-object.h"
|
||||
#include "mm-dispatcher-fcc-unlock.h"
|
||||
|
||||
#if !defined FCCUNLOCKDIRPACKAGE
|
||||
# error FCCUNLOCKDIRPACKAGE must be defined at build time
|
||||
#endif
|
||||
|
||||
#if !defined FCCUNLOCKDIRUSER
|
||||
# error FCCUNLOCKDIRUSER must be defined at build time
|
||||
#endif
|
||||
|
||||
#define OPERATION_DESCRIPTION "fcc unlock"
|
||||
|
||||
/* Maximum time a FCC unlock command is allowed to run before
|
||||
* us killing it */
|
||||
#define MAX_FCC_UNLOCK_EXEC_TIME_SECS 5
|
||||
|
||||
struct _MMDispatcherFccUnlock {
|
||||
MMDispatcher parent;
|
||||
};
|
||||
|
||||
struct _MMDispatcherFccUnlockClass {
|
||||
MMDispatcherClass parent;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MMDispatcherFccUnlock, mm_dispatcher_fcc_unlock, MM_TYPE_DISPATCHER)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
gboolean
|
||||
mm_dispatcher_fcc_unlock_run_finish (MMDispatcherFccUnlock *self,
|
||||
GAsyncResult *res,
|
||||
GError **error)
|
||||
{
|
||||
return g_task_propagate_boolean (G_TASK (res), error);
|
||||
}
|
||||
|
||||
static void
|
||||
dispatcher_run_ready (MMDispatcher *self,
|
||||
GAsyncResult *res,
|
||||
GTask *task)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if (!mm_dispatcher_run_finish (self, res, &error))
|
||||
g_task_return_error (task, error);
|
||||
else
|
||||
g_task_return_boolean (task, TRUE);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
void
|
||||
mm_dispatcher_fcc_unlock_run (MMDispatcherFccUnlock *self,
|
||||
guint vid,
|
||||
guint pid,
|
||||
const gchar *modem_dbus_path,
|
||||
const GStrv modem_ports,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GTask *task;
|
||||
guint i;
|
||||
g_autofree gchar *filename = NULL;
|
||||
const gchar *enabled_dirs[] = {
|
||||
FCCUNLOCKDIRUSER, /* sysconfdir */
|
||||
FCCUNLOCKDIRPACKAGE, /* libdir */
|
||||
};
|
||||
|
||||
task = g_task_new (self, cancellable, callback, user_data);
|
||||
|
||||
filename = g_strdup_printf ("%04x:%04x", vid, pid);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (enabled_dirs); i++) {
|
||||
GPtrArray *aux;
|
||||
g_auto(GStrv) argv = NULL;
|
||||
g_autofree gchar *path = NULL;
|
||||
g_autoptr(GFile) file = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
guint j;
|
||||
|
||||
path = g_build_path (G_DIR_SEPARATOR_S, enabled_dirs[i], filename, NULL);
|
||||
file = g_file_new_for_path (path);
|
||||
|
||||
/* If file exists, we attempt to use it */
|
||||
if (!g_file_query_exists (file, cancellable)) {
|
||||
mm_obj_dbg (self, "Cannot run " OPERATION_DESCRIPTION " operation from %s: file doesn't exist", path);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* build argv */
|
||||
aux = g_ptr_array_new ();
|
||||
g_ptr_array_add (aux, g_steal_pointer (&path));
|
||||
g_ptr_array_add (aux, g_strdup (modem_dbus_path));
|
||||
for (j = 0; modem_ports && modem_ports[j]; j++)
|
||||
g_ptr_array_add (aux, g_strdup (modem_ports[j]));
|
||||
g_ptr_array_add (aux, NULL);
|
||||
argv = (GStrv) g_ptr_array_free (aux, FALSE);
|
||||
|
||||
/* run */
|
||||
mm_dispatcher_run (MM_DISPATCHER (self),
|
||||
argv,
|
||||
MAX_FCC_UNLOCK_EXEC_TIME_SECS,
|
||||
cancellable,
|
||||
(GAsyncReadyCallback) dispatcher_run_ready,
|
||||
task);
|
||||
return;
|
||||
}
|
||||
|
||||
g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
|
||||
OPERATION_DESCRIPTION " operation launch aborted: no valid program found");
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
mm_dispatcher_fcc_unlock_init (MMDispatcherFccUnlock *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
mm_dispatcher_fcc_unlock_class_init (MMDispatcherFccUnlockClass *class)
|
||||
{
|
||||
}
|
||||
|
||||
MM_DEFINE_SINGLETON_GETTER (MMDispatcherFccUnlock, mm_dispatcher_fcc_unlock_get, MM_TYPE_DISPATCHER_FCC_UNLOCK,
|
||||
MM_DISPATCHER_OPERATION_DESCRIPTION, OPERATION_DESCRIPTION)
|
49
src/mm-dispatcher-fcc-unlock.h
Normal file
49
src/mm-dispatcher-fcc-unlock.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details:
|
||||
*
|
||||
* Copyright (C) 2021-2022 Aleksander Morgado <aleksander@aleksander.es>
|
||||
*/
|
||||
|
||||
#ifndef MM_DISPATCHER_FCC_UNLOCK_H
|
||||
#define MM_DISPATCHER_FCC_UNLOCK_H
|
||||
|
||||
#include <config.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "mm-dispatcher.h"
|
||||
|
||||
#define MM_TYPE_DISPATCHER_FCC_UNLOCK (mm_dispatcher_fcc_unlock_get_type ())
|
||||
#define MM_DISPATCHER_FCC_UNLOCK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_DISPATCHER_FCC_UNLOCK, MMDispatcherFccUnlock))
|
||||
#define MM_DISPATCHER_FCC_UNLOCK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_DISPATCHER_FCC_UNLOCK, MMDispatcherFccUnlockClass))
|
||||
#define MM_IS_DISPATCHER_FCC_UNLOCK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_DISPATCHER_FCC_UNLOCK))
|
||||
#define MM_IS_DISPATCHER_FCC_UNLOCK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_DISPATCHER_FCC_UNLOCK))
|
||||
#define MM_DISPATCHER_FCC_UNLOCK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_DISPATCHER_FCC_UNLOCK, MMDispatcherFccUnlockClass))
|
||||
|
||||
typedef struct _MMDispatcherFccUnlock MMDispatcherFccUnlock;
|
||||
typedef struct _MMDispatcherFccUnlockClass MMDispatcherFccUnlockClass;
|
||||
typedef struct _MMDispatcherFccUnlockPrivate MMDispatcherFccUnlockPrivate;
|
||||
|
||||
GType mm_dispatcher_fcc_unlock_get_type (void);
|
||||
MMDispatcherFccUnlock *mm_dispatcher_fcc_unlock_get (void);
|
||||
void mm_dispatcher_fcc_unlock_run (MMDispatcherFccUnlock *self,
|
||||
guint vid,
|
||||
guint pid,
|
||||
const gchar *modem_dbus_path,
|
||||
const GStrv ports,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
gboolean mm_dispatcher_fcc_unlock_run_finish (MMDispatcherFccUnlock *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
|
||||
#endif /* MM_DISPATCHER_FCC_UNLOCK_H */
|
@@ -1,319 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details:
|
||||
*
|
||||
* Copyright (C) 2021 Aleksander Morgado <aleksander@aleksander.es>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <ModemManager.h>
|
||||
#include "mm-errors-types.h"
|
||||
#include "mm-utils.h"
|
||||
#include "mm-log-object.h"
|
||||
#include "mm-fcc-unlock-dispatcher.h"
|
||||
|
||||
#if !defined FCCUNLOCKDIRPACKAGE
|
||||
# error FCCUNLOCKDIRPACKAGE must be defined at build time
|
||||
#endif
|
||||
|
||||
#if !defined FCCUNLOCKDIRUSER
|
||||
# error FCCUNLOCKDIRUSER must be defined at build time
|
||||
#endif
|
||||
|
||||
/* Maximum time a FCC unlock command is allowed to run before
|
||||
* us killing it */
|
||||
#define MAX_FCC_UNLOCK_EXEC_TIME_SECS 5
|
||||
|
||||
struct _MMFccUnlockDispatcher {
|
||||
GObject parent;
|
||||
GSubprocessLauncher *launcher;
|
||||
};
|
||||
|
||||
struct _MMFccUnlockDispatcherClass {
|
||||
GObjectClass parent;
|
||||
};
|
||||
|
||||
static void log_object_iface_init (MMLogObjectInterface *iface);
|
||||
|
||||
G_DEFINE_TYPE_EXTENDED (MMFccUnlockDispatcher, mm_fcc_unlock_dispatcher, G_TYPE_OBJECT, 0,
|
||||
G_IMPLEMENT_INTERFACE (MM_TYPE_LOG_OBJECT, log_object_iface_init))
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static gchar *
|
||||
log_object_build_id (MMLogObject *_self)
|
||||
{
|
||||
return g_strdup ("fcc-unlock-dispatcher");
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
gchar *filename;
|
||||
GSubprocess *subprocess;
|
||||
guint timeout_id;
|
||||
} RunContext;
|
||||
|
||||
static void
|
||||
run_context_free (RunContext *ctx)
|
||||
{
|
||||
g_assert (!ctx->timeout_id);
|
||||
g_clear_object (&ctx->subprocess);
|
||||
g_free (ctx->filename);
|
||||
g_slice_free (RunContext, ctx);
|
||||
}
|
||||
|
||||
gboolean
|
||||
mm_fcc_unlock_dispatcher_run_finish (MMFccUnlockDispatcher *self,
|
||||
GAsyncResult *res,
|
||||
GError **error)
|
||||
{
|
||||
return g_task_propagate_boolean (G_TASK (res), error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
subprocess_wait_timed_out (GTask *task)
|
||||
{
|
||||
MMFccUnlockDispatcher *self;
|
||||
RunContext *ctx;
|
||||
|
||||
self = g_task_get_source_object (task);
|
||||
ctx = g_task_get_task_data (task);
|
||||
|
||||
mm_obj_warn (self, "forcing exit on %s FCC unlock operation", ctx->filename);
|
||||
g_subprocess_force_exit (ctx->subprocess);
|
||||
|
||||
ctx->timeout_id = 0;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
subprocess_wait_ready (GSubprocess *subprocess,
|
||||
GAsyncResult *res,
|
||||
GTask *task)
|
||||
{
|
||||
GError *error = NULL;
|
||||
RunContext *ctx;
|
||||
|
||||
/* cleanup timeout before any return */
|
||||
ctx = g_task_get_task_data (task);
|
||||
if (ctx->timeout_id) {
|
||||
g_source_remove (ctx->timeout_id);
|
||||
ctx->timeout_id = 0;
|
||||
}
|
||||
|
||||
if (!g_subprocess_wait_finish (subprocess, res, &error)) {
|
||||
g_prefix_error (&error, "FCC unlock operation wait failed: ");
|
||||
g_task_return_error (task, error);
|
||||
} else if (!g_subprocess_get_successful (subprocess)) {
|
||||
if (g_subprocess_get_if_signaled (subprocess))
|
||||
g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
|
||||
"FCC unlock operation aborted with signal %d",
|
||||
g_subprocess_get_term_sig (subprocess));
|
||||
else if (g_subprocess_get_if_exited (subprocess))
|
||||
g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
|
||||
"FCC unlock operation finished with status %d",
|
||||
g_subprocess_get_exit_status (subprocess));
|
||||
else
|
||||
g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
|
||||
"FCC unlock operation failed");
|
||||
} else
|
||||
g_task_return_boolean (task, TRUE);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
validate_file (const gchar *path,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(GFile) file = NULL;
|
||||
g_autoptr(GFileInfo) file_info = NULL;
|
||||
guint32 file_mode;
|
||||
guint32 file_uid;
|
||||
|
||||
file = g_file_new_for_path (path);
|
||||
file_info = g_file_query_info (file,
|
||||
(G_FILE_ATTRIBUTE_STANDARD_SIZE ","
|
||||
G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET ","
|
||||
G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK ","
|
||||
G_FILE_ATTRIBUTE_UNIX_MODE ","
|
||||
G_FILE_ATTRIBUTE_UNIX_UID),
|
||||
G_FILE_QUERY_INFO_NONE,
|
||||
NULL,
|
||||
error);
|
||||
if (!file_info)
|
||||
return FALSE;
|
||||
|
||||
if (g_file_info_get_is_symlink (file_info)) {
|
||||
const gchar *link_target;
|
||||
|
||||
link_target = g_file_info_get_symlink_target (file_info);
|
||||
if (g_strcmp0 (link_target, "/dev/null") == 0) {
|
||||
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_ABORTED,
|
||||
"Link '%s' to /dev/null is not executable", path);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_file_info_get_size (file_info) == 0) {
|
||||
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_ABORTED,
|
||||
"File '%s' is empty", path);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
file_uid = g_file_info_get_attribute_uint32 (file_info, G_FILE_ATTRIBUTE_UNIX_UID);
|
||||
if (file_uid != 0) {
|
||||
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_ABORTED,
|
||||
"File '%s' not owned by root", path);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
file_mode = g_file_info_get_attribute_uint32 (file_info, G_FILE_ATTRIBUTE_UNIX_MODE);
|
||||
if (!S_ISREG (file_mode)) {
|
||||
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_ABORTED,
|
||||
"File '%s' is not regular", path);
|
||||
return FALSE;
|
||||
}
|
||||
if (file_mode & (S_IWGRP | S_IWOTH)) {
|
||||
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_ABORTED,
|
||||
"File '%s' is writable by group or other", path);
|
||||
return FALSE;
|
||||
}
|
||||
if (file_mode & S_ISUID) {
|
||||
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_ABORTED,
|
||||
"File '%s' is set-UID", path);
|
||||
return FALSE;
|
||||
}
|
||||
if (!(file_mode & S_IXUSR)) {
|
||||
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_ABORTED,
|
||||
"File '%s' is not executable by the owner", path);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
mm_fcc_unlock_dispatcher_run (MMFccUnlockDispatcher *self,
|
||||
guint vid,
|
||||
guint pid,
|
||||
const gchar *modem_dbus_path,
|
||||
const GStrv modem_ports,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GTask *task;
|
||||
RunContext *ctx;
|
||||
guint i;
|
||||
const gchar *enabled_dirs[] = {
|
||||
FCCUNLOCKDIRUSER, /* sysconfdir */
|
||||
FCCUNLOCKDIRPACKAGE, /* libdir */
|
||||
};
|
||||
|
||||
task = g_task_new (self, cancellable, callback, user_data);
|
||||
ctx = g_slice_new0 (RunContext);
|
||||
g_task_set_task_data (task, ctx, (GDestroyNotify) run_context_free);
|
||||
|
||||
ctx->filename = g_strdup_printf ("%04x:%04x", vid, pid);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (enabled_dirs); i++) {
|
||||
GPtrArray *aux;
|
||||
g_auto(GStrv) argv = NULL;
|
||||
g_autofree gchar *path = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
guint j;
|
||||
|
||||
path = g_build_path (G_DIR_SEPARATOR_S, enabled_dirs[i], ctx->filename, NULL);
|
||||
|
||||
/* Validation checks to see if we should run it or not */
|
||||
if (!validate_file (path, &error)) {
|
||||
mm_obj_dbg (self, "Cannot run FCC unlock operation from %s: %s",
|
||||
path, error->message);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* build argv */
|
||||
aux = g_ptr_array_new ();
|
||||
g_ptr_array_add (aux, g_steal_pointer (&path));
|
||||
g_ptr_array_add (aux, g_strdup (modem_dbus_path));
|
||||
for (j = 0; modem_ports && modem_ports[j]; j++)
|
||||
g_ptr_array_add (aux, g_strdup (modem_ports[j]));
|
||||
g_ptr_array_add (aux, NULL);
|
||||
argv = (GStrv) g_ptr_array_free (aux, FALSE);
|
||||
|
||||
/* create and launch subprocess */
|
||||
ctx->subprocess = g_subprocess_launcher_spawnv (self->launcher,
|
||||
(const gchar * const *)argv,
|
||||
&error);
|
||||
if (!ctx->subprocess) {
|
||||
g_prefix_error (&error, "FCC unlock operation launch from %s failed: ", path);
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
/* setup timeout */
|
||||
ctx->timeout_id = g_timeout_add_seconds (MAX_FCC_UNLOCK_EXEC_TIME_SECS,
|
||||
(GSourceFunc)subprocess_wait_timed_out,
|
||||
task);
|
||||
|
||||
/* wait for subprocess exit */
|
||||
g_subprocess_wait_async (ctx->subprocess,
|
||||
cancellable,
|
||||
(GAsyncReadyCallback)subprocess_wait_ready,
|
||||
task);
|
||||
return;
|
||||
}
|
||||
|
||||
g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
|
||||
"FCC unlock operation launch aborted: no valid program found");
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
mm_fcc_unlock_dispatcher_init (MMFccUnlockDispatcher *self)
|
||||
{
|
||||
self->launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDOUT_SILENCE | G_SUBPROCESS_FLAGS_STDERR_SILENCE);
|
||||
|
||||
/* inherit parent's environment */
|
||||
g_subprocess_launcher_set_environ (self->launcher, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
dispose (GObject *object)
|
||||
{
|
||||
MMFccUnlockDispatcher *self = MM_FCC_UNLOCK_DISPATCHER (object);
|
||||
|
||||
g_clear_object (&self->launcher);
|
||||
|
||||
G_OBJECT_CLASS (mm_fcc_unlock_dispatcher_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
log_object_iface_init (MMLogObjectInterface *iface)
|
||||
{
|
||||
iface->build_id = log_object_build_id;
|
||||
}
|
||||
|
||||
static void
|
||||
mm_fcc_unlock_dispatcher_class_init (MMFccUnlockDispatcherClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->dispose = dispose;
|
||||
}
|
||||
|
||||
MM_DEFINE_SINGLETON_GETTER (MMFccUnlockDispatcher, mm_fcc_unlock_dispatcher_get, MM_TYPE_FCC_UNLOCK_DISPATCHER)
|
@@ -1,47 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details:
|
||||
*
|
||||
* Copyright (C) 2021 Aleksander Morgado <aleksander@aleksander.es>
|
||||
*/
|
||||
|
||||
#ifndef MM_FCC_UNLOCK_DISPATCHER_H
|
||||
#define MM_FCC_UNLOCK_DISPATCHER_H
|
||||
|
||||
#include <config.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#define MM_TYPE_FCC_UNLOCK_DISPATCHER (mm_fcc_unlock_dispatcher_get_type ())
|
||||
#define MM_FCC_UNLOCK_DISPATCHER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_FCC_UNLOCK_DISPATCHER, MMFccUnlockDispatcher))
|
||||
#define MM_FCC_UNLOCK_DISPATCHER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_FCC_UNLOCK_DISPATCHER, MMFccUnlockDispatcherClass))
|
||||
#define MM_IS_FCC_UNLOCK_DISPATCHER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_FCC_UNLOCK_DISPATCHER))
|
||||
#define MM_IS_FCC_UNLOCK_DISPATCHER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_FCC_UNLOCK_DISPATCHER))
|
||||
#define MM_FCC_UNLOCK_DISPATCHER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_FCC_UNLOCK_DISPATCHER, MMFccUnlockDispatcherClass))
|
||||
|
||||
typedef struct _MMFccUnlockDispatcher MMFccUnlockDispatcher;
|
||||
typedef struct _MMFccUnlockDispatcherClass MMFccUnlockDispatcherClass;
|
||||
typedef struct _MMFccUnlockDispatcherPrivate MMFccUnlockDispatcherPrivate;
|
||||
|
||||
GType mm_fcc_unlock_dispatcher_get_type (void);
|
||||
MMFccUnlockDispatcher *mm_fcc_unlock_dispatcher_get (void);
|
||||
void mm_fcc_unlock_dispatcher_run (MMFccUnlockDispatcher *self,
|
||||
guint vid,
|
||||
guint pid,
|
||||
const gchar *modem_dbus_path,
|
||||
const GStrv ports,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
gboolean mm_fcc_unlock_dispatcher_run_finish (MMFccUnlockDispatcher *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
|
||||
#endif /* MM_FCC_UNLOCK_DISPATCHER_H */
|
@@ -28,7 +28,7 @@
|
||||
#include "mm-private-boxed-types.h"
|
||||
#include "mm-log-object.h"
|
||||
#include "mm-context.h"
|
||||
#include "mm-fcc-unlock-dispatcher.h"
|
||||
#include "mm-dispatcher-fcc-unlock.h"
|
||||
#if defined WITH_QMI
|
||||
# include "mm-broadband-modem-qmi.h"
|
||||
#endif
|
||||
@@ -3954,7 +3954,7 @@ modem_after_power_up_ready (MMIfaceModem *self,
|
||||
}
|
||||
|
||||
static void
|
||||
fcc_unlock_dispatcher_ready (MMFccUnlockDispatcher *dispatcher,
|
||||
dispatcher_fcc_unlock_ready (MMDispatcherFccUnlock *dispatcher,
|
||||
GAsyncResult *res,
|
||||
GTask *task)
|
||||
{
|
||||
@@ -3965,7 +3965,7 @@ fcc_unlock_dispatcher_ready (MMFccUnlockDispatcher *dispatcher,
|
||||
self = g_task_get_source_object (task);
|
||||
ctx = g_task_get_task_data (task);
|
||||
|
||||
if (!mm_fcc_unlock_dispatcher_run_finish (dispatcher, res, &error))
|
||||
if (!mm_dispatcher_fcc_unlock_run_finish (dispatcher, res, &error))
|
||||
mm_obj_dbg (self, "couldn't run FCC unlock: %s", error->message);
|
||||
|
||||
/* always retry, even on reported error */
|
||||
@@ -3977,7 +3977,7 @@ static void
|
||||
fcc_unlock (GTask *task)
|
||||
{
|
||||
MMIfaceModem *self;
|
||||
MMFccUnlockDispatcher *dispatcher;
|
||||
MMDispatcherFccUnlock *dispatcher;
|
||||
MMModemPortInfo *port_infos;
|
||||
guint n_port_infos = 0;
|
||||
guint i;
|
||||
@@ -3986,7 +3986,7 @@ fcc_unlock (GTask *task)
|
||||
|
||||
self = g_task_get_source_object (task);
|
||||
|
||||
dispatcher = mm_fcc_unlock_dispatcher_get ();
|
||||
dispatcher = mm_dispatcher_fcc_unlock_get ();
|
||||
|
||||
aux = g_ptr_array_new ();
|
||||
port_infos = mm_base_modem_get_port_infos (MM_BASE_MODEM (self), &n_port_infos);
|
||||
@@ -4011,13 +4011,13 @@ fcc_unlock (GTask *task)
|
||||
g_ptr_array_add (aux, NULL);
|
||||
modem_ports = (GStrv) g_ptr_array_free (aux, FALSE);
|
||||
|
||||
mm_fcc_unlock_dispatcher_run (dispatcher,
|
||||
mm_dispatcher_fcc_unlock_run (dispatcher,
|
||||
mm_base_modem_get_vendor_id (MM_BASE_MODEM (self)),
|
||||
mm_base_modem_get_product_id (MM_BASE_MODEM (self)),
|
||||
g_dbus_object_get_object_path (G_DBUS_OBJECT (self)),
|
||||
modem_ports,
|
||||
g_task_get_cancellable (task),
|
||||
(GAsyncReadyCallback)fcc_unlock_dispatcher_ready,
|
||||
(GAsyncReadyCallback)dispatcher_fcc_unlock_ready,
|
||||
task);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user