aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAleksander Morgado <aleksandermj@chromium.org>2024-03-25 14:46:39 +0000
committerAleksander Morgado <aleksander@aleksander.es>2024-04-23 07:25:12 +0000
commitfcfa9177400654db3e718e01cc5e9ebcfa000fff (patch)
tree669de9622bd878499589038b5e73c68ceb4b0933 /src
parent11c2f7c068663071fe0777662857819148fb2042 (diff)
iface-port-at: new interface exposing AT command/response support
For now implemented in a generic way by the MMPortSerialAt object.
Diffstat (limited to 'src')
-rw-r--r--src/meson.build4
-rw-r--r--src/mm-iface-port-at.c104
-rw-r--r--src/mm-iface-port-at.h71
-rw-r--r--src/mm-port-serial-at.c47
4 files changed, 224 insertions, 2 deletions
diff --git a/src/meson.build b/src/meson.build
index f3a6218f..21ae576e 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -130,11 +130,13 @@ libkerneldevice_dep = declare_dependency(
# ports library
headers = files(
+ 'mm-iface-port-at.h',
'mm-port.h',
'mm-port-serial-at.h',
)
sources = files(
+ 'mm-iface-port-at.c',
'mm-netlink.c',
'mm-port.c',
'mm-port-net.c',
@@ -389,4 +391,4 @@ install_data(
if enable_tests
subdir('tests')
-endif \ No newline at end of file
+endif
diff --git a/src/mm-iface-port-at.c b/src/mm-iface-port-at.c
new file mode 100644
index 00000000..4a21cd9f
--- /dev/null
+++ b/src/mm-iface-port-at.c
@@ -0,0 +1,104 @@
+/* -*- 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) 2024 Google, Inc.
+ */
+
+#include <ModemManager.h>
+#define _LIBMM_INSIDE_MM
+#include <libmm-glib.h>
+
+#include "mm-port.h"
+#include "mm-iface-port-at.h"
+#include "mm-log-object.h"
+
+/*****************************************************************************/
+
+gboolean
+mm_iface_port_at_check_support (MMIfacePortAt *self,
+ gboolean *out_supported,
+ GError **error)
+{
+ g_assert (out_supported);
+
+ /* If the object implementing the interface doesn't provide a check_support() method,
+ * we assume the feature is unconditionally supported. */
+ if (!MM_IFACE_PORT_AT_GET_INTERFACE (self)->check_support) {
+ *out_supported = TRUE;
+ return TRUE;
+ }
+
+ return MM_IFACE_PORT_AT_GET_INTERFACE (self)->check_support (self, out_supported, error);
+}
+
+/*****************************************************************************/
+
+gchar *
+mm_iface_port_at_command_finish (MMIfacePortAt *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return MM_IFACE_PORT_AT_GET_INTERFACE (self)->command_finish (self, res, error);
+}
+
+void
+mm_iface_port_at_command (MMIfacePortAt *self,
+ const gchar *command,
+ guint32 timeout_seconds,
+ gboolean is_raw,
+ gboolean allow_cached,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_assert (MM_IFACE_PORT_AT_GET_INTERFACE (self)->command);
+ g_assert (MM_IFACE_PORT_AT_GET_INTERFACE (self)->command_finish);
+
+ MM_IFACE_PORT_AT_GET_INTERFACE (self)->command (self,
+ command,
+ timeout_seconds,
+ is_raw,
+ allow_cached,
+ cancellable,
+ callback,
+ user_data);
+}
+
+/*****************************************************************************/
+
+static void
+iface_port_at_init (gpointer g_iface)
+{
+}
+
+GType
+mm_iface_port_at_get_type (void)
+{
+ static GType iface_port_at_type = 0;
+
+ if (!G_UNLIKELY (iface_port_at_type)) {
+ static const GTypeInfo info = {
+ sizeof (MMIfacePortAt), /* class_size */
+ iface_port_at_init, /* base_init */
+ NULL, /* base_finalize */
+ };
+
+ iface_port_at_type = g_type_register_static (G_TYPE_INTERFACE,
+ "MMIfacePortAt",
+ &info,
+ 0);
+
+ g_type_interface_add_prerequisite (iface_port_at_type, MM_TYPE_PORT);
+ }
+
+ return iface_port_at_type;
+}
diff --git a/src/mm-iface-port-at.h b/src/mm-iface-port-at.h
new file mode 100644
index 00000000..afcc86dc
--- /dev/null
+++ b/src/mm-iface-port-at.h
@@ -0,0 +1,71 @@
+/* -*- 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) 2024 Google, Inc.
+ */
+
+#ifndef MM_IFACE_PORT_AT_H
+#define MM_IFACE_PORT_AT_H
+
+#include <glib-object.h>
+#include <gio/gio.h>
+
+#define _LIBMM_INSIDE_MM
+#include <libmm-glib.h>
+
+#define MM_TYPE_IFACE_PORT_AT (mm_iface_port_at_get_type ())
+#define MM_IFACE_PORT_AT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_IFACE_PORT_AT, MMIfacePortAt))
+#define MM_IS_IFACE_PORT_AT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_IFACE_PORT_AT))
+#define MM_IFACE_PORT_AT_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), MM_TYPE_IFACE_PORT_AT, MMIfacePortAt))
+
+typedef struct _MMIfacePortAt MMIfacePortAt;
+
+struct _MMIfacePortAt {
+ GTypeInterface g_iface;
+
+ gboolean (* check_support) (MMIfacePortAt *self,
+ gboolean *out_supported,
+ GError **error);
+
+ void (* command) (MMIfacePortAt *self,
+ const gchar *command,
+ guint32 timeout_seconds,
+ gboolean is_raw,
+ gboolean allow_cached,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gchar * (* command_finish) (MMIfacePortAt *self,
+ GAsyncResult *res,
+ GError **error);
+};
+
+GType mm_iface_port_at_get_type (void);
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (MMIfacePortAt, g_object_unref)
+
+gboolean mm_iface_port_at_check_support (MMIfacePortAt *self,
+ gboolean *out_supported,
+ GError **error);
+
+void mm_iface_port_at_command (MMIfacePortAt *self,
+ const gchar *command,
+ guint32 timeout_seconds,
+ gboolean is_raw,
+ gboolean allow_cached,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gchar *mm_iface_port_at_command_finish (MMIfacePortAt *self,
+ GAsyncResult *res,
+ GError **error);
+
+#endif /* MM_IFACE_PORT_AT_H */
diff --git a/src/mm-port-serial-at.c b/src/mm-port-serial-at.c
index 511503a9..bb714ece 100644
--- a/src/mm-port-serial-at.c
+++ b/src/mm-port-serial-at.c
@@ -21,10 +21,14 @@
#include <unistd.h>
#include <string.h>
+#include "mm-iface-port-at.h"
#include "mm-port-serial-at.h"
#include "mm-log-object.h"
-G_DEFINE_TYPE (MMPortSerialAt, mm_port_serial_at, MM_TYPE_PORT_SERIAL)
+static void iface_port_at_init (MMIfacePortAt *iface);
+
+G_DEFINE_TYPE_EXTENDED (MMPortSerialAt, mm_port_serial_at, MM_TYPE_PORT_SERIAL, 0,
+ G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_PORT_AT, iface_port_at_init))
enum {
PROP_0,
@@ -388,6 +392,39 @@ mm_port_serial_at_command (MMPortSerialAt *self,
g_byte_array_unref (buf);
}
+/*****************************************************************************/
+/* Integration with the Port AT interface */
+
+static gchar *
+iface_port_at_command_finish (MMIfacePortAt *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return mm_port_serial_at_command_finish (MM_PORT_SERIAL_AT (self), res, error);
+}
+
+static void
+iface_port_at_command (MMIfacePortAt *self,
+ const gchar *command,
+ guint32 timeout_seconds,
+ gboolean is_raw,
+ gboolean allow_cached,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ mm_port_serial_at_command (MM_PORT_SERIAL_AT (self),
+ command,
+ timeout_seconds,
+ is_raw,
+ allow_cached,
+ cancellable,
+ callback,
+ user_data);
+}
+
+/*****************************************************************************/
+
static void
debug_log (MMPortSerial *self,
const gchar *prefix,
@@ -588,6 +625,14 @@ finalize (GObject *object)
}
static void
+iface_port_at_init (MMIfacePortAt *iface)
+{
+ iface->check_support = NULL;
+ iface->command = iface_port_at_command;
+ iface->command_finish = iface_port_at_command_finish;
+}
+
+static void
mm_port_serial_at_class_init (MMPortSerialAtClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);