iface-port-at: new interface exposing AT command/response support

For now implemented in a generic way by the MMPortSerialAt object.
This commit is contained in:
Aleksander Morgado
2024-04-23 07:25:12 +00:00
committed by Aleksander Morgado
parent 11c2f7c068
commit fcfa917740
4 changed files with 224 additions and 2 deletions
+3 -1
View File
@@ -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
endif
+104
View File
@@ -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;
}
+71
View File
@@ -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 */
+46 -1
View File
@@ -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,
@@ -587,6 +624,14 @@ finalize (GObject *object)
G_OBJECT_CLASS (mm_port_serial_at_parent_class)->finalize (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)
{