diff --git a/src/libgdbofono/dbus-introspect.sh b/src/libgdbofono/dbus-introspect.sh new file mode 100755 index 0000000..5a851ad --- /dev/null +++ b/src/libgdbofono/dbus-introspect.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +DEST="$1" +OBJ_PATH="$2" +METHOD="$3" +shift 3 + +dbus-send "$@" --print-reply --dest="$DEST" "$OBJ_PATH" "$METHOD" | \ + grep -v '^method return' | \ + sed -e 's/^[[:space:]]\+string ""__' diff --git a/src/libgdbofono/manager.xml b/src/libgdbofono/manager.xml new file mode 100644 index 0000000..13e9d56 --- /dev/null +++ b/src/libgdbofono/manager.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + diff --git a/src/libgdbofono/meson.build b/src/libgdbofono/meson.build new file mode 100644 index 0000000..98eb9a3 --- /dev/null +++ b/src/libgdbofono/meson.build @@ -0,0 +1,50 @@ +# +# Copyright (C) 2018 Purism SPC +# +# This file is part of Calls. +# +# Calls 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 3 of the License, or +# (at your option) any later version. +# +# Calls 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 Calls. If not, see . +# +# Author: Bob Ham +# +# SPDX-License-Identifier: GPL-3.0-or-later +# + + +gnome = import('gnome') +dbus_interfaces = ['manager', 'modem'] + +gdbofono_src = [] +gdbofono_headers = [] +foreach iface: dbus_interfaces + src = gnome.gdbus_codegen( + 'gdbo-' + iface, + iface + '.xml', + interface_prefix: 'org.ofono.', + namespace: 'GDBO' + ) + gdbofono_src += src + gdbofono_headers += src[1] +endforeach + +gdbofono_deps = [ + dependency('gio-2.0'), + dependency('gio-unix-2.0'), +] + +gdbofono_lib = static_library( + 'gdbofono', + gdbofono_src, + dependencies: gdbofono_deps +) diff --git a/src/libgdbofono/modem-full.xml b/src/libgdbofono/modem-full.xml new file mode 100644 index 0000000..5319672 --- /dev/null +++ b/src/libgdbofono/modem-full.xml @@ -0,0 +1,249 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libgdbofono/modem.xml b/src/libgdbofono/modem.xml new file mode 100644 index 0000000..c02d250 --- /dev/null +++ b/src/libgdbofono/modem.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/manager.h b/src/manager.h index 5ed9e75..ec5550b 100644 --- a/src/manager.h +++ b/src/manager.h @@ -10,6 +10,7 @@ #include #include #include +#include #include "toml.h" @@ -51,7 +52,10 @@ struct EG25Manager { guint mm_watch; MMManager *mm_manager; MMModem *mm_modem; + guint ofono_watch; + GDBOManager *ofono_manager; + GDBusConnection *ofono_connection; GDBusProxy *suspend_proxy; int suspend_delay_fd; diff --git a/src/meson.build b/src/meson.build index 7429950..6a9f52d 100644 --- a/src/meson.build +++ b/src/meson.build @@ -4,6 +4,9 @@ # SPDX-License-Identifier: GPL-3.0-or-later # + +subdir('libgdbofono') + executable ( 'eg25manager', [ @@ -17,5 +20,6 @@ executable ( 'udev.c', 'udev.h', ], dependencies : mgr_deps, + link_with: gdbofono_lib, install : true ) diff --git a/src/ofono-iface.c b/src/ofono-iface.c index 58c8b5a..bbf8dbc 100644 --- a/src/ofono-iface.c +++ b/src/ofono-iface.c @@ -8,22 +8,111 @@ #include +#include +#include + #define OFONO_SERVICE "org.ofono" +static void modem_added_cb(GDBOManager *manager_proxy, + const gchar *path, + GVariant *properties, + struct EG25Manager *manager) +{ + GVariant *modem_path; + g_debug("Adding ofono modem '%s'", path); + + if (manager->modem_state == EG25_STATE_RESUMING) { + if (manager->modem_recovery_timer) { + g_source_remove(manager->modem_recovery_timer); + manager->modem_recovery_timer = 0; + } + modem_resume_post(manager); + manager->modem_state = EG25_STATE_CONFIGURED; + } + + if (manager->modem_state < EG25_STATE_ACQUIRED) + manager->modem_state = EG25_STATE_ACQUIRED; + + if (manager->modem_state < EG25_STATE_CONFIGURED) + modem_configure(manager); + + modem_path = g_variant_lookup_value(properties, "SystemPath", G_VARIANT_TYPE_STRING); + if (manager->modem_usb_id) + g_free(manager->modem_usb_id); + manager->modem_usb_id = g_strdup(strrchr(g_variant_dup_string(modem_path, NULL), '/') + 1); +} + +static void modem_removed_cb(GDBOManager *manager_proxy, + const gchar *path, + struct EG25Manager *manager) +{ +} + +static void get_modems_cb(GDBOManager *manager_proxy, + GAsyncResult *res, + struct EG25Manager *manager) +{ + gboolean ok; + GVariant *modems; + GVariantIter *modems_iter = NULL; + g_autoptr(GError) error = NULL; + + const gchar *path; + GVariant *properties; + + ok = gdbo_manager_call_get_modems_finish(manager_proxy, &modems, + res, &error); + if (!ok) { + g_warning("Error getting modems from ofono manager: %s", error->message); + return; + } + + g_variant_get(modems, "a(oa{sv})", &modems_iter); + while(g_variant_iter_loop(modems_iter, "(&o@a{sv})", &path, &properties)) { + g_debug("Got modem object path '%s'", path); + modem_added_cb(manager_proxy, path, properties, manager); + } + g_variant_iter_free(modems_iter); + g_variant_unref(modems); +} + static void ofono_appeared_cb(GDBusConnection *connection, const gchar *name, const gchar *name_owner, struct EG25Manager *manager) { + GError *error = NULL; + g_message("oFono appeared on D-Bus"); if (manager->modem_iface != MODEM_IFACE_NONE) { g_critical("Modem interface already found! Make sure to only run either of ModemManager or oFono."); return; } + /* now connect to oFono! */ + manager->ofono_connection = connection; + manager->ofono_manager = gdbo_manager_proxy_new_sync(connection, + G_DBUS_PROXY_FLAGS_NONE, + OFONO_SERVICE, + "/", + NULL, + &error); + if (!manager->ofono_manager) { + g_critical("Error creating ofono object manager proxy: %s", error->message); + return; + } + manager->modem_iface = MODEM_IFACE_OFONO; - /* now connect to oFono! */ + g_signal_connect(manager->ofono_manager, "modem-added", + G_CALLBACK(modem_added_cb), manager); + g_signal_connect(manager->ofono_manager, "modem-removed", + G_CALLBACK(modem_removed_cb), manager); + + gdbo_manager_call_get_modems(manager->ofono_manager, + NULL, + (GAsyncReadyCallback) get_modems_cb, + manager); } static void ofono_vanished_cb(GDBusConnection *connection,