diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2021-08-30 15:42:51 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2021-09-08 11:21:45 +0200 |
commit | 86421f06bd28fb9613f3995984d798827174fb25 (patch) | |
tree | 4cd1b5e131ddcee518db30cb91f367859dce301d | |
parent | ccc7989324aec454cc0267cd133638569d28061b (diff) | |
download | ModemManager-86421f06bd28fb9613f3995984d798827174fb25.tar.gz |
examples: new SMS sending example in C using the async API
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | examples/sms-c/Makefile.am | 26 | ||||
-rw-r--r-- | examples/sms-c/sms-c-async.c | 197 |
3 files changed, 224 insertions, 2 deletions
diff --git a/.gitignore b/.gitignore index de1f0ff89..c54e466b5 100644 --- a/.gitignore +++ b/.gitignore @@ -181,6 +181,7 @@ Makefile.in /tools/tests/test-wrapper.sh /examples/sms-c/sms-c-sync +/examples/sms-c/sms-c-async /ModemManager-*-coverage.info -/ModemManager-*-coverage/
\ No newline at end of file +/ModemManager-*-coverage/ diff --git a/examples/sms-c/Makefile.am b/examples/sms-c/Makefile.am index d4fa4cc84..c8c3c9052 100644 --- a/examples/sms-c/Makefile.am +++ b/examples/sms-c/Makefile.am @@ -1,4 +1,4 @@ -noinst_PROGRAMS = sms-c-sync +noinst_PROGRAMS = sms-c-sync sms-c-async sms_c_sync_CPPFLAGS = \ $(WARN_CFLAGS) \ @@ -23,3 +23,27 @@ sms_c_sync_LDFLAGS = \ $(WARN_LDFLAGS) \ $(MMCLI_LIBS) \ $(NULL) + +sms_c_async_CPPFLAGS = \ + $(WARN_CFLAGS) \ + $(MMCLI_CFLAGS) \ + -I$(top_srcdir) \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/libmm-glib \ + -I${top_srcdir}/libmm-glib/generated \ + -I${top_builddir}/libmm-glib/generated \ + $(NULL) + +sms_c_async_SOURCES = \ + sms-c-async.c \ + $(NULL) + +sms_c_async_LDADD = \ + $(top_builddir)/libmm-glib/libmm-glib.la \ + $(NULL) + +sms_c_async_LDFLAGS = \ + $(WARN_LDFLAGS) \ + $(MMCLI_LIBS) \ + $(NULL) diff --git a/examples/sms-c/sms-c-async.c b/examples/sms-c/sms-c-async.c new file mode 100644 index 000000000..fd2d47eae --- /dev/null +++ b/examples/sms-c/sms-c-async.c @@ -0,0 +1,197 @@ +/* -*- 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Copyright (C) 2021 Aleksander Morgado <aleksander@aleksander.es> + */ + +#include "config.h" + +#include <stdio.h> +#include <stdlib.h> +#include <locale.h> +#include <string.h> + +#include <glib.h> +#include <gio/gio.h> + +#include <libmm-glib.h> + +typedef struct { + GMainLoop *loop; + GDBusConnection *connection; + MMManager *manager; + GList *objects; + MMSmsProperties *properties; + + MMObject *current_obj; + MMModemMessaging *current_messaging; + MMSms *current_sms; +} Context; + +static void send_sms_next (Context *context); + +static void +sms_send_ready (MMSms *sms, + GAsyncResult *res, + Context *context) +{ + g_autoptr(GError) error = NULL; + + if (!mm_sms_send_finish (sms, res, &error)) + g_printerr ("error: couldn't send sms in modem %s: %s\n", + mm_object_get_path (context->current_obj), + error->message); + else + g_print ("successfully sent sms in modem %s\n", + mm_object_get_path (context->current_obj)); + + send_sms_next (context); +} + +static void +messaging_create_ready (MMModemMessaging *messaging, + GAsyncResult *res, + Context *context) +{ + g_autoptr(GError) error = NULL; + + context->current_sms = mm_modem_messaging_create_finish (messaging, res, &error); + if (!context->current_sms) { + g_printerr ("error: couldn't create sms in modem %s: %s\n", + mm_object_get_path (context->current_obj), + error->message); + send_sms_next (context); + return; + } + + mm_sms_send (context->current_sms, + NULL, + (GAsyncReadyCallback) sms_send_ready, + context); +} + +static void +send_sms_next (Context *context) +{ + g_clear_object (&context->current_sms); + g_clear_object (&context->current_messaging); + g_clear_object (&context->current_obj); + + if (!context->objects) { + g_main_loop_quit (context->loop); + return; + } + + context->current_obj = context->objects->data; + context->objects = g_list_delete_link (context->objects, context->objects); + + context->current_messaging = mm_object_get_modem_messaging (context->current_obj); + if (!context->current_messaging) { + g_printerr ("error: modem %s does not have messaging capabilities\n", + mm_object_get_path (context->current_obj)); + send_sms_next (context); + return; + } + + mm_modem_messaging_create (context->current_messaging, + context->properties, + NULL, + (GAsyncReadyCallback)messaging_create_ready, + context); +} + +static void +manager_new_ready (GObject *source, + GAsyncResult *res, + Context *context) +{ + g_autofree gchar *name_owner = NULL; + g_autoptr(GError) error = NULL; + + context->manager = mm_manager_new_finish (res, &error); + if (!context->connection) { + g_printerr ("error: couldn't get manager: %s\n", error->message); + exit (EXIT_FAILURE); + } + + name_owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (context->manager)); + if (!name_owner) { + g_printerr ("error: ModemManager not found in the system bus\n"); + exit (EXIT_FAILURE); + } + + context->objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (context->manager)); + if (!context->objects) { + g_printerr ("error: no modems found\n"); + exit (EXIT_FAILURE); + } + + send_sms_next (context); +} + +static void +bus_get_ready (GObject *source, + GAsyncResult *res, + Context *context) +{ + g_autoptr(GError) error = NULL; + + context->connection = g_bus_get_finish (res, &error); + if (!context->connection) { + g_printerr ("error: couldn't get bus: %s\n", error->message); + exit (EXIT_FAILURE); + } + + mm_manager_new (context->connection, + G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START, + NULL, + (GAsyncReadyCallback) manager_new_ready, + context); +} + +int main (int argc, char **argv) +{ + Context context = { 0 }; + + if (argc < 3) { + g_printerr ("error: missing arguments\n"); + g_printerr ("usage: %s <NUMBER> <TEXT>\n", argv[0]); + exit (EXIT_FAILURE); + } + + context.properties = mm_sms_properties_new (); + mm_sms_properties_set_number (context.properties, argv[1]); + mm_sms_properties_set_text (context.properties, argv[2]); + + g_bus_get (G_BUS_TYPE_SYSTEM, + NULL, + (GAsyncReadyCallback) bus_get_ready, + &context); + + context.loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (context.loop); + + g_assert (!context.current_obj); + g_assert (!context.current_messaging); + g_assert (!context.current_sms); + + g_main_loop_unref (context.loop); + g_clear_object (&context.connection); + g_clear_object (&context.manager); + g_clear_object (&context.properties); + g_list_free_full (g_steal_pointer (&context.objects), g_object_unref); + + return 0; +} |