aboutsummaryrefslogtreecommitdiff
path: root/src/mm-port-mbim.c
diff options
context:
space:
mode:
authorAleksander Morgado <aleksandermj@chromium.org>2022-12-15 22:44:25 +0000
committerAleksander Morgado <aleksandermj@chromium.org>2022-12-18 21:55:21 +0000
commitc7dac253158394389e0428180b27b0eadb64cd37 (patch)
tree2965e007d376edf98558fd77214cda7fe73ab9d3 /src/mm-port-mbim.c
parent309a8a515bf922b679f36971bffc2999bdc6e293 (diff)
port-mbim: chain up device notifications through the port
Instead of having the modem object listen notifications in the MbimDevice, the MMPortMbim will act as an intermediate emitter for the same. The primary benefit is that the lifecycle of the port object is tightly coupled to the life of the modem object, so there is no chance that the port object outlives the modem object. And the port object will ensure its own device notification handler is correctly cleared up on its dispose, so there should be no chance of firing up a signal in the device for a listener that is already freed.
Diffstat (limited to 'src/mm-port-mbim.c')
-rw-r--r--src/mm-port-mbim.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/src/mm-port-mbim.c b/src/mm-port-mbim.c
index ae1021a0..e900ebce 100644
--- a/src/mm-port-mbim.c
+++ b/src/mm-port-mbim.c
@@ -31,11 +31,19 @@
G_DEFINE_TYPE (MMPortMbim, mm_port_mbim, MM_TYPE_PORT)
+enum {
+ SIGNAL_NOTIFICATION,
+ SIGNAL_LAST
+};
+
+static guint signals[SIGNAL_LAST] = { 0 };
+
struct _MMPortMbimPrivate {
gboolean in_progress;
MbimDevice *mbim_device;
/* monitoring */
+ gulong notification_monitoring_id;
gulong timeout_monitoring_id;
gulong removed_monitoring_id;
@@ -396,6 +404,10 @@ static void
reset_monitoring (MMPortMbim *self,
MbimDevice *mbim_device)
{
+ if (self->priv->notification_monitoring_id && mbim_device) {
+ g_signal_handler_disconnect (mbim_device, self->priv->notification_monitoring_id);
+ self->priv->notification_monitoring_id = 0;
+ }
if (self->priv->timeout_monitoring_id && mbim_device) {
g_signal_handler_disconnect (mbim_device, self->priv->timeout_monitoring_id);
self->priv->timeout_monitoring_id = 0;
@@ -421,6 +433,13 @@ device_removed_cb (MMPortMbim *self)
}
static void
+notification_cb (MMPortMbim *self,
+ MbimMessage *notification)
+{
+ g_signal_emit (self, signals[SIGNAL_NOTIFICATION], 0, notification);
+}
+
+static void
setup_monitoring (MMPortMbim *self,
MbimDevice *mbim_device)
{
@@ -428,6 +447,12 @@ setup_monitoring (MMPortMbim *self,
reset_monitoring (self, mbim_device);
+ g_assert (!self->priv->notification_monitoring_id);
+ self->priv->notification_monitoring_id = g_signal_connect_swapped (mbim_device,
+ MBIM_DEVICE_SIGNAL_INDICATE_STATUS,
+ G_CALLBACK (notification_cb),
+ self);
+
g_assert (!self->priv->timeout_monitoring_id);
self->priv->timeout_monitoring_id = g_signal_connect_swapped (mbim_device,
"notify::" MBIM_DEVICE_CONSECUTIVE_TIMEOUTS,
@@ -928,4 +953,13 @@ mm_port_mbim_class_init (MMPortMbimClass *klass)
/* Virtual methods */
object_class->dispose = dispose;
+
+ signals[SIGNAL_NOTIFICATION] =
+ g_signal_new (MM_PORT_MBIM_SIGNAL_NOTIFICATION,
+ G_OBJECT_CLASS_TYPE (G_OBJECT_CLASS (klass)),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (MMPortMbimClass, notification),
+ NULL, NULL,
+ g_cclosure_marshal_generic,
+ G_TYPE_NONE, 1, MBIM_TYPE_MESSAGE);
}