Merge remote-tracking branch 'cros/upstream' into 'cros/master'

d4a45315 cli: add allowed-auth bearer property in output (Aleksander Morgado)
dfc2c51b introspection: use correct node name for ModemManager1 object (Eric Caruso)
479d8e72 huawei: updated HCSQ regex to match unquoted response (Murithi Borona)
18a7d9da broadband-modem-qmi: GByteArray can be casted to GArray in USSD encoding (Aleksander Morgado)
d3c5771b broadband-modem-qmi: USSD data in UTF-16 not always given (Maxim Anisimov)
[...182 other patches...]
b9e6f30b kerneldevice,udev: don't assume interface is the direct parent object (Aleksander Morgado)
6eabfd27 huawei: only tag GETPORTMODE supported if it was really used (Aleksander Morgado)
353e2706 huawei: try to read port type hints from interface descriptions (Aleksander Morgado)
9ef84d2c kerneldevice: support reading interface 'description' (Aleksander Morgado)
5da33df3 huawei: avoid attempting to complete GTask twice (Aleksander Morgado)

The following CLs were also squashed into this merge commit in order to
preserve the ability to bisect the history while also bringing the
Profiles implementation closer to the upstream version. Lack of
atomicity resulted in breakages[1].

* CL:2194928 through CL:2194933 revert the original Profiles
  implementation, and
* CL:2194935 through CL:2194938 reapply it.

[1] crbug.com/1082952

Change-Id: I942c043ece0fcadbf5022d8f6367065dc833a5d5
diff --git a/cli/mmcli-bearer.c b/cli/mmcli-bearer.c
index cae68ea..d589e6e 100644
--- a/cli/mmcli-bearer.c
+++ b/cli/mmcli-bearer.c
@@ -68,7 +68,7 @@
 
     /* Status options */
     group = g_option_group_new ("bearer",
-                                "Bearer options",
+                                "Bearer options:",
                                 "Show bearer options",
                                 NULL,
                                 NULL);
@@ -159,24 +159,27 @@
         const gchar *user = NULL;
         const gchar *password = NULL;
         const gchar *rm_protocol = NULL;
+        gchar       *allowed_auth_str = NULL;
 
         if (properties) {
-            apn           = mm_bearer_properties_get_apn (properties);
-            ip_family_str = (properties ? mm_bearer_ip_family_build_string_from_mask (mm_bearer_properties_get_ip_type (properties)) : NULL);
-            user          = mm_bearer_properties_get_user (properties);
-            password      = mm_bearer_properties_get_password (properties);
+            apn              = mm_bearer_properties_get_apn (properties);
+            ip_family_str    = (properties ? mm_bearer_ip_family_build_string_from_mask (mm_bearer_properties_get_ip_type (properties)) : NULL);
+            allowed_auth_str = (properties ? mm_bearer_allowed_auth_build_string_from_mask (mm_bearer_properties_get_allowed_auth (properties)) : NULL);
+            user             = mm_bearer_properties_get_user (properties);
+            password         = mm_bearer_properties_get_password (properties);
             if (mm_bearer_get_bearer_type (bearer) != MM_BEARER_TYPE_DEFAULT_ATTACH) {
                 roaming     = mm_bearer_properties_get_allow_roaming (properties) ? "allowed" : "forbidden";
                 rm_protocol = mm_modem_cdma_rm_protocol_get_string (mm_bearer_properties_get_rm_protocol (properties));
             }
         }
 
-        mmcli_output_string      (MMC_F_BEARER_PROPERTIES_APN,         apn);
-        mmcli_output_string      (MMC_F_BEARER_PROPERTIES_ROAMING,     roaming);
-        mmcli_output_string_take (MMC_F_BEARER_PROPERTIES_IP_TYPE,     ip_family_str);
-        mmcli_output_string      (MMC_F_BEARER_PROPERTIES_USER,        user);
-        mmcli_output_string      (MMC_F_BEARER_PROPERTIES_PASSWORD,    password);
-        mmcli_output_string      (MMC_F_BEARER_PROPERTIES_RM_PROTOCOL, rm_protocol);
+        mmcli_output_string           (MMC_F_BEARER_PROPERTIES_APN,          apn);
+        mmcli_output_string           (MMC_F_BEARER_PROPERTIES_ROAMING,      roaming);
+        mmcli_output_string_take      (MMC_F_BEARER_PROPERTIES_IP_TYPE,      ip_family_str);
+        mmcli_output_string           (MMC_F_BEARER_PROPERTIES_USER,         user);
+        mmcli_output_string           (MMC_F_BEARER_PROPERTIES_PASSWORD,     password);
+        mmcli_output_string           (MMC_F_BEARER_PROPERTIES_RM_PROTOCOL,  rm_protocol);
+        mmcli_output_string_list_take (MMC_F_BEARER_PROPERTIES_ALLOWED_AUTH, allowed_auth_str);
     }
 
     /* IPv4 config */
@@ -248,6 +251,11 @@
         gchar *duration = NULL;
         gchar *bytes_rx = NULL;
         gchar *bytes_tx = NULL;
+        gchar *attempts = NULL;
+        gchar *failed_attempts = NULL;
+        gchar *total_duration = NULL;
+        gchar *total_bytes_rx = NULL;
+        gchar *total_bytes_tx = NULL;
 
         if (stats) {
             guint64 val;
@@ -261,11 +269,31 @@
             val = mm_bearer_stats_get_tx_bytes (stats);
             if (val)
                 bytes_tx = g_strdup_printf ("%" G_GUINT64_FORMAT, val);
+            val = mm_bearer_stats_get_attempts (stats);
+            if (val)
+                attempts = g_strdup_printf ("%" G_GUINT64_FORMAT, val);
+            val = mm_bearer_stats_get_failed_attempts (stats);
+            if (val)
+                failed_attempts = g_strdup_printf ("%" G_GUINT64_FORMAT, val);
+            val = mm_bearer_stats_get_total_duration (stats);
+            if (val)
+                total_duration = g_strdup_printf ("%" G_GUINT64_FORMAT, val);
+            val = mm_bearer_stats_get_total_rx_bytes (stats);
+            if (val)
+                total_bytes_rx = g_strdup_printf ("%" G_GUINT64_FORMAT, val);
+            val = mm_bearer_stats_get_total_tx_bytes (stats);
+            if (val)
+                total_bytes_tx = g_strdup_printf ("%" G_GUINT64_FORMAT, val);
         }
 
-        mmcli_output_string_take (MMC_F_BEARER_STATS_DURATION, duration);
-        mmcli_output_string_take (MMC_F_BEARER_STATS_BYTES_RX, bytes_rx);
-        mmcli_output_string_take (MMC_F_BEARER_STATS_BYTES_TX, bytes_tx);
+        mmcli_output_string_take (MMC_F_BEARER_STATS_DURATION,        duration);
+        mmcli_output_string_take (MMC_F_BEARER_STATS_BYTES_RX,        bytes_rx);
+        mmcli_output_string_take (MMC_F_BEARER_STATS_BYTES_TX,        bytes_tx);
+        mmcli_output_string_take (MMC_F_BEARER_STATS_ATTEMPTS,        attempts);
+        mmcli_output_string_take (MMC_F_BEARER_STATS_FAILED_ATTEMPTS, failed_attempts);
+        mmcli_output_string_take (MMC_F_BEARER_STATS_TOTAL_DURATION,  total_duration);
+        mmcli_output_string_take (MMC_F_BEARER_STATS_TOTAL_BYTES_RX,  total_bytes_rx);
+        mmcli_output_string_take (MMC_F_BEARER_STATS_TOTAL_BYTES_TX,  total_bytes_tx);
     }
 
     mmcli_output_dump ();
diff --git a/cli/mmcli-call.c b/cli/mmcli-call.c
index 7b4f5ec..ecd1cb7 100644
--- a/cli/mmcli-call.c
+++ b/cli/mmcli-call.c
@@ -94,7 +94,7 @@
 
     /* Status options */
     group = g_option_group_new ("call",
-                                "Call options",
+                                "Call options:",
                                 "Show call options",
                                 NULL,
                                 NULL);
diff --git a/cli/mmcli-common.c b/cli/mmcli-common.c
index 10a1fb7..59498ca 100644
--- a/cli/mmcli-common.c
+++ b/cli/mmcli-common.c
@@ -111,20 +111,94 @@
 }
 
 /******************************************************************************/
+/* Common to all objects */
+
+#define ANY_OBJECT_STR "any"
+
+static void
+get_object_lookup_info (const gchar  *str,
+                        const gchar  *object_type,
+                        const gchar  *object_prefix,
+                        gchar       **object_path,
+                        gchar       **modem_uid,
+                        gboolean     *find_any)
+{
+    gboolean all_numeric;
+    guint    i;
+
+    /* Empty string not allowed */
+    if (!str || !str[0]) {
+        g_printerr ("error: no %s was specified\n", object_type);
+        exit (EXIT_FAILURE);
+    }
+
+    /* User string may come in four ways:
+     *   a) full DBus path
+     *   b) object index
+     *   c) modem UID (for modem or SIM lookup only)
+     *   d) "any" string (for modem or SIM lookup only)
+     */
+
+    *object_path = NULL;
+    if (modem_uid)
+        *modem_uid  = NULL;
+    if (find_any)
+        *find_any = FALSE;
+
+    /* If match the DBus prefix, we have a DBus object path */
+    if (g_str_has_prefix (str, object_prefix)) {
+        g_debug ("Assuming '%s' is the full %s path", str, object_type);
+        *object_path = g_strdup (str);
+        return;
+    }
+
+    /* If all numeric, we have the object index */
+    all_numeric = TRUE;
+    for (i = 0; str[i]; i++) {
+        if (!g_ascii_isdigit (str[i])) {
+            all_numeric = FALSE;
+            break;
+        }
+    }
+    if (all_numeric) {
+        g_debug ("Assuming '%s' is the %s index", str, object_type);
+        *object_path = g_strdup_printf ("%s/%s", object_prefix, str);
+        return;
+    }
+
+    /* If it matches the lookup keyword or any of its substrings, we have
+     * to look for the first available object */
+    if ((find_any) && (g_ascii_strncasecmp (str, ANY_OBJECT_STR, strlen (str)) == 0)) {
+        g_debug ("Will look for first available %s", object_type);
+        *find_any = TRUE;
+        return;
+    }
+
+    /* Otherwise we have the UID */
+    if (modem_uid) {
+        g_debug ("Assuming '%s' is the modem UID", str);
+        *modem_uid = g_strdup (str);
+        return;
+    }
+
+    /* If UID is not a valid input for the object type, error out */
+    g_printerr ("error: invalid %s string specified: '%s'\n", object_type, str);
+    exit (EXIT_FAILURE);
+}
+
+/******************************************************************************/
 /* Modem */
 
 static MMObject *
 find_modem (MMManager   *manager,
             const gchar *modem_path,
-            const gchar *modem_uid)
+            const gchar *modem_uid,
+            gboolean     modem_any)
 {
     GList *modems;
     GList *l;
     MMObject *found = NULL;
 
-    g_assert (modem_path || modem_uid);
-    g_assert (!(modem_path && modem_uid));
-
     modems = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (manager));
     for (l = modems; l; l = g_list_next (l)) {
         MMObject *obj;
@@ -133,12 +207,9 @@
         obj   = MM_OBJECT (l->data);
         modem = MM_MODEM (mm_object_get_modem (obj));
 
-        if (modem_path && g_str_equal (mm_object_get_path (obj), modem_path)) {
-            found = g_object_ref (obj);
-            break;
-        }
-
-        if (modem_uid && g_str_equal (mm_modem_get_device (modem), modem_uid)) {
+        if (modem_any ||
+            (modem_path && g_str_equal (mm_object_get_path (obj), modem_path)) ||
+            (modem_uid && g_str_equal (mm_modem_get_device (modem), modem_uid))) {
             found = g_object_ref (obj);
             break;
         }
@@ -146,10 +217,7 @@
     g_list_free_full (modems, g_object_unref);
 
     if (!found) {
-        if (modem_path)
-            g_printerr ("error: couldn't find modem at '%s'\n", modem_path);
-        else if (modem_uid)
-            g_printerr ("error: couldn't find modem identified by uid '%s'\n", modem_uid);
+        g_printerr ("error: couldn't find modem\n");
         exit (EXIT_FAILURE);
     }
 
@@ -159,8 +227,9 @@
 }
 
 typedef struct {
-    gchar *modem_path;
-    gchar *modem_uid;
+    gchar    *modem_path;
+    gchar    *modem_uid;
+    gboolean  modem_any;
 } GetModemContext;
 
 typedef struct {
@@ -212,62 +281,14 @@
 
     results = g_new (GetModemResults, 1);
     results->manager = mmcli_get_manager_finish (res);
-    results->object = find_modem (results->manager, ctx->modem_path, ctx->modem_uid);
+    results->object = find_modem (results->manager, ctx->modem_path, ctx->modem_uid, ctx->modem_any);
     g_task_return_pointer (task, results, (GDestroyNotify)get_modem_results_free);
     g_object_unref (task);
 }
 
-static void
-get_modem_path_or_uid (const gchar  *str,
-                       gchar       **modem_path,
-                       gchar       **modem_uid)
-{
-    gboolean  all_numeric;
-    guint     i;
-
-    /* We must have a given modem specified */
-    if (!str || !str[0]) {
-        g_printerr ("error: no modem was specified\n");
-        exit (EXIT_FAILURE);
-    }
-
-    /* Modem path may come in three ways:
-     *   a) full DBus path
-     *   b) modem index
-     *   c) uid
-     */
-
-    *modem_path = NULL;
-    *modem_uid  = NULL;
-
-    /* If we have DBus prefix, we have the modem DBus path */
-    if (g_str_has_prefix (str, MM_DBUS_MODEM_PREFIX)) {
-        g_debug ("Assuming '%s' is the full modem path", str);
-        *modem_path = g_strdup (str);
-        return;
-    }
-
-    /* If all numeric, we have the modem index */
-    all_numeric = TRUE;
-    for (i = 0; str[i]; i++) {
-        if (!g_ascii_isdigit (str[i])) {
-            all_numeric = FALSE;
-            break;
-        }
-    }
-    if (all_numeric) {
-        g_debug ("Assuming '%s' is the modem index", str);
-        *modem_path = g_strdup_printf (MM_DBUS_MODEM_PREFIX "/%s", str);
-        return;
-    }
-
-    /* Otherwise we have the UID */
-    *modem_uid = g_strdup (str);
-}
-
 void
 mmcli_get_modem (GDBusConnection     *connection,
-                 const gchar         *modem_str,
+                 const gchar         *str,
                  GCancellable        *cancellable,
                  GAsyncReadyCallback  callback,
                  gpointer             user_data)
@@ -278,8 +299,9 @@
     task = g_task_new (connection, cancellable, callback, user_data);
 
     ctx = g_new0 (GetModemContext, 1);
-    get_modem_path_or_uid (modem_str, &ctx->modem_path, &ctx->modem_uid);
-    g_assert (ctx->modem_path || ctx->modem_uid);
+    get_object_lookup_info (str, "modem", MM_DBUS_MODEM_PREFIX,
+                            &ctx->modem_path, &ctx->modem_uid, &ctx->modem_any);
+    g_assert (!!ctx->modem_path + !!ctx->modem_uid + ctx->modem_any == 1);
     g_task_set_task_data (task, ctx, (GDestroyNotify) get_modem_context_free);
 
     mmcli_get_manager (connection,
@@ -290,18 +312,20 @@
 
 MMObject *
 mmcli_get_modem_sync (GDBusConnection  *connection,
-                      const gchar      *modem_str,
+                      const gchar      *str,
                       MMManager       **o_manager)
 {
     MMManager *manager;
     MMObject *found;
     gchar *modem_path = NULL;
     gchar *modem_uid = NULL;
+    gboolean modem_any = FALSE;
 
     manager = mmcli_get_manager_sync (connection);
-    get_modem_path_or_uid (modem_str, &modem_path, &modem_uid);
-    g_assert (modem_path || modem_uid);
-    found = find_modem (manager, modem_path, modem_uid);
+    get_object_lookup_info (str, "modem", MM_DBUS_MODEM_PREFIX,
+                            &modem_path, &modem_uid, &modem_any);
+    g_assert (!!modem_path + !!modem_uid + modem_any == 1);
+    found = find_modem (manager, modem_path, modem_uid, modem_any);
 
     if (o_manager)
         *o_manager = manager;
@@ -552,37 +576,9 @@
     look_for_bearer_in_modem (task);
 }
 
-static gchar *
-get_bearer_path (const gchar *path_or_index)
-{
-    gchar *bearer_path;
-
-    /* We must have a given bearer specified */
-    if (!path_or_index) {
-        g_printerr ("error: no bearer was specified\n");
-        exit (EXIT_FAILURE);
-    }
-
-    /* Bearer path may come in two ways: full DBus path or just bearer index.
-     * If it is a bearer index, we'll need to generate the DBus path ourselves */
-    if (g_str_has_prefix (path_or_index, MM_DBUS_BEARER_PREFIX)) {
-        g_debug ("Assuming '%s' is the full bearer path", path_or_index);
-        bearer_path = g_strdup (path_or_index);
-    } else if (g_ascii_isdigit (path_or_index[0])) {
-        g_debug ("Assuming '%s' is the bearer index", path_or_index);
-        bearer_path = g_strdup_printf (MM_DBUS_BEARER_PREFIX "/%s", path_or_index);
-    } else {
-        g_printerr ("error: invalid path or index string specified: '%s'\n",
-                    path_or_index);
-        exit (EXIT_FAILURE);
-    }
-
-    return bearer_path;
-}
-
 void
 mmcli_get_bearer (GDBusConnection     *connection,
-                  const gchar         *path_or_index,
+                  const gchar         *str,
                   GCancellable        *cancellable,
                   GAsyncReadyCallback  callback,
                   gpointer             user_data)
@@ -593,7 +589,9 @@
     task = g_task_new (connection, cancellable, callback, user_data);
 
     ctx = g_new0 (GetBearerContext, 1);
-    ctx->bearer_path = get_bearer_path (path_or_index);
+    get_object_lookup_info (str, "bearer", MM_DBUS_BEARER_PREFIX,
+                            &ctx->bearer_path, NULL, NULL);
+    g_assert (ctx->bearer_path);
     g_task_set_task_data (task, ctx, (GDestroyNotify) get_bearer_context_free);
 
     mmcli_get_manager (connection,
@@ -604,7 +602,7 @@
 
 MMBearer *
 mmcli_get_bearer_sync (GDBusConnection  *connection,
-                       const gchar      *path_or_index,
+                       const gchar      *str,
                        MMManager       **o_manager,
                        MMObject        **o_object)
 {
@@ -612,9 +610,11 @@
     GList *modems;
     GList *l;
     MMBearer *found = NULL;
-    gchar *bearer_path;
+    gchar *bearer_path = NULL;
 
-    bearer_path = get_bearer_path (path_or_index);
+    get_object_lookup_info (str, "bearer", MM_DBUS_BEARER_PREFIX,
+                            &bearer_path, NULL, NULL);
+    g_assert (bearer_path);
 
     manager = mmcli_get_manager_sync (connection);
     modems = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (manager));
@@ -695,7 +695,8 @@
 
 typedef struct {
     gchar     *sim_path;
-    gchar     *sim_maybe_uid;
+    gchar     *modem_uid;
+    gboolean   sim_any;
     MMManager *manager;
     MMObject  *current;
 } GetSimContext;
@@ -722,7 +723,7 @@
         g_object_unref (ctx->current);
     if (ctx->manager)
         g_object_unref (ctx->manager);
-    g_free (ctx->sim_maybe_uid);
+    g_free (ctx->modem_uid);
     g_free (ctx->sim_path);
     g_free (ctx);
 }
@@ -760,7 +761,7 @@
 
     sim = mm_modem_get_sim_finish (modem, res, &error);
     if (error) {
-        g_printerr ("error: couldn't get sim '%s' at '%s': '%s'\n",
+        g_printerr ("error: couldn't get SIM '%s' at '%s': '%s'\n",
                     ctx->sim_path,
                     mm_modem_get_path (modem),
                     error->message);
@@ -791,7 +792,7 @@
 
     modems = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (ctx->manager));
     if (!modems) {
-        g_printerr ("error: couldn't find sim at '%s': 'no modems found'\n",
+        g_printerr ("error: couldn't find SIM at '%s': 'no modems found'\n",
                     ctx->sim_path);
         exit (EXIT_FAILURE);
     }
@@ -802,14 +803,23 @@
 
         object = MM_OBJECT (l->data);
         modem = mm_object_get_modem (object);
-        if (!ctx->sim_path) {
-            if (g_str_equal (ctx->sim_maybe_uid, mm_modem_get_device (modem)))
+
+        /* check if we can match the first object found */
+        if (ctx->sim_any) {
+            g_assert (!ctx->sim_path);
+            ctx->sim_path = g_strdup (mm_modem_get_sim_path (modem));
+        }
+        /* check if modem UID matches */
+        else if (ctx->modem_uid) {
+            if (g_str_equal (ctx->modem_uid, mm_modem_get_device (modem))) {
+                g_assert (!ctx->sim_path);
                 ctx->sim_path = g_strdup (mm_modem_get_sim_path (modem));
-            else {
+            } else {
                 g_object_unref (modem);
                 continue;
             }
         }
+
         if (g_str_equal (ctx->sim_path, mm_modem_get_sim_path (modem))) {
             ctx->current = g_object_ref (object);
             mm_modem_get_sim (modem,
@@ -821,46 +831,15 @@
     }
     g_list_free_full (modems, g_object_unref);
 
-    if (!ctx->sim_path) {
-        g_printerr ("error: invalid index string specified: '%s'\n",
-                    ctx->sim_maybe_uid);
-        exit (EXIT_FAILURE);
-    }
-
     if (!ctx->current) {
-        g_printerr ("error: couldn't find sim at '%s'\n",
-                    ctx->sim_path);
+        g_printerr ("error: couldn't find SIM\n");
         exit (EXIT_FAILURE);
     }
 }
 
-static gchar *
-get_sim_path (const gchar *path_or_index)
-{
-    gchar *sim_path = NULL;
-
-    /* We must have a given sim specified */
-    if (!path_or_index) {
-        g_printerr ("error: no sim was specified\n");
-        exit (EXIT_FAILURE);
-    }
-
-    /* Sim path may come in two ways: full DBus path or just sim index.
-     * If it is a sim index, we'll need to generate the DBus path ourselves */
-    if (g_str_has_prefix (path_or_index, MM_DBUS_SIM_PREFIX)) {
-        g_debug ("Assuming '%s' is the full SIM path", path_or_index);
-        sim_path = g_strdup (path_or_index);
-    } else if (g_ascii_isdigit (path_or_index[0])) {
-        g_debug ("Assuming '%s' is the SIM index", path_or_index);
-        sim_path = g_strdup_printf (MM_DBUS_SIM_PREFIX "/%s", path_or_index);
-    }
-
-    return sim_path;
-}
-
 void
 mmcli_get_sim (GDBusConnection     *connection,
-               const gchar         *path_or_index_or_uid,
+               const gchar         *str,
                GCancellable        *cancellable,
                GAsyncReadyCallback  callback,
                gpointer             user_data)
@@ -871,8 +850,9 @@
     task = g_task_new (connection, cancellable, callback, user_data);
 
     ctx = g_new0 (GetSimContext, 1);
-    ctx->sim_path = get_sim_path (path_or_index_or_uid);
-    ctx->sim_maybe_uid = g_strdup (path_or_index_or_uid);
+    get_object_lookup_info (str, "SIM", MM_DBUS_SIM_PREFIX,
+                            &ctx->sim_path, &ctx->modem_uid, &ctx->sim_any);
+    g_assert (!!ctx->sim_path + !!ctx->modem_uid + ctx->sim_any == 1);
     g_task_set_task_data (task, ctx, (GDestroyNotify) get_sim_context_free);
 
     mmcli_get_manager (connection,
@@ -883,7 +863,7 @@
 
 MMSim *
 mmcli_get_sim_sync (GDBusConnection  *connection,
-                    const gchar      *path_or_index_or_uid,
+                    const gchar      *str,
                     MMManager       **o_manager,
                     MMObject        **o_object)
 {
@@ -891,14 +871,18 @@
     GList *modems;
     GList *l;
     MMSim *found = NULL;
-    gchar *sim_path;
+    gchar *sim_path = NULL;
+    gchar *modem_uid = NULL;
+    gboolean sim_any = FALSE;
 
-    sim_path = get_sim_path (path_or_index_or_uid);
+    get_object_lookup_info (str, "SIM", MM_DBUS_SIM_PREFIX,
+                            &sim_path, &modem_uid, &sim_any);
+    g_assert (!!sim_path + !!modem_uid + sim_any == 1);
 
     manager = mmcli_get_manager_sync (connection);
     modems = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (manager));
     if (!modems) {
-        g_printerr ("error: couldn't find sim at '%s': 'no modems found'\n",
+        g_printerr ("error: couldn't find SIM at '%s': 'no modems found'\n",
                     sim_path);
         exit (EXIT_FAILURE);
     }
@@ -911,10 +895,17 @@
         object = MM_OBJECT (l->data);
         modem = mm_object_get_modem (object);
 
-        if (!sim_path) {
-            if (g_str_equal (path_or_index_or_uid, mm_modem_get_device (modem)))
+        /* check if we can match the first object found */
+        if (sim_any) {
+            g_assert (!sim_path);
+            sim_path = g_strdup (mm_modem_get_sim_path (modem));
+        }
+        /* check if modem UID matches */
+        else if (modem_uid) {
+            if (g_str_equal (modem_uid, mm_modem_get_device (modem))) {
+                g_assert (!sim_path);
                 sim_path = g_strdup (mm_modem_get_sim_path (modem));
-            else {
+            } else {
                 g_object_unref (modem);
                 continue;
             }
@@ -923,7 +914,7 @@
         if (g_str_equal (sim_path, mm_modem_get_sim_path (modem))) {
             found = mm_modem_get_sim_sync (modem, NULL, &error);
             if (error) {
-                g_printerr ("error: couldn't get sim '%s' in modem '%s': '%s'\n",
+                g_printerr ("error: couldn't get SIM '%s' in modem '%s': '%s'\n",
                             sim_path,
                             mm_modem_get_path (modem),
                             error->message);
@@ -937,14 +928,8 @@
         g_object_unref (modem);
     }
 
-    if (!sim_path) {
-        g_printerr ("error: invalid index string specified: '%s'\n",
-                    path_or_index_or_uid);
-        exit (EXIT_FAILURE);
-    }
-
     if (!found) {
-        g_printerr ("error: couldn't find sim at '%s'\n", sim_path);
+        g_printerr ("error: couldn't find SIM\n");
         exit (EXIT_FAILURE);
     }
 
@@ -1027,7 +1012,7 @@
         MMSms *sms = MM_SMS (l->data);
 
         if (g_str_equal (mm_sms_get_path (sms), sms_path)) {
-            g_debug ("Sms found at '%s'\n", sms_path);
+            g_debug ("SMS found at '%s'\n", sms_path);
             return g_object_ref (sms);
         }
     }
@@ -1129,37 +1114,9 @@
     look_for_sms_in_modem (task);
 }
 
-static gchar *
-get_sms_path (const gchar *path_or_index)
-{
-    gchar *sms_path;
-
-    /* We must have a given sms specified */
-    if (!path_or_index) {
-        g_printerr ("error: no SMS was specified\n");
-        exit (EXIT_FAILURE);
-    }
-
-    /* Sms path may come in two ways: full DBus path or just sms index.
-     * If it is a sms index, we'll need to generate the DBus path ourselves */
-    if (g_str_has_prefix (path_or_index, MM_DBUS_SMS_PREFIX)) {
-        g_debug ("Assuming '%s' is the full SMS path", path_or_index);
-        sms_path = g_strdup (path_or_index);
-    } else if (g_ascii_isdigit (path_or_index[0])) {
-        g_debug ("Assuming '%s' is the SMS index", path_or_index);
-        sms_path = g_strdup_printf (MM_DBUS_SMS_PREFIX "/%s", path_or_index);
-    } else {
-        g_printerr ("error: invalid path or index string specified: '%s'\n",
-                    path_or_index);
-        exit (EXIT_FAILURE);
-    }
-
-    return sms_path;
-}
-
 void
 mmcli_get_sms (GDBusConnection     *connection,
-               const gchar         *path_or_index,
+               const gchar         *str,
                GCancellable        *cancellable,
                GAsyncReadyCallback  callback,
                gpointer             user_data)
@@ -1170,7 +1127,8 @@
     task = g_task_new (connection, cancellable, callback, user_data);
 
     ctx = g_new0 (GetSmsContext, 1);
-    ctx->sms_path = get_sms_path (path_or_index);
+    get_object_lookup_info (str, "SMS", MM_DBUS_SMS_PREFIX,
+                            &ctx->sms_path, NULL, NULL);
     g_task_set_task_data (task, ctx, (GDestroyNotify) get_sms_context_free);
 
     mmcli_get_manager (connection,
@@ -1181,7 +1139,7 @@
 
 MMSms *
 mmcli_get_sms_sync (GDBusConnection  *connection,
-                    const gchar      *path_or_index,
+                    const gchar      *str,
                     MMManager       **o_manager,
                     MMObject        **o_object)
 {
@@ -1189,14 +1147,15 @@
     GList *modems;
     GList *l;
     MMSms *found = NULL;
-    gchar *sms_path;
+    gchar *sms_path = NULL;
 
-    sms_path = get_sms_path (path_or_index);
+    get_object_lookup_info (str, "SMS", MM_DBUS_SMS_PREFIX,
+                            &sms_path, NULL, NULL);
 
     manager = mmcli_get_manager_sync (connection);
     modems = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (manager));
     if (!modems) {
-        g_printerr ("error: couldn't find sms at '%s': 'no modems found'\n",
+        g_printerr ("error: couldn't find SMS at '%s': 'no modems found'\n",
                     sms_path);
         exit (EXIT_FAILURE);
     }
@@ -1418,37 +1377,9 @@
     look_for_call_in_modem (task);
 }
 
-static gchar *
-get_call_path (const gchar *path_or_index)
-{
-    gchar *call_path;
-
-    /* We must have a given call specified */
-    if (!path_or_index) {
-        g_printerr ("error: no call was specified\n");
-        exit (EXIT_FAILURE);
-    }
-
-    /* Call path may come in two ways: full DBus path or just call index.
-     * If it is a call index, we'll need to generate the DBus path ourselves */
-    if (g_str_has_prefix (path_or_index, MM_DBUS_CALL_PREFIX)) {
-        g_debug ("Assuming '%s' is the full call path", path_or_index);
-        call_path = g_strdup (path_or_index);
-    } else if (g_ascii_isdigit (path_or_index[0])) {
-        g_debug ("Assuming '%s' is the call index", path_or_index);
-        call_path = g_strdup_printf (MM_DBUS_CALL_PREFIX "/%s", path_or_index);
-    } else {
-        g_printerr ("error: invalid path or index string specified: '%s'\n",
-                    path_or_index);
-        exit (EXIT_FAILURE);
-    }
-
-    return call_path;
-}
-
 void
 mmcli_get_call (GDBusConnection     *connection,
-                const gchar         *path_or_index,
+                const gchar         *str,
                 GCancellable        *cancellable,
                 GAsyncReadyCallback  callback,
                 gpointer             user_data)
@@ -1459,7 +1390,8 @@
     task = g_task_new (connection, cancellable, callback, user_data);
 
     ctx = g_new0 (GetCallContext, 1);
-    ctx->call_path = get_call_path (path_or_index);
+    get_object_lookup_info (str, "call", MM_DBUS_CALL_PREFIX,
+                            &ctx->call_path, NULL, NULL);
     g_task_set_task_data (task, ctx, (GDestroyNotify) get_call_context_free);
 
     mmcli_get_manager (connection,
@@ -1470,7 +1402,7 @@
 
 MMCall *
 mmcli_get_call_sync (GDBusConnection  *connection,
-                     const gchar      *path_or_index,
+                     const gchar      *str,
                      MMManager       **o_manager,
                      MMObject        **o_object)
 {
@@ -1478,9 +1410,10 @@
     GList *modems;
     GList *l;
     MMCall *found = NULL;
-    gchar *call_path;
+    gchar *call_path = NULL;
 
-    call_path = get_call_path (path_or_index);
+    get_object_lookup_info (str, "call", MM_DBUS_CALL_PREFIX,
+                            &call_path, NULL, NULL);
 
     manager = mmcli_get_manager_sync (connection);
     modems = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (manager));
@@ -1565,16 +1498,16 @@
 
 static GOptionEntry entries[] = {
     { "modem", 'm', 0, G_OPTION_ARG_STRING, &modem_str,
-      "Specify modem by path or index. Shows modem information if no action specified.",
-      "[PATH|INDEX]"
+      "Specify modem by path, index, UID or 'any'. Shows modem information if no action specified.",
+      "[PATH|INDEX|UID|any]"
     },
     { "bearer", 'b', 0, G_OPTION_ARG_STRING, &bearer_str,
       "Specify bearer by path or index. Shows bearer information if no action specified.",
       "[PATH|INDEX]"
     },
     { "sim", 'i', 0, G_OPTION_ARG_STRING, &sim_str,
-      "Specify SIM card by path or index. Shows SIM card information if no action specified.",
-      "[PATH|INDEX]"
+      "Specify SIM card by path, index, UID or 'any'. Shows SIM card information if no action specified.",
+      "[PATH|INDEX|UID|any]"
     },
     { "sms", 's', 0, G_OPTION_ARG_STRING, &sms_str,
       "Specify SMS by path or index. Shows SMS information if no action specified.",
diff --git a/cli/mmcli-common.h b/cli/mmcli-common.h
index e3d96c0..237ebb5 100644
--- a/cli/mmcli-common.h
+++ b/cli/mmcli-common.h
@@ -34,18 +34,18 @@
 MMManager *mmcli_get_manager_sync   (GDBusConnection     *connection);
 
 void     mmcli_get_modem         (GDBusConnection      *connection,
-                                  const gchar          *modem_str,
+                                  const gchar          *str,
                                   GCancellable         *cancellable,
                                   GAsyncReadyCallback   callback,
                                   gpointer              user_data);
 MMObject *mmcli_get_modem_finish (GAsyncResult         *res,
                                   MMManager           **o_manager);
 MMObject *mmcli_get_modem_sync   (GDBusConnection      *connection,
-                                  const gchar          *modem_str,
+                                  const gchar          *str,
                                   MMManager           **o_manager);
 
 void      mmcli_get_bearer        (GDBusConnection      *connection,
-                                   const gchar          *path_or_index,
+                                   const gchar          *str,
                                    GCancellable         *cancellable,
                                    GAsyncReadyCallback   callback,
                                    gpointer              user_data);
@@ -53,12 +53,12 @@
                                    MMManager           **manager,
                                    MMObject            **object);
 MMBearer *mmcli_get_bearer_sync   (GDBusConnection      *connection,
-                                   const gchar          *path_or_index,
+                                   const gchar          *str,
                                    MMManager           **manager,
                                    MMObject            **object);
 
 void   mmcli_get_sim        (GDBusConnection      *connection,
-                             const gchar          *path_or_index,
+                             const gchar          *str,
                              GCancellable         *cancellable,
                              GAsyncReadyCallback   callback,
                              gpointer              user_data);
@@ -66,12 +66,12 @@
                              MMManager           **manager,
                              MMObject            **object);
 MMSim *mmcli_get_sim_sync   (GDBusConnection      *connection,
-                             const gchar          *path_or_index,
+                             const gchar          *str,
                              MMManager           **manager,
                              MMObject            **object);
 
 void   mmcli_get_sms        (GDBusConnection     *connection,
-                             const gchar         *path_or_index,
+                             const gchar         *str,
                              GCancellable        *cancellable,
                              GAsyncReadyCallback  callback,
                              gpointer             user_data);
@@ -79,12 +79,12 @@
                              MMManager          **manager,
                              MMObject           **object);
 MMSms *mmcli_get_sms_sync   (GDBusConnection     *connection,
-                             const gchar         *path_or_index,
+                             const gchar         *str,
                              MMManager          **manager,
                              MMObject           **object);
 
 void    mmcli_get_call        (GDBusConnection      *connection,
-                               const gchar          *path_or_index,
+                               const gchar          *str,
                                GCancellable         *cancellable,
                                GAsyncReadyCallback   callback,
                                gpointer              user_data);
@@ -92,7 +92,7 @@
                                MMManager           **manager,
                                MMObject            **object);
 MMCall *mmcli_get_call_sync   (GDBusConnection      *connection,
-                               const gchar          *path_or_index,
+                               const gchar          *str,
                                MMManager           **manager,
                                MMObject            **object);
 
diff --git a/cli/mmcli-manager.c b/cli/mmcli-manager.c
index e1e3c36..950617b 100644
--- a/cli/mmcli-manager.c
+++ b/cli/mmcli-manager.c
@@ -108,7 +108,7 @@
 
     /* Status options */
     group = g_option_group_new ("manager",
-                                "Manager options",
+                                "Manager options:",
                                 "Show manager options",
                                 NULL,
                                 NULL);
diff --git a/cli/mmcli-modem-3gpp.c b/cli/mmcli-modem-3gpp.c
index 21031d6..5136e3f 100644
--- a/cli/mmcli-modem-3gpp.c
+++ b/cli/mmcli-modem-3gpp.c
@@ -103,7 +103,7 @@
     GOptionGroup *group;
 
     group = g_option_group_new ("3gpp",
-                                "3GPP options",
+                                "3GPP options:",
                                 "Show 3GPP related options",
                                 NULL,
                                 NULL);
diff --git a/cli/mmcli-modem-cdma.c b/cli/mmcli-modem-cdma.c
index 58651b6..cba33a1 100644
--- a/cli/mmcli-modem-cdma.c
+++ b/cli/mmcli-modem-cdma.c
@@ -70,7 +70,7 @@
     GOptionGroup *group;
 
     group = g_option_group_new ("cdma",
-                                "CDMA options",
+                                "CDMA options:",
                                 "Show CDMA related options",
                                 NULL,
                                 NULL);
diff --git a/cli/mmcli-modem-firmware.c b/cli/mmcli-modem-firmware.c
index 20dce4f..34ceb42 100644
--- a/cli/mmcli-modem-firmware.c
+++ b/cli/mmcli-modem-firmware.c
@@ -71,7 +71,7 @@
     GOptionGroup *group;
 
     group = g_option_group_new ("firmware",
-                                "Firmware options",
+                                "Firmware options:",
                                 "Show Firmware options",
                                 NULL,
                                 NULL);
diff --git a/cli/mmcli-modem-location.c b/cli/mmcli-modem-location.c
index 6ef42b7..cec3220 100644
--- a/cli/mmcli-modem-location.c
+++ b/cli/mmcli-modem-location.c
@@ -163,7 +163,7 @@
     GOptionGroup *group;
 
     group = g_option_group_new ("location",
-                                "Location options",
+                                "Location options:",
                                 "Show Location options",
                                 NULL,
                                 NULL);
diff --git a/cli/mmcli-modem-messaging.c b/cli/mmcli-modem-messaging.c
index 681929a..535cc90 100644
--- a/cli/mmcli-modem-messaging.c
+++ b/cli/mmcli-modem-messaging.c
@@ -82,7 +82,7 @@
     GOptionGroup *group;
 
     group = g_option_group_new ("messaging",
-                                "Messaging options",
+                                "Messaging options:",
                                 "Show Messaging options",
                                 NULL,
                                 NULL);
diff --git a/cli/mmcli-modem-oma.c b/cli/mmcli-modem-oma.c
index 13fdc5a..e1a41ad 100644
--- a/cli/mmcli-modem-oma.c
+++ b/cli/mmcli-modem-oma.c
@@ -87,7 +87,7 @@
     GOptionGroup *group;
 
     group = g_option_group_new ("oma",
-                                "OMA options",
+                                "OMA options:",
                                 "Show OMA options",
                                 NULL,
                                 NULL);
diff --git a/cli/mmcli-modem-signal.c b/cli/mmcli-modem-signal.c
index c5bf435..506d737 100644
--- a/cli/mmcli-modem-signal.c
+++ b/cli/mmcli-modem-signal.c
@@ -66,7 +66,7 @@
     GOptionGroup *group;
 
     group = g_option_group_new ("signal",
-                                "Signal options",
+                                "Signal options:",
                                 "Show Signal options",
                                 NULL,
                                 NULL);
diff --git a/cli/mmcli-modem-simple.c b/cli/mmcli-modem-simple.c
index 35c85a8..174f144 100644
--- a/cli/mmcli-modem-simple.c
+++ b/cli/mmcli-modem-simple.c
@@ -65,7 +65,7 @@
     GOptionGroup *group;
 
     group = g_option_group_new ("simple",
-                                "Simple options",
+                                "Simple options:",
                                 "Show Simple options",
                                 NULL,
                                 NULL);
diff --git a/cli/mmcli-modem-time.c b/cli/mmcli-modem-time.c
index 79f2a80..98fa06e 100644
--- a/cli/mmcli-modem-time.c
+++ b/cli/mmcli-modem-time.c
@@ -61,7 +61,7 @@
     GOptionGroup *group;
 
     group = g_option_group_new ("time",
-                                "Time options",
+                                "Time options:",
                                 "Show Time options",
                                 NULL,
                                 NULL);
diff --git a/cli/mmcli-modem-voice.c b/cli/mmcli-modem-voice.c
index 0f066b3..ab216ea 100644
--- a/cli/mmcli-modem-voice.c
+++ b/cli/mmcli-modem-voice.c
@@ -113,7 +113,7 @@
     GOptionGroup *group;
 
     group = g_option_group_new ("voice",
-                                "Voice options",
+                                "Voice options:",
                                 "Show Voice options",
                                 NULL,
                                 NULL);
diff --git a/cli/mmcli-modem.c b/cli/mmcli-modem.c
index e74c793..a25de31 100644
--- a/cli/mmcli-modem.c
+++ b/cli/mmcli-modem.c
@@ -140,7 +140,7 @@
 
     /* Status options */
     group = g_option_group_new ("modem",
-                                "Modem options",
+                                "Modem options:",
                                 "Show modem options",
                                 NULL,
                                 NULL);
@@ -407,7 +407,7 @@
             pco_list = mm_modem_3gpp_get_pco (ctx->modem_3gpp);
             initial_eps_bearer_path = mm_modem_3gpp_get_initial_eps_bearer_path (ctx->modem_3gpp);
 
-            if (mm_modem_get_current_capabilities (ctx->modem) & (MM_MODEM_CAPABILITY_LTE | MM_MODEM_CAPABILITY_LTE_ADVANCED)) {
+            if (mm_modem_get_current_capabilities (ctx->modem) & (MM_MODEM_CAPABILITY_LTE)) {
                 MMBearerProperties *initial_eps_bearer_properties;
 
                 initial_eps_bearer_properties = mm_modem_3gpp_peek_initial_eps_bearer_settings (ctx->modem_3gpp);
diff --git a/cli/mmcli-output.c b/cli/mmcli-output.c
index 25877b0..6799ab6 100644
--- a/cli/mmcli-output.c
+++ b/cli/mmcli-output.c
@@ -207,6 +207,7 @@
     [MMC_F_BEARER_PROPERTIES_APN]             = { "bearer.properties.apn",                           "apn",                      MMC_S_BEARER_PROPERTIES,       },
     [MMC_F_BEARER_PROPERTIES_ROAMING]         = { "bearer.properties.roaming",                       "roaming",                  MMC_S_BEARER_PROPERTIES,       },
     [MMC_F_BEARER_PROPERTIES_IP_TYPE]         = { "bearer.properties.ip-type",                       "ip type",                  MMC_S_BEARER_PROPERTIES,       },
+    [MMC_F_BEARER_PROPERTIES_ALLOWED_AUTH]    = { "bearer.properties.allowed-auth",                  "allowed-auth",             MMC_S_BEARER_PROPERTIES,       },
     [MMC_F_BEARER_PROPERTIES_USER]            = { "bearer.properties.user",                          "user",                     MMC_S_BEARER_PROPERTIES,       },
     [MMC_F_BEARER_PROPERTIES_PASSWORD]        = { "bearer.properties.password",                      "password",                 MMC_S_BEARER_PROPERTIES,       },
     [MMC_F_BEARER_PROPERTIES_NUMBER]          = { "bearer.properties.number",                        "number",                   MMC_S_BEARER_PROPERTIES,       },
@@ -226,6 +227,11 @@
     [MMC_F_BEARER_STATS_DURATION]             = { "bearer.stats.duration",                           "duration",                 MMC_S_BEARER_STATS,            },
     [MMC_F_BEARER_STATS_BYTES_RX]             = { "bearer.stats.bytes-rx",                           "bytes rx",                 MMC_S_BEARER_STATS,            },
     [MMC_F_BEARER_STATS_BYTES_TX]             = { "bearer.stats.bytes-tx",                           "bytes tx",                 MMC_S_BEARER_STATS,            },
+    [MMC_F_BEARER_STATS_ATTEMPTS]             = { "bearer.stats.attempts",                           "attempts",                 MMC_S_BEARER_STATS,            },
+    [MMC_F_BEARER_STATS_FAILED_ATTEMPTS]      = { "bearer.stats.failed-attempts",                    "attempts",                 MMC_S_BEARER_STATS,            },
+    [MMC_F_BEARER_STATS_TOTAL_DURATION]       = { "bearer.stats.total-duration",                     "total-duration",           MMC_S_BEARER_STATS,            },
+    [MMC_F_BEARER_STATS_TOTAL_BYTES_RX]       = { "bearer.stats.total-bytes-rx",                     "total-bytes rx",           MMC_S_BEARER_STATS,            },
+    [MMC_F_BEARER_STATS_TOTAL_BYTES_TX]       = { "bearer.stats.total-bytes-tx",                     "total-bytes tx",           MMC_S_BEARER_STATS,            },
     [MMC_F_CALL_GENERAL_DBUS_PATH]            = { "call.dbus-path",                                  "dbus path",                MMC_S_CALL_GENERAL,            },
     [MMC_F_CALL_PROPERTIES_NUMBER]            = { "call.properties.number",                          "number",                   MMC_S_CALL_PROPERTIES,         },
     [MMC_F_CALL_PROPERTIES_DIRECTION]         = { "call.properties.direction",                       "direction",                MMC_S_CALL_PROPERTIES,         },
diff --git a/cli/mmcli-output.h b/cli/mmcli-output.h
index bd7b317..2cd02b4 100644
--- a/cli/mmcli-output.h
+++ b/cli/mmcli-output.h
@@ -224,6 +224,7 @@
     MMC_F_BEARER_PROPERTIES_APN,
     MMC_F_BEARER_PROPERTIES_ROAMING,
     MMC_F_BEARER_PROPERTIES_IP_TYPE,
+    MMC_F_BEARER_PROPERTIES_ALLOWED_AUTH,
     MMC_F_BEARER_PROPERTIES_USER,
     MMC_F_BEARER_PROPERTIES_PASSWORD,
     MMC_F_BEARER_PROPERTIES_NUMBER,
@@ -243,6 +244,11 @@
     MMC_F_BEARER_STATS_DURATION,
     MMC_F_BEARER_STATS_BYTES_RX,
     MMC_F_BEARER_STATS_BYTES_TX,
+    MMC_F_BEARER_STATS_ATTEMPTS,
+    MMC_F_BEARER_STATS_FAILED_ATTEMPTS,
+    MMC_F_BEARER_STATS_TOTAL_DURATION,
+    MMC_F_BEARER_STATS_TOTAL_BYTES_RX,
+    MMC_F_BEARER_STATS_TOTAL_BYTES_TX,
     MMC_F_CALL_GENERAL_DBUS_PATH,
     MMC_F_CALL_PROPERTIES_NUMBER,
     MMC_F_CALL_PROPERTIES_DIRECTION,
diff --git a/cli/mmcli-sim.c b/cli/mmcli-sim.c
index 75d3d07..efb15df 100644
--- a/cli/mmcli-sim.c
+++ b/cli/mmcli-sim.c
@@ -83,7 +83,7 @@
 
     /* Status options */
     group = g_option_group_new ("sim",
-                                "SIM options",
+                                "SIM options:",
                                 "Show SIM options",
                                 NULL,
                                 NULL);
diff --git a/cli/mmcli-sms.c b/cli/mmcli-sms.c
index a5fa45b..c468ed6 100644
--- a/cli/mmcli-sms.c
+++ b/cli/mmcli-sms.c
@@ -78,7 +78,7 @@
 
     /* Status options */
     group = g_option_group_new ("sms",
-                                "SMS options",
+                                "SMS options:",
                                 "Show SMS options",
                                 NULL,
                                 NULL);
diff --git a/cli/mmcli.c b/cli/mmcli.c
index 64a2c69..bf59867 100644
--- a/cli/mmcli.c
+++ b/cli/mmcli.c
@@ -147,8 +147,7 @@
 static void
 print_version_and_exit (void)
 {
-    g_print ("\n"
-             PROGRAM_NAME " " PROGRAM_VERSION "\n"
+    g_print (PROGRAM_NAME " " PROGRAM_VERSION "\n"
              "Copyright (2011 - 2020) Aleksander Morgado\n"
              "License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl-2.0.html>\n"
              "This is free software: you are free to change and redistribute it.\n"
diff --git a/configure.ac b/configure.ac
index 5749503..e9883ad 100644
--- a/configure.ac
+++ b/configure.ac
@@ -391,7 +391,7 @@
 dnl QMI support (enabled by default)
 dnl
 
-LIBQMI_VERSION=1.25.1
+LIBQMI_VERSION=1.25.5
 
 AC_ARG_WITH(qmi, AS_HELP_STRING([--without-qmi], [Build without QMI support]), [], [with_qmi=yes])
 AM_CONDITIONAL(WITH_QMI, test "x$with_qmi" = "xyes")
diff --git a/docs/man/mmcli.1 b/docs/man/mmcli.1
index 4a08792..3730a88 100644
--- a/docs/man/mmcli.1
+++ b/docs/man/mmcli.1
@@ -229,9 +229,6 @@
 \fBCOMMAND\fR could be 'AT+GMM' to probe for phone model information. This
 operation is only available when ModemManager is run in debug mode.
 .TP
-.B \-\-list\-bearers
-List packet data bearers that are available for the given modem.
-.TP
 .B \-\-create\-bearer=['KEY1=VALUE1,KEY2=VALUE2,...']
 Create a new packet data bearer for a given modem. The \fBKEY\fRs and
 some \fBVALUE\fRs are listed below:
diff --git a/docs/reference/api/ModemManager-sections.txt b/docs/reference/api/ModemManager-sections.txt
index f1d6b27..e63ce12 100644
--- a/docs/reference/api/ModemManager-sections.txt
+++ b/docs/reference/api/ModemManager-sections.txt
@@ -140,9 +140,11 @@
 MM_MODEM_BAND_CDMA_BC18_US_PS_700
 MM_MODEM_BAND_CDMA_BC19_US_LOWER_700
 MM_MODEM_LOCATION_SOURCE_AGPS
+MM_MODEM_CAPABILITY_LTE_ADVANCED
 <SUBSECTION Private>
 MMModemBandDeprecated
 MMModemLocationSourceDeprecated
+MMModemCapabilityDeprecated
 MM_DEPRECATED
 </SECTION>
 
diff --git a/docs/reference/libmm-glib/libmm-glib-sections.txt b/docs/reference/libmm-glib/libmm-glib-sections.txt
index 64bd2e0..00c3adf 100644
--- a/docs/reference/libmm-glib/libmm-glib-sections.txt
+++ b/docs/reference/libmm-glib/libmm-glib-sections.txt
@@ -1128,6 +1128,11 @@
 mm_bearer_stats_get_duration
 mm_bearer_stats_get_rx_bytes
 mm_bearer_stats_get_tx_bytes
+mm_bearer_stats_get_attempts
+mm_bearer_stats_get_failed_attempts
+mm_bearer_stats_get_total_duration
+mm_bearer_stats_get_total_rx_bytes
+mm_bearer_stats_get_total_tx_bytes
 <SUBSECTION Private>
 mm_bearer_stats_get_dictionary
 mm_bearer_stats_new
@@ -1135,6 +1140,11 @@
 mm_bearer_stats_set_duration
 mm_bearer_stats_set_rx_bytes
 mm_bearer_stats_set_tx_bytes
+mm_bearer_stats_set_attempts
+mm_bearer_stats_set_failed_attempts
+mm_bearer_stats_set_total_duration
+mm_bearer_stats_set_total_rx_bytes
+mm_bearer_stats_set_total_tx_bytes
 <SUBSECTION Standard>
 MMBearerStatsClass
 MMBearerStatsPrivate
diff --git a/include/ModemManager-compat.h b/include/ModemManager-compat.h
index e145840..5aaaddf 100644
--- a/include/ModemManager-compat.h
+++ b/include/ModemManager-compat.h
@@ -709,6 +709,23 @@
  */
 #define MM_MODEM_LOCATION_SOURCE_AGPS ((MMModemLocationSourceDeprecated)MM_MODEM_LOCATION_SOURCE_AGPS_MSA)
 
+/* The following type exists just so that we can get deprecation warnings */
+MM_DEPRECATED
+typedef int MMModemCapabilityDeprecated;
+
+/**
+ * MM_MODEM_CAPABILITY_LTE_ADVANCED:
+ *
+ * Modem has LTE Advanced data capability.
+ *
+ * This value is deprecated because it is not used anywhere. LTE Advanced
+ * capable devices are reported as LTE capable.
+ *
+ * Since: 1.0
+ * Deprecated: 1.14.0.
+ */
+#define MM_MODEM_CAPABILITY_LTE_ADVANCED ((MMModemCapabilityDeprecated)(1 << 4))
+
 #endif /* MM_DISABLE_DEPRECATED */
 
 #endif /* _MODEMMANAGER_COMPAT_H_ */
diff --git a/include/ModemManager-enums.h b/include/ModemManager-enums.h
index bf068bd..9377ba0 100644
--- a/include/ModemManager-enums.h
+++ b/include/ModemManager-enums.h
@@ -36,8 +36,8 @@
  * @MM_MODEM_CAPABILITY_CDMA_EVDO: Modem supports at least one of CDMA 1xRTT, EVDO revision 0, EVDO revision A, or EVDO revision B.
  * @MM_MODEM_CAPABILITY_GSM_UMTS: Modem supports at least one of GSM, GPRS, EDGE, UMTS, HSDPA, HSUPA, or HSPA+ packet switched data capability.
  * @MM_MODEM_CAPABILITY_LTE: Modem has LTE data capability.
- * @MM_MODEM_CAPABILITY_LTE_ADVANCED: Modem has LTE Advanced data capability.
  * @MM_MODEM_CAPABILITY_IRIDIUM: Modem has Iridium capabilities.
+ * @MM_MODEM_CAPABILITY_5GNR: Modem has 5GNR capabilities. Since 1.14.
  * @MM_MODEM_CAPABILITY_ANY: Mask specifying all capabilities.
  *
  * Flags describing one or more of the general access technology families that a
@@ -51,8 +51,9 @@
     MM_MODEM_CAPABILITY_CDMA_EVDO    = 1 << 1,
     MM_MODEM_CAPABILITY_GSM_UMTS     = 1 << 2,
     MM_MODEM_CAPABILITY_LTE          = 1 << 3,
-    MM_MODEM_CAPABILITY_LTE_ADVANCED = 1 << 4,
+    /* MM_MODEM_CAPABILITY_LTE_ADVANCED deprecated */
     MM_MODEM_CAPABILITY_IRIDIUM      = 1 << 5,
+    MM_MODEM_CAPABILITY_5GNR         = 1 << 6,
     MM_MODEM_CAPABILITY_ANY          = 0xFFFFFFFF
 } MMModemCapability;
 
@@ -208,6 +209,7 @@
  * @MM_MODEM_ACCESS_TECHNOLOGY_EVDOA: CDMA2000 EVDO revision A.
  * @MM_MODEM_ACCESS_TECHNOLOGY_EVDOB: CDMA2000 EVDO revision B.
  * @MM_MODEM_ACCESS_TECHNOLOGY_LTE: LTE (ETSI 27.007: "E-UTRAN")
+ * @MM_MODEM_ACCESS_TECHNOLOGY_5GNR: 5GNR (ETSI 27.007: "NG-RAN"). Since 1.14.
  * @MM_MODEM_ACCESS_TECHNOLOGY_ANY: Mask specifying all access technologies.
  *
  * Describes various access technologies that a device uses when registered with
@@ -232,6 +234,7 @@
     MM_MODEM_ACCESS_TECHNOLOGY_EVDOA       = 1 << 12,
     MM_MODEM_ACCESS_TECHNOLOGY_EVDOB       = 1 << 13,
     MM_MODEM_ACCESS_TECHNOLOGY_LTE         = 1 << 14,
+    MM_MODEM_ACCESS_TECHNOLOGY_5GNR        = 1 << 15,
     MM_MODEM_ACCESS_TECHNOLOGY_ANY         = 0xFFFFFFFF,
 } MMModemAccessTechnology;
 
@@ -242,6 +245,7 @@
  * @MM_MODEM_MODE_2G: GPRS, EDGE.
  * @MM_MODEM_MODE_3G: UMTS, HSxPA.
  * @MM_MODEM_MODE_4G: LTE.
+ * @MM_MODEM_MODE_5G: 5GNR. Since 1.14.
  * @MM_MODEM_MODE_ANY: Any mode can be used (only this value allowed for POTS modems).
  *
  * Bitfield to indicate which access modes are supported, allowed or
@@ -255,6 +259,7 @@
     MM_MODEM_MODE_2G   = 1 << 1,
     MM_MODEM_MODE_3G   = 1 << 2,
     MM_MODEM_MODE_4G   = 1 << 3,
+    MM_MODEM_MODE_5G   = 1 << 4,
     MM_MODEM_MODE_ANY  = 0xFFFFFFFF
 } MMModemMode;
 
@@ -1188,6 +1193,7 @@
  * @MM_MODEM_3GPP_REGISTRATION_STATE_EMERGENCY_ONLY: Emergency services only. Since 1.8.
  * @MM_MODEM_3GPP_REGISTRATION_STATE_HOME_CSFB_NOT_PREFERRED: Registered for "CSFB not preferred", home network (applicable only when on LTE). Since 1.8.
  * @MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING_CSFB_NOT_PREFERRED: Registered for "CSFB not preferred", roaming network (applicable only when on LTE). Since 1.8.
+ * @MM_MODEM_3GPP_REGISTRATION_STATE_ATTACHED_RLOS: Attached for access to Restricted Local Operator Services (applicable only when on LTE). Since 1.14.
  *
  * GSM registration code as defined in 3GPP TS 27.007.
  *
@@ -1205,6 +1211,7 @@
     MM_MODEM_3GPP_REGISTRATION_STATE_EMERGENCY_ONLY             = 8,
     MM_MODEM_3GPP_REGISTRATION_STATE_HOME_CSFB_NOT_PREFERRED    = 9,
     MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING_CSFB_NOT_PREFERRED = 10,
+    MM_MODEM_3GPP_REGISTRATION_STATE_ATTACHED_RLOS              = 11,
 } MMModem3gppRegistrationState;
 
 /**
diff --git a/introspection/org.freedesktop.ModemManager1.Bearer.xml b/introspection/org.freedesktop.ModemManager1.Bearer.xml
index e86ef00..a07ee05 100644
--- a/introspection/org.freedesktop.ModemManager1.Bearer.xml
+++ b/introspection/org.freedesktop.ModemManager1.Bearer.xml
@@ -244,28 +244,71 @@
     <!--
         Stats:
 
-        If the modem supports it, this property will show statistics of the
-        ongoing connection.
+        If the modem supports it, this property will show statistics associated
+        to the bearer.
+
+        There are two main different statistic types reported: either applicable
+        to the ongoing connection, or otherwise compiled for all connections
+        that have been done on this bearer object.
 
         When the connection is disconnected automatically or explicitly by the
-        user, the values in this property will show the last values cached.
-        The statistics are reset
+        user, the values applicable to the ongoing connection will show the last
+        values cached.
 
         The following items may appear in the list of statistics:
         <variablelist>
           <varlistentry><term><literal>"rx-bytes"</literal></term>
             <listitem>
-              Number of bytes received without error, given as an unsigned 64-bit integer value (signature <literal>"t"</literal>).
+              Number of bytes received without error in the ongoing connection,
+              given as an unsigned 64-bit integer value (signature
+              <literal>"t"</literal>).
             </listitem>
           </varlistentry>
           <varlistentry><term><literal>"tx-bytes"</literal></term>
             <listitem>
-              Number bytes transmitted without error, given as an unsigned 64-bit integer value (signature <literal>"t"</literal>).
+              Number of bytes transmitted without error in the ongoing
+              connection, given as an unsigned 64-bit integer value (signature
+              <literal>"t"</literal>).
             </listitem>
             </varlistentry>
           <varlistentry><term><literal>"duration"</literal></term>
             <listitem>
-              Duration of the connection, in seconds, given as an unsigned integer value (signature <literal>"u"</literal>).
+              Duration of the ongoing connection, in seconds, given as an
+              unsigned integer value (signature <literal>"u"</literal>).
+            </listitem>
+          </varlistentry>
+          <varlistentry><term><literal>"attempts"</literal></term>
+            <listitem>
+              Total number of connection attempts done with this bearer, given
+              as an unsigned integer value (signature <literal>"u"</literal>).
+            </listitem>
+          </varlistentry>
+          <varlistentry><term><literal>"failed-attempts"</literal></term>
+            <listitem>
+              Number of failed connection attempts done with this bearer,
+              given as an unsigned integer value (signature
+              <literal>"u"</literal>).
+            </listitem>
+          </varlistentry>
+          <varlistentry><term><literal>"total-rx-bytes"</literal></term>
+            <listitem>
+              Total number of bytes received without error in all the successful
+              connection establishments, given as an unsigned 64-bit integer
+              value (signature <literal>"t"</literal>).
+            </listitem>
+          </varlistentry>
+          <varlistentry><term><literal>"total-tx-bytes"</literal></term>
+            <listitem>
+              Total number of bytes transmitted without error in all the
+              successful connection establishments, given as an unsigned 64-bit
+              integer value (signature <literal>"t"</literal>).
+            </listitem>
+          </varlistentry>
+          <varlistentry><term><literal>"total-duration"</literal></term>
+            <listitem>
+              Total duration of all the successful connection establishments, in
+              seconds, given as an unsigned integer value (signature
+              <literal>"u"</literal>).
             </listitem>
           </varlistentry>
         </variablelist>
diff --git a/introspection/org.freedesktop.ModemManager1.Modem.Location.xml b/introspection/org.freedesktop.ModemManager1.Modem.Location.xml
index d785a24..e0ac537 100644
--- a/introspection/org.freedesktop.ModemManager1.Modem.Location.xml
+++ b/introspection/org.freedesktop.ModemManager1.Modem.Location.xml
@@ -33,18 +33,26 @@
         @signal_location: Flag to control whether the device emits signals with the new location information. This argument is ignored when disabling location information gathering.
 
         Configure the location sources to use when gathering location
-        information. Also enable or disable location information gathering.
+        information. Adding new location sources may require to enable them
+        in the device (e.g. the GNSS engine will need to be started explicitly
+        if a GPS source is requested by the user). In the same way, removing
+        location sources may require to disable them in the device (e.g. when
+        no GPS sources are requested by the user, the GNSS engine will need
+        to be stopped explicitly).
+
         This method may require the client to authenticate itself.
 
-        When signals are emitted, any client application (including malicious
-        ones!) can listen for location updates unless D-Bus permissions restrict
-        these signals from certain users. If further security is desired, the
+        When location signaling is enabled by the user, any client application (including
+        malicious ones!) would be able to use the #org.freedesktop.ModemManager1.Modem.Location:Location
+        property to receive location updates. If further security is desired, the
         @signal_location argument can be set to %FALSE to disable location
         updates via D-Bus signals and require applications to call
-        authenticated APIs (like
-        <link linkend="gdbus-method-org-freedesktop-ModemManager1-Modem-Location.GetLocation">GetLocation()</link>
-        ) to get
-        location information.
+        authenticated APIs (like <link linkend="gdbus-method-org-freedesktop-ModemManager1-Modem-Location.GetLocation">GetLocation()</link>)
+        to get the location information.
+
+        By default location signaling is disabled, and therefore the
+        #org.freedesktop.ModemManager1.Modem.Location:Location property will not
+        be usable until explicitly enabled by the user.
 
         The optional
         <link linkend="MM-MODEM-LOCATION-SOURCE-AGPS-MSA:CAPS">MM_MODEM_LOCATION_SOURCE_AGPS_MSA</link>
@@ -96,13 +104,19 @@
         InjectAssistanceData:
         @data: assistance data to be injected to the GNSS module.
 
-        Inject assistance data to the GNSS module.
-        The data files should be downloaded using external means from the URLs specified in
-        the <link linkend="AssistanceDataServers">AssistanceDataServers</link> property.
+        Inject assistance data to the GNSS module, which will allow it to have a more
+        accurate positioning information.
 
-        The user does not need to specify the assistance data type being given.
+        The data files should be downloaded using external means from the URLs specified in
+        the <link linkend="AssistanceDataServers">AssistanceDataServers</link> property. The
+        user does not need to specify the assistance data type being given.
 
         There is no maximum @data size limit specified, default DBus system bus limits apply.
+
+        This method may be used when the device does not have a mobile network connection by
+        itself, and therefore it cannot use any A-GPS server to improve the accuracy of the
+        position. In this case, the user can instead download the assistance data files using
+        a WiFi or LAN network, and inject them to the GNSS engine manually.
     -->
     <method name="InjectAssistanceData">
       <arg name="data" type="ay" direction="in">
@@ -168,9 +182,16 @@
         gathering is enabled. If the modem supports multiple location types it
         may return more than one here.
 
-        Note that if the device was told not to emit updated location
-        information when location information gathering was initially enabled,
-        this property may not return any location information for security reasons.
+        For security reasons, the location information updates via this
+        property are disabled by default. Users can use this property to monitor
+        location updates only if the location signals are enabled with
+        <link linkend="gdbus-method-org-freedesktop-ModemManager1-Modem-Location.Setup">Setup()</link>,
+        but considering that enabling the location signals would allow all users
+        to receive property updates as well, not just the process that enabled them.
+        For a finer grained access control, the user can use the
+        <link linkend="gdbus-method-org-freedesktop-ModemManager1-Modem-Location.GetLocation">GetLocation()</link>
+        method instead, which may require the client to authenticate itself on every
+        call.
 
         This dictionary is composed of a
         <link linkend="MMModemLocationSource">MMModemLocationSource</link>
diff --git a/introspection/org.freedesktop.ModemManager1.Modem.Modem3gpp.xml b/introspection/org.freedesktop.ModemManager1.Modem.Modem3gpp.xml
index ea05feb..8abea6a 100644
--- a/introspection/org.freedesktop.ModemManager1.Modem.Modem3gpp.xml
+++ b/introspection/org.freedesktop.ModemManager1.Modem.Modem3gpp.xml
@@ -200,7 +200,25 @@
     <!--
         Pco:
 
-        The raw PCOs received from the network.
+        The raw PCOs received from the network, given as array of PCO
+        elements (signature <literal>"a(ubay)"</literal>).
+
+        Each PCO is defined as a sequence of 3 fields:
+        <orderedlist>
+          <listitem>
+            The session ID associated with the PCO, given as an
+            unsigned integer value (signature <literal>"u"</literal>).
+          </listitem>
+          <listitem>
+            The flag that indicates whether the PCO data contains the
+            complete PCO structure received from the network, given as
+            a boolean value (signature <literal>"b"</literal>).
+          </listitem>
+          <listitem>
+            The raw  PCO data, given as an array of bytes (signature
+            <literal>"ay"</literal>).
+          </listitem>
+        </orderedlist>
     -->
     <property name="Pco" type="a(ubay)" access="read" />
 
@@ -219,8 +237,9 @@
 
         The network may decide to use different settings during the actual device attach
         procedure, e.g. if the device is roaming or no explicit settings were requested,
-        so the properties shown in the #org.freedesktop.ModemManager1.Modem.Modem3gpp.InitialEpsBearer:InitialEpsBearer
-        may be totally different.
+        so the values shown in the
+        #org.freedesktop.ModemManager1.Modem.Modem3gpp:InitialEpsBearer
+        bearer object may be totally different.
 
         This is a read-only property, updating these settings should be done using the
         <link linkend="gdbus-method-org-freedesktop-ModemManager1-Modem-Modem3gpp.SetInitialEpsBearerSettings">SetInitialEpsBearerSettings()</link>
diff --git a/introspection/org.freedesktop.ModemManager1.Modem.ModemCdma.xml b/introspection/org.freedesktop.ModemManager1.Modem.ModemCdma.xml
index 6000f41..5c27f3f 100644
--- a/introspection/org.freedesktop.ModemManager1.Modem.ModemCdma.xml
+++ b/introspection/org.freedesktop.ModemManager1.Modem.ModemCdma.xml
@@ -112,7 +112,7 @@
         ActivationStateChanged:
         @activation_state: Current activation state, given as a <link linkend="MMModemCdmaActivationState">MMModemCdmaActivationState</link>.
         @activation_error: Carrier-specific error code, given as a <link linkend="MMCdmaActivationError">MMCdmaActivationError</link>.
-        @status_changes: Properties that have changed as a result of this activation state chage, including <literal>"mdn"</literal> and <literal>"min"</literal>. The dictionary may be empty if the changed properties are unknown.
+        @status_changes: Properties that have changed as a result of this activation state change, including <literal>"mdn"</literal> and <literal>"min"</literal>. The dictionary may be empty if the changed properties are unknown.
 
         The device activation state changed.
     -->
diff --git a/introspection/org.freedesktop.ModemManager1.Modem.Simple.xml b/introspection/org.freedesktop.ModemManager1.Modem.Simple.xml
index 91501c5..bbc497e 100644
--- a/introspection/org.freedesktop.ModemManager1.Modem.Simple.xml
+++ b/introspection/org.freedesktop.ModemManager1.Modem.Simple.xml
@@ -156,7 +156,7 @@
               unsigned integer values (signature <literal>"au"</literal>).
             </listitem>
           </varlistentry>
-          <varlistentry><term><literal>"access-technology"</literal></term>
+          <varlistentry><term><literal>"access-technologies"</literal></term>
             <listitem>
               A <link linkend="MMModemAccessTechnology">MMModemAccessTechnology</link> value,
               given only when registered, as an unsigned integer value
diff --git a/introspection/org.freedesktop.ModemManager1.Modem.xml b/introspection/org.freedesktop.ModemManager1.Modem.xml
index eb4debd..b026b01 100644
--- a/introspection/org.freedesktop.ModemManager1.Modem.xml
+++ b/introspection/org.freedesktop.ModemManager1.Modem.xml
@@ -55,7 +55,7 @@
 
     <!--
         CreateBearer:
-        @properties: List of properties to assign to the bearer after creating it.
+        @properties: Dictionary of properties needed to get the bearer connected.
         @path: On success, the object path of the newly created bearer.
 
         Create a new packet data bearer using the given characteristics.
@@ -146,7 +146,12 @@
         SetCurrentCapabilities:
         @capabilities: Bitmask of <link linkend="MMModemCapability">MMModemCapability</link> values, to specify the capabilities to use.
 
-        Set the capabilities of the device. A restart of the modem may be required.
+        Set the capabilities of the device.
+
+        The given bitmask should be supported by the modem, as specified in the
+        #org.freedesktop.ModemManager1.Modem:SupportedCapabilities property.
+
+        This command may power-cycle the device.
     -->
     <method name="SetCurrentCapabilities">
       <arg name="capabilities" type="u" direction="in" />
@@ -178,15 +183,16 @@
     </method>
 
     <!--
-       Command
-       @cmd The command string, e.g. "AT+GCAP" or "+GCAP" (leading AT is inserted if necessary).
-       @timeout The number of seconds to wait for a response.
-       @response The modem's response.
+       Command:
+       @cmd: The command string, e.g. "AT+GCAP" or "+GCAP" (leading AT is inserted if necessary).
+       @timeout: The number of seconds to wait for a response.
+       @response: The modem's response.
 
        Send an arbitrary AT command to a modem and get the response.
 
        Note that using this interface call is only allowed when running
-       ModemManager in debug mode.
+       ModemManager in debug mode or if the project was built using
+       the <literal>with-at-command-via-dbus</literal> configure option.
       -->
     <method name="Command">
       <arg name="cmd"      type="s" direction="in"  />
@@ -230,12 +236,16 @@
         SupportedCapabilities:
 
         List of <link linkend="MMModemCapability">MMModemCapability</link>
-        values, specifying the combinations of generic family of access
+        bitmasks, specifying the combinations of generic family of access
         technologies the modem supports.
 
-        If the modem doesn't allow changing the current capabilities, a single entry with
-        <link linkend="MM-MODEM-CAPABILITY-ANY:CAPS"><constant>MM_MODEM_CAPABILITY_ANY</constant></link>
-        will be given.
+        If the modem doesn't allow changing the current capabilities, the
+        list will report one single entry with the same bitmask as in
+        #org.freedesktop.ModemManager1.Modem:CurrentCapabilities.
+
+        Only multimode devices implementing both 3GPP (GSM/UMTS/LTE/5GNR) and
+        3GPP2 (CDMA/EVDO) specs will report more than one combination of
+        capabilities.
     -->
     <property name="SupportedCapabilities" type="au" access="read" />
 
@@ -243,8 +253,11 @@
         CurrentCapabilities:
 
         Bitmask of <link linkend="MMModemCapability">MMModemCapability</link>
-        values, specifying the  generic family of access technologies the modem
-        currently supports without a firmware reload or reinitialization.
+        values, specifying the currently used generic family of access
+        technologies.
+
+        This bitmask will be one of the ones listed in
+        #org.freedesktop.ModemManager1.Modem:SupportedCapabilities.
     -->
     <property name="CurrentCapabilities" type="u" access="read" />
 
diff --git a/introspection/org.freedesktop.ModemManager1.xml b/introspection/org.freedesktop.ModemManager1.xml
index 85b6213..e9ec032 100644
--- a/introspection/org.freedesktop.ModemManager1.xml
+++ b/introspection/org.freedesktop.ModemManager1.xml
@@ -9,7 +9,7 @@
    Copyright (C) 2011-2013 Lanedo GmbH
 -->
 
-<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
+<node name="/org/freedesktop/ModemManager1" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
 
   <!--
       org.freedesktop.ModemManager1:
diff --git a/libmm-glib/mm-bearer-stats.c b/libmm-glib/mm-bearer-stats.c
index df499ca..49bebc0 100644
--- a/libmm-glib/mm-bearer-stats.c
+++ b/libmm-glib/mm-bearer-stats.c
@@ -11,8 +11,7 @@
  * GNU General Public License for more details:
  *
  * Copyright (C) 2015 Azimut Electronics
- *
- * Author: Aleksander Morgado <aleksander@aleksander.es>
+ * Copyright (C) 2015-2020 Aleksander Morgado <aleksander@aleksander.es>
  */
 
 #include <string.h>
@@ -34,14 +33,24 @@
 
 G_DEFINE_TYPE (MMBearerStats, mm_bearer_stats, G_TYPE_OBJECT)
 
-#define PROPERTY_DURATION "duration"
-#define PROPERTY_RX_BYTES "rx-bytes"
-#define PROPERTY_TX_BYTES "tx-bytes"
+#define PROPERTY_DURATION        "duration"
+#define PROPERTY_RX_BYTES        "rx-bytes"
+#define PROPERTY_TX_BYTES        "tx-bytes"
+#define PROPERTY_ATTEMPTS        "attempts"
+#define PROPERTY_FAILED_ATTEMPTS "failed-attempts"
+#define PROPERTY_TOTAL_DURATION  "total-duration"
+#define PROPERTY_TOTAL_RX_BYTES  "total-rx-bytes"
+#define PROPERTY_TOTAL_TX_BYTES  "total-tx-bytes"
 
 struct _MMBearerStatsPrivate {
     guint   duration;
     guint64 rx_bytes;
     guint64 tx_bytes;
+    guint   attempts;
+    guint   failed_attempts;
+    guint   total_duration;
+    guint64 total_rx_bytes;
+    guint64 total_tx_bytes;
 };
 
 /*****************************************************************************/
@@ -143,6 +152,168 @@
 /*****************************************************************************/
 
 /**
+ * mm_bearer_stats_get_attempts:
+ * @self: a #MMBearerStats.
+ *
+ * Gets the number of connection attempts done with this bearer.
+ *
+ * Returns: a #guint.
+ *
+ * Since: 1.14
+ */
+guint
+mm_bearer_stats_get_attempts (MMBearerStats *self)
+{
+    g_return_val_if_fail (MM_IS_BEARER_STATS (self), 0);
+
+    return self->priv->attempts;
+}
+
+/**
+ * mm_bearer_stats_set_attempts: (skip)
+ */
+void
+mm_bearer_stats_set_attempts (MMBearerStats *self,
+                              guint          attempts)
+{
+    g_return_if_fail (MM_IS_BEARER_STATS (self));
+
+    self->priv->attempts = attempts;
+}
+
+/*****************************************************************************/
+
+/**
+ * mm_bearer_stats_get_failed_attempts:
+ * @self: a #MMBearerStats.
+ *
+ * Gets the number of failed connection attempts done with this bearer.
+ *
+ * Returns: a #guint.
+ *
+ * Since: 1.14
+ */
+guint
+mm_bearer_stats_get_failed_attempts (MMBearerStats *self)
+{
+    g_return_val_if_fail (MM_IS_BEARER_STATS (self), 0);
+
+    return self->priv->failed_attempts;
+}
+
+/**
+ * mm_bearer_stats_set_failed_attempts: (skip)
+ */
+void
+mm_bearer_stats_set_failed_attempts (MMBearerStats *self,
+                                     guint          failed_attempts)
+{
+    g_return_if_fail (MM_IS_BEARER_STATS (self));
+
+    self->priv->failed_attempts = failed_attempts;
+}
+
+/*****************************************************************************/
+
+/**
+ * mm_bearer_stats_get_total_duration:
+ * @self: a #MMBearerStats.
+ *
+ * Gets the total duration of all the connections of this bearer.
+ *
+ * Returns: a #guint.
+ *
+ * Since: 1.14
+ */
+guint
+mm_bearer_stats_get_total_duration (MMBearerStats *self)
+{
+    g_return_val_if_fail (MM_IS_BEARER_STATS (self), 0);
+
+    return self->priv->total_duration;
+}
+
+/**
+ * mm_bearer_stats_set_total_duration: (skip)
+ */
+void
+mm_bearer_stats_set_total_duration (MMBearerStats *self,
+                                    guint          total_duration)
+{
+    g_return_if_fail (MM_IS_BEARER_STATS (self));
+
+    self->priv->total_duration = total_duration;
+}
+
+/*****************************************************************************/
+
+/**
+ * mm_bearer_stats_get_total_rx_bytes:
+ * @self: a #MMBearerStats.
+ *
+ * Gets the total number of bytes received without error during all the
+ * connections of this bearer.
+ *
+ * Returns: a #guint64.
+ *
+ * Since: 1.14
+ */
+guint64
+mm_bearer_stats_get_total_rx_bytes (MMBearerStats *self)
+{
+    g_return_val_if_fail (MM_IS_BEARER_STATS (self), 0);
+
+    return self->priv->total_rx_bytes;
+}
+
+/**
+ * mm_bearer_stats_set_total_rx_bytes: (skip)
+ */
+void
+mm_bearer_stats_set_total_rx_bytes (MMBearerStats *self,
+                                    guint64        total_bytes)
+{
+    g_return_if_fail (MM_IS_BEARER_STATS (self));
+
+    self->priv->total_rx_bytes = total_bytes;
+}
+
+/*****************************************************************************/
+
+/**
+ * mm_bearer_stats_get_total_tx_bytes:
+ * @self: a #MMBearerStats.
+ *
+ * Gets the total number of bytes transmitted without error during all the
+ * connections of this bearer.
+ *
+ * Returns: a #guint64.
+ *
+ * Since: 1.14
+ */
+guint64
+mm_bearer_stats_get_total_tx_bytes (MMBearerStats *self)
+{
+    g_return_val_if_fail (MM_IS_BEARER_STATS (self), 0);
+
+    return self->priv->total_tx_bytes;
+}
+
+/**
+ * mm_bearer_stats_set_total_tx_bytes: (skip)
+ */
+void
+mm_bearer_stats_set_total_tx_bytes (MMBearerStats *self,
+                                    guint64        total_bytes)
+{
+    g_return_if_fail (MM_IS_BEARER_STATS (self));
+
+    self->priv->total_tx_bytes = total_bytes;
+}
+
+/*****************************************************************************/
+
+/**
  * mm_bearer_stats_get_dictionary: (skip)
  */
 GVariant *
@@ -167,6 +338,26 @@
                             "{sv}",
                             PROPERTY_TX_BYTES,
                             g_variant_new_uint64 (self->priv->tx_bytes));
+    g_variant_builder_add  (&builder,
+                            "{sv}",
+                            PROPERTY_ATTEMPTS,
+                            g_variant_new_uint32 (self->priv->attempts));
+    g_variant_builder_add  (&builder,
+                            "{sv}",
+                            PROPERTY_FAILED_ATTEMPTS,
+                            g_variant_new_uint32 (self->priv->failed_attempts));
+    g_variant_builder_add  (&builder,
+                            "{sv}",
+                            PROPERTY_TOTAL_DURATION,
+                            g_variant_new_uint32 (self->priv->total_duration));
+    g_variant_builder_add  (&builder,
+                            "{sv}",
+                            PROPERTY_TOTAL_RX_BYTES,
+                            g_variant_new_uint64 (self->priv->total_rx_bytes));
+    g_variant_builder_add  (&builder,
+                            "{sv}",
+                            PROPERTY_TOTAL_TX_BYTES,
+                            g_variant_new_uint64 (self->priv->total_tx_bytes));
     return g_variant_builder_end (&builder);
 }
 
@@ -212,7 +403,28 @@
             mm_bearer_stats_set_tx_bytes (
                 self,
                 g_variant_get_uint64 (value));
+        } else if (g_str_equal (key, PROPERTY_ATTEMPTS)) {
+            mm_bearer_stats_set_attempts (
+                self,
+                g_variant_get_uint32 (value));
+        } else if (g_str_equal (key, PROPERTY_FAILED_ATTEMPTS)) {
+            mm_bearer_stats_set_failed_attempts (
+                self,
+                g_variant_get_uint32 (value));
+        } else if (g_str_equal (key, PROPERTY_TOTAL_DURATION)) {
+            mm_bearer_stats_set_total_duration (
+                self,
+                g_variant_get_uint32 (value));
+        } else if (g_str_equal (key, PROPERTY_TOTAL_RX_BYTES)) {
+            mm_bearer_stats_set_total_rx_bytes (
+                self,
+                g_variant_get_uint64 (value));
+        } else if (g_str_equal (key, PROPERTY_TOTAL_TX_BYTES)) {
+            mm_bearer_stats_set_total_tx_bytes (
+                self,
+                g_variant_get_uint64 (value));
         }
+
         g_free (key);
         g_variant_unref (value);
     }
diff --git a/libmm-glib/mm-bearer-stats.h b/libmm-glib/mm-bearer-stats.h
index dceb5ae..bfaba1d 100644
--- a/libmm-glib/mm-bearer-stats.h
+++ b/libmm-glib/mm-bearer-stats.h
@@ -58,9 +58,14 @@
 GType mm_bearer_stats_get_type (void);
 G_DEFINE_AUTOPTR_CLEANUP_FUNC (MMBearerStats, g_object_unref)
 
-guint   mm_bearer_stats_get_duration (MMBearerStats *self);
-guint64 mm_bearer_stats_get_rx_bytes (MMBearerStats *self);
-guint64 mm_bearer_stats_get_tx_bytes (MMBearerStats *self);
+guint   mm_bearer_stats_get_duration        (MMBearerStats *self);
+guint64 mm_bearer_stats_get_rx_bytes        (MMBearerStats *self);
+guint64 mm_bearer_stats_get_tx_bytes        (MMBearerStats *self);
+guint   mm_bearer_stats_get_attempts        (MMBearerStats *self);
+guint   mm_bearer_stats_get_failed_attempts (MMBearerStats *self);
+guint   mm_bearer_stats_get_total_duration  (MMBearerStats *self);
+guint64 mm_bearer_stats_get_total_rx_bytes  (MMBearerStats *self);
+guint64 mm_bearer_stats_get_total_tx_bytes  (MMBearerStats *self);
 
 /*****************************************************************************/
 /* ModemManager/libmm-glib/mmcli specific methods */
@@ -73,9 +78,14 @@
 MMBearerStats *mm_bearer_stats_new_from_dictionary (GVariant *dictionary,
                                                     GError **error);
 
-void mm_bearer_stats_set_duration (MMBearerStats *self, guint duration);
-void mm_bearer_stats_set_rx_bytes (MMBearerStats *self, guint64 rx_bytes);
-void mm_bearer_stats_set_tx_bytes (MMBearerStats *self, guint64 tx_bytes);
+void mm_bearer_stats_set_duration             (MMBearerStats *self, guint   duration);
+void mm_bearer_stats_set_rx_bytes             (MMBearerStats *self, guint64 rx_bytes);
+void mm_bearer_stats_set_tx_bytes             (MMBearerStats *self, guint64 tx_bytes);
+void mm_bearer_stats_set_attempts             (MMBearerStats *self, guint   attempts);
+void mm_bearer_stats_set_failed_attempts      (MMBearerStats *self, guint   failed_attempts);
+void mm_bearer_stats_set_total_duration       (MMBearerStats *self, guint   duration);
+void mm_bearer_stats_set_total_rx_bytes       (MMBearerStats *self, guint64 rx_bytes);
+void mm_bearer_stats_set_total_tx_bytes       (MMBearerStats *self, guint64 tx_bytes);
 
 GVariant *mm_bearer_stats_get_dictionary (MMBearerStats *self);
 
diff --git a/libmm-glib/mm-common-helpers.c b/libmm-glib/mm-common-helpers.c
index 484771b..d2c54a1 100644
--- a/libmm-glib/mm-common-helpers.c
+++ b/libmm-glib/mm-common-helpers.c
@@ -538,17 +538,6 @@
     return g_variant_builder_end (&builder);
 }
 
-GVariant *
-mm_common_build_capability_combinations_any (void)
-{
-    GVariantBuilder builder;
-
-    g_variant_builder_init (&builder, G_VARIANT_TYPE ("au"));
-    g_variant_builder_add_value (&builder,
-                                 g_variant_new_uint32 (MM_MODEM_CAPABILITY_ANY));
-    return g_variant_builder_end (&builder);
-}
-
 void
 mm_common_get_bands_from_string (const gchar *str,
                                  MMModemBand **bands,
@@ -1333,7 +1322,14 @@
     glong num;
     guint eol = 0;
 
-    if (!str || !str[0])
+    if (!str)
+        return FALSE;
+
+    /* ignore all leading whitespaces */
+    while (str[0] == ' ')
+        str++;
+
+    if (!str[0])
         return FALSE;
 
     for (num = 0; str[num]; num++) {
@@ -1367,17 +1363,10 @@
                             guint32 match_index,
                             gint *out)
 {
-    gchar *s;
-    gboolean ret;
+    g_autofree gchar *s = NULL;
 
-    s = g_match_info_fetch (match_info, match_index);
-    if (!s)
-        return FALSE;
-
-    ret = mm_get_int_from_str (s, out);
-    g_free (s);
-
-    return ret;
+    s = mm_get_string_unquoted_from_match_info (match_info, match_index);
+    return (s ? mm_get_int_from_str (s, out) : FALSE);
 }
 
 gboolean
@@ -1400,7 +1389,14 @@
     guint64 num;
     guint   eol = 0;
 
-    if (!str || !str[0])
+    if (!str)
+        return FALSE;
+
+    /* ignore all leading whitespaces */
+    while (str[0] == ' ')
+        str++;
+
+    if (!str[0])
         return FALSE;
 
     for (num = 0; str[num]; num++) {
@@ -1452,6 +1448,10 @@
     if (!str)
         return FALSE;
 
+    /* ignore all leading whitespaces */
+    while (str[0] == ' ')
+        str++;
+
     if (g_str_has_prefix (str, "0x"))
         str = &str[2];
 
@@ -1503,17 +1503,35 @@
                             guint32     match_index,
                             guint64    *out)
 {
-    gchar *s;
-    gboolean ret;
+    g_autofree gchar *s = NULL;
 
-    s = g_match_info_fetch (match_info, match_index);
-    if (!s)
+    s = mm_get_string_unquoted_from_match_info (match_info, match_index);
+    return (s ? mm_get_u64_from_str (s, out) : FALSE);
+}
+
+gboolean
+mm_get_uint_from_hex_match_info (GMatchInfo *match_info,
+                                 guint32     match_index,
+                                 guint      *out)
+{
+    guint64 num;
+
+    if (!mm_get_u64_from_hex_match_info (match_info, match_index, &num) || num > G_MAXUINT)
         return FALSE;
 
-    ret = mm_get_u64_from_str (s, out);
-    g_free (s);
+    *out = (guint)num;
+    return TRUE;
+}
 
-    return ret;
+gboolean
+mm_get_u64_from_hex_match_info (GMatchInfo *match_info,
+                                guint32     match_index,
+                                guint64    *out)
+{
+    g_autofree gchar *s = NULL;
+
+    s = mm_get_string_unquoted_from_match_info (match_info, match_index);
+    return (s ? mm_get_u64_from_hex_str (s, out) : FALSE);
 }
 
 gboolean
@@ -1560,17 +1578,10 @@
                                guint32 match_index,
                                gdouble *out)
 {
-    gchar *s;
-    gboolean ret;
+    g_autofree gchar *s = NULL;
 
-    s = g_match_info_fetch (match_info, match_index);
-    if (!s)
-        return FALSE;
-
-    ret = mm_get_double_from_str (s, out);
-    g_free (s);
-
-    return ret;
+    s = mm_get_string_unquoted_from_match_info (match_info, match_index);
+    return (s ? mm_get_double_from_str (s, out) : FALSE);
 }
 
 gchar *
diff --git a/libmm-glib/mm-common-helpers.h b/libmm-glib/mm-common-helpers.h
index e910d8c..65d0e70 100644
--- a/libmm-glib/mm-common-helpers.h
+++ b/libmm-glib/mm-common-helpers.h
@@ -126,7 +126,6 @@
 GVariant          *mm_common_capability_combinations_array_to_variant  (const MMModemCapability *capabilities,
                                                                         guint n_capabilities);
 GVariant          *mm_common_capability_combinations_garray_to_variant (GArray *array);
-GVariant          *mm_common_build_capability_combinations_any         (void);
 GVariant          *mm_common_build_capability_combinations_none        (void);
 
 GArray                              *mm_common_oma_pending_network_initiated_sessions_variant_to_garray (GVariant *variant);
@@ -165,6 +164,12 @@
 gboolean  mm_get_u64_from_match_info             (GMatchInfo  *match_info,
                                                   guint32      match_index,
                                                   guint64     *out);
+gboolean  mm_get_uint_from_hex_match_info        (GMatchInfo  *match_info,
+                                                  guint32      match_index,
+                                                  guint       *out);
+gboolean  mm_get_u64_from_hex_match_info         (GMatchInfo  *match_info,
+                                                  guint32      match_index,
+                                                  guint64     *out);
 gboolean  mm_get_double_from_str                 (const gchar *str,
                                                   gdouble     *out);
 gboolean  mm_get_double_from_match_info          (GMatchInfo  *match_info,
diff --git a/libmm-glib/mm-modem-3gpp.c b/libmm-glib/mm-modem-3gpp.c
index 7170acd..1cfb419 100644
--- a/libmm-glib/mm-modem-3gpp.c
+++ b/libmm-glib/mm-modem-3gpp.c
@@ -38,7 +38,8 @@
  * properties of the 3GPP interface.
  *
  * The 3GPP interface is exposed whenever a modem has any of the 3GPP
- * capabilities (%MM_MODEM_CAPABILITY_GSM_UMTS, %MM_MODEM_CAPABILITY_LTE or %MM_MODEM_CAPABILITY_LTE_ADVANCED).
+ * capabilities (%MM_MODEM_CAPABILITY_GSM_UMTS, %MM_MODEM_CAPABILITY_LTE
+ * or %MM_MODEM_CAPABILITY_5GNR).
  */
 
 G_DEFINE_TYPE (MMModem3gpp, mm_modem_3gpp, MM_GDBUS_TYPE_MODEM3GPP_PROXY)
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index b158bb5..15ba237 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -128,6 +128,9 @@
 	icera/mm-modem-helpers-icera.c \
 	icera/mm-modem-helpers-icera.h \
 	$(NULL)
+libhelpers_icera_la_CPPFLAGS = \
+	-DMM_MODULE_NAME=\"shared-icera\" \
+	$(NULL)
 
 noinst_PROGRAMS += test-modem-helpers-icera
 test_modem_helpers_icera_SOURCES = \
@@ -150,7 +153,10 @@
 	icera/mm-broadband-bearer-icera.h \
 	icera/mm-broadband-bearer-icera.c \
 	$(NULL)
-libmm_shared_icera_la_CPPFLAGS = $(SHARED_COMMON_COMPILER_FLAGS)
+libmm_shared_icera_la_CPPFLAGS = \
+	$(SHARED_COMMON_COMPILER_FLAGS)
+	-DMM_MODULE_NAME=\"shared-icera\" \
+	$(NULL)
 libmm_shared_icera_la_LDFLAGS = $(SHARED_COMMON_LINKER_FLAGS)
 libmm_shared_icera_la_LIBADD = \
 	$(builddir)/libhelpers-icera.la \
@@ -171,6 +177,9 @@
 	sierra/mm-modem-helpers-sierra.c \
 	sierra/mm-modem-helpers-sierra.h \
 	$(NULL)
+libhelpers_sierra_la_CPPFLAGS = \
+	-DMM_MODULE_NAME=\"shared-sierra\" \
+	$(NULL)
 
 noinst_PROGRAMS += test-modem-helpers-sierra
 test_modem_helpers_sierra_SOURCES = \
@@ -197,7 +206,10 @@
 	sierra/mm-broadband-modem-sierra.c  \
 	sierra/mm-broadband-modem-sierra.h  \
 	$(NULL)
-libmm_shared_sierra_la_CPPFLAGS = $(SHARED_COMMON_COMPILER_FLAGS)
+libmm_shared_sierra_la_CPPFLAGS = \
+	$(SHARED_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"shared-sierra\" \
+	$(NULL)
 libmm_shared_sierra_la_LDFLAGS = $(SHARED_COMMON_LINKER_FLAGS)
 libmm_shared_sierra_la_LIBADD = \
 	$(builddir)/libhelpers-sierra.la \
@@ -241,7 +253,10 @@
 	novatel/mm-broadband-modem-novatel.c \
 	novatel/mm-broadband-modem-novatel.h \
 	$(NULL)
-libmm_shared_novatel_la_CPPFLAGS = $(SHARED_COMMON_COMPILER_FLAGS)
+libmm_shared_novatel_la_CPPFLAGS = \
+	$(SHARED_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"shared-novatel\" \
+	$(NULL)
 libmm_shared_novatel_la_LDFLAGS = $(SHARED_COMMON_LINKER_FLAGS)
 
 NOVATEL_COMMON_COMPILER_FLAGS = -I$(top_srcdir)/plugins/novatel
@@ -259,6 +274,9 @@
 	xmm/mm-modem-helpers-xmm.c \
 	xmm/mm-modem-helpers-xmm.h \
 	$(NULL)
+libhelpers_xmm_la_CPPFLAGS = \
+	-DMM_MODULE_NAME=\"shared-xmm\" \
+	$(NULL)
 
 noinst_PROGRAMS += test-modem-helpers-xmm
 test_modem_helpers_xmm_SOURCES = \
@@ -289,7 +307,10 @@
 	$(NULL)
 endif
 
-libmm_shared_xmm_la_CPPFLAGS = $(SHARED_COMMON_COMPILER_FLAGS)
+libmm_shared_xmm_la_CPPFLAGS = \
+	$(SHARED_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"shared-xmm\" \
+	$(NULL)
 libmm_shared_xmm_la_LDFLAGS = $(SHARED_COMMON_LINKER_FLAGS)
 libmm_shared_xmm_la_LIBADD = \
 	$(builddir)/libhelpers-xmm.la \
@@ -340,6 +361,7 @@
 	telit/mm-modem-helpers-telit.h \
 	$(NULL)
 libhelpers_telit_la_CPPFLAGS = \
+	-DMM_MODULE_NAME=\"shared-telit\" \
 	-I$(top_srcdir)/plugins/telit \
 	-I$(top_builddir)/plugins/telit \
 	$(NULL)
@@ -383,6 +405,7 @@
 	-I$(top_srcdir)/plugins/telit \
 	-I$(top_builddir)/plugins/telit \
 	$(SHARED_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"shared-telit\" \
 	$(NULL)
 libmm_shared_telit_la_LDFLAGS = $(SHARED_COMMON_LINKER_FLAGS)
 libmm_shared_telit_la_LIBADD = \
@@ -409,7 +432,10 @@
 	foxconn/mm-broadband-modem-foxconn-t77w968.c \
 	foxconn/mm-broadband-modem-foxconn-t77w968.h \
 	$(NULL)
-libmm_shared_foxconn_la_CPPFLAGS = $(SHARED_COMMON_COMPILER_FLAGS)
+libmm_shared_foxconn_la_CPPFLAGS = \
+	$(SHARED_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"shared-foxconn\" \
+	$(NULL)
 libmm_shared_foxconn_la_LDFLAGS = $(SHARED_COMMON_LINKER_FLAGS)
 
 FOXCONN_COMMON_COMPILER_FLAGS = -I$(top_srcdir)/plugins/foxconn
@@ -427,7 +453,10 @@
 	generic/mm-plugin-generic.c \
 	generic/mm-plugin-generic.h \
 	$(NULL)
-libmm_plugin_generic_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
+libmm_plugin_generic_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"generic\" \
+	$(NULL)
 libmm_plugin_generic_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
 
 noinst_PROGRAMS += test-service-generic
@@ -451,6 +480,9 @@
 	altair/mm-modem-helpers-altair-lte.c \
 	altair/mm-modem-helpers-altair-lte.h \
 	$(NULL)
+libhelpers_altair_lte_la_CPPFLAGS = \
+	-DMM_MODULE_NAME=\"altair-lte\" \
+	$(NULL)
 
 noinst_PROGRAMS += test-modem-helpers-altair-lte
 test_modem_helpers_altair_lte_SOURCES = \
@@ -474,9 +506,12 @@
 	altair/mm-broadband-bearer-altair-lte.c \
 	altair/mm-broadband-bearer-altair-lte.h \
 	$(NULL)
-libmm_plugin_altair_lte_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
-libmm_plugin_altair_lte_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
-libmm_plugin_altair_lte_la_LIBADD   = $(builddir)/libhelpers-altair-lte.la
+libmm_plugin_altair_lte_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"altair-lte\" \
+	$(NULL)
+libmm_plugin_altair_lte_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_altair_lte_la_LIBADD = $(builddir)/libhelpers-altair-lte.la
 
 endif
 
@@ -493,8 +528,11 @@
 	anydata/mm-broadband-modem-anydata.h \
 	anydata/mm-broadband-modem-anydata.c \
 	$(NULL)
-libmm_plugin_anydata_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
-libmm_plugin_anydata_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_anydata_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"anydata\" \
+	$(NULL)
+libmm_plugin_anydata_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
 
 endif
 
@@ -509,6 +547,9 @@
 	cinterion/mm-modem-helpers-cinterion.c \
 	cinterion/mm-modem-helpers-cinterion.h \
 	$(NULL)
+libhelpers_cinterion_la_CPPFLAGS = \
+	-DMM_MODULE_NAME=\"cinterion\" \
+	$(NULL)
 
 noinst_PROGRAMS += test-modem-helpers-cinterion
 test_modem_helpers_cinterion_SOURCES = \
@@ -540,9 +581,12 @@
 	cinterion/mm-broadband-modem-qmi-cinterion.h \
 	$(NULL)
 endif
-libmm_plugin_cinterion_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
-libmm_plugin_cinterion_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
-libmm_plugin_cinterion_la_LIBADD   = $(builddir)/libhelpers-cinterion.la
+libmm_plugin_cinterion_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"cinterion\" \
+	$(NULL)
+libmm_plugin_cinterion_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_cinterion_la_LIBADD = $(builddir)/libhelpers-cinterion.la
 
 dist_udevrules_DATA += cinterion/77-mm-cinterion-port-types.rules
 
@@ -569,6 +613,7 @@
 	$(TELIT_COMMON_COMPILER_FLAGS) \
 	$(XMM_COMMON_COMPILER_FLAGS) \
 	$(FOXCONN_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"dell\" \
 	$(NULL)
 libmm_plugin_dell_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
 
@@ -591,8 +636,11 @@
 	dlink/mm-plugin-dlink.c \
 	dlink/mm-plugin-dlink.h \
 	$(NULL)
-libmm_plugin_dlink_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
-libmm_plugin_dlink_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_dlink_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"d-link\" \
+	$(NULL)
+libmm_plugin_dlink_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
 
 dist_udevrules_DATA += dlink/77-mm-dlink-port-types.rules
 
@@ -611,8 +659,12 @@
 	fibocom/mm-plugin-fibocom.c \
 	fibocom/mm-plugin-fibocom.h \
 	$(NULL)
-libmm_plugin_fibocom_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS) $(XMM_COMMON_COMPILER_FLAGS)
-libmm_plugin_fibocom_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_fibocom_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	$(XMM_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"fibocom\" \
+	$(NULL)
+libmm_plugin_fibocom_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
 
 dist_udevrules_DATA += fibocom/77-mm-fibocom-port-types.rules
 
@@ -631,8 +683,12 @@
 	foxconn/mm-plugin-foxconn.c \
 	foxconn/mm-plugin-foxconn.h \
 	$(NULL)
-libmm_plugin_foxconn_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS) $(FOXCONN_COMMON_COMPILER_FLAGS)
-libmm_plugin_foxconn_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_foxconn_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	$(FOXCONN_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"foxconn\" \
+	$(NULL)
+libmm_plugin_foxconn_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
 
 dist_udevrules_DATA += foxconn/77-mm-foxconn-port-types.rules
 
@@ -656,8 +712,11 @@
 	haier/mm-plugin-haier.c \
 	haier/mm-plugin-haier.h \
 	$(NULL)
-libmm_plugin_haier_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
-libmm_plugin_haier_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_haier_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"haier\" \
+	$(NULL)
+libmm_plugin_haier_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
 
 dist_udevrules_DATA += haier/77-mm-haier-port-types.rules
 
@@ -676,6 +735,9 @@
 	huawei/mm-modem-helpers-huawei.c \
 	huawei/mm-modem-helpers-huawei.h \
 	$(NULL)
+libhelpers_huawei_la_CPPFLAGS = \
+	-DMM_MODULE_NAME=\"huawei\" \
+	$(NULL)
 
 noinst_PROGRAMS += test-modem-helpers-huawei
 test_modem_helpers_huawei_SOURCES = \
@@ -701,9 +763,12 @@
 	huawei/mm-broadband-bearer-huawei.c \
 	huawei/mm-broadband-bearer-huawei.h \
 	$(NULL)
-libmm_plugin_huawei_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
-libmm_plugin_huawei_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
-libmm_plugin_huawei_la_LIBADD   = $(builddir)/libhelpers-huawei.la
+libmm_plugin_huawei_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"huawei\" \
+	$(NULL)
+libmm_plugin_huawei_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_huawei_la_LIBADD = $(builddir)/libhelpers-huawei.la
 
 dist_udevrules_DATA += huawei/77-mm-huawei-net-port-types.rules
 
@@ -728,8 +793,11 @@
 	iridium/mm-sim-iridium.c \
 	iridium/mm-sim-iridium.h \
 	$(NULL)
-libmm_plugin_iridium_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
-libmm_plugin_iridium_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_iridium_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"iridium\" \
+	$(NULL)
+libmm_plugin_iridium_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
 
 endif
 
@@ -744,6 +812,9 @@
 	linktop/mm-modem-helpers-linktop.c \
 	linktop/mm-modem-helpers-linktop.h \
 	$(NULL)
+libhelpers_linktop_la_CPPFLAGS = \
+	-DMM_MODULE_NAME=\"linktop\" \
+	$(NULL)
 
 noinst_PROGRAMS += test-modem-helpers-linktop
 test_modem_helpers_linktop_SOURCES = \
@@ -765,9 +836,12 @@
 	linktop/mm-broadband-modem-linktop.h \
 	linktop/mm-broadband-modem-linktop.c \
 	$(NULL)
-libmm_plugin_linktop_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
-libmm_plugin_linktop_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
-libmm_plugin_linktop_la_LIBADD   = $(builddir)/libhelpers-linktop.la
+libmm_plugin_linktop_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"linktop\" \
+	$(NULL)
+libmm_plugin_linktop_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_linktop_la_LIBADD = $(builddir)/libhelpers-linktop.la
 
 endif
 
@@ -784,8 +858,11 @@
 	longcheer/mm-broadband-modem-longcheer.h \
 	longcheer/mm-broadband-modem-longcheer.c \
 	$(NULL)
-libmm_plugin_longcheer_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
-libmm_plugin_longcheer_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_longcheer_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"longcheer\" \
+	$(NULL)
+libmm_plugin_longcheer_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
 
 dist_udevrules_DATA += longcheer/77-mm-longcheer-port-types.rules
 
@@ -804,6 +881,9 @@
 	mbm/mm-modem-helpers-mbm.c \
 	mbm/mm-modem-helpers-mbm.h \
 	$(NULL)
+libhelpers_mbm_la_CPPFLAGS = \
+	-DMM_MODULE_NAME=\"ericsson-mbm\" \
+	$(NULL)
 
 noinst_PROGRAMS += test-modem-helpers-mbm
 test_modem_helpers_mbm_SOURCES = \
@@ -829,9 +909,12 @@
 	mbm/mm-plugin-mbm.c \
 	mbm/mm-plugin-mbm.h \
 	$(NULL)
-libmm_plugin_ericsson_mbm_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
-libmm_plugin_ericsson_mbm_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
-libmm_plugin_ericsson_mbm_la_LIBADD   = $(builddir)/libhelpers-mbm.la
+libmm_plugin_ericsson_mbm_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"ericsson-mbm\" \
+	$(NULL)
+libmm_plugin_ericsson_mbm_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_ericsson_mbm_la_LIBADD = $(builddir)/libhelpers-mbm.la
 
 dist_udevrules_DATA += mbm/77-mm-ericsson-mbm.rules
 
@@ -852,8 +935,11 @@
 	motorola/mm-broadband-modem-motorola.c \
 	motorola/mm-broadband-modem-motorola.h \
 	$(NULL)
-libmm_plugin_motorola_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
-libmm_plugin_motorola_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_motorola_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"motorola\" \
+	$(NULL)
+libmm_plugin_motorola_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
 
 endif
 
@@ -870,8 +956,11 @@
 	mtk/mm-broadband-modem-mtk.h \
 	mtk/mm-broadband-modem-mtk.c \
 	$(NULL)
-libmm_plugin_mtk_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
-libmm_plugin_mtk_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_mtk_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"mtk\" \
+	$(NULL)
+libmm_plugin_mtk_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
 
 dist_udevrules_DATA += mtk/77-mm-mtk-port-types.rules
 
@@ -894,8 +983,10 @@
 	nokia/mm-broadband-modem-nokia.c \
 	nokia/mm-broadband-modem-nokia.h \
 	$(NULL)
-libmm_plugin_nokia_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
-libmm_plugin_nokia_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_nokia_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"nokia\" \
+	$(NULL)
+libmm_plugin_nokia_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
 
 endif
 
@@ -910,8 +1001,12 @@
 	nokia/mm-plugin-nokia-icera.c \
 	nokia/mm-plugin-nokia-icera.h \
 	$(NULL)
-libmm_plugin_nokia_icera_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS) $(ICERA_COMMON_COMPILER_FLAGS)
-libmm_plugin_nokia_icera_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_nokia_icera_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	$(ICERA_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"nokia-icera\" \
+	$(NULL)
+libmm_plugin_nokia_icera_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
 
 dist_udevrules_DATA += nokia/77-mm-nokia-port-types.rules
 
@@ -930,8 +1025,12 @@
 	novatel/mm-plugin-novatel.c \
 	novatel/mm-plugin-novatel.h \
 	$(NULL)
-libmm_plugin_novatel_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS) $(NOVATEL_COMMON_COMPILER_FLAGS)
-libmm_plugin_novatel_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_novatel_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	$(NOVATEL_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"novatel\" \
+	$(NULL)
+libmm_plugin_novatel_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
 
 endif
 
@@ -952,8 +1051,11 @@
 	novatel/mm-sim-novatel-lte.c \
 	novatel/mm-sim-novatel-lte.h \
 	$(NULL)
-libmm_plugin_novatel_lte_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
-libmm_plugin_novatel_lte_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_novatel_lte_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"novatel-lte\" \
+	$(NULL)
+libmm_plugin_novatel_lte_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
 
 endif
 
@@ -968,8 +1070,12 @@
 	option/mm-plugin-option.c \
 	option/mm-plugin-option.h \
 	$(NULL)
-libmm_plugin_option_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS) $(OPTION_COMMON_COMPILER_FLAGS)
-libmm_plugin_option_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_option_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	$(OPTION_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"option\" \
+	$(NULL)
+libmm_plugin_option_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
 
 endif
 
@@ -988,8 +1094,12 @@
 	option/mm-broadband-modem-hso.c \
 	option/mm-broadband-modem-hso.h \
 	$(NULL)
-libmm_plugin_option_hso_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS) $(OPTION_COMMON_COMPILER_FLAGS)
-libmm_plugin_option_hso_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_option_hso_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	$(OPTION_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"option-hso\" \
+	$(NULL)
+libmm_plugin_option_hso_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
 
 endif
 
@@ -1008,8 +1118,11 @@
 	pantech/mm-broadband-modem-pantech.c \
 	pantech/mm-broadband-modem-pantech.h \
 	$(NULL)
-libmm_plugin_pantech_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
-libmm_plugin_pantech_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_pantech_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"pantech\" \
+	$(NULL)
+libmm_plugin_pantech_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
 
 endif
 
@@ -1036,8 +1149,11 @@
 	quectel/mm-broadband-modem-qmi-quectel.h \
 	$(NULL)
 endif
-libmm_plugin_quectel_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
-libmm_plugin_quectel_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_quectel_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"quectel\" \
+	$(NULL)
+libmm_plugin_quectel_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
 
 endif
 
@@ -1054,7 +1170,11 @@
 	samsung/mm-broadband-modem-samsung.c \
 	samsung/mm-broadband-modem-samsung.h \
 	$(NULL)
-libmm_plugin_samsung_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS) $(ICERA_COMMON_COMPILER_FLAGS)
+libmm_plugin_samsung_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	$(ICERA_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"samsumg\" \
+	$(NULL)
 libmm_plugin_samsung_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
 
 endif
@@ -1072,8 +1192,13 @@
 	sierra/mm-broadband-modem-sierra-icera.c \
 	sierra/mm-broadband-modem-sierra-icera.h \
 	$(NULL)
-libmm_plugin_sierra_legacy_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS) $(ICERA_COMMON_COMPILER_FLAGS) $(SIERRA_COMMON_COMPILER_FLAGS)
-libmm_plugin_sierra_legacy_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_sierra_legacy_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	$(ICERA_COMMON_COMPILER_FLAGS) \
+	$(SIERRA_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"sierra-legacy\" \
+	$(NULL)
+libmm_plugin_sierra_legacy_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
 
 endif
 
@@ -1090,8 +1215,11 @@
 	sierra/mm-plugin-sierra.c \
 	sierra/mm-plugin-sierra.h \
 	$(NULL)
-libmm_plugin_sierra_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
-libmm_plugin_sierra_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_sierra_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"sierra\" \
+	$(NULL)
+libmm_plugin_sierra_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
 
 endif
 
@@ -1106,6 +1234,9 @@
 	simtech/mm-modem-helpers-simtech.c \
 	simtech/mm-modem-helpers-simtech.h \
 	$(NULL)
+libhelpers_simtech_la_CPPFLAGS = \
+	-DMM_MODULE_NAME=\"simtech\" \
+	$(NULL)
 
 noinst_PROGRAMS += test-modem-helpers-simtech
 test_modem_helpers_simtech_SOURCES = \
@@ -1135,9 +1266,12 @@
 	simtech/mm-broadband-modem-qmi-simtech.h \
 	$(NULL)
 endif
-libmm_plugin_simtech_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
-libmm_plugin_simtech_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
-libmm_plugin_simtech_la_LIBADD   = $(builddir)/libhelpers-simtech.la
+libmm_plugin_simtech_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"simtech\" \
+	$(NULL)
+libmm_plugin_simtech_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_simtech_la_LIBADD = $(builddir)/libhelpers-simtech.la
 
 dist_udevrules_DATA += simtech/77-mm-simtech-port-types.rules
 
@@ -1156,8 +1290,12 @@
 	telit/mm-plugin-telit.c \
 	telit/mm-plugin-telit.h \
 	$(NULL)
-libmm_plugin_telit_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS) $(TELIT_COMMON_COMPILER_FLAGS)
-libmm_plugin_telit_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_telit_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	$(TELIT_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"telit\" \
+	$(NULL)
+libmm_plugin_telit_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
 
 dist_udevrules_DATA += telit/77-mm-telit-port-types.rules
 
@@ -1176,6 +1314,9 @@
 	thuraya/mm-modem-helpers-thuraya.c \
 	thuraya/mm-modem-helpers-thuraya.h \
 	$(NULL)
+libhelpers_thuraya_la_CPPFLAGS = \
+	-DMM_MODULE_NAME=\"thuraya\" \
+	$(NULL)
 
 noinst_PROGRAMS += test-modem-helpers-thuraya
 test_modem_helpers_thuraya_SOURCES = \
@@ -1198,9 +1339,12 @@
 	thuraya/mm-broadband-modem-thuraya.c \
 	thuraya/mm-broadband-modem-thuraya.h \
 	$(NULL)
-libmm_plugin_thuraya_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
-libmm_plugin_thuraya_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
-libmm_plugin_thuraya_la_LIBADD   = $(builddir)/libhelpers-thuraya.la
+libmm_plugin_thuraya_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"thuraya\" \
+	$(NULL)
+libmm_plugin_thuraya_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_thuraya_la_LIBADD = $(builddir)/libhelpers-thuraya.la
 
 endif
 
@@ -1215,8 +1359,11 @@
 	tplink/mm-plugin-tplink.c \
 	tplink/mm-plugin-tplink.h \
 	$(NULL)
-libmm_plugin_tplink_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
-libmm_plugin_tplink_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_tplink_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"tp-link\" \
+	$(NULL)
+libmm_plugin_tplink_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
 
 dist_udevrules_DATA += tplink/77-mm-tplink-port-types.rules
 
@@ -1272,7 +1419,10 @@
 
 nodist_libhelpers_ublox_la_SOURCES = $(UBLOX_ENUMS_GENERATED)
 
-libhelpers_ublox_la_CPPFLAGS = $(PLUGIN_UBLOX_COMPILER_FLAGS)
+libhelpers_ublox_la_CPPFLAGS = \
+	$(PLUGIN_UBLOX_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"u-blox\" \
+	$(NULL)
 
 BUILT_SOURCES += $(UBLOX_ENUMS_GENERATED)
 CLEANFILES    += $(UBLOX_ENUMS_GENERATED)
@@ -1303,9 +1453,13 @@
 	ublox/mm-sim-ublox.c \
 	ublox/mm-sim-ublox.h \
 	$(NULL)
-libmm_plugin_ublox_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS) $(PLUGIN_UBLOX_COMPILER_FLAGS)
-libmm_plugin_ublox_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
-libmm_plugin_ublox_la_LIBADD   = $(builddir)/libhelpers-ublox.la
+libmm_plugin_ublox_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	$(PLUGIN_UBLOX_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"u-blox\" \
+	$(NULL)
+libmm_plugin_ublox_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_ublox_la_LIBADD = $(builddir)/libhelpers-ublox.la
 
 endif
 
@@ -1322,8 +1476,11 @@
 	via/mm-broadband-modem-via.c \
 	via/mm-broadband-modem-via.h \
 	$(NULL)
-libmm_plugin_via_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
-libmm_plugin_via_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_via_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"via\" \
+	$(NULL)
+libmm_plugin_via_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
 
 endif
 
@@ -1340,8 +1497,11 @@
 	wavecom/mm-broadband-modem-wavecom.c \
 	wavecom/mm-broadband-modem-wavecom.h \
 	$(NULL)
-libmm_plugin_wavecom_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
-libmm_plugin_wavecom_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_wavecom_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"wavecom\" \
+	$(NULL)
+libmm_plugin_wavecom_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
 
 endif
 
@@ -1358,8 +1518,11 @@
 	x22x/mm-broadband-modem-x22x.h \
 	x22x/mm-broadband-modem-x22x.c \
 	$(NULL)
-libmm_plugin_x22x_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS)
-libmm_plugin_x22x_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_x22x_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"x22x\" \
+	$(NULL)
+libmm_plugin_x22x_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
 
 dist_udevrules_DATA += x22x/77-mm-x22x-port-types.rules
 
@@ -1384,8 +1547,12 @@
 	zte/mm-broadband-modem-zte-icera.h \
 	zte/mm-broadband-modem-zte-icera.c \
 	$(NULL)
-libmm_plugin_zte_la_CPPFLAGS = $(PLUGIN_COMMON_COMPILER_FLAGS) $(ICERA_COMMON_COMPILER_FLAGS)
-libmm_plugin_zte_la_LDFLAGS  = $(PLUGIN_COMMON_LINKER_FLAGS)
+libmm_plugin_zte_la_CPPFLAGS = \
+	$(PLUGIN_COMMON_COMPILER_FLAGS) \
+	$(ICERA_COMMON_COMPILER_FLAGS) \
+	-DMM_MODULE_NAME=\"zte\" \
+	$(NULL)
+libmm_plugin_zte_la_LDFLAGS = $(PLUGIN_COMMON_LINKER_FLAGS)
 
 dist_udevrules_DATA += zte/77-mm-zte-port-types.rules
 
diff --git a/plugins/altair/mm-broadband-bearer-altair-lte.c b/plugins/altair/mm-broadband-bearer-altair-lte.c
index d8e1a0f..4a5b057 100644
--- a/plugins/altair/mm-broadband-bearer-altair-lte.c
+++ b/plugins/altair/mm-broadband-bearer-altair-lte.c
@@ -76,14 +76,11 @@
 
     result = mm_base_modem_at_command_full_finish (modem, res, &error);
     if (!result) {
-        mm_warn ("connect failed: %s", error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
     }
 
-    mm_dbg ("Connected");
-
     ctx = g_task_get_task_data (task);
 
     config = mm_bearer_ip_config_new ();
@@ -111,7 +108,7 @@
 
     result = mm_base_modem_at_command_full_finish (modem, res, &error);
     if (!result) {
-        mm_warn ("setting APN failed: %s", error->message);
+        g_prefix_error (&error, "setting APN failed: ");
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -119,7 +116,6 @@
 
     ctx = g_task_get_task_data (task);
 
-    mm_dbg ("APN set - connecting bearer");
     mm_base_modem_at_command_full (ctx->modem,
                                    ctx->primary,
                                    "%DPDNACT=1",
@@ -168,7 +164,7 @@
      * refresh.
      * */
     if (mm_broadband_modem_altair_lte_is_sim_refresh_detach_in_progress (modem)) {
-        mm_dbg ("Detached from network to process SIM refresh, failing connect request");
+        mm_obj_dbg (self, "detached from network to process SIM refresh, failing connect request");
         g_task_report_new_error (self,
                                  callback,
                                  user_data,
@@ -251,13 +247,10 @@
     GError *error = NULL;
 
     result = mm_base_modem_at_command_full_finish (modem, res, &error);
-    if (!result) {
-        mm_warn ("Disconnect failed: %s", error->message);
+    if (!result)
         g_task_return_error (task, error);
-    }
     else
         g_task_return_boolean (task, TRUE);
-
     g_object_unref (task);
 }
 
diff --git a/plugins/altair/mm-broadband-modem-altair-lte.c b/plugins/altair/mm-broadband-modem-altair-lte.c
index 03912ea..5470217 100644
--- a/plugins/altair/mm-broadband-modem-altair-lte.c
+++ b/plugins/altair/mm-broadband-modem-altair-lte.c
@@ -35,7 +35,7 @@
 #include "mm-iface-modem-3gpp.h"
 #include "mm-iface-modem-3gpp-ussd.h"
 #include "mm-iface-modem-messaging.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-modem-helpers.h"
 #include "mm-modem-helpers-altair-lte.h"
 #include "mm-serial-parsers.h"
@@ -50,7 +50,7 @@
                         G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init)
                         G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init)
                         G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP_USSD, iface_modem_3gpp_ussd_init)
-                        G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_MESSAGING, iface_modem_messaging_init));
+                        G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_MESSAGING, iface_modem_messaging_init))
 
 struct _MMBroadbandModemAltairLtePrivate {
     /* Regex for SIM refresh notifications */
@@ -165,7 +165,6 @@
 
     response = mm_base_modem_at_command_finish (self, res, &error);
     if (!response) {
-        mm_dbg ("Couldn't query unlock retries: '%s'", error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -234,8 +233,6 @@
 {
     GTask *task;
 
-    mm_dbg ("Loading (Altair LTE) current capabilities...");
-
     task = g_task_new (self, NULL, callback, user_data);
     /* This modem is LTE only.*/
     g_task_return_int (task, MM_MODEM_CAPABILITY_LTE);
@@ -266,7 +263,6 @@
 
     response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
     if (!response) {
-        mm_dbg ("Couldn't query supported bands: '%s'", error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -279,7 +275,6 @@
 
     bands = mm_altair_parse_bands_response (response);
     if (!bands) {
-        mm_dbg ("Failed to parse supported bands response");
         g_task_return_new_error (
             task,
             MM_CORE_ERROR,
@@ -335,7 +330,6 @@
 
     response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
     if (!response) {
-        mm_dbg ("Couldn't query current bands: '%s'", error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -348,7 +342,6 @@
 
     bands = mm_altair_parse_bands_response (response);
     if (!bands) {
-        mm_dbg ("Failed to parse current bands response");
         g_task_return_new_error (
             task,
             MM_CORE_ERROR,
@@ -455,7 +448,7 @@
     at_response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
     if (!at_response) {
         g_assert (error);
-        mm_warn ("AT+CEER failed: %s", error->message);
+        mm_obj_warn (self, "AT+CEER failed: %s", error->message);
         g_error_free (error);
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
@@ -465,7 +458,7 @@
     ceer_response = mm_altair_parse_ceer_response (at_response, &error);
     if (!ceer_response) {
         g_assert (error);
-        mm_warn ("Failed to parse AT+CEER response: %s", error->message);
+        mm_obj_warn (self, "Failed to parse AT+CEER response: %s", error->message);
         g_error_free (error);
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
@@ -473,10 +466,10 @@
     }
 
     if (g_strcmp0 ("EPS_AND_NON_EPS_SERVICES_NOT_ALLOWED", ceer_response) == 0) {
-        mm_dbg ("Registration failed due to unprovisioned SIM.");
+        mm_obj_dbg (self, "registration failed due to unprovisioned SIM");
         simulate_unprovisioned_subscription_pco_update (MM_BROADBAND_MODEM_ALTAIR_LTE (self));
     } else {
-        mm_dbg ("Failed to find a better reason for registration failure.");
+        mm_obj_dbg (self, "failed to find a better reason for registration failure");
     }
 
     g_task_return_boolean (task, TRUE);
@@ -501,7 +494,7 @@
         return;
     }
 
-    mm_dbg ("Checking if SIM is unprovisioned (ignoring registration state).");
+    mm_obj_dbg (self, "checking if SIM is unprovisioned (ignoring registration state)");
     mm_base_modem_at_command (MM_BASE_MODEM (self),
                               "+CEER",
                               6,
@@ -511,12 +504,13 @@
 }
 
 static void
-modem_3gpp_run_registration_checks (MMIfaceModem3gpp *self,
-                                    gboolean cs_supported,
-                                    gboolean ps_supported,
-                                    gboolean eps_supported,
-                                    GAsyncReadyCallback callback,
-                                    gpointer user_data)
+modem_3gpp_run_registration_checks (MMIfaceModem3gpp    *self,
+                                    gboolean             is_cs_supported,
+                                    gboolean             is_ps_supported,
+                                    gboolean             is_eps_supported,
+                                    gboolean             is_5gs_supported,
+                                    GAsyncReadyCallback  callback,
+                                    gpointer             user_data)
 {
     GTask *task;
 
@@ -524,9 +518,10 @@
 
     g_assert (iface_modem_3gpp_parent->run_registration_checks);
     iface_modem_3gpp_parent->run_registration_checks (self,
-                                                      cs_supported,
-                                                      ps_supported,
-                                                      eps_supported,
+                                                      is_cs_supported,
+                                                      is_ps_supported,
+                                                      is_eps_supported,
+                                                      is_5gs_supported,
                                                       (GAsyncReadyCallback) run_registration_checks_ready,
                                                       task);
 }
@@ -593,11 +588,10 @@
                          GAsyncResult *res,
                          gpointer user_data)
 {
-    if (!mm_base_modem_at_command_finish (self, res, NULL)) {
-        mm_dbg ("Failed to reregister modem");
-    } else {
-        mm_dbg ("Modem reregistered successfully");
-    }
+    if (!mm_base_modem_at_command_finish (self, res, NULL))
+        mm_obj_dbg (self, "failed to reregister modem");
+    else
+        mm_obj_dbg (self, "modem reregistered successfully");
     MM_BROADBAND_MODEM_ALTAIR_LTE (self)->priv->sim_refresh_detach_in_progress = FALSE;
 }
 
@@ -607,12 +601,12 @@
                          gpointer user_data)
 {
     if (!mm_base_modem_at_command_finish (self, res, NULL)) {
-        mm_dbg ("Deregister modem failed");
+        mm_obj_dbg (self, "deregister modem failed");
         MM_BROADBAND_MODEM_ALTAIR_LTE (self)->priv->sim_refresh_detach_in_progress = FALSE;
         return;
     }
 
-    mm_dbg ("Deregistered modem, now reregistering");
+    mm_obj_dbg (self, "deregistered modem, now reregistering");
 
     /* Register */
     mm_base_modem_at_command (
@@ -634,7 +628,7 @@
 
     str_list = MM_IFACE_MODEM_GET_INTERFACE (self)->load_own_numbers_finish (MM_IFACE_MODEM (self), res, &error);
     if (error) {
-        mm_warn ("Couldn't reload Own Numbers: '%s'", error->message);
+        mm_obj_warn (self, "Couldn't reload Own Numbers: '%s'", error->message);
         g_error_free (error);
     }
     if (str_list) {
@@ -647,7 +641,7 @@
     self->priv->sim_refresh_detach_in_progress = TRUE;
 
     /* Deregister */
-    mm_dbg ("Reregistering modem");
+    mm_obj_dbg (self, "reregistering modem");
     mm_base_modem_at_command (
         MM_BASE_MODEM (self),
         "%CMATT=0",
@@ -660,7 +654,7 @@
 static gboolean
 altair_sim_refresh_timer_expired (MMBroadbandModemAltairLte *self)
 {
-    mm_dbg ("No more SIM refreshes, reloading Own Numbers and reregistering modem");
+    mm_obj_dbg (self, "no more SIM refreshes, reloading own numbers and reregistering modem");
 
     g_assert (MM_IFACE_MODEM_GET_INTERFACE (self)->load_own_numbers);
     g_assert (MM_IFACE_MODEM_GET_INTERFACE (self)->load_own_numbers_finish);
@@ -678,7 +672,7 @@
                             GMatchInfo *match_info,
                             MMBroadbandModemAltairLte *self)
 {
-    mm_dbg ("Received SIM refresh notification");
+    mm_obj_dbg (self, "received SIM refresh notification");
     if (self->priv->sim_refresh_timer_id) {
         g_source_remove (self->priv->sim_refresh_timer_id);
     }
@@ -716,7 +710,7 @@
 
     mm_get_int_from_match_info (match_info, 1, &pdn_event);
 
-    mm_dbg ("altair_statcm_changed %d", pdn_event);
+    mm_obj_dbg (self, "PDN event detected: %d", pdn_event);
 
     /* Currently we only care about bearer disconnection */
 
@@ -1046,7 +1040,6 @@
                                            error))
         return NULL;
 
-    mm_dbg ("loaded Operator Code: %s", operator_code);
     return operator_code;
 }
 
@@ -1055,8 +1048,6 @@
                                GAsyncReadyCallback callback,
                                gpointer user_data)
 {
-    mm_dbg ("loading Operator Code...");
-
     mm_base_modem_at_command (MM_BASE_MODEM (self),
                               "+COPS=3,2",
                               6,
@@ -1096,8 +1087,6 @@
         return NULL;
 
     mm_3gpp_normalize_operator (&operator_name, MM_MODEM_CHARSET_UNKNOWN);
-    if (operator_name)
-        mm_dbg ("loaded Operator Name: %s", operator_name);
     return operator_name;
 }
 
@@ -1106,8 +1095,6 @@
                                GAsyncReadyCallback callback,
                                gpointer user_data)
 {
-    mm_dbg ("Loading Operator Name...");
-
     mm_base_modem_at_command (MM_BASE_MODEM (self),
                               "+COPS=3,0",
                               6,
@@ -1133,15 +1120,14 @@
 {
     const gchar *pco_info;
     MMPco *pco;
-    GError *error = NULL;
+    g_autoptr(GError) error = NULL;
 
     pco_info = g_match_info_fetch (match_info, 0);
 
-    mm_dbg ("Parsing vendor PCO info: %s", pco_info);
+    mm_obj_dbg (self, "parsing vendor PCO info: %s", pco_info);
     pco = mm_altair_parse_vendor_pco_info (pco_info, &error);
     if (error) {
-        mm_warn ("Error parsing vendor PCO info: %s", error->message);
-        g_error_free (error);
+        mm_obj_warn (self, "error parsing vendor PCO info: %s", error->message);
         return;
     }
 
diff --git a/plugins/altair/mm-plugin-altair-lte.c b/plugins/altair/mm-plugin-altair-lte.c
index 7f6a7c0..054a600 100644
--- a/plugins/altair/mm-plugin-altair-lte.c
+++ b/plugins/altair/mm-plugin-altair-lte.c
@@ -77,7 +77,7 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_ALTAIR_LTE,
-                      MM_PLUGIN_NAME,                "Altair LTE",
+                      MM_PLUGIN_NAME,                MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS,  subsystems,
                       MM_PLUGIN_ALLOWED_PRODUCT_IDS, products,
                       MM_PLUGIN_CUSTOM_AT_PROBE,     custom_at_probe,
diff --git a/plugins/anydata/mm-broadband-modem-anydata.c b/plugins/anydata/mm-broadband-modem-anydata.c
index a4acaf2..55804fc 100644
--- a/plugins/anydata/mm-broadband-modem-anydata.c
+++ b/plugins/anydata/mm-broadband-modem-anydata.c
@@ -25,7 +25,7 @@
 
 #include "ModemManager.h"
 #include "mm-serial-parsers.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-modem-helpers.h"
 #include "mm-errors-types.h"
 #include "mm-base-modem-at.h"
@@ -38,7 +38,7 @@
 
 G_DEFINE_TYPE_EXTENDED (MMBroadbandModemAnydata, mm_broadband_modem_anydata, MM_TYPE_BROADBAND_MODEM, 0,
                         G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init)
-                        G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_CDMA, iface_modem_cdma_init));
+                        G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_CDMA, iface_modem_cdma_init))
 
 /*****************************************************************************/
 /* Detailed registration state (CDMA interface) */
@@ -119,7 +119,7 @@
                 results->detailed_evdo_state = MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED;
                 break;
             default:
-                mm_warn ("ANYDATA: unknown *STATE (%d); assuming no service.", val);
+                mm_obj_warn (self, "unknown *HSTATE (%d); assuming no service", val);
                 /* fall through */
             case 0:  /* NO SERVICE */
             case 1:  /* ACQUISITION */
@@ -186,7 +186,7 @@
                 results->detailed_cdma1x_state = MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED;
                 break;
             default:
-                mm_warn ("ANYDATA: unknown *STATE (%d); assuming no service.", val);
+                mm_obj_warn (self, "unknown *HSTATE (%d); assuming no service", val);
                 /* fall through */
             case 0:  /* NO SERVICE */
                 break;
diff --git a/plugins/anydata/mm-plugin-anydata.c b/plugins/anydata/mm-plugin-anydata.c
index 8037fb7..cc11896 100644
--- a/plugins/anydata/mm-plugin-anydata.c
+++ b/plugins/anydata/mm-plugin-anydata.c
@@ -21,7 +21,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-plugin-anydata.h"
 #include "mm-broadband-modem-anydata.h"
 
@@ -47,7 +47,7 @@
 {
 #if defined WITH_QMI
     if (mm_port_probe_list_has_qmi_port (probes)) {
-        mm_dbg ("QMI-powered AnyDATA modem found...");
+        mm_obj_dbg (self, "QMI-powered AnyDATA modem found...");
         return MM_BASE_MODEM (mm_broadband_modem_qmi_new (uid,
                                                           drivers,
                                                           mm_plugin_get_name (self),
@@ -73,7 +73,7 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_ANYDATA,
-                      MM_PLUGIN_NAME,               "AnyDATA",
+                      MM_PLUGIN_NAME,               MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems,
                       MM_PLUGIN_ALLOWED_VENDOR_IDS, vendor_ids,
                       MM_PLUGIN_ALLOWED_AT,         TRUE,
diff --git a/plugins/cinterion/mm-broadband-bearer-cinterion.c b/plugins/cinterion/mm-broadband-bearer-cinterion.c
index 5c893b6..e1a0613 100644
--- a/plugins/cinterion/mm-broadband-bearer-cinterion.c
+++ b/plugins/cinterion/mm-broadband-bearer-cinterion.c
@@ -24,7 +24,7 @@
 #include <ModemManager.h>
 #include "mm-base-modem-at.h"
 #include "mm-broadband-bearer-cinterion.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-modem-helpers.h"
 #include "mm-modem-helpers-cinterion.h"
 #include "mm-daemon-enums-types.h"
@@ -101,11 +101,13 @@
                           GAsyncResult *res,
                           GTask        *task)
 {
-    const gchar              *response;
-    GError                   *error = NULL;
-    MMBearerConnectionStatus  status;
-    guint                     cid;
+    MMBroadbandBearerCinterion *self;
+    const gchar                *response;
+    GError                     *error = NULL;
+    MMBearerConnectionStatus    status;
+    guint                       cid;
 
+    self = g_task_get_source_object (task);
     cid = GPOINTER_TO_UINT (g_task_get_task_data (task));
 
     response = mm_base_modem_at_command_finish (modem, res, &error);
@@ -114,7 +116,7 @@
         goto out;
     }
 
-    status = mm_cinterion_parse_swwan_response (response, cid, &error);
+    status = mm_cinterion_parse_swwan_response (response, cid, self, &error);
     if (status == MM_BEARER_CONNECTION_STATUS_UNKNOWN) {
         g_task_return_error (task, error);
         goto out;
@@ -197,8 +199,9 @@
 
 /* AT^SGAUTH=<cid>[, <auth_type>[, <passwd>, <user>]] */
 static gchar *
-build_auth_string (MMBearerProperties *config,
-                   guint               cid)
+build_auth_string (MMBroadbandBearerCinterion *self,
+                   MMBearerProperties         *config,
+                   guint                       cid)
 {
     const gchar             *user;
     const gchar             *passwd;
@@ -218,7 +221,7 @@
     /* When 'none' requested, we won't require user/password */
     if (encoded_auth == BEARER_CINTERION_AUTH_NONE) {
         if (has_user || has_passwd)
-            mm_warn ("APN user/password given but 'none' authentication requested");
+            mm_obj_warn (self, "APN user/password given but 'none' authentication requested");
         return g_strdup_printf ("^SGAUTH=%u,%d", cid, encoded_auth);
     }
 
@@ -229,7 +232,7 @@
             return NULL;
 
         /* If user/passwd given, default to PAP */
-        mm_dbg ("APN user/password given but no authentication type explicitly requested: defaulting to 'PAP'");
+        mm_obj_dbg (self, "APN user/password given but no authentication type explicitly requested: defaulting to 'PAP'");
         encoded_auth = BEARER_CINTERION_AUTH_PAP;
     }
 
@@ -356,9 +359,11 @@
 static void
 dial_3gpp_context_step (GTask *task)
 {
-    Dial3gppContext *ctx;
+    MMBroadbandBearerCinterion *self;
+    Dial3gppContext            *ctx;
 
-    ctx = (Dial3gppContext *) g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     /* Check for cancellation */
     if (g_task_return_error_if_cancelled (task)) {
@@ -378,7 +383,7 @@
 
             ip_family = mm_base_bearer_get_default_ip_family (MM_BASE_BEARER (ctx->self));
             ip_family_str = mm_bearer_ip_family_build_string_from_mask (ip_family);
-            mm_dbg ("No specific IP family requested, defaulting to %s", ip_family_str);
+            mm_obj_dbg (self, "no specific IP family requested, defaulting to %s", ip_family_str);
             g_free (ip_family_str);
         }
 
@@ -395,9 +400,9 @@
     case DIAL_3GPP_CONTEXT_STEP_AUTH: {
         gchar *command;
 
-        command = build_auth_string (mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self)), ctx->cid);
+        command = build_auth_string (self, mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self)), ctx->cid);
         if (command) {
-            mm_dbg ("cinterion dial step %u/%u: authenticating...", ctx->step, DIAL_3GPP_CONTEXT_STEP_LAST);
+            mm_obj_dbg (self, "dial step %u/%u: authenticating...", ctx->step, DIAL_3GPP_CONTEXT_STEP_LAST);
             /* Send SGAUTH write, if User & Pass are provided.
              * advance to next state by callback */
             mm_base_modem_at_command_full (ctx->modem,
@@ -413,15 +418,15 @@
             return;
         }
 
-        mm_dbg ("cinterion dial step %u/%u: authentication not required", ctx->step, DIAL_3GPP_CONTEXT_STEP_LAST);
+        mm_obj_dbg (self, "dial step %u/%u: authentication not required", ctx->step, DIAL_3GPP_CONTEXT_STEP_LAST);
         ctx->step++;
     } /* fall through */
 
     case DIAL_3GPP_CONTEXT_STEP_START_SWWAN: {
         gchar *command;
 
-        mm_dbg ("cinterion dial step %u/%u: starting SWWAN interface %u connection...",
-                ctx->step, DIAL_3GPP_CONTEXT_STEP_LAST, usb_interface_configs[ctx->usb_interface_config_index].swwan_index);
+        mm_obj_dbg (self, "dial step %u/%u: starting SWWAN interface %u connection...",
+                    ctx->step, DIAL_3GPP_CONTEXT_STEP_LAST, usb_interface_configs[ctx->usb_interface_config_index].swwan_index);
         command = g_strdup_printf ("^SWWAN=1,%u,%u",
                                    ctx->cid,
                                    usb_interface_configs[ctx->usb_interface_config_index].swwan_index);
@@ -439,8 +444,8 @@
     }
 
     case DIAL_3GPP_CONTEXT_STEP_VALIDATE_CONNECTION:
-        mm_dbg ("cinterion dial step %u/%u: checking SWWAN interface %u status...",
-                ctx->step, DIAL_3GPP_CONTEXT_STEP_LAST, usb_interface_configs[ctx->usb_interface_config_index].swwan_index);
+        mm_obj_dbg (self, "dial step %u/%u: checking SWWAN interface %u status...",
+                    ctx->step, DIAL_3GPP_CONTEXT_STEP_LAST, usb_interface_configs[ctx->usb_interface_config_index].swwan_index);
         load_connection_status_by_cid (ctx->self,
                                        ctx->cid,
                                        (GAsyncReadyCallback) dial_connection_status_ready,
@@ -448,7 +453,7 @@
         return;
 
     case DIAL_3GPP_CONTEXT_STEP_LAST:
-        mm_dbg ("cinterion dial step %u/%u: finished", ctx->step, DIAL_3GPP_CONTEXT_STEP_LAST);
+        mm_obj_dbg (self, "dial step %u/%u: finished", ctx->step, DIAL_3GPP_CONTEXT_STEP_LAST);
         g_task_return_pointer (task, g_object_ref (ctx->data), g_object_unref);
         g_object_unref (task);
         return;
@@ -562,7 +567,7 @@
     switch (status) {
     case MM_BEARER_CONNECTION_STATUS_UNKNOWN:
         /* Assume disconnected */
-        mm_dbg ("couldn't get CID %u status, assume disconnected: %s", ctx->cid, error->message);
+        mm_obj_dbg (self, "couldn't get CID %u status, assume disconnected: %s", ctx->cid, error->message);
         g_clear_error (&error);
         break;
     case MM_BEARER_CONNECTION_STATUS_DISCONNECTED:
@@ -604,9 +609,11 @@
 static void
 disconnect_3gpp_context_step (GTask *task)
 {
-    Disconnect3gppContext *ctx;
+    MMBroadbandBearerCinterion *self;
+    Disconnect3gppContext      *ctx;
 
-    ctx = (Disconnect3gppContext *) g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     switch (ctx->step) {
     case DISCONNECT_3GPP_CONTEXT_STEP_FIRST:
@@ -618,8 +625,8 @@
 
         command = g_strdup_printf ("^SWWAN=0,%u,%u",
                                    ctx->cid, usb_interface_configs[ctx->usb_interface_config_index].swwan_index);
-        mm_dbg ("cinterion disconnect step %u/%u: disconnecting PDP CID %u...",
-                ctx->step, DISCONNECT_3GPP_CONTEXT_STEP_LAST, ctx->cid);
+        mm_obj_dbg (self, "disconnect step %u/%u: disconnecting PDP CID %u...",
+                    ctx->step, DISCONNECT_3GPP_CONTEXT_STEP_LAST, ctx->cid);
         mm_base_modem_at_command_full (ctx->modem,
                                        ctx->primary,
                                        command,
@@ -634,9 +641,9 @@
     }
 
     case DISCONNECT_3GPP_CONTEXT_STEP_CONNECTION_STATUS:
-        mm_dbg ("cinterion disconnect step %u/%u: checking SWWAN interface %u status...",
-                ctx->step, DISCONNECT_3GPP_CONTEXT_STEP_LAST,
-                usb_interface_configs[ctx->usb_interface_config_index].swwan_index);
+        mm_obj_dbg (self, "disconnect step %u/%u: checking SWWAN interface %u status...",
+                    ctx->step, DISCONNECT_3GPP_CONTEXT_STEP_LAST,
+                    usb_interface_configs[ctx->usb_interface_config_index].swwan_index);
         load_connection_status_by_cid (MM_BROADBAND_BEARER_CINTERION (ctx->self),
                                        ctx->cid,
                                        (GAsyncReadyCallback) disconnect_connection_status_ready,
@@ -644,8 +651,8 @@
          return;
 
     case DISCONNECT_3GPP_CONTEXT_STEP_LAST:
-        mm_dbg ("cinterion disconnect step %u/%u: finished",
-                ctx->step, DISCONNECT_3GPP_CONTEXT_STEP_LAST);
+        mm_obj_dbg (self, "disconnect step %u/%u: finished",
+                    ctx->step, DISCONNECT_3GPP_CONTEXT_STEP_LAST);
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
         return;
diff --git a/plugins/cinterion/mm-broadband-modem-cinterion.c b/plugins/cinterion/mm-broadband-modem-cinterion.c
index 97c4bcb..09b4e13 100644
--- a/plugins/cinterion/mm-broadband-modem-cinterion.c
+++ b/plugins/cinterion/mm-broadband-modem-cinterion.c
@@ -28,7 +28,7 @@
 #include "ModemManager.h"
 #include "mm-modem-helpers.h"
 #include "mm-serial-parsers.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-errors-types.h"
 #include "mm-iface-modem.h"
 #include "mm-iface-modem-3gpp.h"
@@ -256,7 +256,7 @@
                                        &self->priv->cnmi_supported_ds,
                                        &self->priv->cnmi_supported_bfr,
                                        &error)) {
-        mm_warn ("error reading SMS setup: %s", error->message);
+        mm_obj_warn (self, "error reading SMS setup: %s", error->message);
         g_error_free (error);
     }
 
@@ -333,13 +333,10 @@
              GAsyncResult *res,
              GTask        *task)
 {
-    GError *error = NULL;
+    g_autoptr(GError) error = NULL;
 
-    if (!mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error)) {
-        /* Ignore errors */
-        mm_dbg ("Couldn't send power down command: '%s'", error->message);
-        g_error_free (error);
-    }
+    if (!mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error))
+        mm_obj_dbg (self, "couldn't send power down command: %s", error->message);
 
     g_task_return_boolean (task, TRUE);
     g_object_unref (task);
@@ -374,14 +371,13 @@
 {
     MMBroadbandModemCinterion *self = MM_BROADBAND_MODEM_CINTERION (_self);
     const gchar               *response;
-    GError                    *error = NULL;
+    g_autoptr(GError)          error = NULL;
 
     g_assert (self->priv->sleep_mode_cmd == NULL);
 
     response = mm_base_modem_at_command_finish (_self, res, &error);
     if (!response) {
-        mm_warn ("Couldn't query supported functionality status: '%s'", error->message);
-        g_error_free (error);
+        mm_obj_warn (self, "couldn't query supported functionality status: %s", error->message);
         self->priv->sleep_mode_cmd = g_strdup ("");
     } else {
         /* We need to get which power-off command to use to put the modem in low
@@ -395,13 +391,13 @@
          * not found, report warning and don't use any.
          */
         if (strstr (response, "4") != NULL) {
-            mm_dbg ("Device supports CFUN=4 sleep mode");
+            mm_obj_dbg (self, "device supports CFUN=4 sleep mode");
             self->priv->sleep_mode_cmd = g_strdup ("+CFUN=4");
         } else if (strstr (response, "7") != NULL) {
-            mm_dbg ("Device supports CFUN=7 sleep mode");
+            mm_obj_dbg (self, "device supports CFUN=7 sleep mode");
             self->priv->sleep_mode_cmd = g_strdup ("+CFUN=7");
         } else {
-            mm_warn ("Unknown functionality mode to go into sleep mode");
+            mm_obj_warn (self, "unknown functionality mode to go into sleep mode");
             self->priv->sleep_mode_cmd = g_strdup ("");
         }
     }
@@ -684,12 +680,10 @@
                                          GAsyncResult     *res,
                                          GTask            *task)
 {
-    GError *error = NULL;
+    g_autoptr(GError) error = NULL;
 
-    if (!iface_modem_3gpp_parent->disable_unsolicited_events_finish (self, res, &error)) {
-        mm_warn ("Couldn't disable parent 3GPP unsolicited events: %s", error->message);
-        g_error_free (error);
-    }
+    if (!iface_modem_3gpp_parent->disable_unsolicited_events_finish (self, res, &error))
+        mm_obj_warn (self, "couldn't disable parent 3GPP unsolicited events: %s", error->message);
 
     g_task_return_boolean (task, TRUE);
     g_object_unref (task);
@@ -710,12 +704,10 @@
                            GAsyncResult *res,
                            GTask        *task)
 {
-    GError *error = NULL;
+    g_autoptr(GError) error = NULL;
 
-    if (!mm_base_modem_at_command_finish (self, res, &error)) {
-        mm_warn ("Couldn't disable ^SIND psinfo notifications: %s", error->message);
-        g_error_free (error);
-    }
+    if (!mm_base_modem_at_command_finish (self, res, &error))
+        mm_obj_warn (self, "Couldn't disable ^SIND psinfo notifications: %s", error->message);
 
     parent_disable_unsolicited_messages (task);
 }
@@ -763,7 +755,7 @@
                           GTask        *task)
 {
     MMBroadbandModemCinterion *self;
-    GError                    *error = NULL;
+    g_autoptr(GError)          error = NULL;
     const gchar               *response;
     guint                      mode;
     guint                      val;
@@ -771,20 +763,18 @@
     self = MM_BROADBAND_MODEM_CINTERION (_self);
     if (!(response = mm_base_modem_at_command_finish (_self, res, &error))) {
         self->priv->sind_psinfo_support = FEATURE_NOT_SUPPORTED;
-        mm_warn ("Couldn't enable ^SIND psinfo notifications: %s", error->message);
-        g_error_free (error);
+        mm_obj_warn (self, "couldn't enable ^SIND psinfo notifications: %s", error->message);
     } else if (!mm_cinterion_parse_sind_response (response, NULL, &mode, &val, &error)) {
         self->priv->sind_psinfo_support = FEATURE_NOT_SUPPORTED;
-        mm_warn ("Couldn't parse ^SIND psinfo response: %s", error->message);
-        g_error_free (error);
+        mm_obj_warn (self, "couldn't parse ^SIND psinfo response: %s", error->message);
     } else {
         /* Flag ^SIND psinfo supported so that we don't poll */
         self->priv->sind_psinfo_support = FEATURE_SUPPORTED;
 
         /* Report initial access technology gathered right away */
-        mm_dbg ("Reporting initial access technologies...");
+        mm_obj_dbg (self, "reporting initial access technologies...");
         mm_iface_modem_update_access_technologies (MM_IFACE_MODEM (self),
-                                                   mm_cinterion_get_access_technology_from_sind_psinfo (val),
+                                                   mm_cinterion_get_access_technology_from_sind_psinfo (val, self),
                                                    MM_IFACE_MODEM_3GPP_ALL_ACCESS_TECHNOLOGIES_MASK);
     }
 
@@ -798,14 +788,12 @@
                                         GTask            *task)
 {
     MMBroadbandModemCinterion *self;
-    GError                    *error = NULL;
+    g_autoptr(GError)          error = NULL;
 
     self = MM_BROADBAND_MODEM_CINTERION (_self);
 
-    if (!iface_modem_3gpp_parent->enable_unsolicited_events_finish (_self, res, &error)) {
-        mm_warn ("Couldn't enable parent 3GPP unsolicited events: %s", error->message);
-        g_error_free (error);
-    }
+    if (!iface_modem_3gpp_parent->enable_unsolicited_events_finish (_self, res, &error))
+        mm_obj_warn (self, "couldn't enable parent 3GPP unsolicited events: %s", error->message);
 
     if (self->priv->sind_psinfo_support != FEATURE_NOT_SUPPORTED) {
         /* Enable access technology update reporting */
@@ -851,12 +839,12 @@
 
     indicator = mm_get_string_unquoted_from_match_info (match_info, 1);
     if (!mm_get_uint_from_match_info (match_info, 2, &val))
-        mm_dbg ("couldn't parse indicator '%s' value", indicator);
+        mm_obj_dbg (self, "couldn't parse indicator '%s' value", indicator);
     else {
-        mm_dbg ("received indicator '%s' update: %u", indicator, val);
+        mm_obj_dbg (self, "received indicator '%s' update: %u", indicator, val);
         if (g_strcmp0 (indicator, "psinfo") == 0) {
             mm_iface_modem_update_access_technologies (MM_IFACE_MODEM (self),
-                                                       mm_cinterion_get_access_technology_from_sind_psinfo (val),
+                                                       mm_cinterion_get_access_technology_from_sind_psinfo (val, self),
                                                        MM_IFACE_MODEM_3GPP_ALL_ACCESS_TECHNOLOGIES_MASK);
         }
     }
@@ -1019,7 +1007,7 @@
     }
 
     /* Filter out those unsupported modes */
-    filtered = mm_filter_supported_modes (all, combinations);
+    filtered = mm_filter_supported_modes (all, combinations, self);
     g_array_unref (all);
     g_array_unref (combinations);
 
@@ -1467,23 +1455,22 @@
 {
     LoadUnlockRetriesContext *ctx;
     const gchar              *response;
-    GError                   *error = NULL;
+    g_autoptr(GError)         error = NULL;
 
     ctx = g_task_get_task_data (task);
 
     response = mm_base_modem_at_command_finish (self, res, &error);
     if (!response) {
-        mm_dbg ("Couldn't load retry count for lock '%s': %s",
-                mm_modem_lock_get_string (unlock_retries_map[ctx->i].lock),
-                error->message);
-        g_error_free (error);
+        mm_obj_dbg (self, "Couldn't load retry count for lock '%s': %s",
+                    mm_modem_lock_get_string (unlock_retries_map[ctx->i].lock),
+                    error->message);
     } else {
         guint val;
 
         response = mm_strip_tag (response, "^SPIC:");
         if (!mm_get_uint_from_str (response, &val))
-            mm_dbg ("Couldn't parse retry count value for lock '%s'",
-                    mm_modem_lock_get_string (unlock_retries_map[ctx->i].lock));
+            mm_obj_dbg (self, "couldn't parse retry count value for lock '%s'",
+                        mm_modem_lock_get_string (unlock_retries_map[ctx->i].lock));
         else
             mm_unlock_retries_set (ctx->retries, unlock_retries_map[ctx->i].lock, val);
     }
@@ -1698,7 +1685,7 @@
 
     switch (self->priv->swwan_support) {
     case FEATURE_NOT_SUPPORTED:
-        mm_dbg ("^SWWAN not supported, creating default bearer...");
+        mm_obj_dbg (self, "^SWWAN not supported, creating default bearer...");
         mm_broadband_bearer_new (MM_BROADBAND_MODEM (self),
                                  g_task_get_task_data (task),
                                  NULL, /* cancellable */
@@ -1706,7 +1693,7 @@
                                  task);
         return;
     case FEATURE_SUPPORTED:
-        mm_dbg ("^SWWAN supported, creating cinterion bearer...");
+        mm_obj_dbg (self, "^SWWAN supported, creating cinterion bearer...");
         mm_broadband_bearer_cinterion_new (MM_BROADBAND_MODEM_CINTERION (self),
                                            g_task_get_task_data (task),
                                            NULL, /* cancellable */
@@ -1729,10 +1716,10 @@
     /* Fetch the result to the SWWAN test. If no response given (error triggered),
      * assume unsupported */
     if (!mm_base_modem_at_command_finish (_self, res, NULL)) {
-        mm_dbg ("SWWAN unsupported");
+        mm_obj_dbg (self, "SWWAN unsupported");
         self->priv->swwan_support = FEATURE_NOT_SUPPORTED;
     } else {
-        mm_dbg ("SWWAN supported");
+        mm_obj_dbg (self, "SWWAN supported");
         self->priv->swwan_support = FEATURE_SUPPORTED;
     }
 
@@ -1762,13 +1749,13 @@
     /* If we don't have a data port, don't even bother checking for ^SWWAN
      * support. */
     if (!mm_base_modem_peek_best_data_port (MM_BASE_MODEM (self), MM_PORT_TYPE_NET)) {
-        mm_dbg ("skipping ^SWWAN check as no data port is available");
+        mm_obj_dbg (self, "skipping ^SWWAN check as no data port is available");
         self->priv->swwan_support = FEATURE_NOT_SUPPORTED;
         common_create_bearer (task);
         return;
     }
 
-    mm_dbg ("checking ^SWWAN support...");
+    mm_obj_dbg (self, "checking ^SWWAN support...");
     mm_base_modem_at_command (MM_BASE_MODEM (self),
                               "^SWWAN=?",
                               6,
diff --git a/plugins/cinterion/mm-modem-helpers-cinterion.c b/plugins/cinterion/mm-modem-helpers-cinterion.c
index 0eac912..da2dd64 100644
--- a/plugins/cinterion/mm-modem-helpers-cinterion.c
+++ b/plugins/cinterion/mm-modem-helpers-cinterion.c
@@ -24,7 +24,7 @@
 #include "ModemManager.h"
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-charsets.h"
 #include "mm-errors-types.h"
 #include "mm-modem-helpers-cinterion.h"
@@ -500,6 +500,7 @@
 MMBearerConnectionStatus
 mm_cinterion_parse_swwan_response (const gchar  *response,
                                    guint         cid,
+                                   gpointer      log_object,
                                    GError      **error)
 {
     GRegex                   *r;
@@ -531,9 +532,9 @@
         guint read_cid;
 
         if (!mm_get_uint_from_match_info (match_info, 1, &read_cid))
-            mm_warn ("Couldn't read cid in ^SWWAN response: '%s'", response);
+            mm_obj_warn (log_object, "couldn't read cid in ^SWWAN response: %s", response);
         else if (!mm_get_uint_from_match_info (match_info, 2, &read_state))
-            mm_warn ("Couldn't read state in ^SWWAN response: '%s'", response);
+            mm_obj_warn (log_object, "couldn't read state in ^SWWAN response: %s", response);
         else if (read_cid == cid) {
             if (read_state == MM_SWWAN_STATE_CONNECTED) {
                 status = MM_BEARER_CONNECTION_STATUS_CONNECTED;
@@ -543,7 +544,7 @@
                 status = MM_BEARER_CONNECTION_STATUS_DISCONNECTED;
                 break;
             }
-            mm_warn ("Invalid state read in ^SWWAN response: %u", read_state);
+            mm_obj_warn (log_object, "invalid state read in ^SWWAN response: %u", read_state);
             break;
         }
         g_match_info_next (match_info, &inner_error);
@@ -640,7 +641,8 @@
 /* ^SIND psinfo helper */
 
 MMModemAccessTechnology
-mm_cinterion_get_access_technology_from_sind_psinfo (guint val)
+mm_cinterion_get_access_technology_from_sind_psinfo (guint    val,
+                                                     gpointer log_object)
 {
     switch (val) {
     case 0:
@@ -664,7 +666,7 @@
     case 17:
         return MM_MODEM_ACCESS_TECHNOLOGY_LTE;
     default:
-        mm_dbg ("Unable to identify access technology from psinfo reported value: %u", val);
+        mm_obj_dbg (log_object, "unable to identify access technology from psinfo reported value: %u", val);
         return MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
     }
 }
@@ -694,6 +696,7 @@
 
 gboolean
 mm_cinterion_parse_slcc_list (const gchar *str,
+                              gpointer     log_object,
                               GList      **out_list,
                               GError     **error)
 {
@@ -747,20 +750,20 @@
         call_info = g_slice_new0 (MMCallInfo);
 
         if (!mm_get_uint_from_match_info (match_info, 1, &call_info->index)) {
-            mm_warn ("couldn't parse call index from ^SLCC line");
+            mm_obj_warn (log_object, "couldn't parse call index from ^SLCC line");
             goto next;
         }
 
         if (!mm_get_uint_from_match_info (match_info, 2, &aux) ||
             (aux >= G_N_ELEMENTS (cinterion_call_direction))) {
-            mm_warn ("couldn't parse call direction from ^SLCC line");
+            mm_obj_warn (log_object, "couldn't parse call direction from ^SLCC line");
             goto next;
         }
         call_info->direction = cinterion_call_direction[aux];
 
         if (!mm_get_uint_from_match_info (match_info, 3, &aux) ||
             (aux >= G_N_ELEMENTS (cinterion_call_state))) {
-            mm_warn ("couldn't parse call state from ^SLCC line");
+            mm_obj_warn (log_object, "couldn't parse call state from ^SLCC line");
             goto next;
         }
         call_info->state = cinterion_call_state[aux];
diff --git a/plugins/cinterion/mm-modem-helpers-cinterion.h b/plugins/cinterion/mm-modem-helpers-cinterion.h
index a318b8d..ad6a5fa 100644
--- a/plugins/cinterion/mm-modem-helpers-cinterion.h
+++ b/plugins/cinterion/mm-modem-helpers-cinterion.h
@@ -76,6 +76,7 @@
 
 MMBearerConnectionStatus mm_cinterion_parse_swwan_response (const gchar  *response,
                                                             guint         swwan_index,
+                                                            gpointer      log_object,
                                                             GError      **error);
 
 /*****************************************************************************/
@@ -88,7 +89,8 @@
 /*****************************************************************************/
 /* ^SIND psinfo helper */
 
-MMModemAccessTechnology mm_cinterion_get_access_technology_from_sind_psinfo (guint val);
+MMModemAccessTechnology mm_cinterion_get_access_technology_from_sind_psinfo (guint    val,
+                                                                             gpointer log_object);
 
 /*****************************************************************************/
 /* ^SLCC URC helpers */
@@ -97,6 +99,7 @@
 
 /* MMCallInfo list management */
 gboolean mm_cinterion_parse_slcc_list     (const gchar  *str,
+                                           gpointer      log_object,
                                            GList       **out_list,
                                            GError      **error);
 void     mm_cinterion_call_info_list_free (GList        *call_info_list);
diff --git a/plugins/cinterion/mm-plugin-cinterion.c b/plugins/cinterion/mm-plugin-cinterion.c
index bdca618..5fdd48b 100644
--- a/plugins/cinterion/mm-plugin-cinterion.c
+++ b/plugins/cinterion/mm-plugin-cinterion.c
@@ -29,7 +29,7 @@
 
 #include "mm-plugin-cinterion.h"
 #include "mm-broadband-modem-cinterion.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 #if defined WITH_QMI
 #include "mm-broadband-modem-qmi-cinterion.h"
@@ -115,7 +115,7 @@
 {
 #if defined WITH_QMI
     if (mm_port_probe_list_has_qmi_port (probes)) {
-        mm_dbg ("QMI-powered Cinterion modem found...");
+        mm_obj_dbg (self, "QMI-powered Cinterion modem found...");
         return MM_BASE_MODEM (mm_broadband_modem_qmi_cinterion_new (uid,
                                                                     drivers,
                                                                     mm_plugin_get_name (self),
@@ -143,14 +143,14 @@
     ptype = mm_port_probe_get_port_type (probe);
 
     if (g_object_get_data (G_OBJECT (probe), TAG_CINTERION_APP_PORT)) {
-        mm_dbg ("(%s/%s)' Port flagged as primary",
-                mm_port_probe_get_port_subsys (probe),
-                mm_port_probe_get_port_name (probe));
+        mm_obj_dbg (self, "port '%s/%s' flagged as primary",
+                    mm_port_probe_get_port_subsys (probe),
+                    mm_port_probe_get_port_name (probe));
         pflags = MM_PORT_SERIAL_AT_FLAG_PRIMARY;
     } else if (g_object_get_data (G_OBJECT (probe), TAG_CINTERION_MODEM_PORT)) {
-        mm_dbg ("(%s/%s)' Port flagged as PPP",
-                mm_port_probe_get_port_subsys (probe),
-                mm_port_probe_get_port_name (probe));
+        mm_obj_dbg (self, "port '%s/%s' flagged as PPP",
+                    mm_port_probe_get_port_subsys (probe),
+                    mm_port_probe_get_port_name (probe));
         pflags = MM_PORT_SERIAL_AT_FLAG_PPP;
     }
 
@@ -176,7 +176,7 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_CINTERION,
-                      MM_PLUGIN_NAME,                   "Cinterion",
+                      MM_PLUGIN_NAME,                   MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS,     subsystems,
                       MM_PLUGIN_ALLOWED_VENDOR_STRINGS, vendor_strings,
                       MM_PLUGIN_ALLOWED_VENDOR_IDS,     vendor_ids,
diff --git a/plugins/cinterion/mm-shared-cinterion.c b/plugins/cinterion/mm-shared-cinterion.c
index 8ae8e88..9ad03a7 100644
--- a/plugins/cinterion/mm-shared-cinterion.c
+++ b/plugins/cinterion/mm-shared-cinterion.c
@@ -23,7 +23,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-iface-modem.h"
 #include "mm-iface-modem-location.h"
 #include "mm-base-modem.h"
@@ -217,7 +217,7 @@
     sources = GPOINTER_TO_UINT (g_task_get_task_data (task));
 
     if (priv->sgpss_support == FEATURE_SUPPORTED || priv->sgpsc_support == FEATURE_SUPPORTED) {
-        mm_dbg ("GPS commands supported: GPS capabilities enabled");
+        mm_obj_dbg (self, "GPS commands supported: GPS capabilities enabled");
 
         /* We only flag as supported by this implementation those sources not already
          * supported by the parent implementation */
@@ -236,7 +236,7 @@
                                               self,
                                               NULL);
     } else
-        mm_dbg ("No GPS command supported: no GPS capabilities");
+        mm_obj_dbg (self, "no GPS command supported: no GPS capabilities");
 
     g_task_return_int (task, (gssize) sources);
     g_object_unref (task);
@@ -262,7 +262,7 @@
 
     /* Now our own check. If we don't have any GPS port, we're done */
     if (!mm_base_modem_peek_port_gps (MM_BASE_MODEM (self))) {
-        mm_dbg ("No GPS data port found: no GPS capabilities");
+        mm_obj_dbg (self, "no GPS data port found: no GPS capabilities");
         g_task_return_int (task, sources);
         g_object_unref (task);
         return;
@@ -610,7 +610,7 @@
          * Engine; so we'll run some retries of the same command ourselves. */
         if (ctx->gps_step == ENABLE_LOCATION_GATHERING_GPS_STEP_SGPSC_ENGINE) {
             ctx->sgpsc_engine_retries++;
-            mm_dbg ("GPS Engine setup failed (%u/%u)", ctx->sgpsc_engine_retries, MAX_SGPSC_ENGINE_RETRIES);
+            mm_obj_dbg (self, "GPS engine setup failed (%u/%u)", ctx->sgpsc_engine_retries, MAX_SGPSC_ENGINE_RETRIES);
             if (ctx->sgpsc_engine_retries < MAX_SGPSC_ENGINE_RETRIES) {
                 g_clear_error (&error);
                 goto schedule;
@@ -803,7 +803,7 @@
     /* If ^SLCC is supported create a cinterion call object */
     priv = get_private (MM_SHARED_CINTERION (self));
     if (priv->slcc_support == FEATURE_SUPPORTED) {
-        mm_dbg ("Created new call with ^SLCC support");
+        mm_obj_dbg (self, "created new call with ^SLCC support");
         return mm_base_call_new (MM_BASE_MODEM (self),
                                  direction,
                                  number,
@@ -857,16 +857,14 @@
                     GTask        *task)
 {
     VoiceUnsolicitedEventsContext *ctx;
-    GError                        *error = NULL;
+    g_autoptr(GError)              error = NULL;
 
     ctx = g_task_get_task_data (task);
 
-    if (!mm_base_modem_at_command_full_finish (self, res, &error)) {
-        mm_dbg ("Couldn't %s ^SLCC reporting: '%s'",
-                ctx->enable ? "enable" : "disable",
-                error->message);
-        g_error_free (error);
-    }
+    if (!mm_base_modem_at_command_full_finish (self, res, &error))
+        mm_obj_dbg (self, "couldn't %s ^SLCC reporting: %s",
+                    ctx->enable ? "enable" : "disable",
+                    error->message);
 
     /* Continue on next port */
     run_voice_enable_disable_unsolicited_events (task);
@@ -892,13 +890,13 @@
     }
 
     if (!ctx->slcc_primary_done && ctx->primary) {
-        mm_dbg ("%s ^SLCC  extended list of current calls reporting in primary port...",
-                ctx->enable ? "Enabling" : "Disabling");
+        mm_obj_dbg (self, "%s ^SLCC  extended list of current calls reporting in primary port...",
+                    ctx->enable ? "enabling" : "disabling");
         ctx->slcc_primary_done = TRUE;
         port = ctx->primary;
     } else if (!ctx->slcc_secondary_done && ctx->secondary) {
-        mm_dbg ("%s ^SLCC  extended list of current calls reporting in secondary port...",
-                ctx->enable ? "Enabling" : "Disabling");
+        mm_obj_dbg (self, "%s ^SLCC  extended list of current calls reporting in secondary port...",
+                    ctx->enable ? "enabling" : "disabling");
         ctx->slcc_secondary_done = TRUE;
         port = ctx->secondary;
     }
@@ -961,15 +959,13 @@
                                                GAsyncResult      *res,
                                                GTask             *task)
 {
-    GError  *error = NULL;
-    Private *priv;
+    g_autoptr(GError)  error = NULL;
+    Private           *priv;
 
     priv = get_private (MM_SHARED_CINTERION (self));
 
-    if (!priv->iface_modem_voice_parent->disable_unsolicited_events_finish (self, res, &error)) {
-        mm_warn ("Couldn't disable parent voice unsolicited events: %s", error->message);
-        g_error_free (error);
-    }
+    if (!priv->iface_modem_voice_parent->disable_unsolicited_events_finish (self, res, &error))
+        mm_obj_warn (self, "couldn't disable parent voice unsolicited events: %s", error->message);
 
     g_task_return_boolean (task, TRUE);
     g_object_unref (task);
@@ -980,13 +976,11 @@
                                         GAsyncResult      *res,
                                         GTask             *task)
 {
-    Private *priv;
-    GError  *error = NULL;
+    Private           *priv;
+    g_autoptr(GError)  error = NULL;
 
-    if (!common_voice_enable_disable_unsolicited_events_finish (self, res, &error)) {
-        mm_warn ("Couldn't disable Cinterion-specific voice unsolicited events: %s", error->message);
-        g_error_free (error);
-    }
+    if (!common_voice_enable_disable_unsolicited_events_finish (self, res, &error))
+        mm_obj_warn (self, "couldn't disable Cinterion-specific voice unsolicited events: %s", error->message);
 
     priv = get_private (MM_SHARED_CINTERION (self));
     g_assert (priv->iface_modem_voice_parent);
@@ -1032,12 +1026,10 @@
                                        GAsyncResult      *res,
                                        GTask             *task)
 {
-    GError *error = NULL;
+    g_autoptr(GError) error = NULL;
 
-    if (!common_voice_enable_disable_unsolicited_events_finish (self, res, &error)) {
-        mm_warn ("Couldn't enable Cinterion-specific voice unsolicited events: %s", error->message);
-        g_error_free (error);
-    }
+    if (!common_voice_enable_disable_unsolicited_events_finish (self, res, &error))
+        mm_obj_warn (self, "couldn't enable Cinterion-specific voice unsolicited events: %s", error->message);
 
     g_task_return_boolean (task, TRUE);
     g_object_unref (task);
@@ -1048,15 +1040,13 @@
                                               GAsyncResult      *res,
                                               GTask             *task)
 {
-    GError  *error = NULL;
-    Private *priv;
+    g_autoptr(GError)  error = NULL;
+    Private           *priv;
 
     priv = get_private (MM_SHARED_CINTERION (self));
 
-    if (!priv->iface_modem_voice_parent->enable_unsolicited_events_finish (self, res, &error)) {
-        mm_warn ("Couldn't enable parent voice unsolicited events: %s", error->message);
-        g_error_free (error);
-    }
+    if (!priv->iface_modem_voice_parent->enable_unsolicited_events_finish (self, res, &error))
+        mm_obj_warn (self, "couldn't enable parent voice unsolicited events: %s", error->message);
 
     /* our own enabling next */
     common_voice_enable_disable_unsolicited_events (MM_SHARED_CINTERION (self),
@@ -1095,20 +1085,16 @@
                GMatchInfo        *match_info,
                MMSharedCinterion *self)
 {
-    gchar  *full;
-    GError *error = NULL;
-    GList  *call_info_list = NULL;
+    g_autofree gchar  *full = NULL;
+    g_autoptr(GError)  error = NULL;
+    GList             *call_info_list = NULL;
 
     full = g_match_info_fetch (match_info, 0);
-
-    if (!mm_cinterion_parse_slcc_list (full, &call_info_list, &error)) {
-        mm_warn ("couldn't parse ^SLCC list: %s", error->message);
-        g_error_free (error);
-    } else
+    if (!mm_cinterion_parse_slcc_list (full, self, &call_info_list, &error))
+        mm_obj_warn (self, "couldn't parse ^SLCC list: %s", error->message);
+    else
         mm_iface_modem_voice_report_all_calls (MM_IFACE_MODEM_VOICE (self), call_info_list);
-
     mm_cinterion_call_info_list_free (call_info_list);
-    g_free (full);
 }
 
 static void
@@ -1152,15 +1138,13 @@
                                                GAsyncResult      *res,
                                                GTask             *task)
 {
-    GError  *error = NULL;
-    Private *priv;
+    g_autoptr(GError)  error = NULL;
+    Private           *priv;
 
     priv = get_private (MM_SHARED_CINTERION (self));
 
-    if (!priv->iface_modem_voice_parent->cleanup_unsolicited_events_finish (self, res, &error)) {
-        mm_warn ("Couldn't cleanup parent voice unsolicited events: %s", error->message);
-        g_error_free (error);
-    }
+    if (!priv->iface_modem_voice_parent->cleanup_unsolicited_events_finish (self, res, &error))
+        mm_obj_warn (self, "couldn't cleanup parent voice unsolicited events: %s", error->message);
 
     g_task_return_boolean (task, TRUE);
     g_object_unref (task);
@@ -1207,15 +1191,13 @@
                                              GAsyncResult      *res,
                                              GTask             *task)
 {
-    GError  *error = NULL;
-    Private *priv;
+    g_autoptr(GError)  error = NULL;
+    Private           *priv;
 
     priv = get_private (MM_SHARED_CINTERION (self));
 
-    if (!priv->iface_modem_voice_parent->setup_unsolicited_events_finish (self, res, &error)) {
-        mm_warn ("Couldn't setup parent voice unsolicited events: %s", error->message);
-        g_error_free (error);
-    }
+    if (!priv->iface_modem_voice_parent->setup_unsolicited_events_finish (self, res, &error))
+        mm_obj_warn (self, "Couldn't setup parent voice unsolicited events: %s", error->message);
 
     /* our own setup next */
     common_voice_setup_cleanup_unsolicited_events (MM_SHARED_CINTERION (self), TRUE);
@@ -1337,24 +1319,18 @@
                GMatchInfo        *match_info,
                MMSharedCinterion *self)
 {
-    gchar             *iso8601 = NULL;
-    MMNetworkTimezone *tz = NULL;
-    GError            *error = NULL;
+    g_autofree gchar             *iso8601 = NULL;
+    g_autoptr(MMNetworkTimezone)  tz = NULL;
+    g_autoptr(GError)             error = NULL;
 
     if (!mm_cinterion_parse_ctzu_urc (match_info, &iso8601, &tz, &error)) {
-        mm_dbg ("Couldn't process +CTZU URC: %s", error->message);
-        g_error_free (error);
+        mm_obj_dbg (self, "couldn't process +CTZU URC: %s", error->message);
         return;
     }
 
-    g_assert (iso8601);
-    mm_dbg ("+CTZU URC received: %s", iso8601);
+    mm_obj_dbg (self, "+CTZU URC received: %s", iso8601);
     mm_iface_modem_time_update_network_time (MM_IFACE_MODEM_TIME (self), iso8601);
-    g_free (iso8601);
-
-    g_assert (tz);
     mm_iface_modem_time_update_network_timezone (MM_IFACE_MODEM_TIME (self), tz);
-    g_object_unref (tz);
 }
 
 static void
@@ -1370,8 +1346,8 @@
     ports[0] = mm_base_modem_peek_port_primary   (MM_BASE_MODEM (self));
     ports[1] = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self));
 
-    mm_dbg ("%s up time unsolicited events...",
-            enable ? "Setting" : "Cleaning");
+    mm_obj_dbg (self, "%s up time unsolicited events...",
+                enable ? "setting" : "cleaning");
 
     for (i = 0; i < G_N_ELEMENTS (ports); i++) {
         if (!ports[i])
@@ -1401,15 +1377,13 @@
                                               GAsyncResult     *res,
                                               GTask            *task)
 {
-    GError  *error = NULL;
-    Private *priv;
+    g_autoptr(GError)  error = NULL;
+    Private           *priv;
 
     priv = get_private (MM_SHARED_CINTERION (self));
 
-    if (!priv->iface_modem_time_parent->cleanup_unsolicited_events_finish (self, res, &error)) {
-        mm_warn ("Couldn't cleanup parent time unsolicited events: %s", error->message);
-        g_error_free (error);
-    }
+    if (!priv->iface_modem_time_parent->cleanup_unsolicited_events_finish (self, res, &error))
+        mm_obj_warn (self, "couldn't cleanup parent time unsolicited events: %s", error->message);
 
     g_task_return_boolean (task, TRUE);
     g_object_unref (task);
@@ -1475,15 +1449,13 @@
                                             GAsyncResult     *res,
                                             GTask            *task)
 {
-    GError  *error = NULL;
-    Private *priv;
+    g_autoptr(GError)  error = NULL;
+    Private           *priv;
 
     priv = get_private (MM_SHARED_CINTERION (self));
 
-    if (!priv->iface_modem_time_parent->cleanup_unsolicited_events_finish (self, res, &error)) {
-        mm_warn ("Couldn't cleanup parent time unsolicited events: %s", error->message);
-        g_error_free (error);
-    }
+    if (!priv->iface_modem_time_parent->cleanup_unsolicited_events_finish (self, res, &error))
+        mm_obj_warn (self, "Couldn't cleanup parent time unsolicited events: %s", error->message);
 
     own_time_setup_unsolicited_events (task);
 }
diff --git a/plugins/cinterion/tests/test-modem-helpers-cinterion.c b/plugins/cinterion/tests/test-modem-helpers-cinterion.c
index 78adf30..0baeec3 100644
--- a/plugins/cinterion/tests/test-modem-helpers-cinterion.c
+++ b/plugins/cinterion/tests/test-modem-helpers-cinterion.c
@@ -21,7 +21,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-test.h"
 #include "mm-modem-helpers.h"
 #include "mm-modem-helpers-cinterion.h"
 
@@ -565,7 +565,7 @@
 
         /* Query for the expected items (CIDs 2 and 3) */
         for (j = 0; j < SWWAN_TEST_MAX_CIDS; j++) {
-            read_state = mm_cinterion_parse_swwan_response (swwan_tests[i].response, swwan_tests[i].expected_items[j].cid, &error);
+            read_state = mm_cinterion_parse_swwan_response (swwan_tests[i].response, swwan_tests[i].expected_items[j].cid, NULL, &error);
             if (swwan_tests[i].expected_items[j].state == MM_BEARER_CONNECTION_STATUS_UNKNOWN) {
                 g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED);
                 g_clear_error (&error);
@@ -576,7 +576,7 @@
 
         /* Query for a CID which isn't replied (e.g. 12) */
         if (!swwan_tests[i].skip_test_other_cids) {
-            read_state = mm_cinterion_parse_swwan_response (swwan_tests[i].response, 12, &error);
+            read_state = mm_cinterion_parse_swwan_response (swwan_tests[i].response, 12, NULL, &error);
             g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED);
             g_assert_cmpint (read_state, ==, MM_BEARER_CONNECTION_STATUS_UNKNOWN);
             g_clear_error (&error);
@@ -584,7 +584,7 @@
     }
 
     /* Additional tests for errors */
-    read_state = mm_cinterion_parse_swwan_response ("^GARBAGE", 2, &error);
+    read_state = mm_cinterion_parse_swwan_response ("^GARBAGE", 2, NULL, &error);
     g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED);
     g_assert_cmpint (read_state, ==, MM_BEARER_CONNECTION_STATUS_UNKNOWN);
     g_clear_error (&error);
@@ -695,7 +695,7 @@
     str = g_match_info_fetch (match_info, 0);
     g_assert (str);
 
-    result = mm_cinterion_parse_slcc_list (str, &call_info_list, &error);
+    result = mm_cinterion_parse_slcc_list (str, NULL, &call_info_list, &error);
     g_assert_no_error (error);
     g_assert (result);
 
@@ -858,26 +858,6 @@
 
 /*****************************************************************************/
 
-void
-_mm_log (const char *loc,
-         const char *func,
-         guint32 level,
-         const char *fmt,
-         ...)
-{
-    va_list args;
-    gchar *msg;
-
-    if (!g_test_verbose ())
-        return;
-
-    va_start (args, fmt);
-    msg = g_strdup_vprintf (fmt, args);
-    va_end (args);
-    g_print ("%s\n", msg);
-    g_free (msg);
-}
-
 int main (int argc, char **argv)
 {
     setlocale (LC_ALL, "");
diff --git a/plugins/dell/mm-plugin-dell.c b/plugins/dell/mm-plugin-dell.c
index e9f8a0b..cc0d803 100644
--- a/plugins/dell/mm-plugin-dell.c
+++ b/plugins/dell/mm-plugin-dell.c
@@ -36,7 +36,7 @@
 #include "mm-broadband-modem-telit.h"
 #include "mm-broadband-modem-xmm.h"
 #include "mm-common-telit.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 #if defined WITH_QMI
 #include "mm-broadband-modem-qmi.h"
@@ -170,7 +170,7 @@
     if (error) {
         /* Non-timeout error, jump to next command */
         if (!g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_RESPONSE_TIMEOUT)) {
-            mm_dbg ("(Dell) Error probing AT port: %s", error->message);
+            mm_obj_dbg (probe, "error probing AT port: %s", error->message);
             g_error_free (error);
             custom_init_step_next_command (task);
             return;
@@ -250,8 +250,7 @@
 
     /* If cancelled, end without error right away */
     if (g_cancellable_is_cancelled (g_task_get_cancellable (task))) {
-        mm_dbg ("(Dell) no need to keep on running custom init in (%s)",
-                mm_port_get_device (MM_PORT (ctx->port)));
+        mm_obj_dbg (probe, "no need to keep on running custom init: cancelled");
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
         return;
@@ -260,8 +259,7 @@
 #if defined WITH_QMI
     /* If device has a QMI port, don't run anything else, as we don't care */
     if (mm_port_probe_list_has_qmi_port (mm_device_peek_port_probe_list (mm_port_probe_peek_device (probe)))) {
-        mm_dbg ("(Dell) no need to run custom init in (%s): device has QMI port",
-                mm_port_get_device (MM_PORT (ctx->port)));
+        mm_obj_dbg (probe, "no need to run custom init: device has QMI port");
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
         return;
@@ -271,8 +269,7 @@
 #if defined WITH_MBIM
     /* If device has a MBIM port, don't run anything else, as we don't care */
     if (mm_port_probe_list_has_mbim_port (mm_device_peek_port_probe_list (mm_port_probe_peek_device (probe)))) {
-        mm_dbg ("(Dell) no need to run custom init in (%s): device has MBIM port",
-                mm_port_get_device (MM_PORT (ctx->port)));
+        mm_obj_dbg (probe, "no need to run custom init: device has MBIM port");
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
         return;
@@ -280,8 +277,7 @@
 #endif
 
     if (ctx->timeouts >= MAX_PORT_PROBE_TIMEOUTS) {
-        mm_dbg ("(Dell) couldn't detect real manufacturer in (%s): too many timeouts",
-                mm_port_get_device (MM_PORT (ctx->port)));
+        mm_obj_dbg (probe, "couldn't detect real manufacturer: too many timeouts");
         mm_port_probe_set_result_at (probe, FALSE);
         goto out;
     }
@@ -326,8 +322,7 @@
         return;
     }
 
-    mm_dbg ("(Dell) couldn't detect real manufacturer in (%s): all retries consumed",
-            mm_port_get_device (MM_PORT (ctx->port)));
+    mm_obj_dbg (probe, "couldn't detect real manufacturer: all retries consumed");
 out:
     /* Finish custom_init */
     g_task_return_boolean (task, TRUE);
@@ -387,7 +382,7 @@
 
 #if defined WITH_QMI
     if (mm_port_probe_list_has_qmi_port (probes)) {
-        mm_dbg ("QMI-powered Dell-branded modem found...");
+        mm_obj_dbg (self, "QMI-powered Dell-branded modem found...");
         return MM_BASE_MODEM (mm_broadband_modem_qmi_new (uid,
                                                           drivers,
                                                           mm_plugin_get_name (self),
@@ -400,7 +395,7 @@
     if (mm_port_probe_list_has_mbim_port (probes)) {
         /* Specific implementation for the DW5821e */
         if (vendor == 0x413c && (product == 0x81d7 || product == 0x81e0)) {
-            mm_dbg ("MBIM-powered DW5821e (T77W968) modem found...");
+            mm_obj_dbg (self, "MBIM-powered DW5821e (T77W968) modem found...");
             return MM_BASE_MODEM (mm_broadband_modem_foxconn_t77w968_new (uid,
                                                                           drivers,
                                                                           mm_plugin_get_name (self),
@@ -409,7 +404,7 @@
         }
 
         if (mm_port_probe_list_is_xmm (probes)) {
-            mm_dbg ("MBIM-powered XMM-based modem found...");
+            mm_obj_dbg (self, "MBIM-powered XMM-based modem found...");
             return MM_BASE_MODEM (mm_broadband_modem_mbim_xmm_new (uid,
                                                                    drivers,
                                                                    mm_plugin_get_name (self),
@@ -417,7 +412,7 @@
                                                                    product));
         }
 
-        mm_dbg ("MBIM-powered Dell-branded modem found...");
+        mm_obj_dbg (self, "MBIM-powered Dell-branded modem found...");
         return MM_BASE_MODEM (mm_broadband_modem_mbim_new (uid,
                                                            drivers,
                                                            mm_plugin_get_name (self),
@@ -427,7 +422,7 @@
 #endif
 
     if (port_probe_list_has_manufacturer_port (probes, DELL_MANUFACTURER_NOVATEL)) {
-        mm_dbg ("Novatel-powered Dell-branded modem found...");
+        mm_obj_dbg (self, "Novatel-powered Dell-branded modem found...");
         return MM_BASE_MODEM (mm_broadband_modem_novatel_new (uid,
                                                               drivers,
                                                               mm_plugin_get_name (self),
@@ -436,7 +431,7 @@
     }
 
     if (port_probe_list_has_manufacturer_port (probes, DELL_MANUFACTURER_SIERRA)) {
-        mm_dbg ("Sierra-powered Dell-branded modem found...");
+        mm_obj_dbg (self, "Sierra-powered Dell-branded modem found...");
         return MM_BASE_MODEM (mm_broadband_modem_sierra_new (uid,
                                                              drivers,
                                                              mm_plugin_get_name (self),
@@ -445,7 +440,7 @@
     }
 
     if (port_probe_list_has_manufacturer_port (probes, DELL_MANUFACTURER_TELIT)) {
-        mm_dbg ("Telit-powered Dell-branded modem found...");
+        mm_obj_dbg (self, "Telit-powered Dell-branded modem found...");
         return MM_BASE_MODEM (mm_broadband_modem_telit_new (uid,
                                                             drivers,
                                                             mm_plugin_get_name (self),
@@ -454,7 +449,7 @@
     }
 
     if (mm_port_probe_list_is_xmm (probes)) {
-        mm_dbg ("XMM-based modem found...");
+        mm_obj_dbg (self, "XMM-based modem found...");
         return MM_BASE_MODEM (mm_broadband_modem_xmm_new (uid,
                                                           drivers,
                                                           mm_plugin_get_name (self),
@@ -462,7 +457,7 @@
                                                           product));
     }
 
-    mm_dbg ("Dell-branded generic modem found...");
+    mm_obj_dbg (self, "Dell-branded generic modem found...");
     return MM_BASE_MODEM (mm_broadband_modem_new (uid,
                                                   drivers,
                                                   mm_plugin_get_name (self),
@@ -505,7 +500,7 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_DELL,
-                      MM_PLUGIN_NAME,               "Dell",
+                      MM_PLUGIN_NAME,               MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems,
                       MM_PLUGIN_ALLOWED_VENDOR_IDS, vendors,
                       MM_PLUGIN_ALLOWED_AT,         TRUE,
diff --git a/plugins/dlink/mm-plugin-dlink.c b/plugins/dlink/mm-plugin-dlink.c
index e7c6816..46c9608 100644
--- a/plugins/dlink/mm-plugin-dlink.c
+++ b/plugins/dlink/mm-plugin-dlink.c
@@ -20,7 +20,7 @@
 #include <libmm-glib.h>
 
 #include "mm-port-enums-types.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-plugin-dlink.h"
 #include "mm-broadband-modem.h"
 
@@ -46,7 +46,7 @@
 {
 #if defined WITH_QMI
     if (mm_port_probe_list_has_qmi_port (probes)) {
-        mm_dbg ("QMI-powered D-Link modem found...");
+        mm_obj_dbg (self, "QMI-powered D-Link modem found...");
         return MM_BASE_MODEM (mm_broadband_modem_qmi_new (uid,
                                                           drivers,
                                                           mm_plugin_get_name (self),
@@ -72,7 +72,7 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_DLINK,
-                      MM_PLUGIN_NAME,               "D-Link",
+                      MM_PLUGIN_NAME,               MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems,
                       MM_PLUGIN_ALLOWED_VENDOR_IDS, vendor_ids,
                       MM_PLUGIN_ALLOWED_AT,         TRUE,
diff --git a/plugins/fibocom/77-mm-fibocom-port-types.rules b/plugins/fibocom/77-mm-fibocom-port-types.rules
index 215f1d2..11917f4 100644
--- a/plugins/fibocom/77-mm-fibocom-port-types.rules
+++ b/plugins/fibocom/77-mm-fibocom-port-types.rules
@@ -13,4 +13,14 @@
 #  ttyACM2 (if #6): AT port
 ATTRS{idVendor}=="2cb7", ATTRS{idProduct}=="0007", ENV{.MM_USBIFNUM}=="04", ENV{ID_MM_PORT_IGNORE}="1"
 
+# Fibocom FM150
+#  ttyUSB0 (if #0): QCDM port
+#  ttyUSB1 (if #1): AT port
+#  ttyUSB2 (if #2): AT port
+#  ttyUSB2 (if #3): Ignore
+ATTRS{idVendor}=="2cb7", ATTRS{idProduct}=="0104", ENV{.MM_USBIFNUM}=="00", ENV{ID_MM_PORT_TYPE_QCDM}="1"
+ATTRS{idVendor}=="2cb7", ATTRS{idProduct}=="0104", ENV{.MM_USBIFNUM}=="01", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1"
+ATTRS{idVendor}=="2cb7", ATTRS{idProduct}=="0104", ENV{.MM_USBIFNUM}=="02", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1"
+ATTRS{idVendor}=="2cb7", ATTRS{idProduct}=="0104", ENV{.MM_USBIFNUM}=="03", ENV{ID_MM_PORT_IGNORE}="1"
+
 LABEL="mm_fibocom_port_types_end"
diff --git a/plugins/fibocom/mm-plugin-fibocom.c b/plugins/fibocom/mm-plugin-fibocom.c
index d41dc6a..e218856 100644
--- a/plugins/fibocom/mm-plugin-fibocom.c
+++ b/plugins/fibocom/mm-plugin-fibocom.c
@@ -10,7 +10,7 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details:
  *
- * Copyright (C) 2018 Aleksander Morgado <aleksander@aleksander.es>
+ * Copyright (C) 2018-2020 Aleksander Morgado <aleksander@aleksander.es>
  */
 
 #include <stdlib.h>
@@ -19,7 +19,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-plugin-fibocom.h"
 #include "mm-broadband-modem.h"
 #include "mm-broadband-modem-xmm.h"
@@ -29,6 +29,10 @@
 #include "mm-broadband-modem-mbim-xmm.h"
 #endif
 
+#if defined WITH_QMI
+#include "mm-broadband-modem-qmi.h"
+#endif
+
 G_DEFINE_TYPE (MMPluginFibocom, mm_plugin_fibocom, MM_TYPE_PLUGIN)
 
 MM_PLUGIN_DEFINE_MAJOR_VERSION
@@ -48,14 +52,14 @@
 #if defined WITH_MBIM
     if (mm_port_probe_list_has_mbim_port (probes)) {
         if (mm_port_probe_list_is_xmm (probes)) {
-            mm_dbg ("MBIM-powered XMM-based Fibocom modem found...");
+            mm_obj_dbg (self, "MBIM-powered XMM-based Fibocom modem found...");
             return MM_BASE_MODEM (mm_broadband_modem_mbim_xmm_new (uid,
                                                                    drivers,
                                                                    mm_plugin_get_name (self),
                                                                    vendor,
                                                                    product));
         }
-        mm_dbg ("MBIM-powered Fibocom modem found...");
+        mm_obj_dbg (self, "MBIM-powered Fibocom modem found...");
         return MM_BASE_MODEM (mm_broadband_modem_mbim_new (uid,
                                                            drivers,
                                                            mm_plugin_get_name (self),
@@ -64,8 +68,19 @@
     }
 #endif
 
+#if defined WITH_QMI
+    if (mm_port_probe_list_has_qmi_port (probes)) {
+        mm_obj_dbg (self, "QMI-powered Fibocom modem found...");
+        return MM_BASE_MODEM (mm_broadband_modem_qmi_new (uid,
+                                                          drivers,
+                                                          mm_plugin_get_name (self),
+                                                          vendor,
+                                                          product));
+    }
+#endif
+
     if (mm_port_probe_list_is_xmm (probes)) {
-        mm_dbg ("XMM-based Fibocom modem found...");
+        mm_obj_dbg (self, "XMM-based Fibocom modem found...");
         return MM_BASE_MODEM (mm_broadband_modem_xmm_new (uid,
                                                           drivers,
                                                           mm_plugin_get_name (self),
@@ -73,7 +88,7 @@
                                                           product));
     }
 
-    mm_dbg ("Fibocom modem found...");
+    mm_obj_dbg (self, "Fibocom modem found...");
     return MM_BASE_MODEM (mm_broadband_modem_new (uid,
                                                   drivers,
                                                   mm_plugin_get_name (self),
@@ -88,11 +103,11 @@
 {
     static const gchar *subsystems[] = { "tty", "net", "usb", NULL };
     static const guint16 vendor_ids[] = { 0x2cb7, 0 };
-    static const gchar *drivers[] = { "cdc_mbim", NULL };
+    static const gchar *drivers[] = { "cdc_mbim", "qmi_wwan", NULL };
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_FIBOCOM,
-                      MM_PLUGIN_NAME,               "Fibocom",
+                      MM_PLUGIN_NAME,               MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems,
                       MM_PLUGIN_ALLOWED_VENDOR_IDS, vendor_ids,
                       MM_PLUGIN_ALLOWED_DRIVERS,    drivers,
diff --git a/plugins/foxconn/mm-broadband-modem-foxconn-t77w968.c b/plugins/foxconn/mm-broadband-modem-foxconn-t77w968.c
index c594019..95db6ee 100644
--- a/plugins/foxconn/mm-broadband-modem-foxconn-t77w968.c
+++ b/plugins/foxconn/mm-broadband-modem-foxconn-t77w968.c
@@ -26,7 +26,6 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
 #include "mm-errors-types.h"
 #include "mm-modem-helpers.h"
 #include "mm-base-modem-at.h"
diff --git a/plugins/foxconn/mm-plugin-foxconn.c b/plugins/foxconn/mm-plugin-foxconn.c
index 5bd2f88..1ad0681 100644
--- a/plugins/foxconn/mm-plugin-foxconn.c
+++ b/plugins/foxconn/mm-plugin-foxconn.c
@@ -26,7 +26,7 @@
 #include <libmm-glib.h>
 
 #include "mm-plugin-foxconn.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-broadband-modem.h"
 
 #if defined WITH_QMI
@@ -55,7 +55,7 @@
 {
 #if defined WITH_QMI
     if (mm_port_probe_list_has_qmi_port (probes)) {
-        mm_dbg ("QMI-powered Foxconn-branded modem found...");
+        mm_obj_dbg (self, "QMI-powered Foxconn-branded modem found...");
         return MM_BASE_MODEM (mm_broadband_modem_qmi_new (uid,
                                                           drivers,
                                                           mm_plugin_get_name (self),
@@ -68,7 +68,7 @@
     if (mm_port_probe_list_has_mbim_port (probes)) {
         /* Specific implementation for the T77W968 */
         if (product == 0xe0b4 || product == 0xe0b5) {
-            mm_dbg ("MBIM-powered T77W968 modem found...");
+            mm_obj_dbg (self, "MBIM-powered T77W968 modem found...");
             return MM_BASE_MODEM (mm_broadband_modem_foxconn_t77w968_new (uid,
 									  drivers,
 									  mm_plugin_get_name (self),
@@ -76,7 +76,7 @@
 									  product));
         }
 
-        mm_dbg ("MBIM-powered Foxconn-branded modem found...");
+        mm_obj_dbg (self, "MBIM-powered Foxconn-branded modem found...");
         return MM_BASE_MODEM (mm_broadband_modem_mbim_new (uid,
                                                            drivers,
                                                            mm_plugin_get_name (self),
@@ -85,7 +85,7 @@
     }
 #endif
 
-    mm_dbg ("Foxconn-branded generic modem found...");
+    mm_obj_dbg (self, "Foxconn-branded generic modem found...");
     return MM_BASE_MODEM (mm_broadband_modem_new (uid,
                                                   drivers,
                                                   mm_plugin_get_name (self),
@@ -103,7 +103,7 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_FOXCONN,
-                      MM_PLUGIN_NAME,               "Foxconn",
+                      MM_PLUGIN_NAME,               MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems,
                       MM_PLUGIN_ALLOWED_VENDOR_IDS, vendors,
                       MM_PLUGIN_ALLOWED_AT,         TRUE,
diff --git a/plugins/generic/mm-plugin-generic.c b/plugins/generic/mm-plugin-generic.c
index 8f42930..c2e3a07 100644
--- a/plugins/generic/mm-plugin-generic.c
+++ b/plugins/generic/mm-plugin-generic.c
@@ -31,7 +31,7 @@
 #include "mm-plugin-generic.h"
 #include "mm-broadband-modem.h"
 #include "mm-serial-parsers.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 #if defined WITH_QMI
 #include "mm-broadband-modem-qmi.h"
@@ -59,7 +59,7 @@
 {
 #if defined WITH_QMI
     if (mm_port_probe_list_has_qmi_port (probes)) {
-        mm_dbg ("QMI-powered generic modem found...");
+        mm_obj_dbg (self, "QMI-powered generic modem found...");
         return MM_BASE_MODEM (mm_broadband_modem_qmi_new (uid,
                                                           drivers,
                                                           mm_plugin_get_name (self),
@@ -70,7 +70,7 @@
 
 #if defined WITH_MBIM
     if (mm_port_probe_list_has_mbim_port (probes)) {
-        mm_dbg ("MBIM-powered generic modem found...");
+        mm_obj_dbg (self, "MBIM-powered generic modem found...");
         return MM_BASE_MODEM (mm_broadband_modem_mbim_new (uid,
                                                            drivers,
                                                            mm_plugin_get_name (self),
@@ -95,7 +95,8 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_GENERIC,
-                      MM_PLUGIN_NAME,               MM_PLUGIN_GENERIC_NAME,
+                      MM_PLUGIN_NAME,               MM_MODULE_NAME,
+                      MM_PLUGIN_IS_GENERIC,         TRUE,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems,
                       MM_PLUGIN_ALLOWED_AT,         TRUE,
                       MM_PLUGIN_ALLOWED_QCDM,       TRUE,
diff --git a/plugins/generic/tests/test-service-generic.c b/plugins/generic/tests/test-service-generic.c
index ea29e9e..d7bc4e0 100644
--- a/plugins/generic/tests/test-service-generic.c
+++ b/plugins/generic/tests/test-service-generic.c
@@ -51,7 +51,7 @@
     /* Set the test profile */
     test_fixture_set_profile (fixture,
                               "test-enable-disable",
-                              "Generic",
+                              "generic",
                               (const gchar *const *)ports);
 
     /* Wait and get the modem object */
diff --git a/plugins/haier/mm-plugin-haier.c b/plugins/haier/mm-plugin-haier.c
index 86f1730..0c11aeb 100644
--- a/plugins/haier/mm-plugin-haier.c
+++ b/plugins/haier/mm-plugin-haier.c
@@ -19,7 +19,6 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
 #include "mm-broadband-modem.h"
 #include "mm-plugin-haier.h"
 
@@ -55,7 +54,7 @@
     static const guint16 vendor_ids[] = { 0x201e, 0 };
 
     return MM_PLUGIN (g_object_new (MM_TYPE_PLUGIN_HAIER,
-                                    MM_PLUGIN_NAME,               "Haier",
+                                    MM_PLUGIN_NAME,               MM_MODULE_NAME,
                                     MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems,
                                     MM_PLUGIN_ALLOWED_VENDOR_IDS, vendor_ids,
                                     MM_PLUGIN_ALLOWED_AT,         TRUE,
diff --git a/plugins/huawei/mm-broadband-bearer-huawei.c b/plugins/huawei/mm-broadband-bearer-huawei.c
index a15edc6..81a2e5a 100644
--- a/plugins/huawei/mm-broadband-bearer-huawei.c
+++ b/plugins/huawei/mm-broadband-bearer-huawei.c
@@ -27,7 +27,7 @@
 #include <ModemManager.h>
 #include "mm-base-modem-at.h"
 #include "mm-broadband-bearer-huawei.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-modem-helpers.h"
 #include "mm-modem-helpers-huawei.h"
 #include "mm-daemon-enums-types.h"
@@ -175,7 +175,7 @@
             g_free (strarr[0]);
             g_free (strarr[1]);
         } else {
-            mm_dbg ("Unexpected response to ^DHCP command: %s", error->message);
+            mm_obj_dbg (self, "unexpected response to ^DHCP command: %s", error->message);
         }
     }
 
@@ -233,8 +233,8 @@
                                                &ipv6_connected,
                                                &error)) {
         ctx->failed_ndisstatqry_count++;
-        mm_dbg ("Unexpected response to ^NDISSTATQRY command: %s (Attempts so far: %u)",
-                error->message, ctx->failed_ndisstatqry_count);
+        mm_obj_dbg (self, "unexpected response to ^NDISSTATQRY command: %s (%u attempts so far)",
+                    error->message, ctx->failed_ndisstatqry_count);
         g_error_free (error);
     }
 
@@ -358,8 +358,7 @@
 
             ip_family = mm_base_bearer_get_default_ip_family (MM_BASE_BEARER (self));
             ip_family_str = mm_bearer_ip_family_build_string_from_mask (ip_family);
-            mm_dbg ("No specific IP family requested, defaulting to %s",
-                    ip_family_str);
+            mm_obj_dbg (self, "no specific IP family requested, defaulting to %s", ip_family_str);
             g_free (ip_family_str);
         }
 
@@ -633,8 +632,8 @@
                                                &ipv6_connected,
                                                &error)) {
         ctx->failed_ndisstatqry_count++;
-        mm_dbg ("Unexpected response to ^NDISSTATQRY command: %s (Attempts so far: %u)",
-                error->message, ctx->failed_ndisstatqry_count);
+        mm_obj_dbg (self, "unexpected response to ^NDISSTATQRY command: %s (%u attempts so far)",
+                    error->message, ctx->failed_ndisstatqry_count);
         g_error_free (error);
     }
 
@@ -808,8 +807,7 @@
 static gboolean
 network_disconnect_3gpp_delayed (MMBroadbandBearerHuawei *self)
 {
-    mm_dbg ("Disconnect bearer '%s' on network request.",
-            mm_base_bearer_get_path (MM_BASE_BEARER (self)));
+    mm_obj_dbg (self, "disconnect bearer on network request");
 
     self->priv->network_disconnect_pending_id = 0;
     mm_base_bearer_report_connection_status (MM_BASE_BEARER (self),
@@ -833,8 +831,7 @@
     if (self->priv->connect_pending || self->priv->disconnect_pending)
         return;
 
-    mm_dbg ("Received spontaneous ^NDISSTAT (%s)",
-            mm_bearer_connection_status_get_string (status));
+    mm_obj_dbg (self, "received spontaneous ^NDISSTAT (%s)", mm_bearer_connection_status_get_string (status));
 
     /* Ignore 'CONNECTED' */
     if (status == MM_BEARER_CONNECTION_STATUS_CONNECTED)
@@ -848,8 +845,7 @@
          * bearer_report_connection_status for details. */
         if (mm_base_bearer_get_status (bearer) == MM_BEARER_STATUS_CONNECTED &&
             self->priv->network_disconnect_pending_id == 0) {
-            mm_dbg ("Delay network-initiated disconnection of bearer '%s'",
-                    mm_base_bearer_get_path (MM_BASE_BEARER (self)));
+            mm_obj_dbg (self, "delay network-initiated disconnection of bearer");
             self->priv->network_disconnect_pending_id = (g_timeout_add_seconds (
                                                              4,
                                                              (GSourceFunc) network_disconnect_3gpp_delayed,
diff --git a/plugins/huawei/mm-broadband-modem-huawei.c b/plugins/huawei/mm-broadband-modem-huawei.c
index 20e5fe5..bf009f2 100644
--- a/plugins/huawei/mm-broadband-modem-huawei.c
+++ b/plugins/huawei/mm-broadband-modem-huawei.c
@@ -31,7 +31,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-errors-types.h"
 #include "mm-modem-helpers.h"
 #include "mm-modem-helpers-huawei.h"
@@ -245,7 +245,7 @@
 
     response = mm_base_modem_at_command_finish (self, res, &error);
     if (!response) {
-        mm_dbg ("^SYSINFO failed: %s", error->message);
+        mm_obj_dbg (self, "^SYSINFO failed: %s", error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -262,7 +262,7 @@
                                            &result->sys_submode_valid,
                                            &result->sys_submode,
                                            &error)) {
-        mm_dbg ("^SYSINFO parsing failed: %s", error->message);
+        mm_obj_dbg (self, "^SYSINFO parsing failed: %s", error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         g_free (result);
@@ -300,14 +300,14 @@
         /* First time we try, we fallback to ^SYSINFO */
         if (self->priv->sysinfoex_support == FEATURE_SUPPORT_UNKNOWN) {
             self->priv->sysinfoex_support = FEATURE_NOT_SUPPORTED;
-            mm_dbg ("^SYSINFOEX failed: %s, assuming unsupported", error->message);
+            mm_obj_dbg (self, "^SYSINFOEX failed: %s, assuming unsupported", error->message);
             g_error_free (error);
             run_sysinfo (self, task);
             return;
         }
 
         /* Otherwise, propagate error */
-        mm_dbg ("^SYSINFOEX failed: %s", error->message);
+        mm_obj_dbg (self, "^SYSINFOEX failed: %s", error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -326,7 +326,7 @@
                                              &result->sys_mode,
                                              &result->sys_submode,
                                              &error)) {
-        mm_dbg ("^SYSINFOEX parsing failed: %s", error->message);
+        mm_obj_dbg (self, "^SYSINFOEX parsing failed: %s", error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         g_free (result);
@@ -571,7 +571,6 @@
                                  guint *mask,
                                  GError **error)
 {
-    gchar *str;
     MMModemAccessTechnology act = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
     gboolean extended = FALSE;
     guint srv_status = 0;
@@ -605,10 +604,6 @@
                    huawei_sysinfo_mode_to_act (sys_mode));
     }
 
-    str = mm_modem_access_technology_build_string_from_mask (act);
-    mm_dbg ("Access Technology: '%s'", str);
-    g_free (str);
-
     *access_technologies = act;
     *mask = MM_MODEM_ACCESS_TECHNOLOGY_ANY;
     return TRUE;
@@ -619,7 +614,6 @@
                           GAsyncReadyCallback callback,
                           gpointer user_data)
 {
-    mm_dbg ("loading access technology (huawei)...");
     sysinfo (MM_BROADBAND_MODEM_HUAWEI (self), callback, user_data);
 }
 
@@ -698,7 +692,6 @@
                      GAsyncReadyCallback callback,
                      gpointer user_data)
 {
-    mm_dbg ("loading unlock retries (huawei)...");
     mm_base_modem_at_command (MM_BASE_MODEM (self),
                               "^CPIN?",
                               3,
@@ -872,7 +865,6 @@
                     GAsyncReadyCallback callback,
                     gpointer user_data)
 {
-    mm_dbg ("loading current bands (huawei)...");
     mm_base_modem_at_command (MM_BASE_MODEM (self),
                               "^SYSCFG?",
                               3,
@@ -973,9 +965,9 @@
          * string to get parsed. Ugly, ugly, blame Huawei.
          */
         if (response[0])
-            self->priv->syscfg_supported_modes = mm_huawei_parse_syscfg_test (response, &error);
+            self->priv->syscfg_supported_modes = mm_huawei_parse_syscfg_test (response, self, &error);
         else {
-            self->priv->syscfg_supported_modes = mm_huawei_parse_syscfg_test (MM_HUAWEI_DEFAULT_SYSCFG_FMT, NULL);
+            self->priv->syscfg_supported_modes = mm_huawei_parse_syscfg_test (MM_HUAWEI_DEFAULT_SYSCFG_FMT, self, NULL);
             g_assert (self->priv->syscfg_supported_modes != NULL);
         }
     }
@@ -1006,7 +998,7 @@
                                combinations,
                                (GDestroyNotify)g_array_unref);
     } else {
-        mm_dbg ("Error while checking ^SYSCFG format: %s", error->message);
+        mm_obj_dbg (self, "error while checking ^SYSCFG format: %s", error->message);
         /* If SIM-PIN error, don't mark as feature unsupported; we'll retry later */
         if (!g_error_matches (error,
                               MM_MOBILE_EQUIPMENT_ERROR,
@@ -1062,7 +1054,7 @@
 
     /* If SIM-PIN error, don't mark as feature unsupported; we'll retry later */
     if (error) {
-        mm_dbg ("Error while checking ^SYSCFGEX format: %s", error->message);
+        mm_obj_dbg (self, "error while checking ^SYSCFGEX format: %s", error->message);
         if (g_error_matches (error,
                              MM_MOBILE_EQUIPMENT_ERROR,
                              MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN)) {
@@ -1094,7 +1086,7 @@
 
     response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
     if (response)
-        self->priv->prefmode_supported_modes = mm_huawei_parse_prefmode_test (response, &error);
+        self->priv->prefmode_supported_modes = mm_huawei_parse_prefmode_test (response, self, &error);
 
     if (self->priv->prefmode_supported_modes) {
         MMModemModeCombination mode;
@@ -1122,7 +1114,7 @@
                                combinations,
                                (GDestroyNotify)g_array_unref);
     } else {
-        mm_dbg ("Error while checking ^PREFMODE format: %s", error->message);
+        mm_obj_dbg (self, "error while checking ^PREFMODE format: %s", error->message);
         /* If SIM-PIN error, don't mark as feature unsupported; we'll retry later */
         if (!g_error_matches (error,
                               MM_MOBILE_EQUIPMENT_ERROR,
@@ -1281,8 +1273,6 @@
     MMBroadbandModemHuawei *self = MM_BROADBAND_MODEM_HUAWEI (_self);
     GTask *task;
 
-    mm_dbg ("loading current modes (huawei)...");
-
     task = g_task_new (self, NULL, callback, user_data);
 
     if (self->priv->syscfgex_support == FEATURE_SUPPORTED) {
@@ -1498,8 +1488,6 @@
     GTask *task;
     GError *error = NULL;
 
-    mm_dbg ("setting current modes (huawei)...");
-
     task = g_task_new (self, NULL, callback, user_data);
 
     if (self->priv->syscfgex_support == FEATURE_SUPPORTED)
@@ -1540,7 +1528,6 @@
         quality = MM_CLAMP_HIGH (quality, 31) * 100 / 31;
     }
 
-    mm_dbg ("3GPP signal quality: %u", quality);
     mm_iface_modem_update_signal_quality (MM_IFACE_MODEM (self), quality);
 }
 
@@ -1571,7 +1558,7 @@
             (act < MM_MODEM_ACCESS_TECHNOLOGY_GSM ||
              act > MM_MODEM_ACCESS_TECHNOLOGY_EDGE)) {
             str = mm_modem_access_technology_build_string_from_mask (act);
-            mm_warn ("Unexpected access technology (%s) in GSM/GPRS mode", str);
+            mm_obj_warn (self, "unexpected access technology (%s) in GSM/GPRS mode", str);
             g_free (str);
             act = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
         }
@@ -1584,7 +1571,7 @@
             (act < MM_MODEM_ACCESS_TECHNOLOGY_UMTS ||
              act > MM_MODEM_ACCESS_TECHNOLOGY_HSPA_PLUS)) {
             str = mm_modem_access_technology_build_string_from_mask (act);
-            mm_warn ("Unexpected access technology (%s) in WCDMA mode", str);
+            mm_obj_warn (self, "unexpected access technology (%s) in WCDMA mode", str);
             g_free (str);
             act = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
         }
@@ -1596,7 +1583,7 @@
         if (act != MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN &&
             act != MM_MODEM_ACCESS_TECHNOLOGY_1XRTT) {
             str = mm_modem_access_technology_build_string_from_mask (act);
-            mm_warn ("Unexpected access technology (%s) in CDMA mode", str);
+            mm_obj_warn (self, "unexpected access technology (%s) in CDMA mode", str);
             g_free (str);
             act = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
         }
@@ -1611,7 +1598,7 @@
             (act < MM_MODEM_ACCESS_TECHNOLOGY_EVDO0 ||
              act > MM_MODEM_ACCESS_TECHNOLOGY_EVDOB)) {
             str = mm_modem_access_technology_build_string_from_mask (act);
-            mm_warn ("Unexpected access technology (%s) in EVDO mode", str);
+            mm_obj_warn (self, "unexpected access technology (%s) in EVDO mode", str);
             g_free (str);
             act = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
         }
@@ -1625,14 +1612,10 @@
         break;
 
     default:
-        mm_warn ("Unexpected mode change value reported: '%d'", a);
+        mm_obj_warn (self, "unexpected mode change value reported: '%d'", a);
         return;
     }
 
-    str = mm_modem_access_technology_build_string_from_mask (act);
-    mm_dbg ("Access Technology: '%s'", str);
-    g_free (str);
-
     mm_iface_modem_update_access_technologies (MM_IFACE_MODEM (self), act, mask);
 }
 
@@ -1645,10 +1628,9 @@
     gint n1, n2, n3, n4, n5, n6, n7;
 
     str = g_match_info_fetch (match_info, 1);
-    if (sscanf (str, "%x,%x,%x,%x,%x,%x,%x", &n1, &n2, &n3, &n4, &n5, &n6, &n7)) {
-        mm_dbg ("Duration: %d Up: %d Kbps Down: %d Kbps Total: %d Total: %d\n",
-                n1, n2 * 8 / 1000, n3  * 8 / 1000, n4 / 1024, n5 / 1024);
-    }
+    if (sscanf (str, "%x,%x,%x,%x,%x,%x,%x", &n1, &n2, &n3, &n4, &n5, &n6, &n7))
+        mm_obj_dbg (self, "duration: %d up: %d Kbps down: %d Kbps total: %d total: %d\n",
+                    n1, n2 * 8 / 1000, n3  * 8 / 1000, n4 / 1024, n5 / 1024);
     g_free (str);
 }
 
@@ -1693,19 +1675,19 @@
                                                &ndisstat_result.ipv6_available,
                                                &ndisstat_result.ipv6_connected,
                                                &error)) {
-        mm_dbg ("Ignore invalid ^NDISSTAT unsolicited message: '%s' (error %s)",
-                str, error->message);
+        mm_obj_dbg (self, "ignored invalid ^NDISSTAT unsolicited message '%s': %s",
+                    str, error->message);
         g_error_free (error);
         g_free (str);
         return;
     }
     g_free (str);
 
-    mm_dbg ("NDIS status: IPv4 %s, IPv6 %s",
-            ndisstat_result.ipv4_available ?
-            (ndisstat_result.ipv4_connected ? "connected" : "disconnected") : "not available",
-            ndisstat_result.ipv6_available ?
-            (ndisstat_result.ipv6_connected ? "connected" : "disconnected") : "not available");
+    mm_obj_dbg (self, "NDIS status: IPv4 %s, IPv6 %s",
+                ndisstat_result.ipv4_available ?
+                (ndisstat_result.ipv4_connected ? "connected" : "disconnected") : "not available",
+                ndisstat_result.ipv6_available ?
+                (ndisstat_result.ipv6_connected ? "connected" : "disconnected") : "not available");
 
     /* If empty bearer list, nothing else to do */
     g_object_get (self,
@@ -1805,7 +1787,7 @@
                                         &value4,
                                         &value5,
                                         &error)) {
-        mm_dbg ("Ignored invalid ^HCSQ message: %s (error %s)", str, error->message);
+        mm_obj_dbg (self, "ignored invalid ^HCSQ message '%s': %s", str, error->message);
         g_error_free (error);
         g_free (str);
         return;
@@ -2180,7 +2162,7 @@
 
     switch (self->priv->ndisdup_support) {
     case FEATURE_NOT_SUPPORTED:
-        mm_dbg ("^NDISDUP not supported, creating default bearer...");
+        mm_obj_dbg (self, "^NDISDUP not supported, creating default bearer...");
         mm_broadband_bearer_new (MM_BROADBAND_MODEM (self),
                                  properties,
                                  NULL, /* cancellable */
@@ -2188,7 +2170,7 @@
                                  task);
         return;
     case FEATURE_SUPPORTED:
-        mm_dbg ("^NDISDUP supported, creating huawei bearer...");
+        mm_obj_dbg (self, "^NDISDUP supported, creating huawei bearer...");
         mm_broadband_bearer_huawei_new (MM_BROADBAND_MODEM_HUAWEI (self),
                                         properties,
                                         NULL, /* cancellable */
@@ -2212,7 +2194,7 @@
     g_warn_if_fail (mm_port_get_subsys (port) == MM_PORT_SUBSYS_NET);
     net_port_parent_path = mm_kernel_device_get_interface_sysfs_path (mm_port_peek_kernel_device (port));
     if (!net_port_parent_path) {
-        mm_warn ("(%s) no parent path for net port", mm_port_get_device (port));
+        mm_obj_warn (self, "no parent path for net port %s", mm_port_get_device (port));
         return NULL;
     }
 
@@ -2245,8 +2227,7 @@
 
     found = peek_port_at_for_data (self, port);
     if (!found)
-        mm_warn ("Couldn't find associated cdc-wdm port for 'net/%s'",
-                 mm_port_get_device (port));
+        mm_obj_warn (self, "couldn't find associated cdc-wdm port for %s", mm_port_get_device (port));
     return found;
 }
 
@@ -2261,22 +2242,21 @@
     /* First, check for devices which support NDISDUP on any AT port. These
      * devices are tagged by udev */
     if (mm_kernel_device_get_global_property_as_boolean (mm_port_peek_kernel_device (port), "ID_MM_HUAWEI_NDISDUP_SUPPORTED")) {
-        mm_dbg ("This device (%s) can support ndisdup feature", mm_port_get_device (port));
+        mm_obj_dbg (self, "^NDISDUP is supported");
         self->priv->ndisdup_support = FEATURE_SUPPORTED;
     }
     /* Then, look for devices which have both a net port and a cdc-wdm
      * AT-capable port. We assume that these devices allow NDISDUP only
      * when issued in the cdc-wdm port. */
     else if (peek_port_at_for_data (self, port)) {
-        mm_dbg ("This device (%s) can support ndisdup feature on non-serial AT port",
-                mm_port_get_device (port));
+        mm_obj_dbg (self, "^NDISDUP is supported on non-serial AT port");
         self->priv->ndisdup_support = FEATURE_SUPPORTED;
     }
 
     if (self->priv->ndisdup_support != FEATURE_SUPPORT_UNKNOWN)
         return;
 
-    mm_dbg ("This device (%s) can not support ndisdup feature", mm_port_get_device (port));
+    mm_obj_dbg (self, "^NDISDUP is not supported");
     self->priv->ndisdup_support = FEATURE_NOT_SUPPORTED;
 }
 
@@ -2299,7 +2279,7 @@
         return;
     }
 
-    mm_dbg ("Creating default bearer...");
+    mm_obj_dbg (self, "creating default bearer...");
     mm_broadband_bearer_new (MM_BROADBAND_MODEM (self),
                              properties,
                              NULL, /* cancellable */
@@ -2380,7 +2360,7 @@
         return;
 
     quality = MM_CLAMP_HIGH (quality, 100);
-    mm_dbg ("1X signal quality: %u", quality);
+    mm_obj_dbg (self, "1X signal quality: %u", quality);
     mm_iface_modem_update_signal_quality (MM_IFACE_MODEM (self), quality);
 }
 
@@ -2395,7 +2375,7 @@
         return;
 
     quality = MM_CLAMP_HIGH (quality, 100);
-    mm_dbg ("EVDO signal quality: %u", quality);
+    mm_obj_dbg (self, "EVDO signal quality: %u", quality);
     mm_iface_modem_update_signal_quality (MM_IFACE_MODEM (self), quality);
 }
 
@@ -2487,7 +2467,6 @@
     MMModemCdmaRegistrationState evdo_state = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN;
     const char *command = "^CSQLVL";
 
-    mm_dbg ("loading signal quality...");
     task = g_task_new (self, NULL, callback, user_data);
 
     /* 3GPP modems can just run parent's signal quality loading */
@@ -2838,7 +2817,7 @@
 
         if (!cdma1x && !evdo) {
             /* Say we're registered to something even though sysmode parsing failed */
-            mm_dbg ("Assuming registered at least in CDMA1x");
+            mm_obj_dbg (self, "assuming registered at least in CDMA1x");
             ctx->state.detailed_cdma1x_state = MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED;
         }
     }
@@ -2911,7 +2890,7 @@
                                           &self->priv->audio_bits,
                                           &error)) {
         self->priv->cvoice_support = FEATURE_NOT_SUPPORTED;
-        mm_dbg ("Huawei-specific CVOICE is unsupported: %s", error->message);
+        mm_obj_dbg (self, "CVOICE is unsupported: %s", error->message);
         g_clear_error (&error);
 
         /* Now check generic support */
@@ -2921,7 +2900,7 @@
         return;
     }
 
-    mm_dbg ("Huawei-specific CVOICE is supported");
+    mm_obj_dbg (self, "CVOICE is supported");
     self->priv->cvoice_support = FEATURE_SUPPORTED;
     g_task_return_boolean (task, TRUE);
     g_object_unref (task);
@@ -3097,23 +3076,23 @@
     guint      aux       = 0;
 
     if (!mm_get_uint_from_match_info (match_info, 2, &aux)) {
-        mm_warn ("couldn't parse call type from ^ORIG");
+        mm_obj_warn (self, "couldn't parse call type from ^ORIG");
         return;
     }
     if (aux != HUAWEI_CALL_TYPE_VOICE && aux != HUAWEI_CALL_TYPE_EMERGENCY) {
-        mm_dbg ("ignored ^ORIG for non-voice call");
+        mm_obj_dbg (self, "ignored ^ORIG for non-voice call");
         return;
     }
 
     if (!mm_get_uint_from_match_info (match_info, 1, &aux)) {
-        mm_warn ("couldn't parse call index from ^ORIG");
+        mm_obj_warn (self, "couldn't parse call index from ^ORIG");
         return;
     }
     call_info.index     = aux;
     call_info.state     = MM_CALL_STATE_DIALING;
     call_info.direction = MM_CALL_DIRECTION_OUTGOING;
 
-    mm_dbg ("call %u state updated: dialing", call_info.index);
+    mm_obj_dbg (self, "call %u state updated: dialing", call_info.index);
 
     mm_iface_modem_voice_report_call (MM_IFACE_MODEM_VOICE (self), &call_info);
 }
@@ -3127,14 +3106,14 @@
     guint      aux       = 0;
 
     if (!mm_get_uint_from_match_info (match_info, 1, &aux)) {
-        mm_warn ("couldn't parse call index from ^CONF");
+        mm_obj_warn (self, "couldn't parse call index from ^CONF");
         return;
     }
     call_info.index     = aux;
     call_info.state     = MM_CALL_STATE_RINGING_OUT;
     call_info.direction = MM_CALL_DIRECTION_OUTGOING;
 
-    mm_dbg ("call %u state updated: ringing-out", call_info.index);
+    mm_obj_dbg (self, "call %u state updated: ringing-out", call_info.index);
 
     mm_iface_modem_voice_report_call (MM_IFACE_MODEM_VOICE (self), &call_info);
 }
@@ -3148,14 +3127,14 @@
     guint      aux       = 0;
 
     if (!mm_get_uint_from_match_info (match_info, 1, &aux)) {
-        mm_warn ("couldn't parse call index from ^CONN");
+        mm_obj_warn (self, "couldn't parse call index from ^CONN");
         return;
     }
     call_info.index     = aux;
     call_info.state     = MM_CALL_STATE_ACTIVE;
     call_info.direction = MM_CALL_DIRECTION_UNKNOWN;
 
-    mm_dbg ("call %u state updated: active", aux);
+    mm_obj_dbg (self, "call %u state updated: active", aux);
 
     mm_iface_modem_voice_report_call (MM_IFACE_MODEM_VOICE (self), &call_info);
 }
@@ -3170,20 +3149,20 @@
 
     /* only index is mandatory */
     if (!mm_get_uint_from_match_info (match_info, 1, &aux)) {
-        mm_warn ("couldn't parse call index from ^CEND");
+        mm_obj_warn (self, "couldn't parse call index from ^CEND");
         return;
     }
     call_info.index = aux;
     call_info.state = MM_CALL_STATE_TERMINATED;
     call_info.direction = MM_CALL_DIRECTION_UNKNOWN;
 
-    mm_dbg ("call %u state updated: terminated", call_info.index);
+    mm_obj_dbg (self, "call %u state updated: terminated", call_info.index);
     if (mm_get_uint_from_match_info (match_info, 2, &aux))
-        mm_dbg ("  call duration: %u seconds", aux);
+        mm_obj_dbg (self, "  call duration: %u seconds", aux);
     if (mm_get_uint_from_match_info (match_info, 3, &aux))
-        mm_dbg ("  end status code: %u", aux);
+        mm_obj_dbg (self, "  end status code: %u", aux);
     if (mm_get_uint_from_match_info (match_info, 4, &aux))
-        mm_dbg ("  call control cause: %u", aux);
+        mm_obj_dbg (self, "  call control cause: %u", aux);
 
     mm_iface_modem_voice_report_call (MM_IFACE_MODEM_VOICE (self), &call_info);
 }
@@ -3196,7 +3175,7 @@
     gchar *dtmf;
 
     dtmf = g_match_info_fetch (match_info, 1);
-    mm_dbg ("received DTMF: %s", dtmf);
+    mm_obj_dbg (self, "received DTMF: %s", dtmf);
     /* call index unknown */
     mm_iface_modem_voice_received_dtmf (MM_IFACE_MODEM_VOICE (self), 0, dtmf);
     g_free (dtmf);
@@ -3582,8 +3561,8 @@
 
     ports = mm_broadband_modem_huawei_get_at_port_list (self);
 
-    mm_dbg ("%s ^RFSWITCH unsolicited event handler",
-            enable ? "Enable" : "Disable");
+    mm_obj_dbg (self, "%s ^RFSWITCH unsolicited event handler",
+                enable ? "enable" : "disable");
 
     for (l = ports; l; l = g_list_next (l)) {
         MMPortSerialAt *port = MM_PORT_SERIAL_AT (l->data);
@@ -3639,17 +3618,17 @@
         response = mm_strip_tag (response, "^RFSWITCH:");
         if (sscanf (response, "%d", &sw_state) != 1 ||
             (sw_state != 0 && sw_state != 1)) {
-            mm_warn ("Couldn't parse ^RFSWITCH response: '%s'", response);
+            mm_obj_warn (self, "couldn't parse ^RFSWITCH response '%s'", response);
             error = g_error_new (MM_CORE_ERROR,
                                  MM_CORE_ERROR_FAILED,
-                                 "Couldn't parse ^RFSWITCH response: '%s'",
+                                 "Couldn't parse ^RFSWITCH response '%s'",
                                  response);
         }
     }
 
     if (self->priv->rfswitch_support == FEATURE_SUPPORT_UNKNOWN) {
         if (error) {
-            mm_dbg ("The device does not support ^RFSWITCH");
+            mm_obj_dbg (self, "^RFSWITCH is not supported");
             self->priv->rfswitch_support = FEATURE_NOT_SUPPORTED;
             g_error_free (error);
             /* Fall back to parent's load_power_state */
@@ -3659,7 +3638,7 @@
             return;
         }
 
-        mm_dbg ("The device supports ^RFSWITCH");
+        mm_obj_dbg (self, "^RFSWITCH is supported");
         self->priv->rfswitch_support = FEATURE_SUPPORTED;
     }
 
@@ -4304,7 +4283,7 @@
      * be updated.
      */
     if (!mm_base_modem_at_command_finish (_self, res, &error)) {
-        mm_dbg ("^HCSQ failed: %s", error->message);
+        mm_obj_dbg (self, "^HCSQ failed: %s", error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -4330,8 +4309,6 @@
     MMBroadbandModemHuawei *self = MM_BROADBAND_MODEM_HUAWEI (_self);
     GTask *task;
 
-    mm_dbg ("loading extended signal information...");
-
     task = g_task_new (self, cancellable, callback, user_data);
 
     /* Clear any previous detailed signal values to get new ones */
diff --git a/plugins/huawei/mm-modem-helpers-huawei.c b/plugins/huawei/mm-modem-helpers-huawei.c
index c7fc124..a1422be 100644
--- a/plugins/huawei/mm-modem-helpers-huawei.c
+++ b/plugins/huawei/mm-modem-helpers-huawei.c
@@ -22,7 +22,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-modem-helpers.h"
 #include "mm-modem-helpers-huawei.h"
 
@@ -429,8 +429,9 @@
 }
 
 GArray *
-mm_huawei_parse_prefmode_test (const gchar *response,
-                               GError **error)
+mm_huawei_parse_prefmode_test (const gchar  *response,
+                               gpointer      log_object,
+                               GError      **error)
 {
     gchar **split;
     guint i;
@@ -461,12 +462,12 @@
             continue;
 
         if (!mm_get_uint_from_str (split[i], &val)) {
-            mm_dbg ("Error parsing ^PREFMODE value: %s", split[i]);
+            mm_obj_dbg (log_object, "error parsing ^PREFMODE value '%s'", split[i]);
             continue;
         }
 
         if (!mode_from_prefmode (val, &preferred, &inner_error)) {
-            mm_dbg ("Unhandled ^PREFMODE: %s", inner_error->message);
+            mm_obj_dbg (log_object, "unhandled ^PREFMODE value: %s", inner_error->message);
             g_error_free (inner_error);
             continue;
         }
@@ -708,9 +709,10 @@
 }
 
 static GArray *
-parse_syscfg_modes (const gchar *modes_str,
-                    const gchar *acqorder_str,
-                    GError **error)
+parse_syscfg_modes (const gchar  *modes_str,
+                    const gchar  *acqorder_str,
+                    gpointer      log_object,
+                    GError      **error)
 {
     GArray *out;
     gchar **split;
@@ -720,7 +722,7 @@
 
     /* Start parsing acquisition order */
     if (!sscanf (acqorder_str, "%d-%d", &min_acqorder, &max_acqorder))
-        mm_dbg ("Error parsing ^SYSCFG acquisition order range (%s)", acqorder_str);
+        mm_obj_dbg (log_object, "error parsing ^SYSCFG acquisition order range '%s'", acqorder_str);
 
     /* Just in case, we default to supporting only auto */
     if (max_acqorder < min_acqorder) {
@@ -741,13 +743,13 @@
         MMHuaweiSyscfgCombination combination;
 
         if (!mm_get_uint_from_str (mm_strip_quotes (split[i]), &val)) {
-            mm_dbg ("Error parsing ^SYSCFG mode value: %s", split[i]);
+            mm_obj_dbg (log_object, "error parsing ^SYSCFG mode value: %s", split[i]);
             continue;
         }
 
         if (!mode_from_syscfg (val, &allowed, &inner_error)) {
             if (inner_error) {
-                mm_dbg ("Unhandled ^SYSCFG: %s", inner_error->message);
+                mm_obj_dbg (log_object, "unhandled ^SYSCFG: %s", inner_error->message);
                 g_error_free (inner_error);
             }
             continue;
@@ -808,8 +810,9 @@
 }
 
 GArray *
-mm_huawei_parse_syscfg_test (const gchar *response,
-                             GError **error)
+mm_huawei_parse_syscfg_test (const gchar  *response,
+                             gpointer      log_object,
+                             GError      **error)
 {
     gchar **split;
     GError *inner_error = NULL;
@@ -846,7 +849,7 @@
     }
 
     /* Parse supported mode combinations */
-    out = parse_syscfg_modes (split[0], split[1], &inner_error);
+    out = parse_syscfg_modes (split[0], split[1], log_object, &inner_error);
 
     g_strfreev (split);
 
@@ -1350,7 +1353,7 @@
     gboolean ret = FALSE;
     char *s;
 
-    r = g_regex_new ("\\^HCSQ:\\s*\"([a-zA-Z]*)\",(\\d+),?(\\d+)?,?(\\d+)?,?(\\d+)?,?(\\d+)?$", 0, 0, NULL);
+    r = g_regex_new ("\\^HCSQ:\\s*\"?([a-zA-Z]*)\"?,(\\d+),?(\\d+)?,?(\\d+)?,?(\\d+)?,?(\\d+)?$", 0, 0, NULL);
     g_assert (r != NULL);
 
     if (!g_regex_match_full (r, response, -1, 0, 0, &match_info, &match_error)) {
diff --git a/plugins/huawei/mm-modem-helpers-huawei.h b/plugins/huawei/mm-modem-helpers-huawei.h
index 502f694..2d740b3 100644
--- a/plugins/huawei/mm-modem-helpers-huawei.h
+++ b/plugins/huawei/mm-modem-helpers-huawei.h
@@ -70,8 +70,9 @@
     MMModemMode preferred;
 } MMHuaweiPrefmodeCombination;
 
-GArray *mm_huawei_parse_prefmode_test (const gchar *response,
-                                       GError **error);
+GArray *mm_huawei_parse_prefmode_test (const gchar  *response,
+                                       gpointer      log_object,
+                                       GError      **error);
 
 /*****************************************************************************/
 /* ^PREFMODE response parser */
@@ -94,8 +95,9 @@
     MMModemMode preferred;
 } MMHuaweiSyscfgCombination;
 
-GArray *mm_huawei_parse_syscfg_test (const gchar *response,
-                                     GError **error);
+GArray *mm_huawei_parse_syscfg_test (const gchar  *response,
+                                     gpointer      log_object,
+                                     GError      **error);
 
 /*****************************************************************************/
 /* ^SYSCFG response parser */
diff --git a/plugins/huawei/mm-plugin-huawei.c b/plugins/huawei/mm-plugin-huawei.c
index 58de1ee..b9118ec 100644
--- a/plugins/huawei/mm-plugin-huawei.c
+++ b/plugins/huawei/mm-plugin-huawei.c
@@ -52,9 +52,10 @@
 #define MAX_WAIT_TIME 5
 
 typedef struct {
-    guint first_usbif;
-    guint timeout_id;
-    gboolean custom_init_run;
+    MMPortProbe *probe;
+    guint        first_usbif;
+    guint        timeout_id;
+    gboolean     custom_init_run;
 } FirstInterfaceContext;
 
 static void
@@ -62,6 +63,7 @@
 {
     if (ctx->timeout_id)
         g_source_remove (ctx->timeout_id);
+    g_object_unref (ctx->probe);
     g_slice_free (FirstInterfaceContext, ctx);
 }
 
@@ -73,19 +75,17 @@
 #define TAG_AT_PORT_FLAGS          "at-port-flags"
 
 typedef struct {
-    MMPortProbe *probe;
     MMPortSerialAt *port;
-    gboolean curc_done;
-    guint curc_retries;
-    gboolean getportmode_done;
-    guint getportmode_retries;
+    gboolean        curc_done;
+    guint           curc_retries;
+    gboolean        getportmode_done;
+    guint           getportmode_retries;
 } HuaweiCustomInitContext;
 
 static void
 huawei_custom_init_context_free (HuaweiCustomInitContext *ctx)
 {
     g_object_unref (ctx->port);
-    g_object_unref (ctx->probe);
     g_slice_free (HuaweiCustomInitContext, ctx);
 }
 
@@ -99,7 +99,7 @@
 
 static void huawei_custom_init_step (GTask *task);
 
-static void
+static gboolean
 cache_port_mode (MMDevice *device,
                  const gchar *reply,
                  const gchar *type,
@@ -114,26 +114,30 @@
         errno = 0;
         /* shift by 1 so NULL return from g_object_get_data() means no tag */
         i = 1 + strtol (p + strlen (type), NULL, 10);
-        if (i > 0 && i < 256 && errno == 0)
-            g_object_set_data (G_OBJECT (device), tag, GUINT_TO_POINTER ((guint) i));
+        if (i > 0 && i < 256 && errno == 0) {
+            g_object_set_data (G_OBJECT (device), tag, GINT_TO_POINTER ((gint) i));
+            return TRUE;
+        }
     }
+    return FALSE;
 }
 
 static void
 getportmode_ready (MMPortSerialAt *port,
-                   GAsyncResult *res,
-                   GTask *task)
+                   GAsyncResult   *res,
+                   GTask          *task)
 {
+    MMPortProbe             *probe;
     HuaweiCustomInitContext *ctx;
-    const gchar *response;
-    GError *error = NULL;
+    const gchar             *response;
+    GError                  *error = NULL;
 
-    ctx = g_task_get_task_data (task);
+    probe = g_task_get_source_object (task);
+    ctx   = g_task_get_task_data (task);
 
     response = mm_port_serial_at_command_finish (port, res, &error);
     if (error) {
-        mm_dbg ("(Huawei) couldn't get port mode: '%s'",
-                error->message);
+        mm_obj_dbg (probe, "couldn't get port mode: '%s'", error->message);
 
         /* If any error occurred that was not ERROR or COMMAND NOT SUPPORT then
          * retry the command.
@@ -146,23 +150,25 @@
         /* Port mode not supported */
     } else {
         MMDevice *device;
+        guint     n_cached_port_modes = 0;
 
-        mm_dbg ("(Huawei) port mode layout retrieved");
+        mm_obj_dbg (probe, "port mode layout retrieved");
 
         /* Results are cached in the parent device object */
-        device = mm_port_probe_peek_device (ctx->probe);
-        cache_port_mode (device, response, "PCUI:", TAG_HUAWEI_PCUI_PORT);
-        cache_port_mode (device, response, "MDM:",  TAG_HUAWEI_MODEM_PORT);
-        cache_port_mode (device, response, "NDIS:", TAG_HUAWEI_NDIS_PORT);
-        cache_port_mode (device, response, "DIAG:", TAG_HUAWEI_DIAG_PORT);
+        device = mm_port_probe_peek_device (probe);
+        n_cached_port_modes += cache_port_mode (device, response, "PCUI:", TAG_HUAWEI_PCUI_PORT);
+        n_cached_port_modes += cache_port_mode (device, response, "MDM:",  TAG_HUAWEI_MODEM_PORT);
+        n_cached_port_modes += cache_port_mode (device, response, "NDIS:", TAG_HUAWEI_NDIS_PORT);
+        n_cached_port_modes += cache_port_mode (device, response, "DIAG:", TAG_HUAWEI_DIAG_PORT);
         /* GETPORTMODE response format in newer devices... (e.g. E3372) */
-        cache_port_mode (device, response, "pcui:",  TAG_HUAWEI_PCUI_PORT);
-        cache_port_mode (device, response, "modem:", TAG_HUAWEI_MODEM_PORT);
+        n_cached_port_modes += cache_port_mode (device, response, "pcui:",  TAG_HUAWEI_PCUI_PORT);
+        n_cached_port_modes += cache_port_mode (device, response, "modem:", TAG_HUAWEI_MODEM_PORT);
 
-        g_object_set_data (G_OBJECT (device), TAG_GETPORTMODE_SUPPORTED, GUINT_TO_POINTER (TRUE));
+        if (n_cached_port_modes > 0)
+            g_object_set_data (G_OBJECT (device), TAG_GETPORTMODE_SUPPORTED, GUINT_TO_POINTER (TRUE));
 
         /* Mark port as being AT already */
-        mm_port_probe_set_result_at (ctx->probe, TRUE);
+        mm_port_probe_set_result_at (probe, TRUE);
     }
 
     ctx->getportmode_done = TRUE;
@@ -176,13 +182,15 @@
 
 static void
 curc_ready (MMPortSerialAt *port,
-            GAsyncResult *res,
-            GTask *task)
+            GAsyncResult   *res,
+            GTask          *task)
 {
+    MMPortProbe             *probe;
     HuaweiCustomInitContext *ctx;
-    GError *error = NULL;
+    g_autoptr(GError)        error = NULL;
 
-    ctx = g_task_get_task_data (task);
+    probe = g_task_get_source_object (task);
+    ctx   = g_task_get_task_data (task);
 
     mm_port_serial_at_command_finish (port, res, &error);
     if (error) {
@@ -192,23 +200,20 @@
                              MM_SERIAL_ERROR_RESPONSE_TIMEOUT))
             goto out;
 
-        mm_dbg ("(Huawei) couldn't turn off unsolicited messages in secondary ports: '%s'",
-                error->message);
+        mm_obj_dbg (probe, "couldn't turn off unsolicited messages in secondary ports: %s", error->message);
     }
 
-    mm_dbg ("(Huawei) unsolicited messages in secondary ports turned off");
+    mm_obj_dbg (probe, "unsolicited messages in secondary ports turned off");
 
     ctx->curc_done = TRUE;
 
 out:
-    if (error)
-        g_error_free (error);
-
     huawei_custom_init_step (task);
 }
 
 static void
-try_next_usbif (MMDevice *device)
+try_next_usbif (MMPortProbe *probe,
+                MMDevice    *device)
 {
     FirstInterfaceContext *fi_ctx;
     GList *l;
@@ -221,13 +226,13 @@
      * and enable that one as being first */
     closest = G_MAXUINT;
     for (l = mm_device_peek_port_probe_list (device); l; l = g_list_next (l)) {
-        MMPortProbe *probe = MM_PORT_PROBE (l->data);
+        MMPortProbe *iter = MM_PORT_PROBE (l->data);
 
         /* Only expect ttys for next probing attempt */
-        if (g_str_equal (mm_port_probe_get_port_subsys (probe), "tty")) {
+        if (g_str_equal (mm_port_probe_get_port_subsys (iter), "tty")) {
             guint usbif;
 
-            usbif = mm_kernel_device_get_property_as_int_hex (mm_port_probe_peek_port (probe), "ID_USB_INTERFACE_NUM");
+            usbif = mm_kernel_device_get_property_as_int_hex (mm_port_probe_peek_port (iter), "ID_USB_INTERFACE_NUM");
             if (usbif == fi_ctx->first_usbif) {
                 /* This is the one we just probed, which wasn't yet removed, so just skip it */
             } else if (usbif > fi_ctx->first_usbif &&
@@ -240,10 +245,9 @@
     if (closest == G_MAXUINT) {
         /* No more ttys to try! Just return something */
         closest = 0;
-        mm_dbg ("(Huawei) No more ports to run initial probing");
-    } else {
-        mm_dbg ("(Huawei) Will try initial probing with interface '%d' instead", closest);
-    }
+        mm_obj_dbg (probe, "no more ports to run initial probing");
+    } else
+        mm_obj_dbg (probe, "will try initial probing with interface '%d' instead", closest);
 
     fi_ctx->first_usbif = closest;
 }
@@ -251,17 +255,17 @@
 static void
 huawei_custom_init_step (GTask *task)
 {
+    MMPortProbe             *probe;
     HuaweiCustomInitContext *ctx;
-    FirstInterfaceContext *fi_ctx;
-    MMKernelDevice *port;
+    FirstInterfaceContext   *fi_ctx;
+    MMKernelDevice          *port;
 
-    ctx = g_task_get_task_data (task);
+    probe = g_task_get_source_object (task);
+    ctx   = g_task_get_task_data (task);
 
     /* If cancelled, end */
     if (g_task_return_error_if_cancelled (task)) {
-        mm_dbg ("(Huawei) no need to keep on running custom init in (%s)",
-                mm_port_get_device (MM_PORT (ctx->port)));
-        g_task_return_boolean (task, TRUE);
+        mm_obj_dbg (probe, "no need to keep on running custom init");
         g_object_unref (task);
         return;
     }
@@ -269,9 +273,9 @@
     if (!ctx->curc_done) {
         if (ctx->curc_retries == 0) {
             /* All retries consumed, probably not an AT port */
-            mm_port_probe_set_result_at (ctx->probe, FALSE);
+            mm_port_probe_set_result_at (probe, FALSE);
             /* Try with next */
-            try_next_usbif (mm_port_probe_peek_device (ctx->probe));
+            try_next_usbif (probe, mm_port_probe_peek_device (probe));
             g_task_return_boolean (task, TRUE);
             g_object_unref (task);
             return;
@@ -292,7 +296,7 @@
     }
 
     /* Try to get a port map from the modem */
-    port = mm_port_probe_peek_port (ctx->probe);
+    port = mm_port_probe_peek_port (probe);
     if (!ctx->getportmode_done && !mm_kernel_device_get_global_property_as_boolean (port, "ID_MM_HUAWEI_DISABLE_GETPORTMODE")) {
         if (ctx->getportmode_retries == 0) {
             g_task_return_boolean (task, TRUE);
@@ -314,7 +318,7 @@
     }
 
     /* All done it seems */
-    fi_ctx = g_object_get_data (G_OBJECT (mm_port_probe_peek_device (ctx->probe)), TAG_FIRST_INTERFACE_CONTEXT);
+    fi_ctx = g_object_get_data (G_OBJECT (mm_port_probe_peek_device (probe)), TAG_FIRST_INTERFACE_CONTEXT);
     g_assert (fi_ctx != NULL);
     fi_ctx->custom_init_run = TRUE;
 
@@ -325,7 +329,11 @@
 static gboolean
 first_interface_missing_timeout_cb (MMDevice *device)
 {
-    try_next_usbif (device);
+    FirstInterfaceContext *fi_ctx;
+
+    fi_ctx = g_object_get_data (G_OBJECT (device), TAG_FIRST_INTERFACE_CONTEXT);
+    g_assert (fi_ctx != NULL);
+    try_next_usbif (fi_ctx->probe, device);
 
     /* Reload the timeout, just in case we end up not having the next interface to probe...
      * which is anyway very unlikely as we got it by looking at the real probe list, but anyway... */
@@ -359,6 +367,7 @@
     if (!fi_ctx) {
         /* This is the first time we ask for the context. Set it up. */
         fi_ctx = g_slice_new0 (FirstInterfaceContext);
+        fi_ctx->probe = g_object_ref (probe);
         g_object_set_data_full (G_OBJECT (device),
                                 TAG_FIRST_INTERFACE_CONTEXT,
                                 fi_ctx,
@@ -379,7 +388,6 @@
     }
 
     ctx = g_slice_new (HuaweiCustomInitContext);
-    ctx->probe = g_object_ref (probe);
     ctx->port = g_object_ref (port);
     ctx->curc_done = FALSE;
     ctx->curc_retries = 3;
@@ -419,45 +427,71 @@
 /*****************************************************************************/
 
 static void
-propagate_port_mode_results (GList *probes)
+propagate_port_mode_results (MMPlugin *self,
+                             GList    *probes)
 {
     MMDevice *device;
-    GList *l;
-    gboolean primary_flagged = FALSE;
+    GList    *l;
+    gboolean  primary_flagged = FALSE;
 
     g_assert (probes != NULL);
-    device = mm_port_probe_peek_device (MM_PORT_PROBE (probes->data));
 
     /* Now we propagate the tags to the specific port probes */
+    device = mm_port_probe_peek_device (MM_PORT_PROBE (probes->data));
     for (l = probes; l; l = g_list_next (l)) {
-        MMPortSerialAtFlag at_port_flags = MM_PORT_SERIAL_AT_FLAG_NONE;
-        guint usbif;
+        MMPortSerialAtFlag  at_port_flags = MM_PORT_SERIAL_AT_FLAG_NONE;
+        MMPortProbe        *probe;
+        guint               usbif;
+        const gchar        *description;
 
-        usbif = mm_kernel_device_get_property_as_int_hex (mm_port_probe_peek_port (MM_PORT_PROBE (l->data)), "ID_USB_INTERFACE_NUM");
+        probe = MM_PORT_PROBE (l->data);
 
+        /* Tags only applicable to AT ports */
+        if (!mm_port_probe_is_at (probe))
+            goto next;
+
+        /* Port type hints from AT^GETPORTMODE */
+        usbif = mm_kernel_device_get_property_as_int_hex (mm_port_probe_peek_port (probe), "ID_USB_INTERFACE_NUM");
         if (GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (device), TAG_GETPORTMODE_SUPPORTED))) {
             if (usbif + 1 == GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (device), TAG_HUAWEI_PCUI_PORT))) {
                 at_port_flags = MM_PORT_SERIAL_AT_FLAG_PRIMARY;
                 primary_flagged = TRUE;
-            } else if (usbif + 1 == GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (device), TAG_HUAWEI_MODEM_PORT)))
+            } else if (usbif + 1 == GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (device), TAG_HUAWEI_MODEM_PORT))) {
                 at_port_flags = MM_PORT_SERIAL_AT_FLAG_PPP;
-            else if (!g_object_get_data (G_OBJECT (device), TAG_HUAWEI_MODEM_PORT) &&
-                     usbif + 1 == GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (device), TAG_HUAWEI_NDIS_PORT)))
+            } else if (!g_object_get_data (G_OBJECT (device), TAG_HUAWEI_MODEM_PORT) &&
+                     usbif + 1 == GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (device), TAG_HUAWEI_NDIS_PORT))) {
                 /* If NDIS reported only instead of MDM, use it */
                 at_port_flags = MM_PORT_SERIAL_AT_FLAG_PPP;
-        } else if (usbif == 0 &&
-                   mm_port_probe_is_at (MM_PORT_PROBE (l->data))) {
-            /* If GETPORTMODE is not supported, we assume usbif 0 is the modem port */
-            at_port_flags = MM_PORT_SERIAL_AT_FLAG_PPP;
-
-            /* /\* TODO. */
-            /*  * For CDMA modems we assume usbif0 is both primary and PPP, since */
-            /*  * they don't have problems with talking on secondary ports. */
-            /*  *\/ */
-            /* if (caps & CAP_CDMA) */
-            /*     pflags |= MM_PORT_SERIAL_AT_FLAG_PRIMARY; */
+            }
+            goto next;
         }
 
+        /* Port type hints from interface description */
+        description = mm_kernel_device_get_interface_description (mm_port_probe_peek_port (probe));
+        if (description) {
+            gchar *lower_description;
+
+            mm_obj_dbg (probe, "%s interface description: %s", mm_port_probe_get_port_name (probe), description);
+
+            lower_description = g_ascii_strdown (description, -1);
+            if (strstr (lower_description, "modem"))
+                at_port_flags = MM_PORT_SERIAL_AT_FLAG_PPP;
+            else if (strstr (lower_description, "pcui")) {
+                at_port_flags = MM_PORT_SERIAL_AT_FLAG_PRIMARY;
+                primary_flagged = TRUE;
+            }
+            g_free (lower_description);
+            goto next;
+        }
+
+        /* If GETPORTMODE unsupported and no other port type hints, we assume
+         * usbif 0 is the modem port */
+        if (usbif == 0) {
+            at_port_flags = MM_PORT_SERIAL_AT_FLAG_PPP;
+            goto next;
+        }
+
+    next:
         g_object_set_data (G_OBJECT (l->data), TAG_AT_PORT_FLAGS, GUINT_TO_POINTER (at_port_flags));
     }
 
@@ -488,11 +522,11 @@
               GList *probes,
               GError **error)
 {
-    propagate_port_mode_results (probes);
+    propagate_port_mode_results (self, probes);
 
 #if defined WITH_QMI
     if (mm_port_probe_list_has_qmi_port (probes)) {
-        mm_dbg ("QMI-powered Huawei modem found...");
+        mm_obj_dbg (self, "QMI-powered Huawei modem found...");
         return MM_BASE_MODEM (mm_broadband_modem_qmi_new (uid,
                                                           drivers,
                                                           mm_plugin_get_name (self),
@@ -503,7 +537,7 @@
 
 #if defined WITH_MBIM
     if (mm_port_probe_list_has_mbim_port (probes)) {
-        mm_dbg ("MBIM-powered Huawei modem found...");
+        mm_obj_dbg (self, "MBIM-powered Huawei modem found...");
         return MM_BASE_MODEM (mm_broadband_modem_mbim_new (uid,
                                                            drivers,
                                                            mm_plugin_get_name (self),
@@ -537,10 +571,10 @@
         gchar *str;
 
         str = mm_port_serial_at_flag_build_string_from_mask (pflags);
-        mm_dbg ("(%s/%s) huawei port will have AT flags '%s'",
-                mm_port_probe_get_port_subsys (probe),
-                mm_port_probe_get_port_name (probe),
-                str);
+        mm_obj_dbg (self, "(%s/%s) port will have AT flags '%s'",
+                    mm_port_probe_get_port_subsys (probe),
+                    mm_port_probe_get_port_name (probe),
+                    str);
         g_free (str);
     }
 
@@ -565,7 +599,7 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_HUAWEI,
-                      MM_PLUGIN_NAME,               "Huawei",
+                      MM_PLUGIN_NAME,               MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems,
                       MM_PLUGIN_ALLOWED_VENDOR_IDS, vendor_ids,
                       MM_PLUGIN_ALLOWED_AT,         TRUE,
diff --git a/plugins/huawei/mm-sim-huawei.c b/plugins/huawei/mm-sim-huawei.c
index 49c19c1..54b388b 100644
--- a/plugins/huawei/mm-sim-huawei.c
+++ b/plugins/huawei/mm-sim-huawei.c
@@ -25,7 +25,6 @@
 #include <ModemManager.h>
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
-#include "mm-log.h"
 #include "mm-modem-helpers.h"
 #include "mm-base-modem-at.h"
 
@@ -105,7 +104,6 @@
                   MM_BASE_SIM_MODEM, &modem,
                   NULL);
 
-    mm_dbg ("loading (Huawei) SIM identifier...");
     mm_base_modem_at_command (
         modem,
         "^ICCID?",
diff --git a/plugins/huawei/tests/test-modem-helpers-huawei.c b/plugins/huawei/tests/test-modem-helpers-huawei.c
index b37c0b1..45d48b0 100644
--- a/plugins/huawei/tests/test-modem-helpers-huawei.c
+++ b/plugins/huawei/tests/test-modem-helpers-huawei.c
@@ -22,7 +22,8 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-test.h"
+#include "mm-log-object.h"
 #include "mm-modem-helpers.h"
 #include "mm-modem-helpers-huawei.h"
 
@@ -386,27 +387,21 @@
                 n_expected_combinations++;
         }
 
-        combinations = mm_huawei_parse_prefmode_test (prefmode_tests[i].str, &error);
+        combinations = mm_huawei_parse_prefmode_test (prefmode_tests[i].str, NULL, &error);
         g_assert_no_error (error);
         g_assert (combinations != NULL);
         g_assert_cmpuint (combinations->len, ==, n_expected_combinations);
 
         for (j = 0; j < combinations->len; j++) {
             MMHuaweiPrefmodeCombination *single;
-            gchar *allowed_str;
-            gchar *preferred_str;
+            g_autofree gchar *allowed_str = NULL;
+            g_autofree gchar *preferred_str = NULL;
 
             single = &g_array_index (combinations, MMHuaweiPrefmodeCombination, j);
             allowed_str = mm_modem_mode_build_string_from_mask (single->allowed);
             preferred_str = mm_modem_mode_build_string_from_mask (single->preferred);
-            mm_dbg ("Test[%u], Combination[%u]: %u, \"%s\", \"%s\"",
-                    i,
-                    j,
-                    single->prefmode,
-                    allowed_str,
-                    preferred_str);
-            g_free (allowed_str);
-            g_free (preferred_str);
+            mm_obj_dbg (NULL, "test[%u], combination[%u]: %u, \"%s\", \"%s\"",
+                        i, j, single->prefmode, allowed_str, preferred_str);
         }
 
         for (j = 0; j < combinations->len; j++) {
@@ -472,7 +467,7 @@
         const MMHuaweiPrefmodeCombination *found;
         GError *error = NULL;
 
-        combinations = mm_huawei_parse_prefmode_test (prefmode_response_tests[i].format, NULL);
+        combinations = mm_huawei_parse_prefmode_test (prefmode_response_tests[i].format, NULL, NULL);
         g_assert (combinations != NULL);
 
         found = mm_huawei_parse_prefmode_response (prefmode_response_tests[i].str,
@@ -622,28 +617,21 @@
                 n_expected_combinations++;
         }
 
-        combinations = mm_huawei_parse_syscfg_test (syscfg_tests[i].str, &error);
+        combinations = mm_huawei_parse_syscfg_test (syscfg_tests[i].str, NULL, &error);
         g_assert_no_error (error);
         g_assert (combinations != NULL);
         g_assert_cmpuint (combinations->len, ==, n_expected_combinations);
 
         for (j = 0; j < combinations->len; j++) {
             MMHuaweiSyscfgCombination *single;
-            gchar *allowed_str;
-            gchar *preferred_str;
+            g_autofree gchar *allowed_str = NULL;
+            g_autofree gchar *preferred_str = NULL;
 
             single = &g_array_index (combinations, MMHuaweiSyscfgCombination, j);
             allowed_str = mm_modem_mode_build_string_from_mask (single->allowed);
             preferred_str = mm_modem_mode_build_string_from_mask (single->preferred);
-            mm_dbg ("Test[%u], Combination[%u]: %u, %u, \"%s\", \"%s\"",
-                    i,
-                    j,
-                    single->mode,
-                    single->acqorder,
-                    allowed_str,
-                    preferred_str);
-            g_free (allowed_str);
-            g_free (preferred_str);
+            mm_obj_dbg (NULL, "test[%u], combination[%u]: %u, %u, \"%s\", \"%s\"",
+                        i, j, single->mode, single->acqorder, allowed_str, preferred_str);
         }
 
         for (j = 0; j < combinations->len; j++) {
@@ -736,7 +724,7 @@
         const MMHuaweiSyscfgCombination *found;
         GError *error = NULL;
 
-        combinations = mm_huawei_parse_syscfg_test (syscfg_response_tests[i].format, NULL);
+        combinations = mm_huawei_parse_syscfg_test (syscfg_response_tests[i].format, NULL, NULL);
         g_assert (combinations != NULL);
 
         found = mm_huawei_parse_syscfg_response (syscfg_response_tests[i].str,
@@ -896,20 +884,14 @@
 
         for (j = 0; j < combinations->len; j++) {
             MMHuaweiSyscfgexCombination *single;
-            gchar *allowed_str;
-            gchar *preferred_str;
+            g_autofree gchar *allowed_str = NULL;
+            g_autofree gchar *preferred_str = NULL;
 
             single = &g_array_index (combinations, MMHuaweiSyscfgexCombination, j);
             allowed_str = mm_modem_mode_build_string_from_mask (single->allowed);
             preferred_str = mm_modem_mode_build_string_from_mask (single->preferred);
-            mm_dbg ("Test[%u], Combination[%u]: \"%s\", \"%s\", \"%s\"",
-                    i,
-                    j,
-                    single->mode_str,
-                    allowed_str,
-                    preferred_str);
-            g_free (allowed_str);
-            g_free (preferred_str);
+            mm_obj_dbg (NULL, "test[%u], combination[%u]: \"%s\", \"%s\", \"%s\"",
+                        i, j, single->mode_str, allowed_str, preferred_str);
         }
 
         for (j = 0; j < combinations->len; j++) {
@@ -1220,11 +1202,13 @@
 } HcsqTest;
 
 static const HcsqTest hcsq_tests[] = {
-    { "^HCSQ:\"LTE\",30,19,66,0\r\n",  TRUE,  MM_MODEM_ACCESS_TECHNOLOGY_LTE,     30, 19,  66, 0, 0 },
-    { "^HCSQ: \"WCDMA\",30,30,58\r\n", TRUE,  MM_MODEM_ACCESS_TECHNOLOGY_UMTS,    30, 30,  58, 0, 0 },
-    { "^HCSQ: \"GSM\",36,255\r\n",     TRUE,  MM_MODEM_ACCESS_TECHNOLOGY_GSM,     36, 255,  0, 0, 0 },
-    { "^HCSQ: \"NOSERVICE\"\r\n",      FALSE, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN,  0,   0,  0, 0, 0 },
-    { NULL,                            FALSE, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN,  0,   0,  0, 0, 0 }
+    { "^HCSQ:\"LTE\",30,19,66,0\r\n",  TRUE,  MM_MODEM_ACCESS_TECHNOLOGY_LTE,     30, 19,   66,  0, 0 },
+    { "^HCSQ: \"WCDMA\",30,30,58\r\n", TRUE,  MM_MODEM_ACCESS_TECHNOLOGY_UMTS,    30, 30,   58,  0, 0 },
+    { "^HCSQ: \"GSM\",36,255\r\n",     TRUE,  MM_MODEM_ACCESS_TECHNOLOGY_GSM,     36, 255,   0,  0, 0 },
+    { "^HCSQ: LTE,33,40,135,11\r\n",   TRUE,  MM_MODEM_ACCESS_TECHNOLOGY_LTE,     33,  40, 135, 11, 0 },
+    { "^HCSQ: \"NOSERVICE\"\r\n",      FALSE, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN,  0,   0,   0,  0, 0 },
+    { "^HCSQ: NOSERVICE\r\n",          FALSE, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN,  0,   0,   0,  0, 0 },
+    { NULL,                            FALSE, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN,  0,   0,   0,  0, 0 }
 };
 
 static void
@@ -1267,26 +1251,6 @@
 
 /*****************************************************************************/
 
-void
-_mm_log (const char *loc,
-         const char *func,
-         guint32 level,
-         const char *fmt,
-         ...)
-{
-    va_list args;
-    gchar *msg;
-
-    if (!g_test_verbose ())
-        return;
-
-    va_start (args, fmt);
-    msg = g_strdup_vprintf (fmt, args);
-    va_end (args);
-    g_print ("%s\n", msg);
-    g_free (msg);
-}
-
 int main (int argc, char **argv)
 {
     setlocale (LC_ALL, "");
diff --git a/plugins/icera/mm-broadband-bearer-icera.c b/plugins/icera/mm-broadband-bearer-icera.c
index b0c996d..48bcf49 100644
--- a/plugins/icera/mm-broadband-bearer-icera.c
+++ b/plugins/icera/mm-broadband-bearer-icera.c
@@ -29,7 +29,7 @@
 
 #include "mm-broadband-bearer-icera.h"
 #include "mm-base-modem-at.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-modem-helpers.h"
 #include "mm-error-helpers.h"
 #include "mm-daemon-enums-types.h"
@@ -299,37 +299,39 @@
                           GAsyncResult *res,
                           MMBroadbandBearerIcera *self)
 {
-    GTask *task;
     GError *error = NULL;
+    GTask  *task;
 
     /* Try to recover the disconnection task. If none found, it means the
      * task was already completed and we have nothing else to do. */
-    task = self->priv->disconnect_pending;
-
-    /* Balance refcount with the extra ref we passed to command_full() */
-    g_object_unref (self);
+    task = g_steal_pointer (&self->priv->disconnect_pending);
 
     if (!task) {
-        mm_dbg ("Disconnection context was finished already by an unsolicited message");
-
+        mm_obj_dbg (self, "disconnection context was finished already by an unsolicited message");
         /* Run _finish() to finalize the async call, even if we don't care
-         * the result */
+         * about the result */
         mm_base_modem_at_command_full_finish (modem, res, NULL);
-        return;
+        goto out;
     }
 
     mm_base_modem_at_command_full_finish (modem, res, &error);
     if (error) {
-        self->priv->disconnect_pending = NULL;
         g_task_return_error (task, error);
         g_object_unref (task);
-        return;
+        goto out;
     }
 
+    /* Track again */
+    self->priv->disconnect_pending = task;
+
     /* Set a 60-second disconnection-failure timeout */
     self->priv->disconnect_pending_id = g_timeout_add_seconds (60,
                                                                (GSourceFunc)disconnect_3gpp_timed_out_cb,
                                                                self);
+
+out:
+    /* Balance refcount with the extra ref we passed to command_full() */
+    g_object_unref (self);
 }
 
 static void
@@ -483,8 +485,11 @@
                  GAsyncResult *res,
                  GTask        *task)
 {
-    const gchar *response;
-    GError      *activation_error = NULL;
+    MMBroadbandBearerIcera *self;
+    const gchar            *response;
+    GError                 *activation_error = NULL;
+
+    self = g_task_get_source_object (task);
 
     response = mm_base_modem_at_command_full_finish (modem, res, NULL);
     if (response) {
@@ -497,8 +502,7 @@
              * 33 - Requested service option not subscribed
              */
             if (nw_activation_err == 27 || nw_activation_err == 33)
-                activation_error = mm_mobile_equipment_error_for_code (
-                    MM_MOBILE_EQUIPMENT_ERROR_GPRS_SERVICE_OPTION_NOT_SUBSCRIBED);
+                activation_error = mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_GPRS_SERVICE_OPTION_NOT_SUBSCRIBED, self);
         }
     }
 
@@ -594,13 +598,12 @@
     Dial3gppContext *ctx;
     GError          *error = NULL;
 
-    task = self->priv->connect_pending;
-    self->priv->connect_pending = NULL;
+    task = g_steal_pointer (&self->priv->connect_pending);
 
     /* Try to recover the connection context. If none found, it means the
      * context was already completed and we have nothing else to do. */
     if (!task) {
-        mm_dbg ("Connection context was finished already by an unsolicited message");
+        mm_obj_dbg (self, "connection context was finished already by an unsolicited message");
         /* Run _finish() to finalize the async call, even if we don't care
          * the result */
         mm_base_modem_at_command_full_finish (modem, res, NULL);
@@ -670,7 +673,7 @@
          * error ["a profile (CID) is currently active"] if a connect
          * is attempted too soon after a disconnect. */
         if (++ctx->authentication_retries < 3) {
-            mm_dbg ("Authentication failed: '%s'; retrying...", error->message);
+            mm_obj_dbg (self, "authentication failed: %s; retrying...", error->message);
             g_error_free (error);
             g_timeout_add_seconds (1, (GSourceFunc)retry_authentication_cb, task);
             return;
@@ -723,7 +726,7 @@
 
     /* Both user and password are required; otherwise firmware returns an error */
     if (!user || !password || allowed_auth == MM_BEARER_ALLOWED_AUTH_NONE) {
-        mm_dbg ("Not using authentication");
+        mm_obj_dbg (self, "not using authentication");
         command = g_strdup_printf ("%%IPDPCFG=%d,0,0,\"\",\"\"", ctx->cid);
     } else {
         gchar *quoted_user;
@@ -731,13 +734,13 @@
         guint  icera_auth;
 
         if (allowed_auth == MM_BEARER_ALLOWED_AUTH_UNKNOWN) {
-            mm_dbg ("Using default (PAP) authentication method");
+            mm_obj_dbg (self, "using default (PAP) authentication method");
             icera_auth = 1;
         } else if (allowed_auth & MM_BEARER_ALLOWED_AUTH_PAP) {
-            mm_dbg ("Using PAP authentication method");
+            mm_obj_dbg (self, "using PAP authentication method");
             icera_auth = 1;
         } else if (allowed_auth & MM_BEARER_ALLOWED_AUTH_CHAP) {
-            mm_dbg ("Using CHAP authentication method");
+            mm_obj_dbg (self, "using CHAP authentication method");
             icera_auth = 2;
         } else {
             gchar *str;
@@ -879,8 +882,7 @@
         return;
     }
 
-    mm_dbg ("Received spontaneous %%IPDPACT (%s)",
-            mm_bearer_connection_status_get_string (status));
+    mm_obj_dbg (self, "received spontaneous %%IPDPACT (%s)", mm_bearer_connection_status_get_string (status));
 
     /* Received a random 'DISCONNECTED'...*/
     if (status == MM_BEARER_CONNECTION_STATUS_DISCONNECTED ||
diff --git a/plugins/icera/mm-broadband-modem-icera.c b/plugins/icera/mm-broadband-modem-icera.c
index c57ffa7..b459cb5 100644
--- a/plugins/icera/mm-broadband-modem-icera.c
+++ b/plugins/icera/mm-broadband-modem-icera.c
@@ -25,7 +25,7 @@
 
 #include "ModemManager.h"
 #include "mm-serial-parsers.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-modem-helpers.h"
 #include "mm-errors-types.h"
 #include "mm-iface-modem.h"
@@ -71,38 +71,38 @@
 /* Load supported modes (Modem interface) */
 
 static void
-add_supported_mode (GArray **combinations,
-                    guint mode)
+add_supported_mode (MMBroadbandModemIcera  *self,
+                    GArray                **combinations,
+                    guint                   mode)
 {
     MMModemModeCombination combination;
 
     switch (mode) {
     case 0:
-        mm_dbg ("Modem supports 2G-only mode");
+        mm_obj_dbg (self, "2G-only mode supported");
         combination.allowed = MM_MODEM_MODE_2G;
         combination.preferred = MM_MODEM_MODE_NONE;
         break;
     case 1:
-        mm_dbg ("Modem supports 3G-only mode");
+        mm_obj_dbg (self, "3G-only mode supported");
         combination.allowed = MM_MODEM_MODE_3G;
         combination.preferred = MM_MODEM_MODE_NONE;
         break;
     case 2:
-        mm_dbg ("Modem supports 2G/3G mode with 2G preferred");
+        mm_obj_dbg (self, "2G/3G mode with 2G preferred supported");
         combination.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
         combination.preferred = MM_MODEM_MODE_2G;
         break;
     case 3:
-        mm_dbg ("Modem supports 2G/3G mode with 3G preferred");
+        mm_obj_dbg (self, "2G/3G mode with 3G preferred supported");
         combination.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
         combination.preferred = MM_MODEM_MODE_3G;
         break;
     case 5:
-        mm_dbg ("Modem supports 'any', but not explicitly listing it");
         /* Any, no need to add it to the list */
         return;
     default:
-        mm_warn ("Unsupported Icera mode found: %u", mode);
+        mm_obj_warn (self, "unsupported mode found in %%IPSYS=?: %u", mode);
         return;
     }
 
@@ -182,18 +182,18 @@
                 guint j;
 
                 for (j = modefirst; j <= modelast; j++)
-                    add_supported_mode (&combinations, j);
+                    add_supported_mode (MM_BROADBAND_MODEM_ICERA (self), &combinations, j);
             } else
-                mm_warn ("Couldn't parse mode interval (%s) in %%IPSYS=? response", split[i]);
+                mm_obj_warn (self, "couldn't parse mode interval in %%IPSYS=? response: %s", split[i]);
             g_free (first);
         } else {
             guint mode;
 
             /* Add single */
             if (mm_get_uint_from_str (split[i], &mode))
-                add_supported_mode (&combinations, mode);
+                add_supported_mode (MM_BROADBAND_MODEM_ICERA (self), &combinations, mode);
             else
-                mm_warn ("Couldn't parse mode (%s) in %%IPSYS=? response", split[i]);
+                mm_obj_warn (self, "couldn't parse mode in %%IPSYS=? response: %s", split[i]);
         }
     }
 
@@ -441,7 +441,7 @@
         ctx.status = MM_BEARER_CONNECTION_STATUS_CONNECTION_FAILED;
         break;
     default:
-        mm_warn ("Unknown Icera connect status %d", status);
+        mm_obj_warn (self, "unknown %%IPDPACT connect status %d", status);
         break;
     }
 
@@ -614,10 +614,9 @@
     GError *error = NULL;
 
     mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
-    if (error) {
-        mm_dbg ("Couldn't query access technology: '%s'", error->message);
+    if (error)
         g_task_return_error (task, error);
-    } else {
+    else {
         /*
          * The unsolicited message handler will already have run and
          * removed the NWSTATE response, so we use the result from there.
@@ -1022,7 +1021,6 @@
 
     response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
     if (!response) {
-        mm_dbg ("Couldn't query unlock retries: '%s'", error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -1260,7 +1258,6 @@
 
     response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
     if (!response) {
-        mm_dbg ("Couldn't query current bands: '%s'", error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -1346,7 +1343,6 @@
 
     response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
     if (!response) {
-        mm_dbg ("Couldn't query current bands: '%s'", error->message);
         g_task_return_error (task, error);
     } else {
         /* Parse bands from Icera response into MM band numbers */
@@ -1413,7 +1409,6 @@
     GError *error = NULL;
 
     if (!mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error)) {
-        mm_dbg ("Couldn't set current bands: '%s'", error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -1448,15 +1443,15 @@
 
     /* Note that ffs() returning 2 corresponds to 1 << 1, not 1 << 2 */
     band--;
-    mm_dbg("1. enablebits %x disablebits %x band %d enable %d",
-           ctx->enablebits, ctx->disablebits, band, enable);
+    mm_obj_dbg (self, "preparing %%IPBM command (1/2): enablebits %x, disablebits %x, band %d, enable %d",
+                ctx->enablebits, ctx->disablebits, band, enable);
 
     if (enable)
         ctx->enablebits &= ~(1 << band);
     else
         ctx->disablebits &= ~(1 << band);
-    mm_dbg("2. enablebits %x disablebits %x",
-           ctx->enablebits, ctx->disablebits);
+    mm_obj_dbg (self, "preparing %%IPBM command (2/2): enablebits %x, disablebits %x",
+                ctx->enablebits, ctx->disablebits);
 
     command = g_strdup_printf ("%%IPBM=\"%s\",%d",
                                modem_bands[band].name,
diff --git a/plugins/icera/tests/test-modem-helpers-icera.c b/plugins/icera/tests/test-modem-helpers-icera.c
index 592b8b2..518e9af 100644
--- a/plugins/icera/tests/test-modem-helpers-icera.c
+++ b/plugins/icera/tests/test-modem-helpers-icera.c
@@ -24,7 +24,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-test.h"
 #include "mm-modem-helpers.h"
 #include "mm-modem-helpers-icera.h"
 
@@ -175,26 +175,6 @@
 
 /*****************************************************************************/
 
-void
-_mm_log (const char *loc,
-         const char *func,
-         guint32 level,
-         const char *fmt,
-         ...)
-{
-    va_list args;
-    gchar *msg;
-
-    if (!g_test_verbose ())
-        return;
-
-    va_start (args, fmt);
-    msg = g_strdup_vprintf (fmt, args);
-    va_end (args);
-    g_print ("%s\n", msg);
-    g_free (msg);
-}
-
 int main (int argc, char **argv)
 {
     setlocale (LC_ALL, "");
diff --git a/plugins/iridium/mm-bearer-iridium.c b/plugins/iridium/mm-bearer-iridium.c
index d0adeb0..2c4430c 100644
--- a/plugins/iridium/mm-bearer-iridium.c
+++ b/plugins/iridium/mm-bearer-iridium.c
@@ -26,12 +26,11 @@
 
 #include "mm-bearer-iridium.h"
 #include "mm-base-modem-at.h"
-#include "mm-log.h"
 
 /* Allow up to 200s to get a proper IP connection */
 #define BEARER_IRIDIUM_IP_TIMEOUT_DEFAULT 200
 
-G_DEFINE_TYPE (MMBearerIridium, mm_bearer_iridium, MM_TYPE_BASE_BEARER);
+G_DEFINE_TYPE (MMBearerIridium, mm_bearer_iridium, MM_TYPE_BASE_BEARER)
 
 /*****************************************************************************/
 /* Connect */
diff --git a/plugins/iridium/mm-broadband-modem-iridium.c b/plugins/iridium/mm-broadband-modem-iridium.c
index 5cd73b6..bef4a34 100644
--- a/plugins/iridium/mm-broadband-modem-iridium.c
+++ b/plugins/iridium/mm-broadband-modem-iridium.c
@@ -23,7 +23,7 @@
 #include <ctype.h>
 
 #include "ModemManager.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-errors-types.h"
 #include "mm-base-modem-at.h"
 #include "mm-iface-modem.h"
@@ -41,7 +41,7 @@
 G_DEFINE_TYPE_EXTENDED (MMBroadbandModemIridium, mm_broadband_modem_iridium, MM_TYPE_BROADBAND_MODEM, 0,
                         G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init)
                         G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init)
-                        G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_MESSAGING, iface_modem_messaging_init));
+                        G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_MESSAGING, iface_modem_messaging_init))
 
 /*****************************************************************************/
 /* Operator Code loading (3GPP interface) */
@@ -296,7 +296,7 @@
     MMBaseBearer *bearer;
     GTask *task;
 
-    mm_dbg ("Creating Iridium bearer...");
+    mm_obj_dbg (self, "creating Iridium bearer...");
     bearer = mm_bearer_iridium_new (MM_BROADBAND_MODEM_IRIDIUM (self),
                                     properties);
     task = g_task_new (self, NULL, callback, user_data);
@@ -325,7 +325,7 @@
     MM_BROADBAND_MODEM_CLASS (mm_broadband_modem_iridium_parent_class)->setup_ports (self);
 
     /* Set 9600 baudrate by default in the AT port */
-    mm_dbg ("Baudrate will be set to 9600 bps...");
+    mm_obj_dbg (self, "baudrate will be set to 9600 bps...");
     primary = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));
     if (!primary)
         return;
diff --git a/plugins/iridium/mm-plugin-iridium.c b/plugins/iridium/mm-plugin-iridium.c
index c8ae131..582d86a 100644
--- a/plugins/iridium/mm-plugin-iridium.c
+++ b/plugins/iridium/mm-plugin-iridium.c
@@ -29,7 +29,6 @@
 #include "mm-plugin-iridium.h"
 #include "mm-broadband-modem-iridium.h"
 #include "mm-private-boxed-types.h"
-#include "mm-log.h"
 
 G_DEFINE_TYPE (MMPluginIridium, mm_plugin_iridium, MM_TYPE_PLUGIN)
 
@@ -66,7 +65,7 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_IRIDIUM,
-                      MM_PLUGIN_NAME,                    "Iridium",
+                      MM_PLUGIN_NAME,                    MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS,      subsystems,
                       MM_PLUGIN_ALLOWED_VENDOR_STRINGS,  vendor_strings,
                       MM_PLUGIN_ALLOWED_PRODUCT_STRINGS, product_strings,
diff --git a/plugins/linktop/mm-broadband-modem-linktop.c b/plugins/linktop/mm-broadband-modem-linktop.c
index 9c3ecb7..9f42cdd 100644
--- a/plugins/linktop/mm-broadband-modem-linktop.c
+++ b/plugins/linktop/mm-broadband-modem-linktop.c
@@ -28,7 +28,6 @@
 
 #include "ModemManager.h"
 #include "mm-serial-parsers.h"
-#include "mm-log.h"
 #include "mm-modem-helpers.h"
 #include "mm-iface-modem.h"
 #include "mm-base-modem-at.h"
@@ -88,7 +87,7 @@
     g_array_append_val (combinations, mode);
 
     /* Filter out those unsupported modes */
-    filtered = mm_filter_supported_modes (all, combinations);
+    filtered = mm_filter_supported_modes (all, combinations, self);
     g_array_unref (all);
     g_array_unref (combinations);
 
diff --git a/plugins/linktop/mm-modem-helpers-linktop.c b/plugins/linktop/mm-modem-helpers-linktop.c
index 7b9b5f1..2ca46bb 100644
--- a/plugins/linktop/mm-modem-helpers-linktop.c
+++ b/plugins/linktop/mm-modem-helpers-linktop.c
@@ -15,7 +15,6 @@
  * Copyright (C) 2016 Aleksander Morgado <aleksander@aleksander.es>
  */
 
-#include "mm-log.h"
 #include "mm-modem-helpers.h"
 #include "mm-modem-helpers-linktop.h"
 
diff --git a/plugins/linktop/mm-plugin-linktop.c b/plugins/linktop/mm-plugin-linktop.c
index 771f335..d4b0bdc 100644
--- a/plugins/linktop/mm-plugin-linktop.c
+++ b/plugins/linktop/mm-plugin-linktop.c
@@ -57,7 +57,7 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_LINKTOP,
-                      MM_PLUGIN_NAME,               "Linktop",
+                      MM_PLUGIN_NAME,               MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems,
                       MM_PLUGIN_ALLOWED_VENDOR_IDS, vendor_ids,
                       MM_PLUGIN_ALLOWED_AT,         TRUE,
diff --git a/plugins/linktop/tests/test-modem-helpers-linktop.c b/plugins/linktop/tests/test-modem-helpers-linktop.c
index 827d044..07aa837 100644
--- a/plugins/linktop/tests/test-modem-helpers-linktop.c
+++ b/plugins/linktop/tests/test-modem-helpers-linktop.c
@@ -21,7 +21,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-test.h"
 #include "mm-modem-helpers.h"
 #include "mm-modem-helpers-linktop.h"
 
@@ -59,26 +59,6 @@
 
 /*****************************************************************************/
 
-void
-_mm_log (const char *loc,
-         const char *func,
-         guint32 level,
-         const char *fmt,
-         ...)
-{
-    va_list args;
-    gchar *msg;
-
-    if (!g_test_verbose ())
-        return;
-
-    va_start (args, fmt);
-    msg = g_strdup_vprintf (fmt, args);
-    va_end (args);
-    g_print ("%s\n", msg);
-    g_free (msg);
-}
-
 int main (int argc, char **argv)
 {
     setlocale (LC_ALL, "");
diff --git a/plugins/longcheer/mm-broadband-modem-longcheer.c b/plugins/longcheer/mm-broadband-modem-longcheer.c
index 7dc6d37..f158bc4 100644
--- a/plugins/longcheer/mm-broadband-modem-longcheer.c
+++ b/plugins/longcheer/mm-broadband-modem-longcheer.c
@@ -88,7 +88,7 @@
     g_array_append_val (combinations, mode);
 
     /* Filter out those unsupported modes */
-    filtered = mm_filter_supported_modes (all, combinations);
+    filtered = mm_filter_supported_modes (all, combinations, self);
     g_array_unref (all);
     g_array_unref (combinations);
 
@@ -294,7 +294,6 @@
                           GAsyncReadyCallback callback,
                           gpointer user_data)
 {
-    mm_dbg ("loading access technology (longcheer)...");
     mm_base_modem_at_command (MM_BASE_MODEM (self),
                               "+PSRAT",
                               3,
@@ -325,7 +324,6 @@
 
     response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
     if (!response) {
-        mm_dbg ("Couldn't query unlock retries: '%s'", error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
diff --git a/plugins/longcheer/mm-plugin-longcheer.c b/plugins/longcheer/mm-plugin-longcheer.c
index 59b8457..4331d21 100644
--- a/plugins/longcheer/mm-plugin-longcheer.c
+++ b/plugins/longcheer/mm-plugin-longcheer.c
@@ -21,7 +21,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-modem-helpers.h"
 #include "mm-plugin-longcheer.h"
 #include "mm-broadband-modem-longcheer.h"
@@ -58,18 +58,18 @@
 
 static void
 gmr_ready (MMPortSerialAt *port,
-           GAsyncResult *res,
-           GTask *task)
+           GAsyncResult   *res,
+           GTask          *task)
 {
+    MMPortProbe *probe;
     const gchar *p;
     const gchar *response;
-    GError *error = NULL;
 
-    response = mm_port_serial_at_command_finish (port, res, &error);
-    if (error) {
-        g_error_free (error);
+    probe = g_task_get_source_object (task);
 
-        /* Just retry... */
+    response = mm_port_serial_at_command_finish (port, res, NULL);
+    if (!response) {
+        mm_obj_dbg (probe, "retrying custom init step...");
         longcheer_custom_init_step (task);
         return;
     }
@@ -88,7 +88,7 @@
                                  MM_CORE_ERROR_UNSUPPORTED,
                                  "X200 cannot be supported with the Longcheer plugin");
     } else {
-        mm_dbg ("(Longcheer) device is not a X200");
+        mm_obj_dbg (probe, "device is not a X200");
         g_task_return_boolean (task, TRUE);
     }
     g_object_unref (task);
@@ -97,16 +97,17 @@
 static void
 longcheer_custom_init_step (GTask *task)
 {
+    MMPortProbe                *probe;
     LongcheerCustomInitContext *ctx;
-    GCancellable *cancellable;
+    GCancellable               *cancellable;
 
-    ctx = g_task_get_task_data (task);
+    probe       = g_task_get_source_object (task);
+    ctx         = g_task_get_task_data (task);
     cancellable = g_task_get_cancellable (task);
 
     /* If cancelled, end */
     if (g_cancellable_is_cancelled (cancellable)) {
-        mm_dbg ("(Longcheer) no need to keep on running custom init in (%s)",
-                mm_port_get_device (MM_PORT (ctx->port)));
+        mm_obj_dbg (probe, "no need to keep on running custom init");
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
         return;
@@ -218,7 +219,7 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_LONGCHEER,
-                      MM_PLUGIN_NAME,               "Longcheer",
+                      MM_PLUGIN_NAME,               MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems,
                       MM_PLUGIN_ALLOWED_VENDOR_IDS, vendor_ids,
                       MM_PLUGIN_ALLOWED_AT,         TRUE,
diff --git a/plugins/mbm/mm-broadband-bearer-mbm.c b/plugins/mbm/mm-broadband-bearer-mbm.c
index c4795aa..761ad86 100644
--- a/plugins/mbm/mm-broadband-bearer-mbm.c
+++ b/plugins/mbm/mm-broadband-bearer-mbm.c
@@ -38,7 +38,7 @@
 
 #include "mm-base-modem-at.h"
 #include "mm-broadband-bearer-mbm.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-modem-helpers.h"
 #include "mm-modem-helpers-mbm.h"
 #include "mm-daemon-enums-types.h"
@@ -180,11 +180,10 @@
     const gchar     *response;
     guint            state;
 
-    task = self->priv->connect_pending;
-    self->priv->connect_pending = NULL;
+    task = g_steal_pointer (&self->priv->connect_pending);
 
     if (!task) {
-        mm_dbg ("Connection context was finished already by an unsolicited message");
+        mm_obj_dbg (self, "connection context was finished already by an unsolicited message");
         /* Run _finish() to finalize the async call, even if we don't care
          * the result */
         mm_base_modem_at_command_full_finish (modem, res, NULL);
@@ -219,8 +218,7 @@
     GTask           *task;
     Dial3gppContext *ctx;
 
-    task = self->priv->connect_pending;
-    self->priv->connect_pending = NULL;
+    task = g_steal_pointer (&self->priv->connect_pending);
 
     g_assert (task);
     ctx = g_task_get_task_data (task);
@@ -269,11 +267,10 @@
 
     /* Try to recover the connection context. If none found, it means the
      * context was already completed and we have nothing else to do. */
-    task = self->priv->connect_pending;
-    self->priv->connect_pending = NULL;
+    task = g_steal_pointer (&self->priv->connect_pending);
 
     if (!task) {
-        mm_dbg ("Connection context was finished already by an unsolicited message");
+        mm_obj_dbg (self, "connection context was finished already by an unsolicited message");
         /* Run _finish() to finalize the async call, even if we don't care
          * the result */
         mm_base_modem_at_command_full_finish (modem, res, NULL);
@@ -391,7 +388,7 @@
         return;
     }
 
-    mm_dbg ("Authentication not needed");
+    mm_obj_dbg (self, "authentication not needed");
     activate (task);
 }
 
@@ -602,11 +599,8 @@
     DisconnectContext *ctx;
 
     /* Recover disconnection task */
-    task = self->priv->disconnect_pending;
-    self->priv->disconnect_pending = NULL;
-    g_assert (task != NULL);
-
-    ctx = g_task_get_task_data (task);
+    task = g_steal_pointer (&self->priv->disconnect_pending);
+    ctx  = g_task_get_task_data (task);
 
     if (ctx->poll_id) {
         g_source_remove (ctx->poll_id);
@@ -615,7 +609,7 @@
 
     /* Received 'DISCONNECTED' during a disconnection attempt? */
     if (status == MM_BEARER_CONNECTION_STATUS_DISCONNECTED) {
-        mm_dbg ("Connection disconnect indicated by an unsolicited message");
+        mm_obj_dbg (self, "connection disconnect indicated by an unsolicited message");
         g_task_return_boolean (task, TRUE);
     } else {
         /* Otherwise, report error */
@@ -638,11 +632,10 @@
     const gchar       *response;
     guint              state;
 
-    task = self->priv->disconnect_pending;
-    self->priv->disconnect_pending = NULL;
+    task = g_steal_pointer (&self->priv->disconnect_pending);
 
     if (!task) {
-        mm_dbg ("Disconnection context was finished already by an unsolicited message");
+        mm_obj_dbg (self, "disconnection context was finished already by an unsolicited message");
         /* Run _finish() to finalize the async call, even if we don't care
          * the result */
         mm_base_modem_at_command_full_finish (modem, res, NULL);
@@ -722,8 +715,7 @@
     GTask             *task;
     GError            *error = NULL;
 
-    task = self->priv->disconnect_pending;
-    self->priv->disconnect_pending = NULL;
+    task = g_steal_pointer (&self->priv->disconnect_pending);
 
     /* Try to recover the disconnection context. If none found, it means the
      * context was already completed and we have nothing else to do. */
@@ -737,7 +729,7 @@
     /* Ignore errors for now */
     mm_base_modem_at_command_full_finish (modem, res, &error);
     if (error) {
-        mm_dbg ("Disconnection failed (not fatal): %s", error->message);
+        mm_obj_dbg (self, "disconnection failed (not fatal): %s", error->message);
         g_error_free (error);
     }
 
@@ -815,8 +807,8 @@
         return;
     }
 
-    mm_dbg ("Received spontaneous E2NAP (%s)",
-            mm_bearer_connection_status_get_string (status));
+    mm_obj_dbg (self, "received spontaneous E2NAP (%s)",
+                mm_bearer_connection_status_get_string (status));
 
     /* Received a random 'DISCONNECTED'...*/
     if (status == MM_BEARER_CONNECTION_STATUS_DISCONNECTED ||
diff --git a/plugins/mbm/mm-broadband-modem-mbm.c b/plugins/mbm/mm-broadband-modem-mbm.c
index a4b89fd..49f9421 100644
--- a/plugins/mbm/mm-broadband-modem-mbm.c
+++ b/plugins/mbm/mm-broadband-modem-mbm.c
@@ -31,7 +31,7 @@
 #include <ctype.h>
 
 #include "ModemManager.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-bearer-list.h"
 #include "mm-errors-types.h"
 #include "mm-modem-helpers.h"
@@ -115,7 +115,7 @@
                      GAsyncReadyCallback callback,
                      gpointer user_data)
 {
-    mm_dbg ("Creating MBM bearer...");
+    mm_obj_dbg (self, "creating MBM bearer...");
     mm_broadband_bearer_mbm_new (MM_BROADBAND_MODEM_MBM (self),
                                  properties,
                                  NULL, /* cancellable */
@@ -196,7 +196,7 @@
     if (!response)
         return FALSE;
 
-    if (!mm_mbm_parse_cfun_test (response, &mask, error))
+    if (!mm_mbm_parse_cfun_test (response, self, &mask, error))
         return FALSE;
 
     /* Build list of combinations */
@@ -448,7 +448,7 @@
         if (g_error_matches (error,
                              MM_SERIAL_ERROR,
                              MM_SERIAL_ERROR_RESPONSE_TIMEOUT))
-            mm_warn ("timed out waiting for EMRDY response.");
+            mm_obj_warn (self, "timed out waiting for EMRDY response");
         else
             MM_BROADBAND_MODEM_MBM (self)->priv->have_emrdy = TRUE;
         g_error_free (error);
@@ -635,7 +635,7 @@
                GAsyncReadyCallback callback,
                gpointer user_data)
 {
-    mm_dbg ("Ignoring factory reset code: '%s'", code);
+    mm_obj_dbg (self, "ignoring user-provided factory reset code: '%s'", code);
 
     mm_base_modem_at_sequence (MM_BASE_MODEM (self),
                                factory_reset_sequence,
@@ -695,7 +695,6 @@
                      GAsyncReadyCallback callback,
                      gpointer user_data)
 {
-    mm_dbg ("loading unlock retries (mbm)...");
     mm_base_modem_at_command (MM_BASE_MODEM (self),
                               "*EPIN?",
                               10,
@@ -734,19 +733,19 @@
 
     switch (state) {
     case MBM_E2NAP_DISCONNECTED:
-        mm_dbg ("disconnected");
+        mm_obj_dbg (self, "disconnected");
         ctx.status = MM_BEARER_CONNECTION_STATUS_DISCONNECTED;
         break;
     case MBM_E2NAP_CONNECTED:
-        mm_dbg ("connected");
+        mm_obj_dbg (self, "connected");
         ctx.status = MM_BEARER_CONNECTION_STATUS_CONNECTED;
         break;
     case MBM_E2NAP_CONNECTING:
-        mm_dbg ("connecting");
+        mm_obj_dbg (self, "connecting");
         break;
     default:
         /* Should not happen */
-        mm_dbg ("unhandled E2NAP state %d", state);
+        mm_obj_dbg (self, "unhandled E2NAP state %d", state);
     }
 
     /* If unknown status, don't try to report anything */
diff --git a/plugins/mbm/mm-modem-helpers-mbm.c b/plugins/mbm/mm-modem-helpers-mbm.c
index 18656e5..31fbb37 100644
--- a/plugins/mbm/mm-modem-helpers-mbm.c
+++ b/plugins/mbm/mm-modem-helpers-mbm.c
@@ -169,21 +169,22 @@
 #define CFUN_TAG "+CFUN:"
 
 static void
-add_supported_mode (guint32 *mask,
-                    guint mode)
+add_supported_mode (guint     mode,
+                    gpointer  log_object,
+                    guint32  *mask)
 {
     g_assert (mask);
-
     if (mode >= 32)
-        mm_warn ("Ignored unexpected mode in +CFUN match: %d", mode);
+        mm_obj_warn (log_object, "ignored unexpected mode in +CFUN match: %d", mode);
     else
         *mask |= (1 << mode);
 }
 
 gboolean
 mm_mbm_parse_cfun_test (const gchar *response,
-                        guint32 *supported_mask,
-                        GError **error)
+                        gpointer     log_object,
+                        guint32     *supported_mask,
+                        GError     **error)
 {
     gchar **groups;
     guint32 mask = 0;
@@ -236,20 +237,20 @@
                     last_str = separator + 1;
 
                     if (!mm_get_uint_from_str (first_str, &first))
-                        mm_warn ("Couldn't match range start: '%s'", first_str);
+                        mm_obj_warn (log_object, "couldn't match range start: '%s'", first_str);
                     else if (!mm_get_uint_from_str (last_str, &last))
-                        mm_warn ("Couldn't match range stop: '%s'", last_str);
+                        mm_obj_warn (log_object, "couldn't match range stop: '%s'", last_str);
                     else if (first >= last)
-                        mm_warn ("Couldn't match range: wrong first '%s' and last '%s' items", first_str, last_str);
+                        mm_obj_warn (log_object, "couldn't match range: wrong first '%s' and last '%s' items", first_str, last_str);
                     else {
                         for (mode = first; mode <= last; mode++)
-                            add_supported_mode (&mask, mode);
+                            add_supported_mode (mode, log_object, &mask);
                     }
                 } else {
                     if (!mm_get_uint_from_str (supported_modes[i], &mode))
-                        mm_warn ("Couldn't match mode: '%s'", supported_modes[i]);
+                        mm_obj_warn (log_object, "couldn't match mode: '%s'", supported_modes[i]);
                     else
-                        add_supported_mode (&mask, mode);
+                        add_supported_mode (mode, log_object, &mask);
                 }
             }
 
diff --git a/plugins/mbm/mm-modem-helpers-mbm.h b/plugins/mbm/mm-modem-helpers-mbm.h
index a7df1b0..3e3bf57 100644
--- a/plugins/mbm/mm-modem-helpers-mbm.h
+++ b/plugins/mbm/mm-modem-helpers-mbm.h
@@ -34,9 +34,10 @@
 
 /* AT+CFUN=? test parser
  * Returns a bitmask, bit index set for the supported modes reported */
-gboolean mm_mbm_parse_cfun_test (const gchar *response,
-                                 guint32 *supported_mask,
-                                 GError **error);
+gboolean mm_mbm_parse_cfun_test (const gchar  *response,
+                                 gpointer      log_object,
+                                 guint32      *supported_mask,
+                                 GError      **error);
 
 /* AT+CFUN? response parsers */
 gboolean mm_mbm_parse_cfun_query_power_state   (const gchar        *response,
diff --git a/plugins/mbm/mm-plugin-mbm.c b/plugins/mbm/mm-plugin-mbm.c
index 4f3b52a..cae41d8 100644
--- a/plugins/mbm/mm-plugin-mbm.c
+++ b/plugins/mbm/mm-plugin-mbm.c
@@ -23,7 +23,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-plugin-mbm.h"
 #include "mm-broadband-modem-mbm.h"
 
@@ -49,7 +49,7 @@
 {
 #if defined WITH_MBIM
     if (mm_port_probe_list_has_mbim_port (probes)) {
-        mm_dbg ("MBIM-powered Ericsson modem found...");
+        mm_obj_dbg (self, "MBIM-powered Ericsson modem found...");
         return MM_BASE_MODEM (mm_broadband_modem_mbim_new (uid,
                                                            drivers,
                                                            mm_plugin_get_name (self),
@@ -78,7 +78,7 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_MBM,
-                      MM_PLUGIN_NAME,               "Ericsson MBM",
+                      MM_PLUGIN_NAME,               MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems,
                       MM_PLUGIN_ALLOWED_UDEV_TAGS,  udev_tags,
                       MM_PLUGIN_ALLOWED_AT,         TRUE,
diff --git a/plugins/mbm/mm-sim-mbm.c b/plugins/mbm/mm-sim-mbm.c
index f321870..1b160d6 100644
--- a/plugins/mbm/mm-sim-mbm.c
+++ b/plugins/mbm/mm-sim-mbm.c
@@ -24,7 +24,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-base-modem-at.h"
 #include "mm-sim-mbm.h"
 
@@ -93,9 +93,11 @@
 static void
 wait_for_unlocked_status (GTask *task)
 {
+    MMSimMbm          *self;
     SendPinPukContext *ctx;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     /* Oops... :/ */
     if (ctx->retries == 0) {
@@ -109,7 +111,7 @@
 
     /* Check status */
     ctx->retries--;
-    mm_dbg ("Scheduling lock state check...");
+    mm_obj_dbg (self, "scheduling lock state check...");
     g_timeout_add_seconds (1, (GSourceFunc)cpin_query_cb, task);
 }
 
diff --git a/plugins/mbm/tests/test-modem-helpers-mbm.c b/plugins/mbm/tests/test-modem-helpers-mbm.c
index cca121b..4169140 100644
--- a/plugins/mbm/tests/test-modem-helpers-mbm.c
+++ b/plugins/mbm/tests/test-modem-helpers-mbm.c
@@ -24,7 +24,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-test.h"
 #include "mm-modem-helpers.h"
 #include "mm-modem-helpers-mbm.h"
 
@@ -179,7 +179,7 @@
         gboolean success;
         GError *error = NULL;
 
-        success = mm_mbm_parse_cfun_test (cfun_tests[i].str, &mask, &error);
+        success = mm_mbm_parse_cfun_test (cfun_tests[i].str, NULL, &mask, &error);
         g_assert_no_error (error);
         g_assert (success);
         g_assert_cmpuint (mask, ==, cfun_tests[i].expected_mask);
@@ -253,26 +253,6 @@
 
 /*****************************************************************************/
 
-void
-_mm_log (const char *loc,
-         const char *func,
-         guint32 level,
-         const char *fmt,
-         ...)
-{
-    va_list args;
-    gchar *msg;
-
-    if (!g_test_verbose ())
-        return;
-
-    va_start (args, fmt);
-    msg = g_strdup_vprintf (fmt, args);
-    va_end (args);
-    g_print ("%s\n", msg);
-    g_free (msg);
-}
-
 int main (int argc, char **argv)
 {
     setlocale (LC_ALL, "");
diff --git a/plugins/motorola/mm-plugin-motorola.c b/plugins/motorola/mm-plugin-motorola.c
index 68c8d48..368e898 100644
--- a/plugins/motorola/mm-plugin-motorola.c
+++ b/plugins/motorola/mm-plugin-motorola.c
@@ -62,7 +62,7 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_MOTOROLA,
-                      MM_PLUGIN_NAME,                "Motorola",
+                      MM_PLUGIN_NAME,                MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS,  subsystems,
                       MM_PLUGIN_ALLOWED_PRODUCT_IDS, product_ids,
                       MM_PLUGIN_ALLOWED_AT,          TRUE,
diff --git a/plugins/mtk/mm-broadband-modem-mtk.c b/plugins/mtk/mm-broadband-modem-mtk.c
index 8170984..5439b52 100644
--- a/plugins/mtk/mm-broadband-modem-mtk.c
+++ b/plugins/mtk/mm-broadband-modem-mtk.c
@@ -24,7 +24,7 @@
 #include <ctype.h>
 
 #include "ModemManager.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-errors-types.h"
 #include "mm-modem-helpers.h"
 #include "mm-base-modem-at.h"
@@ -77,7 +77,6 @@
 
     response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
     if (!response) {
-        mm_dbg ("Couldn't query unlock retries: '%s'", error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -190,7 +189,6 @@
 
     response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
     if (!response) {
-        mm_dbg ("Fail to get response");
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -382,7 +380,7 @@
             break;
         default:
             result = FALSE;
-            mm_dbg ("Not supported allowed mode %d", erat_mode);
+            mm_obj_dbg (self, "unsupported allowed mode reported in +ERAT: %d", erat_mode);
             goto done;
     }
 
@@ -401,7 +399,7 @@
             break;
         default:
             result = FALSE;
-            mm_dbg ("Not supported preferred mode %d", erat_pref);
+            mm_obj_dbg (self, "unsupported preferred mode %d", erat_pref);
             goto done;
     }
 
@@ -547,7 +545,7 @@
     else
         quality = MM_CLAMP_HIGH (quality, 31) * 100 / 31;
 
-    mm_dbg ("6280 signal quality URC received: quality = %u", quality);
+    mm_obj_dbg (self, "6280 signal quality URC received: %u", quality);
     mm_iface_modem_update_signal_quality (MM_IFACE_MODEM (self), quality);
 }
 
@@ -566,7 +564,7 @@
     else
         quality = MM_CLAMP_HIGH (quality, 63) * 100 / 63;
 
-    mm_dbg ("2G signal quality URC received: quality = %u", quality);
+    mm_obj_dbg (self, "2G signal quality URC received: %u", quality);
     mm_iface_modem_update_signal_quality (MM_IFACE_MODEM (self), quality);
 }
 
@@ -582,7 +580,7 @@
 
     quality = MM_CLAMP_HIGH (quality, 96) * 100 / 96;
 
-    mm_dbg ("3G signal quality URC received: quality = %u", quality);
+    mm_obj_dbg (self, "3G signal quality URC received: %u", quality);
     mm_iface_modem_update_signal_quality (MM_IFACE_MODEM (self), quality);
 }
 
@@ -598,7 +596,7 @@
 
     quality = MM_CLAMP_HIGH (quality, 97) * 100 / 97;
 
-    mm_dbg ("4G signal quality URC received: quality = %u", quality);
+    mm_obj_dbg (self, "4G signal quality URC received: %u", quality);
     mm_iface_modem_update_signal_quality (MM_IFACE_MODEM (self), quality);
 }
 
diff --git a/plugins/mtk/mm-plugin-mtk.c b/plugins/mtk/mm-plugin-mtk.c
index 3f6745a..5a4ea1c 100644
--- a/plugins/mtk/mm-plugin-mtk.c
+++ b/plugins/mtk/mm-plugin-mtk.c
@@ -21,7 +21,6 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
 #include "mm-plugin-mtk.h"
 #include "mm-broadband-modem-mtk.h"
 
@@ -61,7 +60,7 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_MTK,
-                      MM_PLUGIN_NAME,               "MTK",
+                      MM_PLUGIN_NAME,               MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems,
                       MM_PLUGIN_ALLOWED_UDEV_TAGS,  udev_tags,
                       MM_PLUGIN_ALLOWED_AT,         TRUE,
diff --git a/plugins/nokia/mm-broadband-modem-nokia.c b/plugins/nokia/mm-broadband-modem-nokia.c
index 5e5ca5c..55af164 100644
--- a/plugins/nokia/mm-broadband-modem-nokia.c
+++ b/plugins/nokia/mm-broadband-modem-nokia.c
@@ -25,7 +25,6 @@
 
 #include "ModemManager.h"
 #include "mm-serial-parsers.h"
-#include "mm-log.h"
 #include "mm-errors-types.h"
 #include "mm-iface-modem.h"
 #include "mm-iface-modem-messaging.h"
diff --git a/plugins/nokia/mm-plugin-nokia-icera.c b/plugins/nokia/mm-plugin-nokia-icera.c
index e2d587a..f8cbc43 100644
--- a/plugins/nokia/mm-plugin-nokia-icera.c
+++ b/plugins/nokia/mm-plugin-nokia-icera.c
@@ -20,7 +20,6 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
 #include "mm-plugin-nokia-icera.h"
 #include "mm-broadband-modem-icera.h"
 
@@ -67,7 +66,7 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_NOKIA_ICERA,
-                      MM_PLUGIN_NAME,               "Nokia (Icera)",
+                      MM_PLUGIN_NAME,               MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems,
                       MM_PLUGIN_ALLOWED_VENDOR_IDS, vendor_ids,
                       MM_PLUGIN_CUSTOM_AT_PROBE,    custom_at_probe,
diff --git a/plugins/nokia/mm-plugin-nokia.c b/plugins/nokia/mm-plugin-nokia.c
index cb3374c..29b8c8f 100644
--- a/plugins/nokia/mm-plugin-nokia.c
+++ b/plugins/nokia/mm-plugin-nokia.c
@@ -21,7 +21,6 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
 #include "mm-plugin-nokia.h"
 #include "mm-broadband-modem-nokia.h"
 
@@ -69,7 +68,7 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_NOKIA,
-                      MM_PLUGIN_NAME,                   "Nokia",
+                      MM_PLUGIN_NAME,                   MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS,     subsystems,
                       MM_PLUGIN_ALLOWED_VENDOR_IDS,     vendor_ids,
                       MM_PLUGIN_ALLOWED_VENDOR_STRINGS, vendor_strings,
diff --git a/plugins/novatel/mm-broadband-bearer-novatel-lte.c b/plugins/novatel/mm-broadband-bearer-novatel-lte.c
index 72001ef..43eeed1 100644
--- a/plugins/novatel/mm-broadband-bearer-novatel-lte.c
+++ b/plugins/novatel/mm-broadband-bearer-novatel-lte.c
@@ -30,7 +30,7 @@
 
 #include "mm-base-modem-at.h"
 #include "mm-broadband-bearer-novatel-lte.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-modem-helpers.h"
 
 #define QMISTATUS_TAG "$NWQMISTATUS:"
@@ -176,32 +176,36 @@
                               GAsyncResult *res,
                               GTask *task)
 {
+    MMBroadbandBearerNovatelLte *self;
     DetailedConnectContext *ctx;
     const gchar *result;
     gchar *normalized_result;
     GError *error = NULL;
 
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
+
     if (g_task_return_error_if_cancelled (task)) {
         g_object_unref (task);
         return;
     }
 
-    ctx = g_task_get_task_data (task);
-
     result = mm_base_modem_at_command_full_finish (modem, res, &error);
     if (!result) {
-        mm_warn ("QMI connection status failed: %s", error->message);
         if (!g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN)) {
             g_task_return_error (task, error);
             g_object_unref (task);
             return;
         }
+        mm_obj_dbg (self, "connection status failed: %s; will retry", error->message);
         g_error_free (error);
-        result = "Unknown error";
-    } else if (is_qmistatus_connected (result)) {
+        goto retry;
+    }
+
+    if (is_qmistatus_connected (result)) {
         MMBearerIpConfig *config;
 
-        mm_dbg("Connected");
+        mm_obj_dbg (self, "connected");
         config = mm_bearer_ip_config_new ();
         mm_bearer_ip_config_set_method (config, MM_BEARER_IP_METHOD_DHCP);
         g_task_return_pointer (
@@ -211,17 +215,18 @@
         g_object_unref (task);
         g_object_unref (config);
         return;
-    } else if (is_qmistatus_call_failed (result)) {
-        /* Don't retry if the call failed */
+    }
+
+    /* Don't retry if the call failed */
+    if (is_qmistatus_call_failed (result)) {
+        mm_obj_dbg (self, "not retrying: call failed");
         ctx->retries = 0;
     }
 
-    mm_dbg ("Error: '%s'", result);
-
+retry:
     if (ctx->retries > 0) {
         ctx->retries--;
-        mm_dbg ("Retrying status check in a second. %d retries left.",
-                ctx->retries);
+        mm_obj_dbg (self, "retrying status check in a second: %d retries left", ctx->retries);
         g_timeout_add_seconds (1, (GSourceFunc)connect_3gpp_qmistatus, task);
         return;
     }
@@ -268,7 +273,6 @@
 
     result = mm_base_modem_at_command_full_finish (modem, res, &error);
     if (!result) {
-        mm_warn ("QMI connection failed: %s", error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -381,27 +385,30 @@
 static gboolean disconnect_3gpp_qmistatus (GTask *task);
 
 static void
-disconnect_3gpp_status_ready (MMBaseModem *modem,
+disconnect_3gpp_status_ready (MMBaseModem  *modem,
                               GAsyncResult *res,
-                              GTask *task)
+                              GTask        *task)
 {
-    DetailedDisconnectContext *ctx;
-    const gchar *result;
-    GError *error = NULL;
-    gboolean is_connected = FALSE;
+    MMBroadbandBearerNovatelLte *self;
+    DetailedDisconnectContext   *ctx;
+    const gchar                 *result;
+    GError                      *error = NULL;
+    gboolean                     is_connected = FALSE;
+
+    self = g_task_get_source_object (task);
 
     result = mm_base_modem_at_command_full_finish (modem, res, &error);
     if (result) {
-        mm_dbg ("QMI connection status: %s", result);
+        mm_obj_dbg (self, "QMI connection status: %s", result);
         if (is_qmistatus_disconnected (result)) {
             g_task_return_boolean (task, TRUE);
             g_object_unref (task);
             return;
-        } else if (is_qmistatus_connected (result)) {
-            is_connected = TRUE;
         }
+        if (is_qmistatus_connected (result))
+            is_connected = TRUE;
     } else {
-        mm_dbg ("QMI connection status failed: %s", error->message);
+        mm_obj_dbg (self, "QMI connection status failed: %s", error->message);
         g_error_free (error);
         result = "Unknown error";
     }
@@ -410,8 +417,7 @@
 
     if (ctx->retries > 0) {
         ctx->retries--;
-        mm_dbg ("Retrying status check in a second. %d retries left.",
-                ctx->retries);
+        mm_obj_dbg (self, "retrying status check in a second: %d retries left", ctx->retries);
         g_timeout_add_seconds (1, (GSourceFunc)disconnect_3gpp_qmistatus, task);
         return;
     }
@@ -457,15 +463,18 @@
 
 
 static void
-disconnect_3gpp_check_status (MMBaseModem *modem,
+disconnect_3gpp_check_status (MMBaseModem  *modem,
                               GAsyncResult *res,
-                              GTask *task)
+                              GTask        *task)
 {
-    GError *error = NULL;
+    MMBroadbandBearerNovatelLte *self;
+    GError                      *error = NULL;
+
+    self = g_task_get_source_object (task);
 
     mm_base_modem_at_command_full_finish (modem, res, &error);
     if (error) {
-        mm_dbg("Disconnection error: %s", error->message);
+        mm_obj_dbg (self, "disconnection error: %s", error->message);
         g_error_free (error);
     }
 
diff --git a/plugins/novatel/mm-broadband-modem-novatel-lte.c b/plugins/novatel/mm-broadband-modem-novatel-lte.c
index 5fa11c4..d2a3bde 100644
--- a/plugins/novatel/mm-broadband-modem-novatel-lte.c
+++ b/plugins/novatel/mm-broadband-modem-novatel-lte.c
@@ -31,7 +31,7 @@
 #include "mm-iface-modem.h"
 #include "mm-iface-modem-3gpp.h"
 #include "mm-iface-modem-messaging.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-modem-helpers.h"
 #include "mm-serial-parsers.h"
 
@@ -256,7 +256,6 @@
                   GAsyncReadyCallback callback,
                   gpointer user_data)
 {
-    mm_dbg ("loading (Novatel LTE) own numbers...");
     mm_base_modem_at_sequence (
         MM_BASE_MODEM (self),
         own_numbers_commands,
@@ -365,7 +364,6 @@
 
     response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
     if (!response) {
-        mm_dbg ("Couldn't query supported bands: '%s'", error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -424,7 +422,6 @@
 
     response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
     if (!response) {
-        mm_dbg ("Couldn't query unlock retries: '%s'", error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -499,7 +496,6 @@
 
     response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
     if (!response) {
-        mm_dbg ("Couldn't query access technology: '%s'", error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -598,7 +594,7 @@
     GTask *task;
     MMModemAccessTechnology access_tech;
 
-    mm_dbg ("scanning for networks (Novatel LTE)...");
+    mm_obj_dbg (self, "scanning for networks (Novatel LTE)...");
 
     task = g_task_new (self, NULL, callback, user_data);
 
@@ -608,17 +604,16 @@
      */
     access_tech = mm_iface_modem_get_access_technologies (MM_IFACE_MODEM (self));
     if (access_tech & MM_MODEM_ACCESS_TECHNOLOGY_LTE) {
-        gchar *access_tech_string;
+        g_autofree gchar *access_tech_string = NULL;
 
         access_tech_string = mm_modem_access_technology_build_string_from_mask (access_tech);
-        mm_warn ("Couldn't scan for networks with access technologies: %s", access_tech_string);
+        mm_obj_warn (self, "couldn't scan for networks with access technologies: %s", access_tech_string);
         g_task_return_new_error (task,
                                  MM_CORE_ERROR,
                                  MM_CORE_ERROR_UNSUPPORTED,
                                  "Couldn't scan for networks with access technologies: %s",
                                  access_tech_string);
         g_object_unref (task);
-        g_free (access_tech_string);
         return;
     }
 
diff --git a/plugins/novatel/mm-broadband-modem-novatel.c b/plugins/novatel/mm-broadband-modem-novatel.c
index 2675a7e..aeec787 100644
--- a/plugins/novatel/mm-broadband-modem-novatel.c
+++ b/plugins/novatel/mm-broadband-modem-novatel.c
@@ -35,7 +35,7 @@
 #include "mm-modem-helpers.h"
 #include "libqcdm/src/commands.h"
 #include "libqcdm/src/result.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 static void iface_modem_init (MMIfaceModem *iface);
 static void iface_modem_messaging_init (MMIfaceModemMessaging *iface);
@@ -104,7 +104,7 @@
     g_array_append_val (combinations, mode);
 
     /* Filter out those unsupported modes */
-    filtered = mm_filter_supported_modes (all, combinations);
+    filtered = mm_filter_supported_modes (all, combinations, self);
     g_array_unref (all);
     g_array_unref (combinations);
 
@@ -413,7 +413,7 @@
     response = mm_port_serial_qcdm_command_finish (port, res, &error);
     if (error) {
         /* Just ignore the error and complete with the input info */
-        mm_dbg ("Couldn't run QCDM Novatel Modem MSM6500 snapshot: '%s'", error->message);
+        g_prefix_error (&error, "Couldn't run QCDM Novatel Modem MSM6500 snapshot: ");
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -423,7 +423,7 @@
     result = qcdm_cmd_nw_subsys_modem_snapshot_cdma_result ((const gchar *) response->data, response->len, NULL);
     g_byte_array_unref (response);
     if (!result) {
-        mm_dbg ("Failed to get QCDM Novatel Modem MSM6500 snapshot: %s", error->message);
+        g_prefix_error (&error, "Failed to get QCDM Novatel Modem MSM6500 snapshot: ");
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -439,18 +439,21 @@
 
 static void
 nw_snapshot_new_ready (MMPortSerialQcdm *port,
-                       GAsyncResult *res,
-                       GTask *task)
+                       GAsyncResult     *res,
+                       GTask            *task)
 {
-    QcdmResult *result;
-    GByteArray *nwsnap;
-    GError *error = NULL;
-    GByteArray *response;
-    guint8 hdr_revision = QCDM_HDR_REV_UNKNOWN;
+    MMBroadbandModemNovatel *self;
+    QcdmResult              *result;
+    GByteArray              *nwsnap;
+    GError                  *error = NULL;
+    GByteArray              *response;
+    guint8                   hdr_revision = QCDM_HDR_REV_UNKNOWN;
+
+    self = g_task_get_source_object (task);
 
     response = mm_port_serial_qcdm_command_finish (port, res, &error);
     if (error) {
-        mm_dbg ("Couldn't run QCDM Novatel Modem MSM6800 snapshot: '%s'", error->message);
+        g_prefix_error (&error, "couldn't run QCDM Novatel Modem MSM6800 snapshot: ");
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -469,7 +472,7 @@
         return;
     }
 
-    mm_dbg ("Failed to get QCDM Novatel Modem MSM6800 snapshot.");
+    mm_obj_dbg (self, "failed to get QCDM Novatel Modem MSM6800 snapshot");
 
     /* Try for MSM6500 */
     nwsnap = g_byte_array_sized_new (25);
@@ -498,9 +501,7 @@
 
     port = mm_base_modem_get_port_qcdm (self);
     if (!port) {
-        error = g_error_new (MM_CORE_ERROR,
-                             MM_CORE_ERROR_FAILED,
-                             "No available QCDM port.");
+        error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "No available QCDM port");
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -508,7 +509,7 @@
     g_task_set_task_data (task, port, (GDestroyNotify) close_and_unref_port);
 
     if (!mm_port_serial_open (MM_PORT_SERIAL (port), &error)) {
-        g_prefix_error (&error, "Couldn't open QCDM port: ");
+        g_prefix_error (&error, "couldn't open QCDM port: ");
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -543,24 +544,24 @@
                                        guint *mask,
                                        GError **error)
 {
-    GTask *task = G_TASK (res);
-    AccessTechContext *ctx = g_task_get_task_data (task);
+    AccessTechContext *ctx;
 
-    if (!g_task_propagate_boolean (task, error))
+    if (!g_task_propagate_boolean (G_TASK (res), error))
         return FALSE;
 
     /* Update access technology with specific EVDO revision from QCDM if we have them */
+    ctx = g_task_get_task_data (G_TASK (res));
     if (ctx->act & MM_IFACE_MODEM_CDMA_ALL_EVDO_ACCESS_TECHNOLOGIES_MASK) {
         if (ctx->hdr_revision == QCDM_HDR_REV_0) {
-            mm_dbg ("Novatel Modem Snapshot EVDO revision: 0");
+            mm_obj_dbg (self, "modem snapshot EVDO revision: 0");
             ctx->act &= ~MM_IFACE_MODEM_CDMA_ALL_EVDO_ACCESS_TECHNOLOGIES_MASK;
             ctx->act |= MM_MODEM_ACCESS_TECHNOLOGY_EVDO0;
         } else if (ctx->hdr_revision == QCDM_HDR_REV_A) {
-            mm_dbg ("Novatel Modem Snapshot EVDO revision: A");
+            mm_obj_dbg (self, "modem snapshot EVDO revision: A");
             ctx->act &= ~MM_IFACE_MODEM_CDMA_ALL_EVDO_ACCESS_TECHNOLOGIES_MASK;
             ctx->act |= MM_MODEM_ACCESS_TECHNOLOGY_EVDOA;
         } else
-            mm_dbg ("Novatel Modem Snapshot EVDO revision: %d (unknown)", ctx->hdr_revision);
+            mm_obj_dbg (self, "modem snapshot EVDO revision: %d (unknown)", ctx->hdr_revision);
     }
 
     *access_technologies = ctx->act;
@@ -820,7 +821,6 @@
 {
     GTask *task;
 
-    mm_dbg ("loading signal quality...");
     task = g_task_new (self, NULL, callback, user_data);
 
     /* 3GPP modems can just run parent's signal quality loading */
@@ -865,7 +865,7 @@
     if (!response)
         g_task_return_error (task, error);
     else {
-        mm_dbg ("Current profile information retrieved: %s", response);
+        mm_obj_dbg (self, "current profile information retrieved: %s", response);
         g_task_return_boolean (task, TRUE);
     }
     g_object_unref (task);
@@ -1044,14 +1044,14 @@
 
     switch (ctx->step) {
     case CDMA_ACTIVATION_STEP_FIRST:
-        mm_dbg ("Launching manual activation...");
+        mm_obj_dbg (self, "launching manual activation...");
         ctx->step++;
         /* fall-through */
 
     case CDMA_ACTIVATION_STEP_REQUEST_ACTIVATION: {
         gchar *command;
 
-        mm_info ("Activation step [1/5]: setting up activation details");
+        mm_obj_info (self, "activation step [1/5]: setting up activation details");
         command = g_strdup_printf ("$NWACTIVATION=%s,%s,%s",
                                    mm_cdma_manual_activation_properties_get_spc (ctx->properties),
                                    mm_cdma_manual_activation_properties_get_mdn (ctx->properties),
@@ -1067,7 +1067,7 @@
     }
 
     case CDMA_ACTIVATION_STEP_OTA_UPDATE:
-        mm_info ("Activation step [2/5]: starting OTA activation");
+        mm_obj_info (self, "activation step [2/5]: starting OTA activation");
         mm_base_modem_at_command (MM_BASE_MODEM (self),
                                   "+IOTA=1",
                                   20,
@@ -1077,7 +1077,7 @@
         return;
 
     case CDMA_ACTIVATION_STEP_PRL_UPDATE:
-        mm_info ("Activation step [3/5]: starting PRL update");
+        mm_obj_info (self, "activation step [3/5]: starting PRL update");
         mm_base_modem_at_command (MM_BASE_MODEM (self),
                                   "+IOTA=2",
                                   20,
@@ -1087,7 +1087,7 @@
         return;
 
     case CDMA_ACTIVATION_STEP_WAIT_UNTIL_FINISHED:
-        mm_info ("Activation step [4/5]: checking activation process status");
+        mm_obj_info (self, "activation step [4/5]: checking activation process status");
         mm_base_modem_at_command (MM_BASE_MODEM (self),
                                   "+IOTA?",
                                   20,
@@ -1097,7 +1097,7 @@
         return;
 
     case CDMA_ACTIVATION_STEP_LAST:
-        mm_info ("Activation step [5/5]: activation process finished");
+        mm_obj_info (self, "activation step [5/5]: activation process finished");
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
         return;
@@ -1253,18 +1253,22 @@
 
 static void
 reg_eri_6500_cb (MMPortSerialQcdm *port,
-                 GAsyncResult *res,
-                 GTask *task)
+                 GAsyncResult     *res,
+                 GTask            *task)
 {
-    DetailedRegistrationStateContext *ctx = g_task_get_task_data (task);
-    GError *error = NULL;
-    GByteArray *response;
-    QcdmResult *result;
+    MMBroadbandModemNovatel          *self;
+    DetailedRegistrationStateContext *ctx;
+    GError                           *error = NULL;
+    GByteArray                       *response;
+    QcdmResult                       *result;
+
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     response = mm_port_serial_qcdm_command_finish (port, res, &error);
     if (error) {
         /* Just ignore the error and complete with the input info */
-        mm_dbg ("Couldn't run QCDM MSM6500 ERI: '%s'", error->message);
+        mm_obj_dbg (self, "couldn't run QCDM MSM6500 ERI: %s", error->message);
         g_error_free (error);
         goto done;
     }
@@ -1286,16 +1290,20 @@
                  GAsyncResult *res,
                  GTask *task)
 {
-    DetailedRegistrationStateContext *ctx = g_task_get_task_data (task);
-    GError *error = NULL;
-    GByteArray *response;
-    GByteArray *nweri;
-    QcdmResult *result;
+    MMBroadbandModemNovatel          *self;
+    DetailedRegistrationStateContext *ctx;
+    GError                           *error = NULL;
+    GByteArray                       *response;
+    GByteArray                       *nweri;
+    QcdmResult                       *result;
+
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     response = mm_port_serial_qcdm_command_finish (port, res, &error);
     if (error) {
         /* Just ignore the error and complete with the input info */
-        mm_dbg ("Couldn't run QCDM MSM6800 ERI: '%s'", error->message);
+        mm_obj_dbg (self, "couldn't run QCDM MSM6800 ERI: %s", error->message);
         g_error_free (error);
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
@@ -1350,7 +1358,7 @@
     ctx->port = mm_base_modem_get_port_qcdm (MM_BASE_MODEM (self));
     if (!ctx->port) {
         /* Ignore errors and use non-detailed registration state */
-        mm_dbg ("No available QCDM port.");
+        mm_obj_dbg (self, "no available QCDM port");
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
         return;
@@ -1358,7 +1366,7 @@
 
     if (!mm_port_serial_open (MM_PORT_SERIAL (ctx->port), &error)) {
         /* Ignore errors and use non-detailed registration state */
-        mm_dbg ("Couldn't open QCDM port: %s", error->message);
+        mm_obj_dbg (self, "couldn't open QCDM port: %s", error->message);
         g_error_free (error);
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
diff --git a/plugins/novatel/mm-common-novatel.c b/plugins/novatel/mm-common-novatel.c
index 6932f5a..b6b0e27 100644
--- a/plugins/novatel/mm-common-novatel.c
+++ b/plugins/novatel/mm-common-novatel.c
@@ -14,7 +14,7 @@
  */
 
 #include "mm-common-novatel.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 /*****************************************************************************/
 /* Custom init */
@@ -44,30 +44,27 @@
 
 static void
 nwdmat_ready (MMPortSerialAt *port,
-              GAsyncResult *res,
-              GTask* task)
+              GAsyncResult   *res,
+              GTask          *task)
 {
-    GError *error = NULL;
+    g_autoptr(GError)  error = NULL;
+    MMPortProbe       *probe;
+
+    probe = g_task_get_source_object (task);
 
     mm_port_serial_at_command_finish (port, res, &error);
     if (error) {
-        if (g_error_matches (error,
-                             MM_SERIAL_ERROR,
-                             MM_SERIAL_ERROR_RESPONSE_TIMEOUT)) {
+        if (g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_RESPONSE_TIMEOUT)) {
             custom_init_step (task);
-            goto out;
+            return;
         }
 
-        mm_dbg ("(Novatel) Error flipping secondary ports to AT mode: %s", error->message);
+        mm_obj_dbg (probe, "error flipping secondary ports to AT mode: %s", error->message);
     }
 
     /* Finish custom_init */
     g_task_return_boolean (task, TRUE);
     g_object_unref (task);
-
-out:
-    if (error)
-        g_error_free (error);
 }
 
 static gboolean
@@ -81,24 +78,21 @@
 custom_init_step (GTask *task)
 {
     CustomInitContext *ctx;
-    MMPortProbe *probe;
+    MMPortProbe       *probe;
 
-    ctx = g_task_get_task_data (task);
+    probe = g_task_get_source_object (task);
+    ctx   = g_task_get_task_data (task);
 
     /* If cancelled, end */
     if (g_task_return_error_if_cancelled (task)) {
-        mm_dbg ("(Novatel) no need to keep on running custom init in (%s)",
-                mm_port_get_device (MM_PORT (ctx->port)));
+        mm_obj_dbg (probe, "no need to keep on running custom init");
         g_object_unref (task);
         return;
     }
 
-    probe = g_task_get_source_object (task);
-
     /* If device has a QMI port, don't run $NWDMAT */
     if (mm_port_probe_list_has_qmi_port (mm_device_peek_port_probe_list (mm_port_probe_peek_device (probe)))) {
-        mm_dbg ("(Novatel) no need to run custom init in (%s): device has QMI port",
-                mm_port_get_device (MM_PORT (ctx->port)));
+        mm_obj_dbg (probe, "no need to run custom init: device has QMI port");
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
         return;
@@ -124,8 +118,7 @@
     }
 
     /* Finish custom_init */
-    mm_dbg ("(Novatel) couldn't flip secondary port to AT in (%s): all retries consumed",
-            mm_port_get_device (MM_PORT (ctx->port)));
+    mm_obj_dbg (probe, "couldn't flip secondary port to AT: all retries consumed");
     g_task_return_boolean (task, TRUE);
     g_object_unref (task);
 }
diff --git a/plugins/novatel/mm-plugin-novatel-lte.c b/plugins/novatel/mm-plugin-novatel-lte.c
index 9182c57..18aac32 100644
--- a/plugins/novatel/mm-plugin-novatel-lte.c
+++ b/plugins/novatel/mm-plugin-novatel-lte.c
@@ -26,7 +26,6 @@
 #include "mm-plugin-novatel-lte.h"
 #include "mm-private-boxed-types.h"
 #include "mm-broadband-modem-novatel-lte.h"
-#include "mm-log.h"
 
 G_DEFINE_TYPE (MMPluginNovatelLte, mm_plugin_novatel_lte, MM_TYPE_PLUGIN)
 
@@ -60,7 +59,7 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_NOVATEL_LTE,
-                      MM_PLUGIN_NAME,                "Novatel LTE",
+                      MM_PLUGIN_NAME,                MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS,  subsystems,
                       MM_PLUGIN_ALLOWED_PRODUCT_IDS, products,
                       MM_PLUGIN_ALLOWED_SINGLE_AT,   TRUE,
diff --git a/plugins/novatel/mm-plugin-novatel.c b/plugins/novatel/mm-plugin-novatel.c
index 292f758..f90a878 100644
--- a/plugins/novatel/mm-plugin-novatel.c
+++ b/plugins/novatel/mm-plugin-novatel.c
@@ -31,7 +31,7 @@
 #include "mm-common-novatel.h"
 #include "mm-private-boxed-types.h"
 #include "mm-broadband-modem-novatel.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 #if defined WITH_QMI
 #include "mm-broadband-modem-qmi.h"
@@ -55,7 +55,7 @@
 {
 #if defined WITH_QMI
     if (mm_port_probe_list_has_qmi_port (probes)) {
-        mm_dbg ("QMI-powered Novatel modem found...");
+        mm_obj_dbg (self, "QMI-powered Novatel modem found...");
         return MM_BASE_MODEM (mm_broadband_modem_qmi_new (uid,
                                                           drivers,
                                                           mm_plugin_get_name (self),
@@ -87,7 +87,7 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_NOVATEL,
-                      MM_PLUGIN_NAME,                  "Novatel",
+                      MM_PLUGIN_NAME,                  MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS,    subsystems,
                       MM_PLUGIN_ALLOWED_VENDOR_IDS,    vendors,
                       MM_PLUGIN_FORBIDDEN_PRODUCT_IDS, forbidden_products,
diff --git a/plugins/novatel/mm-sim-novatel-lte.c b/plugins/novatel/mm-sim-novatel-lte.c
index 1088d0d..676db56 100644
--- a/plugins/novatel/mm-sim-novatel-lte.c
+++ b/plugins/novatel/mm-sim-novatel-lte.c
@@ -23,7 +23,6 @@
 #include <ModemManager.h>
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
-#include "mm-log.h"
 #include "mm-modem-helpers.h"
 #include "mm-base-modem-at.h"
 
@@ -172,7 +171,6 @@
                   MM_BASE_SIM_MODEM, &modem,
                   NULL);
 
-    mm_dbg ("loading (Novatel LTE) IMSI...");
     mm_base_modem_at_command (
         modem,
         "+CRSM=176,28423,0,0,9",
diff --git a/plugins/option/mm-broadband-bearer-hso.c b/plugins/option/mm-broadband-bearer-hso.c
index d626a64..3ca5cd7 100644
--- a/plugins/option/mm-broadband-bearer-hso.c
+++ b/plugins/option/mm-broadband-bearer-hso.c
@@ -30,7 +30,7 @@
 
 #include "mm-base-modem-at.h"
 #include "mm-broadband-bearer-hso.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-modem-helpers.h"
 #include "mm-daemon-enums-types.h"
 
@@ -380,14 +380,13 @@
     Dial3gppContext *ctx;
     GError          *error = NULL;
 
-    task = self->priv->connect_pending;
-    self->priv->connect_pending = NULL;
+    task = g_steal_pointer (&self->priv->connect_pending);
 
     /* Try to recover the connection task. If none found, it means the
      * task was already completed and we have nothing else to do.
      * But note that we won't take owneship of the task yet! */
     if (!task) {
-        mm_dbg ("Connection context was finished already by an unsolicited message");
+        mm_obj_dbg (self, "connection context was finished already by an unsolicited message");
         /* Run _finish() to finalize the async call, even if we don't care
          * about the result */
         mm_base_modem_at_command_full_finish (modem, res, NULL);
@@ -517,7 +516,7 @@
 
     /* Both user and password are required; otherwise firmware returns an error */
     if (!user || !password || allowed_auth == MM_BEARER_ALLOWED_AUTH_NONE) {
-        mm_dbg ("Not using authentication");
+        mm_obj_dbg (self, "not using authentication");
         command = g_strdup_printf ("%s=%d,0",
                                    auth_commands[ctx->auth_idx],
                                    ctx->cid);
@@ -527,13 +526,13 @@
         guint  hso_auth;
 
         if (allowed_auth == MM_BEARER_ALLOWED_AUTH_UNKNOWN) {
-            mm_dbg ("Using default (PAP) authentication method");
+            mm_obj_dbg (self, "using default (PAP) authentication method");
             hso_auth = 1;
         } else if (allowed_auth & MM_BEARER_ALLOWED_AUTH_PAP) {
-            mm_dbg ("Using PAP authentication method");
+            mm_obj_dbg (self, "using PAP authentication method");
             hso_auth = 1;
         } else if (allowed_auth & MM_BEARER_ALLOWED_AUTH_CHAP) {
-            mm_dbg ("Using CHAP authentication method");
+            mm_obj_dbg (self, "using CHAP authentication method");
             hso_auth = 2;
         } else {
             gchar *str;
@@ -639,16 +638,19 @@
 }
 
 static void
-disconnect_owancall_ready (MMBaseModem *modem,
+disconnect_owancall_ready (MMBaseModem  *modem,
                            GAsyncResult *res,
-                           GTask *task)
+                           GTask        *task)
 {
-    GError *error = NULL;
+    MMBroadbandBearerHso *self;
+    GError               *error = NULL;
+
+    self = g_task_get_source_object (task);
 
     /* Ignore errors for now */
     mm_base_modem_at_command_full_finish (modem, res, &error);
     if (error) {
-        mm_dbg ("Disconnection failed (not fatal): %s", error->message);
+        mm_obj_dbg (self, "disconnection failed (not fatal): %s", error->message);
         g_error_free (error);
     }
 
@@ -711,8 +713,8 @@
         return;
     }
 
-    mm_dbg ("Received spontaneous _OWANCALL (%s)",
-            mm_bearer_connection_status_get_string (status));
+    mm_obj_dbg (self, "received spontaneous _OWANCALL (%s)",
+                mm_bearer_connection_status_get_string (status));
 
     if (status == MM_BEARER_CONNECTION_STATUS_DISCONNECTED) {
         /* If no connection attempt on-going, make sure we mark ourselves as
diff --git a/plugins/option/mm-broadband-modem-hso.c b/plugins/option/mm-broadband-modem-hso.c
index 3623d84..0089944 100644
--- a/plugins/option/mm-broadband-modem-hso.c
+++ b/plugins/option/mm-broadband-modem-hso.c
@@ -25,7 +25,7 @@
 
 #include "ModemManager.h"
 #include "mm-modem-helpers.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-errors-types.h"
 #include "mm-iface-modem.h"
 #include "mm-iface-modem-3gpp.h"
@@ -111,7 +111,7 @@
 
     if (mm_bearer_properties_get_ip_type (properties) &
         (MM_BEARER_IP_FAMILY_IPV6 | MM_BEARER_IP_FAMILY_IPV4V6)) {
-        mm_dbg ("Creating generic bearer (IPv6 requested)...");
+        mm_obj_dbg (self, "creating generic bearer (IPv6 requested)...");
         mm_broadband_bearer_new (MM_BROADBAND_MODEM (self),
                                  properties,
                                  NULL, /* cancellable */
@@ -120,7 +120,7 @@
         return;
     }
 
-    mm_dbg ("Creating HSO bearer...");
+    mm_obj_dbg (self, "creating HSO bearer...");
     mm_broadband_bearer_hso_new (MM_BROADBAND_MODEM_HSO (self),
                                  properties,
                                  NULL, /* cancellable */
@@ -150,7 +150,6 @@
 
     response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
     if (!response) {
-        mm_dbg ("Couldn't query unlock retries: '%s'", error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
diff --git a/plugins/option/mm-broadband-modem-option.c b/plugins/option/mm-broadband-modem-option.c
index eaf5a00..b266dac 100644
--- a/plugins/option/mm-broadband-modem-option.c
+++ b/plugins/option/mm-broadband-modem-option.c
@@ -25,7 +25,7 @@
 
 #include "ModemManager.h"
 #include "mm-modem-helpers.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-errors-types.h"
 #include "mm-iface-modem.h"
 #include "mm-iface-modem-3gpp.h"
@@ -111,7 +111,7 @@
     g_array_append_val (combinations, mode);
 
     /* Filter out those unsupported modes */
-    filtered = mm_filter_supported_modes (all, combinations);
+    filtered = mm_filter_supported_modes (all, combinations, self);
     g_array_unref (all);
     g_array_unref (combinations);
 
@@ -712,7 +712,6 @@
     if (comma)
         *comma = '\0';
 
-    mm_dbg ("loaded IMEI: %s", imei);
     return imei;
 }
 
@@ -721,7 +720,6 @@
                       GAsyncReadyCallback callback,
                       gpointer user_data)
 {
-    mm_dbg ("loading (Option) IMEI...");
     mm_base_modem_at_command (MM_BASE_MODEM (self),
                               "+CGSN",
                               3,
diff --git a/plugins/option/mm-plugin-hso.c b/plugins/option/mm-plugin-hso.c
index a842b0c..dbc41c1 100644
--- a/plugins/option/mm-plugin-hso.c
+++ b/plugins/option/mm-plugin-hso.c
@@ -24,7 +24,7 @@
 #include "mm-private-boxed-types.h"
 #include "mm-plugin-hso.h"
 #include "mm-broadband-modem-hso.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 G_DEFINE_TYPE (MMPluginHso, mm_plugin_hso, MM_TYPE_PLUGIN)
 
@@ -70,7 +70,7 @@
 
         hsotype_path = g_build_filename (sysfs_path, "hsotype", NULL);
         if (g_file_get_contents (hsotype_path, &contents, NULL, NULL)) {
-            mm_dbg ("HSO port type %s: %s", hsotype_path, contents);
+            mm_obj_dbg (probe, "HSO port type %s: %s", hsotype_path, contents);
             if (g_str_has_prefix (contents, "Control")) {
                 g_object_set_data (G_OBJECT (probe), TAG_HSO_AT_CONTROL, GUINT_TO_POINTER (TRUE));
                 mm_port_probe_set_result_at (probe, TRUE);
@@ -176,7 +176,7 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_HSO,
-                      MM_PLUGIN_NAME,               "Option High-Speed",
+                      MM_PLUGIN_NAME,               MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems,
                       MM_PLUGIN_ALLOWED_DRIVERS,    drivers,
                       MM_PLUGIN_ALLOWED_AT,         TRUE,
diff --git a/plugins/option/mm-plugin-option.c b/plugins/option/mm-plugin-option.c
index 9396537..3ba183e 100644
--- a/plugins/option/mm-plugin-option.c
+++ b/plugins/option/mm-plugin-option.c
@@ -97,7 +97,7 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_OPTION,
-                      MM_PLUGIN_NAME,                "Option",
+                      MM_PLUGIN_NAME,                MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS,  subsystems,
                       MM_PLUGIN_ALLOWED_DRIVERS,     drivers,
                       MM_PLUGIN_ALLOWED_VENDOR_IDS,  vendor_ids,
diff --git a/plugins/pantech/mm-broadband-modem-pantech.c b/plugins/pantech/mm-broadband-modem-pantech.c
index cd18e14..bc35b28 100644
--- a/plugins/pantech/mm-broadband-modem-pantech.c
+++ b/plugins/pantech/mm-broadband-modem-pantech.c
@@ -24,7 +24,6 @@
 #include "ModemManager.h"
 #include "mm-iface-modem.h"
 #include "mm-iface-modem-messaging.h"
-#include "mm-log.h"
 #include "mm-errors-types.h"
 #include "mm-broadband-modem-pantech.h"
 #include "mm-sim-pantech.h"
diff --git a/plugins/pantech/mm-plugin-pantech.c b/plugins/pantech/mm-plugin-pantech.c
index 66eb645..5301ea9 100644
--- a/plugins/pantech/mm-plugin-pantech.c
+++ b/plugins/pantech/mm-plugin-pantech.c
@@ -19,7 +19,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-plugin-pantech.h"
 #include "mm-broadband-modem-pantech.h"
 
@@ -85,7 +85,7 @@
 {
 #if defined WITH_QMI
     if (mm_port_probe_list_has_qmi_port (probes)) {
-        mm_dbg ("QMI-powered Pantech modem found...");
+        mm_obj_dbg (self, "QMI-powered Pantech modem found...");
         return MM_BASE_MODEM (mm_broadband_modem_qmi_new (uid,
                                                           drivers,
                                                           mm_plugin_get_name (self),
@@ -135,7 +135,7 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_PANTECH,
-                      MM_PLUGIN_NAME,               "Pantech",
+                      MM_PLUGIN_NAME,               MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems,
                       MM_PLUGIN_ALLOWED_VENDOR_IDS, vendor_ids,
                       MM_PLUGIN_ALLOWED_AT,         TRUE,
diff --git a/plugins/quectel/77-mm-quectel-port-types.rules b/plugins/quectel/77-mm-quectel-port-types.rules
index 7368c13..7113858 100644
--- a/plugins/quectel/77-mm-quectel-port-types.rules
+++ b/plugins/quectel/77-mm-quectel-port-types.rules
@@ -37,4 +37,14 @@
 ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0296", ENV{.MM_USBIFNUM}=="02", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1"
 ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0296", ENV{.MM_USBIFNUM}=="03", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1"
 
+# Quectel EC25/EG25
+#  ttyUSB0 (if #0): QCDM/DIAG port
+#  ttyUSB1 (if #1): GPS data port
+#  ttyUSB2 (if #2): AT primary port
+#  ttyUSB3 (if #3): AT secondary port
+ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0125", ENV{.MM_USBIFNUM}=="00", ENV{ID_MM_PORT_TYPE_QCDM}="1"
+ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0125", ENV{.MM_USBIFNUM}=="01", ENV{ID_MM_PORT_TYPE_GPS}="1"
+ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0125", ENV{.MM_USBIFNUM}=="02", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1"
+ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0125", ENV{.MM_USBIFNUM}=="03", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1"
+
 LABEL="mm_quectel_port_types_end"
diff --git a/plugins/quectel/mm-broadband-modem-qmi-quectel.c b/plugins/quectel/mm-broadband-modem-qmi-quectel.c
index 14adf98..96eda0e 100644
--- a/plugins/quectel/mm-broadband-modem-qmi-quectel.c
+++ b/plugins/quectel/mm-broadband-modem-qmi-quectel.c
@@ -19,10 +19,12 @@
 #include "mm-shared-quectel.h"
 #include "mm-iface-modem-firmware.h"
 
+static void iface_modem_init          (MMIfaceModem *iface);
 static void shared_quectel_init       (MMSharedQuectel      *iface);
 static void iface_modem_firmware_init (MMIfaceModemFirmware *iface);
 
 G_DEFINE_TYPE_EXTENDED (MMBroadbandModemQmiQuectel, mm_broadband_modem_qmi_quectel, MM_TYPE_BROADBAND_MODEM_QMI, 0,
+                        G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init)
                         G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_FIRMWARE, iface_modem_firmware_init)
                         G_IMPLEMENT_INTERFACE (MM_TYPE_SHARED_QUECTEL, shared_quectel_init))
 
@@ -50,6 +52,13 @@
 }
 
 static void
+iface_modem_init (MMIfaceModem *iface)
+{
+    iface->setup_sim_hot_swap = mm_shared_quectel_setup_sim_hot_swap;
+    iface->setup_sim_hot_swap_finish = mm_shared_quectel_setup_sim_hot_swap_finish;
+}
+
+static void
 iface_modem_firmware_init (MMIfaceModemFirmware *iface)
 {
     iface->load_update_settings = mm_shared_quectel_firmware_load_update_settings;
diff --git a/plugins/quectel/mm-broadband-modem-quectel.c b/plugins/quectel/mm-broadband-modem-quectel.c
index 6a43a87..6dfa5bb 100644
--- a/plugins/quectel/mm-broadband-modem-quectel.c
+++ b/plugins/quectel/mm-broadband-modem-quectel.c
@@ -19,10 +19,12 @@
 #include "mm-shared-quectel.h"
 #include "mm-iface-modem-firmware.h"
 
+static void iface_modem_init          (MMIfaceModem *iface);
 static void shared_quectel_init       (MMSharedQuectel      *iface);
 static void iface_modem_firmware_init (MMIfaceModemFirmware *iface);
 
 G_DEFINE_TYPE_EXTENDED (MMBroadbandModemQuectel, mm_broadband_modem_quectel, MM_TYPE_BROADBAND_MODEM, 0,
+                        G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init)
                         G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_FIRMWARE, iface_modem_firmware_init)
                         G_IMPLEMENT_INTERFACE (MM_TYPE_SHARED_QUECTEL, shared_quectel_init))
 
@@ -57,6 +59,13 @@
 }
 
 static void
+iface_modem_init (MMIfaceModem *iface)
+{
+    iface->setup_sim_hot_swap = mm_shared_quectel_setup_sim_hot_swap;
+    iface->setup_sim_hot_swap_finish = mm_shared_quectel_setup_sim_hot_swap_finish;
+}
+
+static void
 shared_quectel_init (MMSharedQuectel *iface)
 {
 }
diff --git a/plugins/quectel/mm-plugin-quectel.c b/plugins/quectel/mm-plugin-quectel.c
index 383b08c..12e4612 100644
--- a/plugins/quectel/mm-plugin-quectel.c
+++ b/plugins/quectel/mm-plugin-quectel.c
@@ -19,7 +19,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-plugin-quectel.h"
 #include "mm-broadband-modem-quectel.h"
 
@@ -45,7 +45,7 @@
 {
 #if defined WITH_QMI
     if (mm_port_probe_list_has_qmi_port (probes)) {
-        mm_dbg ("QMI-powered Quectel modem found...");
+        mm_obj_dbg (self, "QMI-powered Quectel modem found...");
         return MM_BASE_MODEM (mm_broadband_modem_qmi_quectel_new (uid,
                                                                   drivers,
                                                                   mm_plugin_get_name (self),
@@ -72,7 +72,7 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_QUECTEL,
-                      MM_PLUGIN_NAME,                   "Quectel",
+                      MM_PLUGIN_NAME,                   MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS,     subsystems,
                       MM_PLUGIN_ALLOWED_VENDOR_IDS,     vendor_ids,
                       MM_PLUGIN_ALLOWED_VENDOR_STRINGS, vendor_strings,
diff --git a/plugins/quectel/mm-shared-quectel.c b/plugins/quectel/mm-shared-quectel.c
index f451026..76107e7 100644
--- a/plugins/quectel/mm-shared-quectel.c
+++ b/plugins/quectel/mm-shared-quectel.c
@@ -21,6 +21,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
+#include "mm-log-object.h"
 #include "mm-iface-modem-firmware.h"
 #include "mm-base-modem.h"
 #include "mm-base-modem-at.h"
@@ -72,6 +73,94 @@
 }
 
 /*****************************************************************************/
+/* "+QUSIM: 1" URC is emitted by Quectel modems after the USIM has been
+ * (re)initialized. We register a handler for this URC and perform a check
+ * for SIM swap when it is encountered. The motivation for this is to detect
+ * M2M eUICC profile switches. According to SGP.02 chapter 3.2.1, the eUICC
+ * shall trigger a REFRESH operation with eUICC reset when a new profile is
+ * enabled. The +QUSIM URC appears after the eUICC has restarted and can act
+ * as a trigger for profile switch check. This should basically be handled
+ * the same as a physical SIM swap, so the existing SIM hot swap mechanism
+ * is used.
+ */
+
+static void
+quectel_qusim_check_for_sim_swap_ready (MMIfaceModem *self,
+                                        GAsyncResult *res)
+{
+    GError *error = NULL;
+
+    if (!MM_IFACE_MODEM_GET_INTERFACE (self)->check_for_sim_swap_finish (self, res, &error)) {
+        mm_obj_warn (self, "couldn't check SIM swap: %s", error->message);
+        g_error_free (error);
+    } else
+        mm_obj_dbg (self, "check SIM swap completed");
+}
+
+static void
+quectel_qusim_unsolicited_handler (MMPortSerialAt *port,
+                                   GMatchInfo *match_info,
+                                   MMIfaceModem* self)
+{
+    if (MM_IFACE_MODEM_GET_INTERFACE (self)->check_for_sim_swap &&
+        MM_IFACE_MODEM_GET_INTERFACE (self)->check_for_sim_swap_finish) {
+        mm_obj_dbg (self, "checking SIM swap");
+        MM_IFACE_MODEM_GET_INTERFACE (self)->check_for_sim_swap (
+            self,
+            (GAsyncReadyCallback)quectel_qusim_check_for_sim_swap_ready,
+            NULL);
+    }
+}
+
+gboolean
+mm_shared_quectel_setup_sim_hot_swap_finish (MMIfaceModem *self,
+                                             GAsyncResult *res,
+                                             GError **error)
+{
+    return g_task_propagate_boolean (G_TASK (res), error);
+}
+
+void
+mm_shared_quectel_setup_sim_hot_swap (MMIfaceModem *self,
+                                      GAsyncReadyCallback callback,
+                                      gpointer user_data)
+{
+    MMPortSerialAt *port_primary;
+    MMPortSerialAt *port_secondary;
+    GTask *task;
+    GRegex *pattern;
+
+    task = g_task_new (self, NULL, callback, user_data);
+
+    port_primary = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));
+    port_secondary = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self));
+
+    pattern = g_regex_new ("\\+QUSIM:\\s*1\\r\\n", G_REGEX_RAW, 0, NULL);
+    g_assert (pattern);
+
+    if (port_primary)
+        mm_port_serial_at_add_unsolicited_msg_handler (
+            port_primary,
+            pattern,
+            (MMPortSerialAtUnsolicitedMsgFn)quectel_qusim_unsolicited_handler,
+            self,
+            NULL);
+
+    if (port_secondary)
+        mm_port_serial_at_add_unsolicited_msg_handler (
+            port_secondary,
+            pattern,
+            (MMPortSerialAtUnsolicitedMsgFn)quectel_qusim_unsolicited_handler,
+            self,
+            NULL);
+
+    g_regex_unref (pattern);
+    mm_obj_dbg (self, "+QUSIM detection set up");
+    g_task_return_boolean (task, TRUE);
+    g_object_unref (task);
+}
+
+/*****************************************************************************/
 
 static void
 shared_quectel_init (gpointer g_iface)
diff --git a/plugins/quectel/mm-shared-quectel.h b/plugins/quectel/mm-shared-quectel.h
index 4ebcfd6..22ee8be 100644
--- a/plugins/quectel/mm-shared-quectel.h
+++ b/plugins/quectel/mm-shared-quectel.h
@@ -45,5 +45,11 @@
 MMFirmwareUpdateSettings *mm_shared_quectel_firmware_load_update_settings_finish (MMIfaceModemFirmware  *self,
                                                                                   GAsyncResult          *res,
                                                                                   GError               **error);
+void                      mm_shared_quectel_setup_sim_hot_swap (MMIfaceModem *self,
+                                                                GAsyncReadyCallback callback,
+                                                                gpointer user_data);
+gboolean                  mm_shared_quectel_setup_sim_hot_swap_finish (MMIfaceModem *self,
+                                                                       GAsyncResult *res,
+                                                                       GError **error);
 
 #endif  /* MM_SHARED_QUECTEL_H */
diff --git a/plugins/samsung/mm-broadband-modem-samsung.c b/plugins/samsung/mm-broadband-modem-samsung.c
index 9f6fb37..b0eb17b 100644
--- a/plugins/samsung/mm-broadband-modem-samsung.c
+++ b/plugins/samsung/mm-broadband-modem-samsung.c
@@ -28,9 +28,8 @@
 #include "mm-broadband-modem-samsung.h"
 #include "mm-broadband-bearer-icera.h"
 #include "mm-modem-helpers.h"
-#include "mm-log.h"
 
-G_DEFINE_TYPE (MMBroadbandModemSamsung, mm_broadband_modem_samsung, MM_TYPE_BROADBAND_MODEM_ICERA);
+G_DEFINE_TYPE (MMBroadbandModemSamsung, mm_broadband_modem_samsung, MM_TYPE_BROADBAND_MODEM_ICERA)
 
 /*****************************************************************************/
 /* Setup ports (Broadband modem class) */
diff --git a/plugins/samsung/mm-plugin-samsung.c b/plugins/samsung/mm-plugin-samsung.c
index e78f689..18b0b9d 100644
--- a/plugins/samsung/mm-plugin-samsung.c
+++ b/plugins/samsung/mm-plugin-samsung.c
@@ -27,7 +27,6 @@
 #include "mm-plugin-samsung.h"
 #include "mm-private-boxed-types.h"
 #include "mm-broadband-modem-samsung.h"
-#include "mm-log.h"
 
 G_DEFINE_TYPE (MMPluginSamsung, mm_plugin_samsung, MM_TYPE_PLUGIN)
 
@@ -61,7 +60,7 @@
                                                { 0, 0 } };
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_SAMSUNG,
-                      MM_PLUGIN_NAME,                "Samsung",
+                      MM_PLUGIN_NAME,                MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS,  subsystems,
                       MM_PLUGIN_ALLOWED_PRODUCT_IDS, products,
                       MM_PLUGIN_ALLOWED_AT,          TRUE,
diff --git a/plugins/sierra/mm-broadband-bearer-sierra.c b/plugins/sierra/mm-broadband-bearer-sierra.c
index cdfd63e..24bde73 100644
--- a/plugins/sierra/mm-broadband-bearer-sierra.c
+++ b/plugins/sierra/mm-broadband-bearer-sierra.c
@@ -29,7 +29,7 @@
 
 #include "mm-base-modem-at.h"
 #include "mm-broadband-bearer-sierra.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-modem-helpers.h"
 #include "mm-modem-helpers-sierra.h"
 
@@ -327,7 +327,7 @@
             allowed_auth = mm_bearer_properties_get_allowed_auth (mm_base_bearer_peek_config (MM_BASE_BEARER (self)));
 
             if (!user || !password || allowed_auth == MM_BEARER_ALLOWED_AUTH_NONE) {
-                mm_dbg ("Not using authentication");
+                mm_obj_dbg (self, "not using authentication");
                 if (self->priv->is_icera)
                     command = g_strdup_printf ("%%IPDPCFG=%d,0,0,\"\",\"\"", ctx->cid);
                 else
@@ -338,13 +338,13 @@
                 guint sierra_auth;
 
                 if (allowed_auth == MM_BEARER_ALLOWED_AUTH_UNKNOWN) {
-                    mm_dbg ("Using default (PAP) authentication method");
+                    mm_obj_dbg (self, "using default (PAP) authentication method");
                     sierra_auth = 1;
                 } else if (allowed_auth & MM_BEARER_ALLOWED_AUTH_PAP) {
-                    mm_dbg ("Using PAP authentication method");
+                    mm_obj_dbg (self, "using PAP authentication method");
                     sierra_auth = 1;
                 } else if (allowed_auth & MM_BEARER_ALLOWED_AUTH_CHAP) {
-                    mm_dbg ("Using CHAP authentication method");
+                    mm_obj_dbg (self, "using CHAP authentication method");
                     sierra_auth = 2;
                 } else {
                     gchar *str;
@@ -479,13 +479,13 @@
 
 static void
 parent_disconnect_3gpp_ready (MMBroadbandBearer *self,
-                              GAsyncResult *res,
-                              GTask *task)
+                              GAsyncResult      *res,
+                              GTask             *task)
 {
     GError *error = NULL;
 
     if (!MM_BROADBAND_BEARER_CLASS (mm_broadband_bearer_sierra_parent_class)->disconnect_3gpp_finish (self, res, &error)) {
-        mm_dbg ("Parent disconnection failed (not fatal): %s", error->message);
+        mm_obj_dbg (self, "parent disconnection failed (not fatal): %s", error->message);
         g_error_free (error);
     }
 
@@ -494,16 +494,19 @@
 }
 
 static void
-disconnect_scact_ready (MMBaseModem *modem,
+disconnect_scact_ready (MMBaseModem  *modem,
                         GAsyncResult *res,
-                        GTask *task)
+                        GTask        *task)
 {
-    GError *error = NULL;
+    MMBroadbandBearerSierra *self;
+    GError                  *error = NULL;
+
+    self = g_task_get_source_object (task);
 
     /* Ignore errors for now */
     mm_base_modem_at_command_full_finish (modem, res, &error);
     if (error) {
-        mm_dbg ("Disconnection failed (not fatal): %s", error->message);
+        mm_obj_dbg (self, "disconnection failed (not fatal): %s", error->message);
         g_error_free (error);
     }
 
diff --git a/plugins/sierra/mm-broadband-modem-sierra-icera.c b/plugins/sierra/mm-broadband-modem-sierra-icera.c
index 5749f55..796260d 100644
--- a/plugins/sierra/mm-broadband-modem-sierra-icera.c
+++ b/plugins/sierra/mm-broadband-modem-sierra-icera.c
@@ -27,7 +27,7 @@
 #include "mm-broadband-modem-sierra-icera.h"
 #include "mm-iface-modem.h"
 #include "mm-modem-helpers.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-common-sierra.h"
 #include "mm-broadband-bearer-sierra.h"
 
@@ -74,7 +74,7 @@
 
     task = g_task_new (self, NULL, callback, user_data);
 
-    mm_dbg ("Creating Sierra bearer...");
+    mm_obj_dbg (self, "creating sierra bearer...");
     mm_broadband_bearer_sierra_new (MM_BROADBAND_MODEM (self),
                                     properties,
                                     TRUE, /* is_icera */
diff --git a/plugins/sierra/mm-broadband-modem-sierra.c b/plugins/sierra/mm-broadband-modem-sierra.c
index c1ac89a..c08aec4 100644
--- a/plugins/sierra/mm-broadband-modem-sierra.c
+++ b/plugins/sierra/mm-broadband-modem-sierra.c
@@ -26,7 +26,7 @@
 #include "ModemManager.h"
 #include "mm-broadband-modem-sierra.h"
 #include "mm-base-modem-at.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-modem-helpers.h"
 #include "mm-errors-types.h"
 #include "mm-iface-modem.h"
@@ -108,7 +108,6 @@
                      GAsyncReadyCallback callback,
                      gpointer user_data)
 {
-    mm_dbg ("loading unlock retries (sierra)...");
     mm_base_modem_at_command (MM_BASE_MODEM (self),
                               "+CPINC?",
                               3,
@@ -589,7 +588,7 @@
     }
 
     /* Filter out those unsupported modes */
-    filtered = mm_filter_supported_modes (all, combinations);
+    filtered = mm_filter_supported_modes (all, combinations, self);
     g_array_unref (all);
     g_array_unref (combinations);
 
@@ -1004,7 +1003,7 @@
 
     /* MDNs are 10 digits in length */
     if (i != 10) {
-        mm_warn ("Failed to parse MDN: expected 10 digits, got %d", i);
+        mm_obj_warn (self, "failed to parse MDN: expected 10 digits, got %d", i);
         goto fallback;
     }
 
@@ -1029,7 +1028,6 @@
 {
     GTask *task;
 
-    mm_dbg ("loading own numbers (Sierra)...");
     task = g_task_new (self, NULL, callback, user_data);
 
     /* 3GPP modems can just run parent's own number loading */
@@ -1091,7 +1089,7 @@
 
     task = g_task_new (self, NULL, callback, user_data);
 
-    mm_dbg ("Creating Sierra bearer...");
+    mm_obj_dbg (self, "creating Sierra bearer...");
     mm_broadband_bearer_sierra_new (MM_BROADBAND_MODEM (self),
                                     properties,
                                     FALSE, /* is_icera */
@@ -1407,7 +1405,7 @@
         /* fall-through */
 
     case CDMA_AUTOMATIC_ACTIVATION_STEP_UNLOCK:
-        mm_info ("Activation step [1/4]: unlocking device");
+        mm_obj_info (self, "activation step [1/4]: unlocking device");
         mm_base_modem_at_command (MM_BASE_MODEM (self),
                                   "~NAMLCK=000000",
                                   20,
@@ -1419,7 +1417,7 @@
     case CDMA_AUTOMATIC_ACTIVATION_STEP_CDV: {
         gchar *command;
 
-        mm_info ("Activation step [2/4]: requesting OTASP");
+        mm_obj_info (self, "activation step [2/4]: requesting OTASP");
         command = g_strdup_printf ("+CDV%s", ctx->carrier_code);
         mm_base_modem_at_command (MM_BASE_MODEM (self),
                                   command,
@@ -1432,7 +1430,7 @@
     }
 
     case CDMA_AUTOMATIC_ACTIVATION_STEP_CHECK:
-        mm_info ("Activation step [3/4]: checking activation info");
+        mm_obj_info (self, "activation step [3/4]: checking activation info");
         mm_base_modem_at_command (MM_BASE_MODEM (self),
                                   "~NAMVAL?0",
                                   3,
@@ -1442,7 +1440,7 @@
         return;
 
     case CDMA_AUTOMATIC_ACTIVATION_STEP_LAST:
-        mm_info ("Activation step [4/4]: activation process finished");
+        mm_obj_info (self, "activation step [4/4]: activation process finished");
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
         return;
@@ -1539,7 +1537,7 @@
     case CDMA_MANUAL_ACTIVATION_STEP_SPC: {
         gchar *command;
 
-        mm_info ("Activation step [1/5]: unlocking device");
+        mm_obj_info (self, "activation step [1/5]: unlocking device");
         command = g_strdup_printf ("~NAMLCK=%s",
                                    mm_cdma_manual_activation_properties_get_spc (ctx->properties));
         mm_base_modem_at_command (MM_BASE_MODEM (self),
@@ -1555,7 +1553,7 @@
     case CDMA_MANUAL_ACTIVATION_STEP_MDN_MIN: {
         gchar *command;
 
-        mm_info ("Activation step [2/5]: setting MDN/MIN/SID");
+        mm_obj_info (self, "activation step [2/5]: setting MDN/MIN/SID");
         command = g_strdup_printf ("~NAMVAL=0,%s,%s,%" G_GUINT16_FORMAT ",65535",
                                    mm_cdma_manual_activation_properties_get_mdn (ctx->properties),
                                    mm_cdma_manual_activation_properties_get_min (ctx->properties),
@@ -1571,7 +1569,7 @@
     }
 
     case CDMA_MANUAL_ACTIVATION_STEP_OTASP:
-        mm_info ("Activation step [3/5]: requesting OTASP");
+        mm_obj_info (self, "activation step [3/5]: requesting OTASP");
         mm_base_modem_at_command (MM_BASE_MODEM (self),
                                   "!IOTASTART",
                                   20,
@@ -1581,7 +1579,7 @@
         return;
 
     case CDMA_MANUAL_ACTIVATION_STEP_CHECK:
-        mm_info ("Activation step [4/5]: checking activation info");
+        mm_obj_info (self, "activation step [4/5]: checking activation info");
         mm_base_modem_at_command (MM_BASE_MODEM (self),
                                   "~NAMVAL?0",
                                   20,
@@ -1591,7 +1589,7 @@
         return;
 
     case CDMA_MANUAL_ACTIVATION_STEP_LAST:
-        mm_info ("Activation step [5/5]: activation process finished");
+        mm_obj_info (self, "activation step [5/5]: activation process finished");
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
         return;
diff --git a/plugins/sierra/mm-common-sierra.c b/plugins/sierra/mm-common-sierra.c
index 1f14eb0..f366050 100644
--- a/plugins/sierra/mm-common-sierra.c
+++ b/plugins/sierra/mm-common-sierra.c
@@ -160,7 +160,7 @@
          * on the APP1 port or not.
          */
         if (getenv ("MM_SIERRA_APP1_PPP_OK")) {
-            mm_dbg ("Sierra: APP1 PPP OK '%s'", response);
+            mm_obj_dbg (probe, "APP1 PPP OK '%s'", response);
             g_object_set_data (G_OBJECT (probe), TAG_SIERRA_APP1_PPP_OK, GUINT_TO_POINTER (TRUE));
         }
     } else if (strstr (response, "APP2") ||
@@ -183,24 +183,24 @@
 static void
 sierra_custom_init_step (GTask *task)
 {
+    MMPortProbe             *probe;
     SierraCustomInitContext *ctx;
-    GCancellable *cancellable;
+    GCancellable            *cancellable;
 
-    ctx = g_task_get_task_data (task);
+    probe       = g_task_get_source_object (task);
+    ctx         = g_task_get_task_data (task);
     cancellable = g_task_get_cancellable (task);
 
     /* If cancelled, end */
     if (g_cancellable_is_cancelled (cancellable)) {
-        mm_dbg ("(Sierra) no need to keep on running custom init in '%s'",
-                mm_port_get_device (MM_PORT (ctx->port)));
+        mm_obj_dbg (probe, "no need to keep on running custom init");
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
         return;
     }
 
     if (ctx->retries == 0) {
-        mm_dbg ("(Sierra) Couldn't get port type hints from '%s'",
-                mm_port_get_device (MM_PORT (ctx->port)));
+        mm_obj_dbg (probe, "couldn't get port type hints");
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
         return;
@@ -328,8 +328,8 @@
         return;
     }
 
-    mm_warn ("Not in full functionality status, power-up command is needed. "
-             "Note that it may reboot the modem.");
+    mm_obj_warn (self, "not in full functionality status, power-up command is needed");
+    mm_obj_warn (self, "device may be rebooted");
 
     /* Try to go to full functionality mode without rebooting the system.
      * Works well if we previously switched off the power with CFUN=4
diff --git a/plugins/sierra/mm-modem-helpers-sierra.c b/plugins/sierra/mm-modem-helpers-sierra.c
index 2d5fd7d..ac07c9e 100644
--- a/plugins/sierra/mm-modem-helpers-sierra.c
+++ b/plugins/sierra/mm-modem-helpers-sierra.c
@@ -16,7 +16,6 @@
 #include <glib.h>
 #include <string.h>
 
-#include "mm-log.h"
 #include "mm-modem-helpers.h"
 #include "mm-modem-helpers-sierra.h"
 
diff --git a/plugins/sierra/mm-plugin-sierra-legacy.c b/plugins/sierra/mm-plugin-sierra-legacy.c
index 47bdf11..ebbca1b 100644
--- a/plugins/sierra/mm-plugin-sierra-legacy.c
+++ b/plugins/sierra/mm-plugin-sierra-legacy.c
@@ -22,7 +22,6 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
 #include "mm-plugin-sierra-legacy.h"
 #include "mm-common-sierra.h"
 #include "mm-broadband-modem-sierra.h"
@@ -73,7 +72,7 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_SIERRA_LEGACY,
-                      MM_PLUGIN_NAME,                "Sierra (legacy)",
+                      MM_PLUGIN_NAME,                MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS,  subsystems,
                       MM_PLUGIN_ALLOWED_DRIVERS,     drivers,
                       MM_PLUGIN_FORBIDDEN_DRIVERS,   forbidden_drivers,
diff --git a/plugins/sierra/mm-plugin-sierra.c b/plugins/sierra/mm-plugin-sierra.c
index 03a06bd..6622c5e 100644
--- a/plugins/sierra/mm-plugin-sierra.c
+++ b/plugins/sierra/mm-plugin-sierra.c
@@ -22,7 +22,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-plugin-sierra.h"
 #include "mm-broadband-modem.h"
 
@@ -52,7 +52,7 @@
 {
 #if defined WITH_QMI
     if (mm_port_probe_list_has_qmi_port (probes)) {
-        mm_dbg ("QMI-powered Sierra modem found...");
+        mm_obj_dbg (self, "QMI-powered Sierra modem found...");
         return MM_BASE_MODEM (mm_broadband_modem_qmi_new (uid,
                                                           drivers,
                                                           mm_plugin_get_name (self),
@@ -63,7 +63,7 @@
 
 #if defined WITH_MBIM
     if (mm_port_probe_list_has_mbim_port (probes)) {
-        mm_dbg ("MBIM-powered Sierra modem found...");
+        mm_obj_dbg (self, "MBIM-powered Sierra modem found...");
         return MM_BASE_MODEM (mm_broadband_modem_mbim_new (uid,
                                                            drivers,
                                                            mm_plugin_get_name (self),
@@ -91,7 +91,7 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_SIERRA,
-                      MM_PLUGIN_NAME,               "Sierra",
+                      MM_PLUGIN_NAME,               MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems,
                       MM_PLUGIN_ALLOWED_VENDOR_IDS, vendor_ids,
                       MM_PLUGIN_ALLOWED_DRIVERS,    drivers,
diff --git a/plugins/sierra/mm-sim-sierra.c b/plugins/sierra/mm-sim-sierra.c
index 233bf2f..d81e82b 100644
--- a/plugins/sierra/mm-sim-sierra.c
+++ b/plugins/sierra/mm-sim-sierra.c
@@ -25,7 +25,6 @@
 #include <ModemManager.h>
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
-#include "mm-log.h"
 #include "mm-modem-helpers.h"
 #include "mm-base-modem-at.h"
 
@@ -96,7 +95,6 @@
 
     task = g_task_new (self, NULL, callback, user_data);
 
-    mm_dbg ("loading (Sierra) SIM identifier...");
     mm_base_modem_at_command (
         modem,
         "!ICCID?",
diff --git a/plugins/sierra/tests/test-modem-helpers-sierra.c b/plugins/sierra/tests/test-modem-helpers-sierra.c
index 629572e..b0c6649 100644
--- a/plugins/sierra/tests/test-modem-helpers-sierra.c
+++ b/plugins/sierra/tests/test-modem-helpers-sierra.c
@@ -22,7 +22,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-test.h"
 #include "mm-modem-helpers.h"
 #include "mm-modem-helpers-sierra.h"
 
@@ -115,26 +115,6 @@
 
 /*****************************************************************************/
 
-void
-_mm_log (const char *loc,
-         const char *func,
-         guint32 level,
-         const char *fmt,
-         ...)
-{
-    va_list args;
-    gchar *msg;
-
-    if (!g_test_verbose ())
-        return;
-
-    va_start (args, fmt);
-    msg = g_strdup_vprintf (fmt, args);
-    va_end (args);
-    g_print ("%s\n", msg);
-    g_free (msg);
-}
-
 int main (int argc, char **argv)
 {
     setlocale (LC_ALL, "");
diff --git a/plugins/simtech/mm-broadband-modem-qmi-simtech.c b/plugins/simtech/mm-broadband-modem-qmi-simtech.c
index 392f562..7295960 100644
--- a/plugins/simtech/mm-broadband-modem-qmi-simtech.c
+++ b/plugins/simtech/mm-broadband-modem-qmi-simtech.c
@@ -22,7 +22,6 @@
 #include <ctype.h>
 
 #include "ModemManager.h"
-#include "mm-log.h"
 #include "mm-errors-types.h"
 #include "mm-iface-modem-location.h"
 #include "mm-iface-modem-voice.h"
diff --git a/plugins/simtech/mm-broadband-modem-simtech.c b/plugins/simtech/mm-broadband-modem-simtech.c
index f967479..c95cffd 100644
--- a/plugins/simtech/mm-broadband-modem-simtech.c
+++ b/plugins/simtech/mm-broadband-modem-simtech.c
@@ -28,7 +28,7 @@
 
 #include "ModemManager.h"
 #include "mm-modem-helpers.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-base-modem-at.h"
 #include "mm-iface-modem.h"
 #include "mm-iface-modem-3gpp.h"
@@ -261,7 +261,7 @@
     ctx = g_task_get_task_data (task);
 
     if (!mm_base_modem_at_command_finish (self, res, &error)) {
-        mm_dbg ("Couldn't enable automatic signal quality reporting: %s", error->message);
+        mm_obj_dbg (self, "couldn't enable automatic signal quality reporting: %s", error->message);
         g_error_free (error);
     } else
         csq_urcs_enabled = TRUE;
@@ -309,7 +309,7 @@
     ctx = g_task_get_task_data (task);
 
     if (!mm_base_modem_at_command_finish (self, res, &error)) {
-        mm_dbg ("Couldn't enable automatic access technology reporting: %s", error->message);
+        mm_obj_dbg (self, "couldn't enable automatic access technology reporting: %s", error->message);
         g_error_free (error);
     } else
         cnsmod_urcs_enabled = TRUE;
@@ -525,7 +525,7 @@
     ctx = g_task_get_task_data (task);
 
     if (!mm_base_modem_at_command_finish (self, res, &error)) {
-        mm_dbg ("Couldn't disable automatic access technology reporting: %s", error->message);
+        mm_obj_dbg (self, "couldn't disable automatic access technology reporting: %s", error->message);
         g_error_free (error);
     }
 
@@ -545,7 +545,7 @@
     ctx = g_task_get_task_data (task);
 
     if (!mm_base_modem_at_command_finish (self, res, &error)) {
-        mm_dbg ("Couldn't disable automatic signal quality reporting: %s", error->message);
+        mm_obj_dbg (self, "couldn't disable automatic signal quality reporting: %s", error->message);
         g_error_free (error);
     }
 
@@ -850,7 +850,7 @@
     g_array_append_val (combinations, mode);
 
     /* Filter out those unsupported modes */
-    filtered = mm_filter_supported_modes (all, combinations);
+    filtered = mm_filter_supported_modes (all, combinations, self);
     g_array_unref (all);
     g_array_unref (combinations);
 
diff --git a/plugins/simtech/mm-modem-helpers-simtech.c b/plugins/simtech/mm-modem-helpers-simtech.c
index d452e0b..0403c14 100644
--- a/plugins/simtech/mm-modem-helpers-simtech.c
+++ b/plugins/simtech/mm-modem-helpers-simtech.c
@@ -21,7 +21,6 @@
 #include "ModemManager.h"
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
-#include "mm-log.h"
 #include "mm-errors-types.h"
 #include "mm-modem-helpers-simtech.h"
 #include "mm-modem-helpers.h"
@@ -79,13 +78,14 @@
 
 gboolean
 mm_simtech_parse_clcc_list (const gchar *str,
+                            gpointer     log_object,
                             GList      **out_list,
                             GError     **error)
 {
     /* Parse the URC contents as a plain +CLCC response, but make sure to skip first
      * EOL in the string because the plain +CLCC response would never have that.
      */
-    return mm_3gpp_parse_clcc_response (mm_strip_tag (str, "\r\n"), out_list, error);
+    return mm_3gpp_parse_clcc_response (mm_strip_tag (str, "\r\n"), log_object, out_list, error);
 }
 
 void
diff --git a/plugins/simtech/mm-modem-helpers-simtech.h b/plugins/simtech/mm-modem-helpers-simtech.h
index efcc23f..1949d2e 100644
--- a/plugins/simtech/mm-modem-helpers-simtech.h
+++ b/plugins/simtech/mm-modem-helpers-simtech.h
@@ -32,6 +32,7 @@
 
 GRegex   *mm_simtech_get_clcc_urc_regex  (void);
 gboolean  mm_simtech_parse_clcc_list     (const gchar *str,
+                                          gpointer     log_object,
                                           GList      **out_list,
                                           GError     **error);
 void      mm_simtech_call_info_list_free (GList       *call_info_list);
diff --git a/plugins/simtech/mm-plugin-simtech.c b/plugins/simtech/mm-plugin-simtech.c
index 79afeb5..48daa84 100644
--- a/plugins/simtech/mm-plugin-simtech.c
+++ b/plugins/simtech/mm-plugin-simtech.c
@@ -21,7 +21,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-plugin-simtech.h"
 #include "mm-broadband-modem-simtech.h"
 
@@ -47,7 +47,7 @@
 {
 #if defined WITH_QMI
     if (mm_port_probe_list_has_qmi_port (probes)) {
-        mm_dbg ("QMI-powered SimTech modem found...");
+        mm_obj_dbg (self, "QMI-powered SimTech modem found...");
         return MM_BASE_MODEM (mm_broadband_modem_qmi_simtech_new (uid,
                                                                   drivers,
                                                                   mm_plugin_get_name (self),
@@ -74,7 +74,7 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_SIMTECH,
-                      MM_PLUGIN_NAME,               "SimTech",
+                      MM_PLUGIN_NAME,               MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems,
                       MM_PLUGIN_ALLOWED_VENDOR_IDS, vendor_ids,
                       MM_PLUGIN_ALLOWED_AT,         TRUE,
diff --git a/plugins/simtech/mm-shared-simtech.c b/plugins/simtech/mm-shared-simtech.c
index aa5a66a..0d3da87 100644
--- a/plugins/simtech/mm-shared-simtech.c
+++ b/plugins/simtech/mm-shared-simtech.c
@@ -21,7 +21,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-iface-modem.h"
 #include "mm-iface-modem-voice.h"
 #include "mm-iface-modem-location.h"
@@ -177,7 +177,7 @@
     sources = GPOINTER_TO_UINT (g_task_get_task_data (task));
 
     if (priv->cgps_support == FEATURE_SUPPORTED) {
-        mm_dbg ("GPS commands supported: GPS capabilities enabled");
+        mm_obj_dbg (self, "GPS commands supported: GPS capabilities enabled");
 
         /* We only flag as supported by this implementation those sources not already
          * supported by the parent implementation */
@@ -196,7 +196,7 @@
                                               self,
                                               NULL);
     } else
-        mm_dbg ("No GPS command supported: no GPS capabilities");
+        mm_obj_dbg (self, "no GPS command supported: no GPS capabilities");
 
     g_task_return_int (task, (gssize) sources);
     g_object_unref (task);
@@ -222,7 +222,7 @@
 
     /* Now our own check. If we don't have any GPS port, we're done */
     if (!mm_base_modem_peek_port_gps (MM_BASE_MODEM (self))) {
-        mm_dbg ("No GPS data port found: no GPS capabilities");
+        mm_obj_dbg (self, "no GPS data port found: no GPS capabilities");
         g_task_return_int (task, sources);
         g_object_unref (task);
         return;
@@ -542,9 +542,9 @@
     ctx = g_task_get_task_data (task);
 
     if (!mm_base_modem_at_command_finish (self, res, &error)) {
-        mm_dbg ("Couldn't %s +CLCC reporting: '%s'",
-                ctx->enable ? "enable" : "disable",
-                error->message);
+        mm_obj_dbg (self, "couldn't %s +CLCC reporting: '%s'",
+                    ctx->enable ? "enable" : "disable",
+                    error->message);
         g_error_free (error);
     }
 
@@ -572,13 +572,13 @@
     }
 
     if (!ctx->clcc_primary_done && ctx->primary) {
-        mm_dbg ("%s +CLCC extended list of current calls reporting in primary port...",
-                ctx->enable ? "Enabling" : "Disabling");
+        mm_obj_dbg (self, "%s +CLCC extended list of current calls reporting in primary port...",
+                    ctx->enable ? "enabling" : "disabling");
         ctx->clcc_primary_done = TRUE;
         port = ctx->primary;
     } else if (!ctx->clcc_secondary_done && ctx->secondary) {
-        mm_dbg ("%s +CLCC extended list of current calls reporting in secondary port...",
-                ctx->enable ? "Enabling" : "Disabling");
+        mm_obj_dbg (self, "%s +CLCC extended list of current calls reporting in secondary port...",
+                    ctx->enable ? "enabling" : "disabling");
         ctx->clcc_secondary_done = TRUE;
         port = ctx->secondary;
     }
@@ -647,7 +647,7 @@
     priv = get_private (MM_SHARED_SIMTECH (self));
 
     if (!priv->iface_modem_voice_parent->disable_unsolicited_events_finish (self, res, &error)) {
-        mm_warn ("Couldn't disable parent voice unsolicited events: %s", error->message);
+        mm_obj_warn (self, "couldn't disable parent voice unsolicited events: %s", error->message);
         g_error_free (error);
     }
 
@@ -664,7 +664,7 @@
     GError  *error = NULL;
 
     if (!common_voice_enable_disable_unsolicited_events_finish (self, res, &error)) {
-        mm_warn ("Couldn't disable Simtech-specific voice unsolicited events: %s", error->message);
+        mm_obj_warn (self, "couldn't disable Simtech-specific voice unsolicited events: %s", error->message);
         g_error_free (error);
     }
 
@@ -715,7 +715,7 @@
     GError *error = NULL;
 
     if (!common_voice_enable_disable_unsolicited_events_finish (self, res, &error)) {
-        mm_warn ("Couldn't enable Simtech-specific voice unsolicited events: %s", error->message);
+        mm_obj_warn (self, "couldn't enable Simtech-specific voice unsolicited events: %s", error->message);
         g_error_free (error);
     }
 
@@ -734,7 +734,7 @@
     priv = get_private (MM_SHARED_SIMTECH (self));
 
     if (!priv->iface_modem_voice_parent->enable_unsolicited_events_finish (self, res, &error)) {
-        mm_warn ("Couldn't enable parent voice unsolicited events: %s", error->message);
+        mm_obj_warn (self, "couldn't enable parent voice unsolicited events: %s", error->message);
         g_error_free (error);
     }
 
@@ -781,8 +781,8 @@
 
     full = g_match_info_fetch (match_info, 0);
 
-    if (!mm_simtech_parse_clcc_list (full, &call_info_list, &error)) {
-        mm_warn ("couldn't parse +CLCC list in URC: %s", error->message);
+    if (!mm_simtech_parse_clcc_list (full, self, &call_info_list, &error)) {
+        mm_obj_warn (self, "couldn't parse +CLCC list in URC: %s", error->message);
         g_error_free (error);
     } else
         mm_iface_modem_voice_report_all_calls (MM_IFACE_MODEM_VOICE (self), call_info_list);
@@ -800,12 +800,12 @@
     gchar  *details = NULL;
 
     if (!mm_simtech_parse_missed_call_urc (match_info, &details, &error)) {
-        mm_warn ("couldn't parse missed call URC: %s", error->message);
+        mm_obj_warn (self, "couldn't parse missed call URC: %s", error->message);
         g_error_free (error);
         return;
     }
 
-    mm_dbg ("missed call reported: %s", details);
+    mm_obj_dbg (self, "missed call reported: %s", details);
     g_free (details);
 }
 
@@ -819,22 +819,22 @@
     guint     duration = 0;
 
     if (!mm_simtech_parse_voice_call_urc (match_info, &start_or_stop, &duration, &error)) {
-        mm_warn ("couldn't parse VOICE CALL URC: %s", error->message);
+        mm_obj_warn (self, "couldn't parse voice call URC: %s", error->message);
         g_error_free (error);
         return;
     }
 
     if (start_or_stop) {
-        mm_dbg ("voice call started");
+        mm_obj_dbg (self, "voice call started");
         return;
     }
 
     if (duration) {
-        mm_dbg ("voice call finished (duration: %us)", duration);
+        mm_obj_dbg (self, "voice call finished (duration: %us)", duration);
         return;
     }
 
-    mm_dbg ("voice call finished");
+    mm_obj_dbg (self, "voice call finished");
 }
 
 static void
@@ -842,13 +842,12 @@
                     GMatchInfo      *info,
                     MMSharedSimtech *self)
 {
-    MMCallInfo  call_info;
-    gchar      *str;
+    MMCallInfo        call_info;
+    g_autofree gchar *str = NULL;
 
     /* We could have "VOICE" or "DATA". Now consider only "VOICE" */
     str = mm_get_string_unquoted_from_match_info (info, 1);
-    mm_dbg ("Ringing (%s)", str);
-    g_free (str);
+    mm_obj_dbg (self, "ringing (%s)", str);
 
     call_info.index     = 0;
     call_info.direction = MM_CALL_DIRECTION_INCOMING;
@@ -863,13 +862,12 @@
                      GMatchInfo      *match_info,
                      MMSharedSimtech *self)
 {
-    gchar *dtmf;
+    g_autofree gchar *dtmf = NULL;
 
     dtmf = g_match_info_fetch (match_info, 1);
-    mm_dbg ("Received DTMF: %s", dtmf);
+    mm_obj_dbg (self, "received DTMF: %s", dtmf);
     /* call index unknown */
     mm_iface_modem_voice_received_dtmf (MM_IFACE_MODEM_VOICE (self), 0, dtmf);
-    g_free (dtmf);
 }
 
 static void
@@ -944,7 +942,7 @@
     priv = get_private (MM_SHARED_SIMTECH (self));
 
     if (!priv->iface_modem_voice_parent->cleanup_unsolicited_events_finish (self, res, &error)) {
-        mm_warn ("Couldn't cleanup parent voice unsolicited events: %s", error->message);
+        mm_obj_warn (self, "couldn't cleanup parent voice unsolicited events: %s", error->message);
         g_error_free (error);
     }
 
@@ -999,7 +997,7 @@
     priv = get_private (MM_SHARED_SIMTECH (self));
 
     if (!priv->iface_modem_voice_parent->setup_unsolicited_events_finish (self, res, &error)) {
-        mm_warn ("Couldn't setup parent voice unsolicited events: %s", error->message);
+        mm_obj_warn (self, "couldn't setup parent voice unsolicited events: %s", error->message);
         g_error_free (error);
     }
 
@@ -1150,7 +1148,7 @@
 
     priv->cpcmreg_support = (mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, NULL) ?
                              FEATURE_SUPPORTED : FEATURE_NOT_SUPPORTED);
-    mm_dbg ("modem %s USB audio control", (priv->cpcmreg_support == FEATURE_SUPPORTED) ? "supports" : "doesn't support");
+    mm_obj_dbg (self, "modem %s USB audio control", (priv->cpcmreg_support == FEATURE_SUPPORTED) ? "supports" : "doesn't support");
 
     g_task_return_boolean (task, TRUE);
     g_object_unref (task);
@@ -1170,12 +1168,12 @@
 
     response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, NULL);
     if (response && !mm_simtech_parse_clcc_test (response, &clcc_urc_supported, &error)) {
-        mm_dbg ("failed checking CLCC URC support: %s", error->message);
+        mm_obj_dbg (self, "failed checking CLCC URC support: %s", error->message);
         g_clear_error (&error);
     }
 
     priv->clcc_urc_support = (clcc_urc_supported ? FEATURE_SUPPORTED : FEATURE_NOT_SUPPORTED);
-    mm_dbg ("modem %s +CLCC URCs", (priv->clcc_urc_support == FEATURE_SUPPORTED) ? "supports" : "doesn't support");
+    mm_obj_dbg (self, "modem %s +CLCC URCs", (priv->clcc_urc_support == FEATURE_SUPPORTED) ? "supports" : "doesn't support");
 
     /* If +CLCC URC supported we won't need polling in the parent */
     g_object_set (self,
diff --git a/plugins/simtech/tests/test-modem-helpers-simtech.c b/plugins/simtech/tests/test-modem-helpers-simtech.c
index 78a8a59..d5d774f 100644
--- a/plugins/simtech/tests/test-modem-helpers-simtech.c
+++ b/plugins/simtech/tests/test-modem-helpers-simtech.c
@@ -21,7 +21,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-test.h"
 #include "mm-modem-helpers.h"
 #include "mm-modem-helpers-simtech.h"
 
@@ -52,7 +52,7 @@
     str = g_match_info_fetch (match_info, 0);
     g_assert (str);
 
-    result = mm_simtech_parse_clcc_list (str, &call_info_list, &error);
+    result = mm_simtech_parse_clcc_list (str, NULL, &call_info_list, &error);
     g_assert_no_error (error);
     g_assert (result);
 
@@ -317,26 +317,6 @@
 
 /*****************************************************************************/
 
-void
-_mm_log (const char *loc,
-         const char *func,
-         guint32 level,
-         const char *fmt,
-         ...)
-{
-    va_list args;
-    gchar *msg;
-
-    if (!g_test_verbose ())
-        return;
-
-    va_start (args, fmt);
-    msg = g_strdup_vprintf (fmt, args);
-    va_end (args);
-    g_print ("%s\n", msg);
-    g_free (msg);
-}
-
 int main (int argc, char **argv)
 {
     setlocale (LC_ALL, "");
diff --git a/plugins/telit/mm-broadband-modem-mbim-telit.c b/plugins/telit/mm-broadband-modem-mbim-telit.c
index 43bce7f..1a2c386 100644
--- a/plugins/telit/mm-broadband-modem-mbim-telit.c
+++ b/plugins/telit/mm-broadband-modem-mbim-telit.c
@@ -22,7 +22,7 @@
 #include <ctype.h>
 
 #include "ModemManager.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-modem-helpers.h"
 #include "mm-iface-modem.h"
 #include "mm-base-modem-at.h"
@@ -30,8 +30,8 @@
 #include "mm-modem-helpers-telit.h"
 #include "mm-shared-telit.h"
 
-static void iface_modem_init          (MMIfaceModem         *iface);
-static void shared_telit_init         (MMSharedTelit        *iface);
+static void iface_modem_init  (MMIfaceModem  *iface);
+static void shared_telit_init (MMSharedTelit *iface);
 
 G_DEFINE_TYPE_EXTENDED (MMBroadbandModemMbimTelit, mm_broadband_modem_mbim_telit, MM_TYPE_BROADBAND_MODEM_MBIM, 0,
                         G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init)
@@ -65,7 +65,7 @@
 
     response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
     if (error) {
-        mm_dbg ("Generic query of supported 3GPP networks with WS46=? failed: '%s'", error->message);
+        g_prefix_error (&error, "ceneric query of supported 3GPP networks with WS46=? failed: ");
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -73,23 +73,22 @@
 
     modes = mm_3gpp_parse_ws46_test_response (response, &error);
     if (!modes) {
-        mm_dbg ("Parsing WS46=? response failed: '%s'", error->message);
+        g_prefix_error (&error, "parsing WS46=? response failed: ");
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
     }
 
     for (i = 0; i < modes->len; i++) {
-        MMModemMode  mode;
-        gchar       *str;
+        MMModemMode       mode;
+        g_autofree gchar *str = NULL;
 
         mode = g_array_index (modes, MMModemMode, i);
 
         modes_mask |= mode;
 
         str = mm_modem_mode_build_string_from_mask (mode);
-        mm_dbg ("Device allows (3GPP) mode combination: %s", str);
-        g_free (str);
+        mm_obj_dbg (self, "device allows (3GPP) mode combination: %s", str);
     }
 
     g_array_unref (modes);
@@ -102,7 +101,7 @@
 
     /* Filter out those unsupported modes */
     combinations = mm_telit_build_modes_list();
-    filtered = mm_filter_supported_modes (all, combinations);
+    filtered = mm_filter_supported_modes (all, combinations, self);
     g_array_unref (all);
     g_array_unref (combinations);
 
@@ -117,8 +116,6 @@
 {
     GTask *task;
 
-    mm_dbg ("loading Telit mbim supported modes...");
-
     task = g_task_new (self, NULL, callback, user_data);
     mm_base_modem_at_command (MM_BASE_MODEM (self),
                               "+WS46=?",
diff --git a/plugins/telit/mm-broadband-modem-telit.c b/plugins/telit/mm-broadband-modem-telit.c
index dde60a9..48ae4de 100644
--- a/plugins/telit/mm-broadband-modem-telit.c
+++ b/plugins/telit/mm-broadband-modem-telit.c
@@ -24,7 +24,7 @@
 #include <ctype.h>
 
 #include "ModemManager.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-errors-types.h"
 #include "mm-modem-helpers.h"
 #include "mm-base-modem-at.h"
@@ -182,7 +182,7 @@
 
     ctx = g_task_get_task_data (task);
     if (!mm_base_modem_at_command_finish (self, res, &error)) {
-        mm_warn ("telit: couldn't power up GNSS controller: '%s'", error->message);
+        g_prefix_error (&error, "couldn't power up GNSS controller: ");
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -197,7 +197,9 @@
                                   task);
         return;
     }
-    mm_info("telit: GNSS controller is powered up");
+
+    mm_obj_dbg (self, "GNSS controller is powered up");
+
     /* Only use the GPS port in NMEA/RAW setups */
     if (ctx->source & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA |
                        MM_MODEM_LOCATION_SOURCE_GPS_RAW)) {
@@ -355,7 +357,7 @@
     sources = GPOINTER_TO_UINT (g_task_get_task_data (task));
     mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
     if (error) {
-        mm_dbg ("telit: GPS controller not supported: %s", error->message);
+        mm_obj_dbg (self, "GPS controller not supported: %s", error->message);
         g_clear_error (&error);
     } else if (mm_base_modem_get_port_gps (MM_BASE_MODEM (self)))
         sources |= (MM_MODEM_LOCATION_SOURCE_GPS_NMEA |
@@ -473,12 +475,12 @@
     if (self->priv->csim_lock_state >= CSIM_LOCK_STATE_LOCK_REQUESTED) {
 
         if (prev_qss_status > QSS_STATUS_SIM_REMOVED && cur_qss_status == QSS_STATUS_SIM_REMOVED) {
-            mm_dbg ("QSS handler: #QSS=0 after +CSIM=1 -> CSIM locked!");
+            mm_obj_dbg (self, "QSS handler: #QSS=0 after +CSIM=1: CSIM locked!");
             self->priv->csim_lock_state = CSIM_LOCK_STATE_LOCKED;
         }
 
         if (prev_qss_status == QSS_STATUS_SIM_REMOVED && cur_qss_status != QSS_STATUS_SIM_REMOVED) {
-            mm_dbg ("QSS handler: #QSS>=1 after +CSIM=0 -> CSIM unlocked!");
+            mm_obj_dbg (self, "QSS handler: #QSS>=1 after +CSIM=0: CSIM unlocked!");
             self->priv->csim_lock_state = CSIM_LOCK_STATE_UNLOCKED;
 
             if (self->priv->csim_lock_timeout_id) {
@@ -493,18 +495,18 @@
     }
 
     if (cur_qss_status != prev_qss_status)
-        mm_dbg ("QSS handler: status changed '%s -> %s'",
-                mm_telit_qss_status_get_string (prev_qss_status),
-                mm_telit_qss_status_get_string (cur_qss_status));
+        mm_obj_dbg (self, "QSS handler: status changed %s -> %s",
+                    mm_telit_qss_status_get_string (prev_qss_status),
+                    mm_telit_qss_status_get_string (cur_qss_status));
 
     if (self->priv->parse_qss == FALSE) {
-        mm_dbg ("QSS: message ignored");
+        mm_obj_dbg (self, "QSS handler: message ignored");
         return;
     }
 
     if ((prev_qss_status == QSS_STATUS_SIM_REMOVED && cur_qss_status != QSS_STATUS_SIM_REMOVED) ||
         (prev_qss_status > QSS_STATUS_SIM_REMOVED && cur_qss_status == QSS_STATUS_SIM_REMOVED)) {
-        mm_info ("QSS handler: SIM swap detected");
+        mm_obj_info (self, "QSS handler: SIM swap detected");
         mm_broadband_modem_update_sim_hot_swap_detected (MM_BROADBAND_MODEM (self));
     }
 }
@@ -549,7 +551,7 @@
         g_assert_not_reached ();
 
     if (!mm_base_modem_at_command_full_finish (self, res, error)) {
-        mm_warn ("QSS: error enabling unsolicited on port %s: %s", mm_port_get_device (MM_PORT (port)), (*error)->message);
+        mm_obj_warn (self, "QSS: error enabling unsolicited on port %s: %s", mm_port_get_device (MM_PORT (port)), (*error)->message);
         goto next_step;
     }
 
@@ -584,19 +586,19 @@
 
     response = mm_base_modem_at_command_finish (_self, res, &error);
     if (error) {
-        mm_warn ("Could not get \"#QSS?\" reply: %s", error->message);
+        mm_obj_warn (self, "could not get \"#QSS?\" reply: %s", error->message);
         g_error_free (error);
         goto next_step;
     }
 
     qss_status = mm_telit_parse_qss_query (response, &error);
     if (error) {
-        mm_warn ("QSS query parse error: %s", error->message);
+        mm_obj_warn (self, "QSS query parse error: %s", error->message);
         g_error_free (error);
         goto next_step;
     }
 
-    mm_info ("QSS: current status is '%s'", mm_telit_qss_status_get_string (qss_status));
+    mm_obj_dbg (self, "QSS: current status is '%s'", mm_telit_qss_status_get_string (qss_status));
     self->priv->qss_status = qss_status;
 
 next_step:
@@ -754,7 +756,7 @@
                              MM_MOBILE_EQUIPMENT_ERROR_NOT_SUPPORTED)) {
             self->priv->csim_lock_support = FEATURE_NOT_SUPPORTED;
         }
-        mm_warn ("Couldn't unlock SIM card: %s", error->message);
+        mm_obj_warn (self, "couldn't unlock SIM card: %s", error->message);
         g_error_free (error);
     }
 
@@ -776,7 +778,7 @@
     ctx = g_task_get_task_data (task);
 
     if (!(ctx->retries = iface_modem_parent->load_unlock_retries_finish (self, res, &error))) {
-        mm_warn ("couldn't load unlock retries with generic logic: %s", error->message);
+        mm_obj_warn (self, "couldn't load unlock retries with generic logic: %s", error->message);
         g_error_free (error);
     }
 
@@ -803,7 +805,7 @@
                              MM_MOBILE_EQUIPMENT_ERROR,
                              MM_MOBILE_EQUIPMENT_ERROR_NOT_SUPPORTED)) {
             self->priv->csim_lock_support = FEATURE_NOT_SUPPORTED;
-            mm_warn ("Couldn't lock SIM card: %s. Continuing without CSIM lock.", error->message);
+            mm_obj_warn (self, "couldn't lock SIM card: %s; continuing without CSIM lock", error->message);
             g_error_free (error);
         } else {
             g_prefix_error (&error, "Couldn't lock SIM card: ");
@@ -853,8 +855,8 @@
             }
             break;
         case FEATURE_NOT_SUPPORTED:
-            mm_dbg ("CSIM lock not supported by this modem. Skipping %s command",
-                    is_lock ? "lock" : "unlock");
+            mm_obj_dbg (self, "CSIM lock not supported by this modem; skipping %s command",
+                        is_lock ? "lock" : "unlock");
             ctx->step++;
             load_unlock_retries_step (task);
             break;
@@ -884,9 +886,8 @@
 static gboolean
 csim_unlock_periodic_check (MMBroadbandModemTelit *self)
 {
-    if (self->priv->csim_lock_state != CSIM_LOCK_STATE_UNLOCKED) {
-        mm_warn ("CSIM is still locked after %d seconds. Trying to continue anyway", CSIM_UNLOCK_MAX_TIMEOUT);
-    }
+    if (self->priv->csim_lock_state != CSIM_LOCK_STATE_UNLOCKED)
+        mm_obj_warn (self, "CSIM is still locked after %d seconds; trying to continue anyway", CSIM_UNLOCK_MAX_TIMEOUT);
 
     self->priv->csim_lock_timeout_id = 0;
     pending_csim_unlock_complete (self);
@@ -922,7 +923,7 @@
         case LOAD_UNLOCK_RETRIES_STEP_LAST:
             self->priv->csim_lock_task = task;
             if (self->priv->csim_lock_state == CSIM_LOCK_STATE_LOCKED) {
-                mm_dbg ("CSIM is locked. Waiting for #QSS=1");
+                mm_obj_dbg (self, "CSIM is locked, waiting for #QSS=1");
                 self->priv->csim_lock_timeout_id = g_timeout_add_seconds (CSIM_UNLOCK_MAX_TIMEOUT,
                                                                           (GSourceFunc) csim_unlock_periodic_check,
                                                                           g_object_ref(self));
@@ -977,7 +978,7 @@
 
     task = g_task_new (self, NULL, callback, user_data);
 
-    mm_dbg ("Stop ignoring #QSS");
+    mm_obj_dbg (self, "stop ignoring #QSS");
     modem->priv->parse_qss = TRUE;
 
     g_task_return_boolean (task, TRUE);
@@ -1003,12 +1004,12 @@
     GError *error = NULL;
 
     if (mm_base_modem_at_command_finish (self, res, &error)) {
-        mm_dbg ("Ignore #QSS unsolicited during power down/low");
+        mm_obj_dbg (self, "sgnore #QSS unsolicited during power down/low");
         MM_BROADBAND_MODEM_TELIT (self)->priv->parse_qss = FALSE;
     }
 
     if (error) {
-        mm_err ("modem power down: %s", error->message);
+        mm_obj_warn (self, "failed modem power down: %s", error->message);
         g_clear_error (&error);
     }
 
@@ -1194,7 +1195,6 @@
                           GAsyncReadyCallback callback,
                           gpointer user_data)
 {
-    mm_dbg ("loading access technology (Telit)...");
     mm_base_modem_at_sequence (
         MM_BASE_MODEM (self),
         access_tech_commands,
@@ -1241,7 +1241,7 @@
 
     /* Filter out those unsupported modes */
     combinations = mm_telit_build_modes_list();
-    filtered = mm_filter_supported_modes (all, combinations);
+    filtered = mm_filter_supported_modes (all, combinations, self);
     g_array_unref (all);
     g_array_unref (combinations);
 
@@ -1280,7 +1280,7 @@
     GError *error = NULL;
 
     if (!mm_base_modem_at_command_finish (self, res, &error)) {
-        mm_warn ("Couldn't enable custom +CIND settings: %s", error->message);
+        mm_obj_warn (self, "couldn't enable custom +CIND settings: %s", error->message);
         g_error_free (error);
     }
 
@@ -1296,7 +1296,7 @@
     GError *error = NULL;
 
     if (!iface_modem_3gpp_parent->enable_unsolicited_events_finish (self, res, &error)) {
-        mm_warn ("Couldn't enable parent 3GPP unsolicited events: %s", error->message);
+        mm_obj_warn (self, "couldn't enable parent 3GPP unsolicited events: %s", error->message);
         g_error_free (error);
     }
 
diff --git a/plugins/telit/mm-common-telit.c b/plugins/telit/mm-common-telit.c
index 3cdbd7f..0493fd5 100644
--- a/plugins/telit/mm-common-telit.c
+++ b/plugins/telit/mm-common-telit.c
@@ -16,7 +16,7 @@
 #include <string.h>
 
 #include "mm-common-telit.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 /*****************************************************************************/
 
@@ -55,19 +55,19 @@
 
         usbif = mm_kernel_device_get_property_as_int_hex (port, "ID_USB_INTERFACE_NUM");
         if (usbif == GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (device), TAG_TELIT_MODEM_PORT))) {
-            mm_dbg ("telit: AT port '%s/%s' flagged as primary",
-                mm_port_probe_get_port_subsys (probe),
-                mm_port_probe_get_port_name (probe));
+            mm_obj_dbg (self, "AT port '%s/%s' flagged as primary",
+                        mm_port_probe_get_port_subsys (probe),
+                        mm_port_probe_get_port_name (probe));
             pflags = MM_PORT_SERIAL_AT_FLAG_PRIMARY;
         } else if (usbif == GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (device), TAG_TELIT_AUX_PORT))) {
-            mm_dbg ("telit: AT port '%s/%s' flagged as secondary",
-                mm_port_probe_get_port_subsys (probe),
-                mm_port_probe_get_port_name (probe));
+            mm_obj_dbg (self, "AT port '%s/%s' flagged as secondary",
+                        mm_port_probe_get_port_subsys (probe),
+                        mm_port_probe_get_port_name (probe));
             pflags = MM_PORT_SERIAL_AT_FLAG_SECONDARY;
         } else if (usbif == GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (device), TAG_TELIT_NMEA_PORT))) {
-            mm_dbg ("telit: port '%s/%s' flagged as NMEA",
-                mm_port_probe_get_port_subsys (probe),
-                mm_port_probe_get_port_name (probe));
+            mm_obj_dbg (self, "port '%s/%s' flagged as NMEA",
+                        mm_port_probe_get_port_subsys (probe),
+                        mm_port_probe_get_port_name (probe));
             ptype = MM_PORT_TYPE_GPS;
         } else
             ptype = MM_PORT_TYPE_IGNORED;
@@ -101,7 +101,8 @@
 static void telit_custom_init_step (GTask *task);
 
 static gboolean
-cache_port_mode (MMDevice *device,
+cache_port_mode (MMPortProbe *probe,
+                 MMDevice    *device,
                  const gchar *reply)
 {
     GRegex *r = NULL;
@@ -119,7 +120,7 @@
         goto out;
 
     if (!mm_get_uint_from_match_info (match_info, 2, &portcfg_current)) {
-        mm_dbg ("telit: unrecognized #PORTCFG <active> value");
+        mm_obj_dbg (probe, "unrecognized #PORTCFG <active> value");
         goto out;
     }
 
@@ -168,8 +169,8 @@
     g_match_info_free (match_info);
     g_regex_unref (r);
     if (error != NULL) {
-      mm_dbg ("telit: error while matching: %s", error->message);
-      g_error_free (error);
+        mm_obj_dbg (probe, "error while matching #PORTCFG: %s", error->message);
+        g_error_free (error);
     }
     return ret;
 }
@@ -189,8 +190,7 @@
 
     response = mm_port_serial_at_command_finish (port, res, &error);
     if (error) {
-        mm_dbg ("telit: couldn't get port mode: '%s'",
-                error->message);
+        mm_obj_dbg (probe, "couldn't get telit port mode: '%s'", error->message);
 
         /* If ERROR or COMMAND NOT SUPPORT occur then do not retry the
          * command.
@@ -206,8 +206,8 @@
 
         /* Results are cached in the parent device object */
         if (g_object_get_data (G_OBJECT (device), TAG_GETPORTCFG_SUPPORTED) == NULL) {
-            mm_dbg ("telit: retrieving port mode layout");
-            if (cache_port_mode (device, response)) {
+            mm_obj_dbg (probe, "retrieving telit port mode layout");
+            if (cache_port_mode (probe, device, response)) {
                 g_object_set_data (G_OBJECT (device), TAG_GETPORTCFG_SUPPORTED, GUINT_TO_POINTER (TRUE));
                 ctx->getportcfg_done = TRUE;
             }
@@ -242,8 +242,7 @@
 
     /* If cancelled, end */
     if (g_cancellable_is_cancelled (g_task_get_cancellable (task))) {
-        mm_dbg ("telit: no need to keep on running custom init in (%s)",
-                mm_port_get_device (MM_PORT (ctx->port)));
+        mm_obj_dbg (probe, "no need to keep on running custom init");
         goto out;
     }
 
diff --git a/plugins/telit/mm-modem-helpers-telit.c b/plugins/telit/mm-modem-helpers-telit.c
index 07d46b8..f77afee 100644
--- a/plugins/telit/mm-modem-helpers-telit.c
+++ b/plugins/telit/mm-modem-helpers-telit.c
@@ -23,7 +23,7 @@
 #define _LIBMM_INSIDE_MMCLI
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-modem-helpers.h"
 #include "mm-modem-helpers-telit.h"
 
@@ -375,6 +375,7 @@
 
 static gboolean
 telit_get_2g_mm_bands (GMatchInfo  *match_info,
+                       gpointer     log_object,
                        GArray     **bands,
                        GError     **error)
 {
@@ -406,7 +407,7 @@
                     *bands = g_array_append_val (*bands, j);
             }
         } else
-            mm_dbg ("unhandled telit 2G band value configuration: %u", value);
+            mm_obj_dbg (log_object, "unhandled telit 2G band value configuration: %u", value);
     }
 
 out:
@@ -422,8 +423,9 @@
 
 static gboolean
 telit_get_3g_mm_bands (GMatchInfo  *match_info,
-                       GArray     **bands,
+                       gpointer     log_object,
                        gboolean     modem_alternate_3g_bands,
+                       GArray     **bands,
                        GError     **error)
 {
     GError        *inner_error = NULL;
@@ -472,7 +474,7 @@
                     *bands = g_array_append_val (*bands, j);
             }
         } else
-            mm_dbg ("unhandled telit 3G band value configuration: %u", value);
+            mm_obj_dbg (log_object, "unhandled telit 3G band value configuration: %u", value);
     }
 
 out:
@@ -542,6 +544,7 @@
                            gboolean        modem_is_4g,
                            gboolean        modem_alternate_3g_bands,
                            LoadBandsType   load_type,
+                           gpointer        log_object,
                            GError        **error)
 {
     GError     *inner_error = NULL;
@@ -571,10 +574,10 @@
 
     bands = g_array_new (TRUE, TRUE, sizeof (MMModemBand));
 
-    if (modem_is_2g && !telit_get_2g_mm_bands (match_info, &bands, &inner_error))
+    if (modem_is_2g && !telit_get_2g_mm_bands (match_info, log_object, &bands, &inner_error))
         goto out;
 
-    if (modem_is_3g && !telit_get_3g_mm_bands (match_info, &bands, modem_alternate_3g_bands, &inner_error))
+    if (modem_is_3g && !telit_get_3g_mm_bands (match_info, log_object, modem_alternate_3g_bands, &bands, &inner_error))
         goto out;
 
     if (modem_is_4g && !telit_get_4g_mm_bands (match_info, &bands, &inner_error))
@@ -599,12 +602,14 @@
                                    gboolean      modem_is_3g,
                                    gboolean      modem_is_4g,
                                    gboolean      modem_alternate_3g_bands,
+                                   gpointer      log_object,
                                    GError      **error)
 {
     return common_parse_bnd_response (response,
                                       modem_is_2g, modem_is_3g, modem_is_4g,
                                       modem_alternate_3g_bands,
                                       LOAD_BANDS_TYPE_CURRENT,
+                                      log_object,
                                       error);
 }
 
@@ -614,12 +619,14 @@
                                   gboolean      modem_is_3g,
                                   gboolean      modem_is_4g,
                                   gboolean      modem_alternate_3g_bands,
+                                  gpointer      log_object,
                                   GError      **error)
 {
     return common_parse_bnd_response (response,
                                       modem_is_2g, modem_is_3g, modem_is_4g,
                                       modem_alternate_3g_bands,
                                       LOAD_BANDS_TYPE_SUPPORTED,
+                                      log_object,
                                       error);
 }
 
diff --git a/plugins/telit/mm-modem-helpers-telit.h b/plugins/telit/mm-modem-helpers-telit.h
index 491e8fa..0c52bb7 100644
--- a/plugins/telit/mm-modem-helpers-telit.h
+++ b/plugins/telit/mm-modem-helpers-telit.h
@@ -25,12 +25,14 @@
                                            gboolean      modem_is_3g,
                                            gboolean      modem_is_4g,
                                            gboolean      modem_alternate_3g_bands,
+                                           gpointer      log_object,
                                            GError      **error);
 GArray *mm_telit_parse_bnd_test_response  (const gchar  *response,
                                            gboolean      modem_is_2g,
                                            gboolean      modem_is_3g,
                                            gboolean      modem_is_4g,
                                            gboolean      modem_alternate_3g_bands,
+                                           gpointer      log_object,
                                            GError      **error);
 gchar  *mm_telit_build_bnd_request        (GArray       *bands_array,
                                            gboolean      modem_is_2g,
diff --git a/plugins/telit/mm-plugin-telit.c b/plugins/telit/mm-plugin-telit.c
index 093975a..aa6f52a 100644
--- a/plugins/telit/mm-plugin-telit.c
+++ b/plugins/telit/mm-plugin-telit.c
@@ -22,7 +22,7 @@
 #include <libmm-glib.h>
 
 #include "mm-port-enums-types.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-modem-helpers.h"
 #include "mm-plugin-telit.h"
 #include "mm-common-telit.h"
@@ -55,7 +55,7 @@
 {
 #if defined WITH_QMI
     if (mm_port_probe_list_has_qmi_port (probes)) {
-        mm_dbg ("QMI-powered Telit modem found...");
+        mm_obj_dbg (self, "QMI-powered Telit modem found...");
         return MM_BASE_MODEM (mm_broadband_modem_qmi_new (uid,
                                                           drivers,
                                                           mm_plugin_get_name (self),
@@ -66,7 +66,7 @@
 
 #if defined WITH_MBIM
     if (mm_port_probe_list_has_mbim_port (probes)) {
-        mm_dbg ("MBIM-powered Telit modem found...");
+        mm_obj_dbg (self, "MBIM-powered Telit modem found...");
         return MM_BASE_MODEM (mm_broadband_modem_mbim_telit_new (uid,
                                                                  drivers,
                                                                  mm_plugin_get_name (self),
@@ -99,7 +99,7 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_TELIT,
-                      MM_PLUGIN_NAME,                   "Telit",
+                      MM_PLUGIN_NAME,                   MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS,     subsystems,
                       MM_PLUGIN_ALLOWED_VENDOR_IDS,     vendor_ids,
                       MM_PLUGIN_ALLOWED_VENDOR_STRINGS, vendor_strings,
diff --git a/plugins/telit/mm-shared-telit.c b/plugins/telit/mm-shared-telit.c
index f1eb051..9a5aa83 100644
--- a/plugins/telit/mm-shared-telit.c
+++ b/plugins/telit/mm-shared-telit.c
@@ -23,7 +23,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-iface-modem.h"
 #include "mm-iface-modem-location.h"
 #include "mm-base-modem.h"
@@ -63,7 +63,7 @@
     /* Lookup for the tag specifying that we're using the alternate 3G band mapping */
     priv->alternate_3g_bands = mm_kernel_device_get_global_property_as_boolean (port, "ID_MM_TELIT_BND_ALTERNATE");
     if (priv->alternate_3g_bands)
-        mm_dbg ("Telit modem using alternate 3G band mask setup");
+        mm_obj_dbg (self, "telit modem using alternate 3G band mask setup");
 }
 
 static Private *
@@ -197,6 +197,7 @@
                                                   mm_iface_modem_is_3g (MM_IFACE_MODEM (self)),
                                                   mm_iface_modem_is_4g (MM_IFACE_MODEM (self)),
                                                   priv->alternate_3g_bands,
+                                                  self,
                                                   &error);
         if (!bands)
             g_task_return_error (task, error);
@@ -256,6 +257,7 @@
                                                    mm_iface_modem_is_3g (MM_IFACE_MODEM (self)),
                                                    mm_iface_modem_is_4g (MM_IFACE_MODEM (self)),
                                                    priv->alternate_3g_bands,
+                                                   self,
                                                    &error);
         if (!bands)
             g_task_return_error (task, error);
diff --git a/plugins/telit/tests/test-mm-modem-helpers-telit.c b/plugins/telit/tests/test-mm-modem-helpers-telit.c
index e6bff0b..251abd1 100644
--- a/plugins/telit/tests/test-mm-modem-helpers-telit.c
+++ b/plugins/telit/tests/test-mm-modem-helpers-telit.c
@@ -23,7 +23,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-test.h"
 #include "mm-modem-helpers.h"
 #include "mm-modem-helpers-telit.h"
 
@@ -170,6 +170,7 @@
                                                   supported_band_mapping_tests[i].modem_is_3g,
                                                   supported_band_mapping_tests[i].modem_is_4g,
                                                   supported_band_mapping_tests[i].modem_alternate_3g_bands,
+                                                  NULL,
                                                   &error);
         g_assert_no_error (error);
         g_assert (bands);
@@ -278,6 +279,7 @@
                                                    current_band_mapping_tests[i].modem_is_3g,
                                                    current_band_mapping_tests[i].modem_is_4g,
                                                    current_band_mapping_tests[i].modem_alternate_3g_bands,
+                                                   NULL,
                                                    &error);
         g_assert_no_error (error);
         g_assert (bands);
@@ -570,26 +572,6 @@
 
 /******************************************************************************/
 
-void
-_mm_log (const char *loc,
-         const char *func,
-         guint32 level,
-         const char *fmt,
-         ...)
-{
-    va_list args;
-    gchar *msg;
-
-    if (!g_test_verbose ())
-        return;
-
-    va_start (args, fmt);
-    msg = g_strdup_vprintf (fmt, args);
-    va_end (args);
-    g_print ("%s\n", msg);
-    g_free (msg);
-}
-
 int main (int argc, char **argv)
 {
     setlocale (LC_ALL, "");
diff --git a/plugins/tests/test-keyfiles.c b/plugins/tests/test-keyfiles.c
index 35ec4b4..d528cac 100644
--- a/plugins/tests/test-keyfiles.c
+++ b/plugins/tests/test-keyfiles.c
@@ -23,7 +23,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-test.h"
 
 /************************************************************/
 
@@ -64,26 +64,6 @@
 
 /************************************************************/
 
-void
-_mm_log (const char *loc,
-         const char *func,
-         guint32 level,
-         const char *fmt,
-         ...)
-{
-    va_list args;
-    gchar *msg;
-
-    if (!g_test_verbose ())
-        return;
-
-    va_start (args, fmt);
-    msg = g_strdup_vprintf (fmt, args);
-    va_end (args);
-    g_print ("%s\n", msg);
-    g_free (msg);
-}
-
 int main (int argc, char **argv)
 {
     setlocale (LC_ALL, "");
diff --git a/plugins/tests/test-udev-rules.c b/plugins/tests/test-udev-rules.c
index 83ba95b..36cc412 100644
--- a/plugins/tests/test-udev-rules.c
+++ b/plugins/tests/test-udev-rules.c
@@ -25,7 +25,7 @@
 #include <libmm-glib.h>
 
 #include "mm-kernel-device-generic-rules.h"
-#include "mm-log.h"
+#include "mm-log-test.h"
 
 /************************************************************/
 
@@ -162,26 +162,6 @@
 
 /************************************************************/
 
-void
-_mm_log (const char *loc,
-         const char *func,
-         guint32 level,
-         const char *fmt,
-         ...)
-{
-    va_list args;
-    gchar *msg;
-
-    if (!g_test_verbose ())
-        return;
-
-    va_start (args, fmt);
-    msg = g_strdup_vprintf (fmt, args);
-    va_end (args);
-    g_print ("%s\n", msg);
-    g_free (msg);
-}
-
 int main (int argc, char **argv)
 {
     setlocale (LC_ALL, "");
diff --git a/plugins/thuraya/mm-broadband-modem-thuraya.c b/plugins/thuraya/mm-broadband-modem-thuraya.c
index 071ef3f..a401341 100644
--- a/plugins/thuraya/mm-broadband-modem-thuraya.c
+++ b/plugins/thuraya/mm-broadband-modem-thuraya.c
@@ -24,7 +24,6 @@
 #include <ctype.h>
 
 #include "ModemManager.h"
-#include "mm-log.h"
 #include "mm-errors-types.h"
 #include "mm-base-modem-at.h"
 #include "mm-iface-modem.h"
@@ -185,13 +184,10 @@
     if (!mm_thuraya_3gpp_parse_cpms_test_response (response,
                                                    &result->mem1,
                                                    &result->mem2,
-                                                   &result->mem3)) {
+                                                   &result->mem3,
+                                                   &error)) {
         supported_storages_result_free (result);
-        g_task_return_new_error (task,
-                                 MM_CORE_ERROR,
-                                 MM_CORE_ERROR_FAILED,
-                                 "Couldn't parse supported storages reply: '%s'",
-                                 response);
+        g_task_return_error (task, error);
         g_object_unref (task);
         return;
     }
diff --git a/plugins/thuraya/mm-modem-helpers-thuraya.c b/plugins/thuraya/mm-modem-helpers-thuraya.c
index 1dad59f..0c713a1 100644
--- a/plugins/thuraya/mm-modem-helpers-thuraya.c
+++ b/plugins/thuraya/mm-modem-helpers-thuraya.c
@@ -47,29 +47,33 @@
 }
 
 gboolean
-mm_thuraya_3gpp_parse_cpms_test_response (const gchar *reply,
-                                          GArray **mem1,
-                                          GArray **mem2,
-                                          GArray **mem3)
+mm_thuraya_3gpp_parse_cpms_test_response (const gchar  *reply,
+                                          GArray      **mem1,
+                                          GArray      **mem2,
+                                          GArray      **mem3,
+                                          GError      **error)
 {
 #define N_EXPECTED_GROUPS 3
 
-    GRegex *r;
-    gchar **split;
-    gchar **splitp;
-    const gchar *splita[N_EXPECTED_GROUPS];
-    guint i;
-    GArray *tmp1 = NULL;
-    GArray *tmp2 = NULL;
-    GArray *tmp3 = NULL;
+    gchar            **splitp;
+    const gchar       *splita[N_EXPECTED_GROUPS];
+    guint              i;
+    g_auto(GStrv)      split = NULL;
+    g_autoptr(GRegex)  r = NULL;
+    g_autoptr(GArray)  tmp1 = NULL;
+    g_autoptr(GArray)  tmp2 = NULL;
+    g_autoptr(GArray)  tmp3 = NULL;
 
     g_assert (mem1 != NULL);
     g_assert (mem2 != NULL);
     g_assert (mem3 != NULL);
 
     split = g_strsplit (mm_strip_tag (reply, "+CPMS:"), " ", -1);
-    if (!split)
+    if (!split) {
+        g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+                     "Couldn't split +CPMS response");
         return FALSE;
+    }
 
     /* remove empty strings, and count non-empty strings */
     i = 0;
@@ -82,9 +86,9 @@
     }
 
     if (i != N_EXPECTED_GROUPS) {
-        mm_warn ("Cannot parse +CPMS test response: invalid number of groups (%u != %u)",
-                 i, N_EXPECTED_GROUPS);
-        g_strfreev (split);
+        g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+                     "Couldn't parse +CPMS response: invalid number of groups (%u != %u)",
+                     i, N_EXPECTED_GROUPS);
         return FALSE;
     }
 
@@ -92,8 +96,8 @@
     g_assert (r);
 
     for (i = 0; i < N_EXPECTED_GROUPS; i++) {
-        GMatchInfo *match_info = NULL;
-        GArray *array;
+        g_autoptr(GMatchInfo)  match_info = NULL;
+        GArray                *array;
 
         /* We always return a valid array, even if it may be empty */
         array = g_array_new (FALSE, FALSE, sizeof (MMSmsStorage));
@@ -101,7 +105,7 @@
         /* Got a range group to match */
         if (g_regex_match (r, splita[i], 0, &match_info)) {
             while (g_match_info_matches (match_info)) {
-                gchar *str;
+                g_autofree gchar *str = NULL;
 
                 str = g_match_info_fetch (match_info, 1);
                 if (str) {
@@ -109,13 +113,11 @@
 
                     storage = storage_from_str (str);
                     g_array_append_val (array, storage);
-                    g_free (str);
                 }
 
                 g_match_info_next (match_info, NULL);
             }
         }
-        g_match_info_free (match_info);
 
         if (!tmp1)
             tmp1 = array;
@@ -127,30 +129,20 @@
             g_assert_not_reached ();
     }
 
-    g_strfreev (split);
-    g_regex_unref (r);
-
-    g_warn_if_fail (tmp1 != NULL);
-    g_warn_if_fail (tmp2 != NULL);
-    g_warn_if_fail (tmp3 != NULL);
-
     /* Only return TRUE if all sets have been parsed correctly
      * (even if the arrays may be empty) */
     if (tmp1 && tmp2 && tmp3) {
-        *mem1 = tmp1;
-        *mem2 = tmp2;
-        *mem3 = tmp3;
+        *mem1 = g_steal_pointer (&tmp1);
+        *mem2 = g_steal_pointer (&tmp2);
+        *mem3 = g_steal_pointer (&tmp3);
         return TRUE;
     }
 
     /* Otherwise, cleanup and return FALSE */
-    if (tmp1)
-        g_array_unref (tmp1);
-    if (tmp2)
-        g_array_unref (tmp2);
-    if (tmp3)
-        g_array_unref (tmp3);
+    g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+                 "Couldn't parse +CPMS response: not all groups detected (mem1 %s, mem2 %s, mem3 %s)",
+                 tmp1 ? "yes" : "no",
+                 tmp2 ? "yes" : "no",
+                 tmp3 ? "yes" : "no");
     return FALSE;
 }
-
-/*****************************************************************************/
diff --git a/plugins/thuraya/mm-modem-helpers-thuraya.h b/plugins/thuraya/mm-modem-helpers-thuraya.h
index 454baf4..33bb079 100644
--- a/plugins/thuraya/mm-modem-helpers-thuraya.h
+++ b/plugins/thuraya/mm-modem-helpers-thuraya.h
@@ -19,9 +19,10 @@
 #include <glib.h>
 
 /* AT+CPMS=? (Preferred SMS storage) response parser */
-gboolean mm_thuraya_3gpp_parse_cpms_test_response (const gchar *reply,
-                                                   GArray **mem1,
-                                                   GArray **mem2,
-                                                   GArray **mem3);
+gboolean mm_thuraya_3gpp_parse_cpms_test_response (const gchar  *reply,
+                                                   GArray      **mem1,
+                                                   GArray      **mem2,
+                                                   GArray      **mem3,
+                                                   GError      **error);
 
 #endif  /* MM_MODEM_HELPERS_THURAYA_H */
diff --git a/plugins/thuraya/mm-plugin-thuraya.c b/plugins/thuraya/mm-plugin-thuraya.c
index ce1da62..64e1b45 100644
--- a/plugins/thuraya/mm-plugin-thuraya.c
+++ b/plugins/thuraya/mm-plugin-thuraya.c
@@ -31,7 +31,6 @@
 #include "mm-broadband-modem.h"
 #include "mm-broadband-modem-thuraya.h"
 #include "mm-private-boxed-types.h"
-#include "mm-log.h"
 
 G_DEFINE_TYPE (MMPluginThuraya, mm_plugin_thuraya, MM_TYPE_PLUGIN)
 
@@ -64,10 +63,10 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_THURAYA,
-                      MM_PLUGIN_NAME,                    "Thuraya",
-                      MM_PLUGIN_ALLOWED_SUBSYSTEMS,      subsystems,
-                      MM_PLUGIN_ALLOWED_VENDOR_IDS,      vendor_ids,
-                      MM_PLUGIN_ALLOWED_AT,              TRUE,
+                      MM_PLUGIN_NAME,               MM_MODULE_NAME,
+                      MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems,
+                      MM_PLUGIN_ALLOWED_VENDOR_IDS, vendor_ids,
+                      MM_PLUGIN_ALLOWED_AT,         TRUE,
                       NULL));
 }
 
diff --git a/plugins/thuraya/tests/test-mm-modem-helpers-thuraya.c b/plugins/thuraya/tests/test-mm-modem-helpers-thuraya.c
index dcd4ab2..bdc073d 100644
--- a/plugins/thuraya/tests/test-mm-modem-helpers-thuraya.c
+++ b/plugins/thuraya/tests/test-mm-modem-helpers-thuraya.c
@@ -24,7 +24,7 @@
 
 #include "mm-modem-helpers.h"
 #include "mm-modem-helpers-thuraya.h"
-#include "mm-log.h"
+#include "mm-log-test.h"
 
 /*****************************************************************************/
 /* Test CPMS response */
@@ -55,10 +55,12 @@
     GArray *mem1 = NULL;
     GArray *mem2 = NULL;
     GArray *mem3 = NULL;
+    GError *error = NULL;
 
     g_debug ("Testing thuraya +CPMS=? response...");
 
-    g_assert (mm_thuraya_3gpp_parse_cpms_test_response (reply, &mem1, &mem2, &mem3));
+    g_assert (mm_thuraya_3gpp_parse_cpms_test_response (reply, &mem1, &mem2, &mem3, &error));
+    g_assert_no_error (error);
     g_assert_cmpuint (mem1->len, ==, 5);
     g_assert (is_storage_supported (mem1, MM_SMS_STORAGE_MT));
     g_assert (is_storage_supported (mem1, MM_SMS_STORAGE_SM));
@@ -85,26 +87,6 @@
 
 /*****************************************************************************/
 
-void
-_mm_log (const char *loc,
-         const char *func,
-         guint32 level,
-         const char *fmt,
-         ...)
-{
-    va_list args;
-    gchar *msg;
-
-    if (!g_test_verbose ())
-        return;
-
-    va_start (args, fmt);
-    msg = g_strdup_vprintf (fmt, args);
-    va_end (args);
-    g_print ("%s\n", msg);
-    g_free (msg);
-}
-
 #define TESTCASE(t, d) g_test_create_case (#t, 0, d, NULL, (GTestFixtureFunc) t, NULL)
 
 int main (int argc, char **argv)
diff --git a/plugins/tplink/mm-plugin-tplink.c b/plugins/tplink/mm-plugin-tplink.c
index 20cf9db..da70d0f 100644
--- a/plugins/tplink/mm-plugin-tplink.c
+++ b/plugins/tplink/mm-plugin-tplink.c
@@ -20,7 +20,7 @@
 #include <libmm-glib.h>
 
 #include "mm-port-enums-types.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-plugin-tplink.h"
 #include "mm-broadband-modem.h"
 
@@ -46,7 +46,7 @@
 {
 #if defined WITH_QMI
     if (mm_port_probe_list_has_qmi_port (probes)) {
-        mm_dbg ("QMI-powered TP-Link modem found...");
+        mm_obj_dbg (self, "QMI-powered TP-Link modem found...");
         return MM_BASE_MODEM (mm_broadband_modem_qmi_new (uid,
                                                           drivers,
                                                           mm_plugin_get_name (self),
@@ -72,7 +72,7 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_TPLINK,
-                      MM_PLUGIN_NAME,               "TP-Link",
+                      MM_PLUGIN_NAME,               MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems,
                       MM_PLUGIN_ALLOWED_VENDOR_IDS, vendor_ids,
                       MM_PLUGIN_ALLOWED_AT,         TRUE,
diff --git a/plugins/ublox/mm-broadband-bearer-ublox.c b/plugins/ublox/mm-broadband-bearer-ublox.c
index 377ead5..1e2ea4d 100644
--- a/plugins/ublox/mm-broadband-bearer-ublox.c
+++ b/plugins/ublox/mm-broadband-bearer-ublox.c
@@ -28,7 +28,7 @@
 
 #include "mm-broadband-bearer-ublox.h"
 #include "mm-base-modem-at.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-ublox-enums-types.h"
 #include "mm-modem-helpers.h"
 #include "mm-modem-helpers-ublox.h"
@@ -56,14 +56,12 @@
 /* Common connection context and task */
 
 typedef struct {
-    MMBroadbandBearerUblox *self;
-    MMBroadbandModem       *modem;
-    MMPortSerialAt         *primary;
-    MMPort                 *data;
-    guint                   cid;
-    gboolean                auth_required;
-    /* For IPv4 settings */
-    MMBearerIpConfig       *ip_config;
+    MMBroadbandModem *modem;
+    MMPortSerialAt   *primary;
+    MMPort           *data;
+    guint             cid;
+    gboolean          auth_required;
+    MMBearerIpConfig *ip_config; /* For IPv4 settings */
 } CommonConnectContext;
 
 static void
@@ -73,7 +71,6 @@
         g_object_unref (ctx->ip_config);
     if (ctx->data)
         g_object_unref (ctx->data);
-    g_object_unref (ctx->self);
     g_object_unref (ctx->modem);
     g_object_unref (ctx->primary);
     g_slice_free (CommonConnectContext, ctx);
@@ -93,7 +90,6 @@
     GTask                *task;
 
     ctx = g_slice_new0 (CommonConnectContext);
-    ctx->self    = g_object_ref (self);
     ctx->modem   = g_object_ref (modem);
     ctx->primary = g_object_ref (primary);
     ctx->cid     = cid;
@@ -152,7 +148,7 @@
 {
     CommonConnectContext *ctx;
 
-    ctx = (CommonConnectContext *) g_task_get_task_data (task);
+    ctx = g_task_get_task_data (task);
     g_assert (mm_bearer_ip_config_get_method (ctx->ip_config) != MM_BEARER_IP_METHOD_UNKNOWN);
     g_task_return_pointer (task,
                            mm_bearer_connect_result_new (ctx->data, ctx->ip_config, NULL),
@@ -165,14 +161,16 @@
                  GAsyncResult *res,
                  GTask        *task)
 {
-    const gchar          *response;
-    GError               *error = NULL;
-    CommonConnectContext *ctx;
-    gchar                *local_address = NULL;
-    gchar                *subnet = NULL;
-    gchar                *dns_addresses[3] = { NULL, NULL, NULL };
+    MMBroadbandBearerUblox *self;
+    const gchar            *response;
+    GError                 *error = NULL;
+    CommonConnectContext   *ctx;
+    gchar                  *local_address = NULL;
+    gchar                  *subnet = NULL;
+    gchar                  *dns_addresses[3] = { NULL, NULL, NULL };
 
-    ctx = (CommonConnectContext *) g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     response = mm_base_modem_at_command_finish (modem, res, &error);
     if (!response || !mm_3gpp_parse_cgcontrdp_response (response,
@@ -190,14 +188,14 @@
         return;
     }
 
-    mm_dbg ("IPv4 address retrieved: %s", local_address);
+    mm_obj_dbg (self, "IPv4 address retrieved: %s", local_address);
     mm_bearer_ip_config_set_address (ctx->ip_config, local_address);
-    mm_dbg ("IPv4 subnet retrieved: %s", subnet);
+    mm_obj_dbg (self, "IPv4 subnet retrieved: %s", subnet);
     mm_bearer_ip_config_set_prefix (ctx->ip_config, mm_netmask_to_cidr (subnet));
     if (dns_addresses[0])
-        mm_dbg ("Primary DNS retrieved: %s", dns_addresses[0]);
+        mm_obj_dbg (self, "primary DNS retrieved: %s", dns_addresses[0]);
     if (dns_addresses[1])
-        mm_dbg ("Secondary DNS retrieved: %s", dns_addresses[1]);
+        mm_obj_dbg (self, "secondary DNS retrieved: %s", dns_addresses[1]);
     mm_bearer_ip_config_set_dns (ctx->ip_config, (const gchar **) dns_addresses);
 
     g_free (local_address);
@@ -205,7 +203,7 @@
     g_free (dns_addresses[0]);
     g_free (dns_addresses[1]);
 
-    mm_dbg ("finished IP settings retrieval for PDP context #%u...", ctx->cid);
+    mm_obj_dbg (self, "finished IP settings retrieval for PDP context #%u...", ctx->cid);
 
     complete_get_ip_config_3gpp (task);
 }
@@ -215,13 +213,15 @@
                GAsyncResult *res,
                GTask        *task)
 {
-    const gchar          *response;
-    gchar                *cmd;
-    GError               *error = NULL;
-    CommonConnectContext *ctx;
-    gchar                *gw_ipv4_address = NULL;
+    MMBroadbandBearerUblox *self;
+    const gchar            *response;
+    gchar                  *cmd;
+    GError                 *error = NULL;
+    CommonConnectContext   *ctx;
+    gchar                  *gw_ipv4_address = NULL;
 
-    ctx = (CommonConnectContext *) g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     response = mm_base_modem_at_command_finish (modem, res, &error);
     if (!response || !mm_ublox_parse_uipaddr_response (response,
@@ -237,12 +237,12 @@
         return;
     }
 
-    mm_dbg ("IPv4 gateway address retrieved: %s", gw_ipv4_address);
+    mm_obj_dbg (self, "IPv4 gateway address retrieved: %s", gw_ipv4_address);
     mm_bearer_ip_config_set_gateway (ctx->ip_config, gw_ipv4_address);
     g_free (gw_ipv4_address);
 
     cmd = g_strdup_printf ("+CGCONTRDP=%u", ctx->cid);
-    mm_dbg ("gathering IP and DNS information for PDP context #%u...", ctx->cid);
+    mm_obj_dbg (self, "gathering IP and DNS information for PDP context #%u...", ctx->cid);
     mm_base_modem_at_command (MM_BASE_MODEM (modem),
                               cmd,
                               10,
@@ -253,7 +253,7 @@
 }
 
 static void
-get_ip_config_3gpp (MMBroadbandBearer   *self,
+get_ip_config_3gpp (MMBroadbandBearer   *_self,
                     MMBroadbandModem    *modem,
                     MMPortSerialAt      *primary,
                     MMPortSerialAt      *secondary,
@@ -263,8 +263,9 @@
                     GAsyncReadyCallback  callback,
                     gpointer             user_data)
 {
-    GTask                *task;
-    CommonConnectContext *ctx;
+    MMBroadbandBearerUblox *self = MM_BROADBAND_BEARER_UBLOX (_self);
+    GTask                  *task;
+    CommonConnectContext   *ctx;
 
     if (!(task = common_connect_task_new (MM_BROADBAND_BEARER_UBLOX (self),
                                           MM_BROADBAND_MODEM (modem),
@@ -276,20 +277,20 @@
                                           user_data)))
         return;
 
-    ctx = (CommonConnectContext *) g_task_get_task_data (task);
+    ctx = g_task_get_task_data (task);
     ctx->ip_config = mm_bearer_ip_config_new ();
 
     /* If we're in BRIDGE mode, we need to ask for static IP addressing details:
      *  - AT+UIPADDR=[CID] will give us the default gateway address.
      *  - +CGCONTRDP?[CID] will give us the IP address, subnet and DNS addresses.
      */
-    if (ctx->self->priv->mode == MM_UBLOX_NETWORKING_MODE_BRIDGE) {
+    if (self->priv->mode == MM_UBLOX_NETWORKING_MODE_BRIDGE) {
         gchar *cmd;
 
         mm_bearer_ip_config_set_method (ctx->ip_config, MM_BEARER_IP_METHOD_STATIC);
 
         cmd = g_strdup_printf ("+UIPADDR=%u", cid);
-        mm_dbg ("gathering gateway information for PDP context #%u...", cid);
+        mm_obj_dbg (self, "gathering gateway information for PDP context #%u...", cid);
         mm_base_modem_at_command (MM_BASE_MODEM (modem),
                                   cmd,
                                   10,
@@ -302,7 +303,7 @@
 
     /* If we're in ROUTER networking mode, we just need to request DHCP on the
      * network interface. Early return with that result. */
-    if (ctx->self->priv->mode == MM_UBLOX_NETWORKING_MODE_ROUTER) {
+    if (self->priv->mode == MM_UBLOX_NETWORKING_MODE_ROUTER) {
         mm_bearer_ip_config_set_method (ctx->ip_config, MM_BEARER_IP_METHOD_DHCP);
         complete_get_ip_config_3gpp (task);
         return;
@@ -332,7 +333,7 @@
 
     response = mm_base_modem_at_command_finish (modem, res, &error);
     if (!response) {
-        mm_warn ("ECM data connection attempt failed: %s", error->message);
+        mm_obj_warn (self, "ECM data connection attempt failed: %s", error->message);
         mm_base_bearer_report_connection_status (MM_BASE_BEARER (self),
                                                  MM_BEARER_CONNECTION_STATUS_DISCONNECTED);
         g_error_free (error);
@@ -350,7 +351,7 @@
     GError               *error = NULL;
     CommonConnectContext *ctx;
 
-    ctx = (CommonConnectContext *) g_task_get_task_data (task);
+    ctx = g_task_get_task_data (task);
 
     response = mm_base_modem_at_command_finish (modem, res, &error);
     if (!response)
@@ -363,40 +364,42 @@
 static void
 activate_3gpp (GTask *task)
 {
-    CommonConnectContext *ctx;
-    gchar                *cmd;
+    MMBroadbandBearerUblox *self;
+    CommonConnectContext   *ctx;
+    g_autofree gchar       *cmd = NULL;
 
-    ctx = (CommonConnectContext *) g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
-    if (ctx->self->priv->profile == MM_UBLOX_USB_PROFILE_ECM &&
-        ctx->self->priv->cedata == FEATURE_SUPPORTED) {
-        /* SARA-U2xx and LISA-U20x only expose one CDC-ECM interface. Hence,
-           the fixed 0 as the interface index here. When we see modems with
-           multiple interfaces, this needs to be revisited. */
+    /* SARA-U2xx and LISA-U20x only expose one CDC-ECM interface. Hence,
+     * the fixed 0 as the interface index here. When we see modems with
+     * multiple interfaces, this needs to be revisited. */
+    if (self->priv->profile == MM_UBLOX_USB_PROFILE_ECM && self->priv->cedata == FEATURE_SUPPORTED) {
         cmd = g_strdup_printf ("+UCEDATA=%u,0", ctx->cid);
-        mm_dbg ("establishing ECM data connection for PDP context #%u...", ctx->cid);
+        mm_obj_dbg (self, "establishing ECM data connection for PDP context #%u...", ctx->cid);
         mm_base_modem_at_command (MM_BASE_MODEM (ctx->modem),
                                   cmd,
                                   180,
                                   FALSE,
                                   (GAsyncReadyCallback) cedata_activate_ready,
-                                  g_object_ref (ctx->self));
+                                  g_object_ref (self));
+
         /* We'll mark the task done here since the modem expects the DHCP
            discover packet while +UCEDATA runs. If the command fails, we'll
            mark the bearer disconnected later in the callback. */
         g_task_return_pointer (task, g_object_ref (ctx->data), g_object_unref);
         g_object_unref (task);
-   } else {
-        cmd = g_strdup_printf ("+CGACT=1,%u", ctx->cid);
-        mm_dbg ("activating PDP context #%u...", ctx->cid);
-        mm_base_modem_at_command (MM_BASE_MODEM (ctx->modem),
-                                  cmd,
-                                  120,
-                                  FALSE,
-                                  (GAsyncReadyCallback) cgact_activate_ready,
-                                  task);
-    }
-    g_free (cmd);
+        return;
+   }
+
+    cmd = g_strdup_printf ("+CGACT=1,%u", ctx->cid);
+    mm_obj_dbg (self, "activating PDP context #%u...", ctx->cid);
+    mm_base_modem_at_command (MM_BASE_MODEM (ctx->modem),
+                              cmd,
+                              120,
+                              FALSE,
+                              (GAsyncReadyCallback) cgact_activate_ready,
+                              task);
 }
 
 static void
@@ -404,18 +407,18 @@
                    GAsyncResult *res,
                    GTask        *task)
 {
-    CommonConnectContext *ctx;
-    const gchar         *response;
+    MMBroadbandBearerUblox *self;
+    const gchar            *response;
 
-    ctx = (CommonConnectContext *) g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
 
     response = mm_base_modem_at_command_finish (modem, res, NULL);
     if (response)
-        ctx->self->priv->cedata = FEATURE_SUPPORTED;
+        self->priv->cedata = FEATURE_SUPPORTED;
     else
-        ctx->self->priv->cedata = FEATURE_UNSUPPORTED;
-    mm_dbg ("u-blox: +UCEDATA command%s available",
-        (ctx->self->priv->cedata == FEATURE_SUPPORTED) ? "" : " not");
+        self->priv->cedata = FEATURE_UNSUPPORTED;
+    mm_obj_dbg (self, "+UCEDATA command%s available",
+                (self->priv->cedata == FEATURE_SUPPORTED) ? "" : " not");
 
     activate_3gpp (task);
 }
@@ -423,19 +426,20 @@
 static void
 test_cedata (GTask *task)
 {
-    CommonConnectContext *ctx;
+    MMBroadbandBearerUblox *self;
+    CommonConnectContext   *ctx;
 
-    ctx = (CommonConnectContext *) g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     /* We don't need to test for +UCEDATA if we're not using CDC-ECM or if we
        have tested before. Instead, we jump right to the activation. */
-    if (ctx->self->priv->profile != MM_UBLOX_USB_PROFILE_ECM ||
-        ctx->self->priv->cedata != FEATURE_SUPPORT_UNKNOWN) {
+    if (self->priv->profile != MM_UBLOX_USB_PROFILE_ECM || self->priv->cedata != FEATURE_SUPPORT_UNKNOWN) {
         activate_3gpp (task);
         return;
     }
 
-    mm_dbg ("u-blox: checking availability of +UCEDATA command...");
+    mm_obj_dbg (self, "checking availability of +UCEDATA command...");
     mm_base_modem_at_command (MM_BASE_MODEM (ctx->modem),
                               "+UCEDATA=?",
                               3,
@@ -456,7 +460,7 @@
     if (!response) {
         CommonConnectContext *ctx;
 
-        ctx = (CommonConnectContext *) g_task_get_task_data (task);
+        ctx = g_task_get_task_data (task);
         /* If authentication required and the +UAUTHREQ failed, abort */
         if (ctx->auth_required) {
             g_task_return_error (task, error);
@@ -475,23 +479,23 @@
 {
     MMBroadbandBearerUblox *self;
     CommonConnectContext   *ctx;
-    gchar                  *cmd = NULL;
+    g_autofree gchar       *cmd = NULL;
     MMBearerAllowedAuth     allowed_auth;
     gint                    ublox_auth = -1;
 
     self = g_task_get_source_object (task);
-    ctx = (CommonConnectContext *) g_task_get_task_data (task);
+    ctx  = g_task_get_task_data (task);
 
-    allowed_auth = mm_bearer_properties_get_allowed_auth (mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self)));
+    allowed_auth = mm_bearer_properties_get_allowed_auth (mm_base_bearer_peek_config (MM_BASE_BEARER (self)));
 
     if (!ctx->auth_required) {
-        mm_dbg ("Not using authentication");
+        mm_obj_dbg (self, "not using authentication");
         ublox_auth = 0;
         goto out;
     }
 
     if (allowed_auth == MM_BEARER_ALLOWED_AUTH_UNKNOWN || allowed_auth == (MM_BEARER_ALLOWED_AUTH_PAP | MM_BEARER_ALLOWED_AUTH_CHAP)) {
-        mm_dbg ("Using automatic authentication method");
+        mm_obj_dbg (self, "using automatic authentication method");
         if (self->priv->allowed_auths & MM_UBLOX_BEARER_ALLOWED_AUTH_AUTO)
             ublox_auth = 3;
         else if (self->priv->allowed_auths & MM_UBLOX_BEARER_ALLOWED_AUTH_PAP)
@@ -501,34 +505,33 @@
         else if (self->priv->allowed_auths & MM_UBLOX_BEARER_ALLOWED_AUTH_NONE)
             ublox_auth = 0;
     } else if (allowed_auth & MM_BEARER_ALLOWED_AUTH_PAP) {
-        mm_dbg ("Using PAP authentication method");
+        mm_obj_dbg (self, "using PAP authentication method");
         ublox_auth = 1;
     } else if (allowed_auth & MM_BEARER_ALLOWED_AUTH_CHAP) {
-        mm_dbg ("Using CHAP authentication method");
+        mm_obj_dbg (self, "using CHAP authentication method");
         ublox_auth = 2;
     }
 
 out:
 
     if (ublox_auth < 0) {
-        gchar *str;
+        g_autofree gchar *str = NULL;
 
         str = mm_bearer_allowed_auth_build_string_from_mask (allowed_auth);
         g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED,
                                  "Cannot use any of the specified authentication methods (%s)", str);
         g_object_unref (task);
-        g_free (str);
         return;
     }
 
     if (ublox_auth > 0) {
-        const gchar *user;
-        const gchar *password;
-        gchar       *quoted_user;
-        gchar       *quoted_password;
+        const gchar      *user;
+        const gchar      *password;
+        g_autofree gchar *quoted_user = NULL;
+        g_autofree gchar *quoted_password = NULL;
 
-        user     = mm_bearer_properties_get_user     (mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self)));
-        password = mm_bearer_properties_get_password (mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self)));
+        user     = mm_bearer_properties_get_user     (mm_base_bearer_peek_config (MM_BASE_BEARER (self)));
+        password = mm_bearer_properties_get_password (mm_base_bearer_peek_config (MM_BASE_BEARER (self)));
 
         quoted_user     = mm_port_serial_at_quote_string (user);
         quoted_password = mm_port_serial_at_quote_string (password);
@@ -538,20 +541,16 @@
                                ublox_auth,
                                quoted_user,
                                quoted_password);
-
-        g_free (quoted_user);
-        g_free (quoted_password);
     } else
         cmd = g_strdup_printf ("+UAUTHREQ=%u,0,\"\",\"\"", ctx->cid);
 
-    mm_dbg ("setting up authentication preferences in PDP context #%u...", ctx->cid);
+    mm_obj_dbg (self, "setting up authentication preferences in PDP context #%u...", ctx->cid);
     mm_base_modem_at_command (MM_BASE_MODEM (ctx->modem),
                               cmd,
                               10,
                               FALSE,
                               (GAsyncReadyCallback) uauthreq_ready,
                               task);
-    g_free (cmd);
 }
 
 static void
@@ -569,12 +568,12 @@
     if (!response)
         goto out;
 
-    self->priv->allowed_auths = mm_ublox_parse_uauthreq_test (response, &error);
+    self->priv->allowed_auths = mm_ublox_parse_uauthreq_test (response, self, &error);
 out:
     if (error) {
         CommonConnectContext *ctx;
 
-        ctx = (CommonConnectContext *) g_task_get_task_data (task);
+        ctx = g_task_get_task_data (task);
         /* If authentication required and the +UAUTHREQ test failed, abort */
         if (ctx->auth_required) {
             g_task_return_error (task, error);
@@ -601,11 +600,11 @@
     MMBearerAllowedAuth     allowed_auth;
 
     self = g_task_get_source_object (task);
-    ctx = (CommonConnectContext *) g_task_get_task_data (task);
+    ctx  = g_task_get_task_data (task);
 
-    user         = mm_bearer_properties_get_user         (mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self)));
-    password     = mm_bearer_properties_get_password     (mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self)));
-    allowed_auth = mm_bearer_properties_get_allowed_auth (mm_base_bearer_peek_config (MM_BASE_BEARER (ctx->self)));
+    user         = mm_bearer_properties_get_user         (mm_base_bearer_peek_config (MM_BASE_BEARER (self)));
+    password     = mm_bearer_properties_get_password     (mm_base_bearer_peek_config (MM_BASE_BEARER (self)));
+    allowed_auth = mm_bearer_properties_get_allowed_auth (mm_base_bearer_peek_config (MM_BASE_BEARER (self)));
 
     /* Flag whether authentication is required. If it isn't, we won't fail
      * connection attempt if the +UAUTHREQ command fails */
@@ -617,7 +616,7 @@
         return;
     }
 
-    mm_dbg ("checking supported authentication methods...");
+    mm_obj_dbg (self, "checking supported authentication methods...");
     mm_base_modem_at_command (MM_BASE_MODEM (ctx->modem),
                               "+UAUTHREQ=?",
                               10,
@@ -666,8 +665,11 @@
                         GAsyncResult *res,
                         GTask        *task)
 {
-    const gchar *response;
-    GError      *error = NULL;
+    MMBroadbandBearerUblox *self;
+    const gchar            *response;
+    GError                 *error = NULL;
+
+    self = g_task_get_source_object (task);
 
     response = mm_base_modem_at_command_finish (modem, res, &error);
     if (!response) {
@@ -693,7 +695,7 @@
             return;
         }
 
-        mm_dbg ("ignored error when disconnecting last LTE bearer: %s", error->message);
+        mm_obj_dbg (self, "ignored error when disconnecting last LTE bearer: %s", error->message);
         g_clear_error (&error);
     }
 
@@ -711,8 +713,8 @@
                   GAsyncReadyCallback  callback,
                   gpointer             user_data)
 {
-    GTask *task;
-    gchar *cmd;
+    GTask            *task;
+    g_autofree gchar *cmd = NULL;
 
     if (!(task = common_connect_task_new (MM_BROADBAND_BEARER_UBLOX (self),
                                           MM_BROADBAND_MODEM (modem),
@@ -725,14 +727,13 @@
         return;
 
     cmd = g_strdup_printf ("+CGACT=0,%u", cid);
-    mm_dbg ("deactivating PDP context #%u...", cid);
+    mm_obj_dbg (self, "deactivating PDP context #%u...", cid);
     mm_base_modem_at_command (MM_BASE_MODEM (modem),
                               cmd,
                               120,
                               FALSE,
                               (GAsyncReadyCallback) cgact_deactivate_ready,
                               task);
-    g_free (cmd);
 }
 
 /*****************************************************************************/
diff --git a/plugins/ublox/mm-broadband-modem-ublox.c b/plugins/ublox/mm-broadband-modem-ublox.c
index d5ce452..0af2e93 100644
--- a/plugins/ublox/mm-broadband-modem-ublox.c
+++ b/plugins/ublox/mm-broadband-modem-ublox.c
@@ -22,7 +22,7 @@
 #include <ctype.h>
 
 #include "ModemManager.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-iface-modem.h"
 #include "mm-iface-modem-3gpp.h"
 #include "mm-iface-modem-voice.h"
@@ -87,7 +87,7 @@
     model = mm_iface_modem_get_model (MM_IFACE_MODEM (self));
 
     if (!mm_ublox_get_support_config (model, &self->priv->support_config, &error)) {
-        mm_warn ("loading support configuration failed: %s", error->message);
+        mm_obj_warn (self, "loading support configuration failed: %s", error->message);
         g_error_free (error);
 
         /* default to NOT SUPPORTED if unknown model */
@@ -95,14 +95,14 @@
         self->priv->support_config.uact = FEATURE_UNSUPPORTED;
         self->priv->support_config.ubandsel = FEATURE_UNSUPPORTED;
     } else
-        mm_dbg ("support configuration found for '%s'", model);
+        mm_obj_dbg (self, "support configuration found for '%s'", model);
 
     switch (self->priv->support_config.method) {
         case SETTINGS_UPDATE_METHOD_CFUN:
-            mm_dbg ("  band update requires low-power mode");
+            mm_obj_dbg (self, "  band update requires low-power mode");
             break;
         case SETTINGS_UPDATE_METHOD_COPS:
-            mm_dbg ("  band update requires explicit unregistration");
+            mm_obj_dbg (self, "  band update requires explicit unregistration");
             break;
         case SETTINGS_UPDATE_METHOD_UNKNOWN:
             /* not an error, this just means we don't need anything special */
@@ -113,10 +113,10 @@
 
     switch (self->priv->support_config.uact) {
         case FEATURE_SUPPORTED:
-            mm_dbg ("  UACT based band configuration supported");
+            mm_obj_dbg (self, "  UACT based band configuration supported");
             break;
         case FEATURE_UNSUPPORTED:
-            mm_dbg ("  UACT based band configuration unsupported");
+            mm_obj_dbg (self, "  UACT based band configuration unsupported");
             break;
         case FEATURE_SUPPORT_UNKNOWN:
         default:
@@ -125,10 +125,10 @@
 
     switch (self->priv->support_config.ubandsel) {
         case FEATURE_SUPPORTED:
-            mm_dbg ("  UBANDSEL based band configuration supported");
+            mm_obj_dbg (self, "  UBANDSEL based band configuration supported");
             break;
         case FEATURE_UNSUPPORTED:
-            mm_dbg ("  UBANDSEL based band configuration unsupported");
+            mm_obj_dbg (self, "  UBANDSEL based band configuration unsupported");
             break;
         case FEATURE_SUPPORT_UNKNOWN:
         default:
@@ -182,7 +182,7 @@
     model = mm_iface_modem_get_model (self);
     task  = g_task_new (self, NULL, callback, user_data);
 
-    bands = mm_ublox_get_supported_bands (model, &error);
+    bands = mm_ublox_get_supported_bands (model, self, &error);
     if (!bands)
         g_task_return_error (task, error);
     else
@@ -246,7 +246,7 @@
     }
 
     model = mm_iface_modem_get_model (MM_IFACE_MODEM (self));
-    out = mm_ublox_parse_ubandsel_response (response, model, &error);
+    out = mm_ublox_parse_ubandsel_response (response, model, self, &error);
     if (!out) {
         g_task_return_error (task, error);
         g_object_unref (task);
@@ -311,7 +311,6 @@
 } SetCurrentModesBandsStep;
 
 typedef struct {
-    MMBroadbandModemUblox    *self;
     SetCurrentModesBandsStep  step;
     gchar                    *command;
     MMModemPowerState         initial_state;
@@ -323,19 +322,16 @@
 {
     g_assert (!ctx->saved_error);
     g_free (ctx->command);
-    g_object_unref (ctx->self);
     g_slice_free (SetCurrentModesBandsContext, ctx);
 }
 
 static void
-set_current_modes_bands_context_new (GTask        *task,
-                                     MMIfaceModem *self,
-                                     gchar        *command)
+set_current_modes_bands_context_new (GTask *task,
+                                     gchar *command)
 {
     SetCurrentModesBandsContext *ctx;
 
     ctx = g_slice_new0 (SetCurrentModesBandsContext);
-    ctx->self = MM_BROADBAND_MODEM_UBLOX (g_object_ref (self));
     ctx->command = command;
     ctx->initial_state = MM_MODEM_POWER_STATE_UNKNOWN;
     ctx->step = SET_CURRENT_MODES_BANDS_STEP_FIRST;
@@ -359,8 +355,7 @@
 {
     SetCurrentModesBandsContext *ctx;
 
-    ctx = (SetCurrentModesBandsContext *) g_task_get_task_data (task);
-    g_assert (ctx);
+    ctx = g_task_get_task_data (task);
 
     /* propagate the error if none already set */
     mm_iface_modem_3gpp_reregister_in_network_finish (self, res, ctx->saved_error ? NULL : &ctx->saved_error);
@@ -377,8 +372,7 @@
 {
     SetCurrentModesBandsContext *ctx;
 
-    ctx = (SetCurrentModesBandsContext *) g_task_get_task_data (task);
-    g_assert (ctx);
+    ctx = g_task_get_task_data (task);
 
     /* propagate the error if none already set */
     mm_base_modem_at_command_finish (self, res, ctx->saved_error ? NULL : &ctx->saved_error);
@@ -395,8 +389,7 @@
 {
     SetCurrentModesBandsContext *ctx;
 
-    ctx = (SetCurrentModesBandsContext *) g_task_get_task_data (task);
-    g_assert (ctx);
+    ctx = g_task_get_task_data (task);
 
     if (!mm_base_modem_at_command_finish (self, res, &ctx->saved_error))
         ctx->step = SET_CURRENT_MODES_BANDS_STEP_RELEASE;
@@ -413,8 +406,7 @@
 {
     SetCurrentModesBandsContext *ctx;
 
-    ctx = (SetCurrentModesBandsContext *) g_task_get_task_data (task);
-    g_assert (ctx);
+    ctx = g_task_get_task_data (task);
 
     if (!mm_base_modem_at_command_finish (self, res, &ctx->saved_error))
         ctx->step = SET_CURRENT_MODES_BANDS_STEP_RELEASE;
@@ -425,18 +417,19 @@
 }
 
 static void
-set_current_modes_bands_current_power_ready (MMBaseModem  *self,
+set_current_modes_bands_current_power_ready (MMBaseModem  *_self,
                                              GAsyncResult *res,
                                              GTask        *task)
 {
+    MMBroadbandModemUblox       *self = MM_BROADBAND_MODEM_UBLOX (_self);
     SetCurrentModesBandsContext *ctx;
     const gchar                 *response;
 
-    ctx = (SetCurrentModesBandsContext *) g_task_get_task_data (task);
-    g_assert (ctx);
-    g_assert (ctx->self->priv->support_config.method == SETTINGS_UPDATE_METHOD_CFUN);
+    ctx = g_task_get_task_data (task);
 
-    response = mm_base_modem_at_command_finish (self, res, &ctx->saved_error);
+    g_assert (self->priv->support_config.method == SETTINGS_UPDATE_METHOD_CFUN);
+
+    response = mm_base_modem_at_command_finish (_self, res, &ctx->saved_error);
     if (!response || !mm_ublox_parse_cfun_response (response, &ctx->initial_state, &ctx->saved_error))
         ctx->step = SET_CURRENT_MODES_BANDS_STEP_RELEASE;
     else
@@ -448,10 +441,11 @@
 static void
 set_current_modes_bands_step (GTask *task)
 {
+    MMBroadbandModemUblox       *self;
     SetCurrentModesBandsContext *ctx;
 
-    ctx = (SetCurrentModesBandsContext *) g_task_get_task_data (task);
-    g_assert (ctx);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     switch (ctx->step) {
     case SET_CURRENT_MODES_BANDS_STEP_FIRST:
@@ -459,8 +453,8 @@
         /* fall through */
 
     case SET_CURRENT_MODES_BANDS_STEP_ACQUIRE:
-        mm_dbg ("acquiring power operation...");
-        if (!acquire_power_operation (ctx->self, &ctx->saved_error)) {
+        mm_obj_dbg (self, "acquiring power operation...");
+        if (!acquire_power_operation (self, &ctx->saved_error)) {
             ctx->step = SET_CURRENT_MODES_BANDS_STEP_LAST;
             set_current_modes_bands_step (task);
             return;
@@ -472,9 +466,9 @@
         /* If using CFUN, we check whether we're already in low-power mode.
          * And if we are, we just skip triggering low-power mode ourselves.
          */
-        if (ctx->self->priv->support_config.method == SETTINGS_UPDATE_METHOD_CFUN) {
-            mm_dbg ("checking current power operation...");
-            mm_base_modem_at_command (MM_BASE_MODEM (ctx->self),
+        if (self->priv->support_config.method == SETTINGS_UPDATE_METHOD_CFUN) {
+            mm_obj_dbg (self, "checking current power operation...");
+            mm_base_modem_at_command (MM_BASE_MODEM (self),
                                       "+CFUN?",
                                       3,
                                       FALSE,
@@ -487,10 +481,10 @@
 
     case SET_CURRENT_MODES_BANDS_STEP_BEFORE_COMMAND:
         /* If COPS required around the set command, run it unconditionally */
-        if (ctx->self->priv->support_config.method == SETTINGS_UPDATE_METHOD_COPS) {
-            mm_dbg ("deregistering from the network for configuration change...");
+        if (self->priv->support_config.method == SETTINGS_UPDATE_METHOD_COPS) {
+            mm_obj_dbg (self, "deregistering from the network for configuration change...");
             mm_base_modem_at_command (
-                    MM_BASE_MODEM (ctx->self),
+                    MM_BASE_MODEM (self),
                     "+COPS=2",
                     10,
                     FALSE,
@@ -499,12 +493,12 @@
                 return;
         }
         /* If CFUN required, check initial state before triggering low-power mode ourselves */
-        else if (ctx->self->priv->support_config.method == SETTINGS_UPDATE_METHOD_CFUN) {
+        else if (self->priv->support_config.method == SETTINGS_UPDATE_METHOD_CFUN) {
             /* Do nothing if already in low-power mode */
             if (ctx->initial_state != MM_MODEM_POWER_STATE_LOW) {
-                mm_dbg ("powering down for configuration change...");
+                mm_obj_dbg (self, "powering down for configuration change...");
                 mm_base_modem_at_command (
-                    MM_BASE_MODEM (ctx->self),
+                    MM_BASE_MODEM (self),
                     "+CFUN=4",
                     3,
                     FALSE,
@@ -518,9 +512,9 @@
         /* fall through */
 
     case SET_CURRENT_MODES_BANDS_STEP_COMMAND:
-        mm_dbg ("updating configuration...");
+        mm_obj_dbg (self, "updating configuration...");
         mm_base_modem_at_command (
-            MM_BASE_MODEM (ctx->self),
+            MM_BASE_MODEM (self),
             ctx->command,
             3,
             FALSE,
@@ -530,20 +524,20 @@
 
     case SET_CURRENT_MODES_BANDS_STEP_AFTER_COMMAND:
         /* If COPS required around the set command, run it unconditionally */
-        if (ctx->self->priv->support_config.method == SETTINGS_UPDATE_METHOD_COPS) {
-            mm_iface_modem_3gpp_reregister_in_network (MM_IFACE_MODEM_3GPP (ctx->self),
+        if (self->priv->support_config.method == SETTINGS_UPDATE_METHOD_COPS) {
+            mm_iface_modem_3gpp_reregister_in_network (MM_IFACE_MODEM_3GPP (self),
                                                        (GAsyncReadyCallback) set_current_modes_bands_reregister_in_network_ready,
                                                        task);
             return;
         }
         /* If CFUN required, see if we need to recover power */
-        else if (ctx->self->priv->support_config.method == SETTINGS_UPDATE_METHOD_CFUN) {
+        else if (self->priv->support_config.method == SETTINGS_UPDATE_METHOD_CFUN) {
             /* If we were in low-power mode before the change, do nothing, otherwise,
              * full power mode back */
             if (ctx->initial_state != MM_MODEM_POWER_STATE_LOW) {
-                mm_dbg ("recovering power state after configuration change...");
+                mm_obj_dbg (self, "recovering power state after configuration change...");
                 mm_base_modem_at_command (
-                    MM_BASE_MODEM (ctx->self),
+                    MM_BASE_MODEM (self),
                     "+CFUN=1",
                     3,
                     FALSE,
@@ -556,8 +550,8 @@
         /* fall through */
 
     case SET_CURRENT_MODES_BANDS_STEP_RELEASE:
-        mm_dbg ("releasing power operation...");
-        release_power_operation (ctx->self);
+        mm_obj_dbg (self, "releasing power operation...");
+        release_power_operation (self);
         ctx->step++;
         /* fall through */
 
@@ -602,7 +596,7 @@
         return;
     }
 
-    set_current_modes_bands_context_new (task, self, command);
+    set_current_modes_bands_context_new (task, command);
     set_current_modes_bands_step (task);
 }
 
@@ -636,7 +630,7 @@
         return;
     }
 
-    set_current_modes_bands_context_new (task, _self, command);
+    set_current_modes_bands_context_new (task, command);
     set_current_modes_bands_step (task);
 }
 
@@ -656,7 +650,7 @@
     if (!response)
         return FALSE;
 
-    return mm_ublox_parse_urat_read_response (response, allowed, preferred, error);
+    return mm_ublox_parse_urat_read_response (response, self, allowed, preferred, error);
 }
 
 static void
@@ -687,10 +681,10 @@
     if (!response)
         return FALSE;
 
-    if (!(combinations = mm_ublox_parse_urat_test_response (response, error)))
+    if (!(combinations = mm_ublox_parse_urat_test_response (response, self, error)))
         return FALSE;
 
-    if (!(combinations = mm_ublox_filter_supported_modes (mm_iface_modem_get_model (self), combinations, error)))
+    if (!(combinations = mm_ublox_filter_supported_modes (mm_iface_modem_get_model (self), combinations, self, error)))
         return FALSE;
 
     /* Decide and store which combination to apply when ANY requested */
@@ -929,9 +923,9 @@
     ctx = g_task_get_task_data (task);
 
     if (!mm_base_modem_at_command_full_finish (self, res, &error)) {
-        mm_dbg ("Couldn't %s +UUDTMFD reporting: '%s'",
-                ctx->enable ? "enable" : "disable",
-                error->message);
+        mm_obj_dbg (self, "couldn't %s +UUDTMFD reporting: '%s'",
+                    ctx->enable ? "enable" : "disable",
+                    error->message);
         g_error_free (error);
     }
 
@@ -950,9 +944,9 @@
     ctx = g_task_get_task_data (task);
 
     if (!mm_base_modem_at_command_full_finish (self, res, &error)) {
-        mm_dbg ("Couldn't %s +UCALLSTAT reporting: '%s'",
-                ctx->enable ? "enable" : "disable",
-                error->message);
+        mm_obj_dbg (self, "couldn't %s +UCALLSTAT reporting: '%s'",
+                    ctx->enable ? "enable" : "disable",
+                    error->message);
         g_error_free (error);
     }
 
@@ -966,7 +960,7 @@
     MMBroadbandModemUblox         *self;
     VoiceUnsolicitedEventsContext *ctx;
 
-    self = MM_BROADBAND_MODEM_UBLOX (g_task_get_source_object (task));
+    self = g_task_get_source_object (task);
     ctx  = g_task_get_task_data (task);
 
     switch (ctx->step) {
@@ -976,8 +970,8 @@
 
     case VOICE_UNSOLICITED_EVENTS_STEP_UCALLSTAT_PRIMARY:
         if (ctx->primary) {
-            mm_dbg ("%s extended call status reporting in primary port...",
-                    ctx->enable ? "Enabling" : "Disabling");
+            mm_obj_dbg (self, "%s extended call status reporting in primary port...",
+                        ctx->enable ? "enabling" : "disabling");
             mm_base_modem_at_command_full (MM_BASE_MODEM (self),
                                            ctx->primary,
                                            ctx->ucallstat_command,
@@ -994,8 +988,8 @@
 
     case VOICE_UNSOLICITED_EVENTS_STEP_UCALLSTAT_SECONDARY:
         if (ctx->secondary) {
-            mm_dbg ("%s extended call status reporting in secondary port...",
-                    ctx->enable ? "Enabling" : "Disabling");
+            mm_obj_dbg (self, "%s extended call status reporting in secondary port...",
+                        ctx->enable ? "enabling" : "disabling");
             mm_base_modem_at_command_full (MM_BASE_MODEM (self),
                                            ctx->secondary,
                                            ctx->ucallstat_command,
@@ -1012,8 +1006,8 @@
 
     case VOICE_UNSOLICITED_EVENTS_STEP_UDTMFD_PRIMARY:
         if ((self->priv->udtmfd_support == FEATURE_SUPPORTED) && (ctx->primary)) {
-            mm_dbg ("%s DTMF detection and reporting in primary port...",
-                    ctx->enable ? "Enabling" : "Disabling");
+            mm_obj_dbg (self, "%s DTMF detection and reporting in primary port...",
+                        ctx->enable ? "enabling" : "disabling");
             mm_base_modem_at_command_full (MM_BASE_MODEM (self),
                                            ctx->primary,
                                            ctx->udtmfd_command,
@@ -1030,8 +1024,8 @@
 
     case VOICE_UNSOLICITED_EVENTS_STEP_UDTMFD_SECONDARY:
         if ((self->priv->udtmfd_support == FEATURE_SUPPORTED) && (ctx->secondary)) {
-            mm_dbg ("%s DTMF detection and reporting in secondary port...",
-                    ctx->enable ? "Enabling" : "Disabling");
+            mm_obj_dbg (self, "%s DTMF detection and reporting in secondary port...",
+                        ctx->enable ? "enabling" : "disabling");
             mm_base_modem_at_command_full (MM_BASE_MODEM (self),
                                            ctx->secondary,
                                            ctx->udtmfd_command,
@@ -1103,7 +1097,7 @@
     GError *error = NULL;
 
     if (!common_voice_enable_disable_unsolicited_events_finish (self, res, &error)) {
-        mm_warn ("Couldn't enable u-blox-specific voice unsolicited events: %s", error->message);
+        mm_obj_warn (self, "Couldn't enable u-blox-specific voice unsolicited events: %s", error->message);
         g_error_free (error);
     }
 
@@ -1182,7 +1176,7 @@
     GError *error = NULL;
 
     if (!common_voice_enable_disable_unsolicited_events_finish (self, res, &error)) {
-        mm_warn ("Couldn't disable u-blox-specific voice unsolicited events: %s", error->message);
+        mm_obj_warn (self, "Couldn't disable u-blox-specific voice unsolicited events: %s", error->message);
         g_error_free (error);
     }
 
@@ -1230,14 +1224,14 @@
     guint      aux;
 
     if (!mm_get_uint_from_match_info (match_info, 1, &aux)) {
-        mm_warn ("couldn't parse call index from +UCALLSTAT");
+        mm_obj_warn (self, "couldn't parse call index from +UCALLSTAT");
         return;
     }
     call_info.index = aux;
 
     if (!mm_get_uint_from_match_info (match_info, 2, &aux) ||
         (aux >= G_N_ELEMENTS (ublox_call_state))) {
-        mm_warn ("couldn't parse call state from +UCALLSTAT");
+        mm_obj_warn (self, "couldn't parse call state from +UCALLSTAT");
         return;
     }
     call_info.state = ublox_call_state[aux];
@@ -1269,13 +1263,12 @@
                  GMatchInfo            *match_info,
                  MMBroadbandModemUblox *self)
 {
-    gchar *dtmf;
+    g_autofree gchar *dtmf = NULL;
 
     dtmf = g_match_info_fetch (match_info, 1);
-    mm_dbg ("received DTMF: %s", dtmf);
+    mm_obj_dbg (self, "received DTMF: %s", dtmf);
     /* call index unknown */
     mm_iface_modem_voice_received_dtmf (MM_IFACE_MODEM_VOICE (self), 0, dtmf);
-    g_free (dtmf);
 }
 
 static void
@@ -1333,7 +1326,7 @@
     GError *error = NULL;
 
     if (!iface_modem_voice_parent->cleanup_unsolicited_events_finish (self, res, &error)) {
-        mm_warn ("Couldn't cleanup parent voice unsolicited events: %s", error->message);
+        mm_obj_warn (self, "Couldn't cleanup parent voice unsolicited events: %s", error->message);
         g_error_free (error);
     }
 
@@ -1379,7 +1372,7 @@
     GError  *error = NULL;
 
     if (!iface_modem_voice_parent->setup_unsolicited_events_finish (self, res, &error)) {
-        mm_warn ("Couldn't setup parent voice unsolicited events: %s", error->message);
+        mm_obj_warn (self, "Couldn't setup parent voice unsolicited events: %s", error->message);
         g_error_free (error);
     }
 
@@ -1497,20 +1490,17 @@
 } CreateBearerStep;
 
 typedef struct {
-    MMBroadbandModemUblox *self;
-    CreateBearerStep       step;
-    MMBearerProperties    *properties;
-    MMBaseBearer          *bearer;
-    gboolean               has_net;
+    CreateBearerStep    step;
+    MMBearerProperties *properties;
+    MMBaseBearer       *bearer;
+    gboolean            has_net;
 } CreateBearerContext;
 
 static void
 create_bearer_context_free (CreateBearerContext *ctx)
 {
-    if (ctx->bearer)
-        g_object_unref (ctx->bearer);
+    g_clear_object (&ctx->bearer);
     g_object_unref (ctx->properties);
-    g_object_unref (ctx->self);
     g_slice_free (CreateBearerContext, ctx);
 }
 
@@ -1529,10 +1519,12 @@
                             GAsyncResult *res,
                             GTask        *task)
 {
-    CreateBearerContext *ctx;
-    GError *error = NULL;
+    MMBroadbandModemUblox *self;
+    CreateBearerContext   *ctx;
+    GError                *error = NULL;
 
-    ctx = (CreateBearerContext *) g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     g_assert (!ctx->bearer);
     ctx->bearer = mm_broadband_bearer_new_finish (res, &error);
@@ -1542,7 +1534,7 @@
         return;
     }
 
-    mm_dbg ("u-blox: new generic broadband bearer created at DBus path '%s'", mm_base_bearer_get_path (ctx->bearer));
+    mm_obj_dbg (self, "new generic broadband bearer created at DBus path '%s'", mm_base_bearer_get_path (ctx->bearer));
     ctx->step++;
     create_bearer_step (task);
 }
@@ -1552,10 +1544,12 @@
                                   GAsyncResult *res,
                                   GTask        *task)
 {
-    CreateBearerContext *ctx;
-    GError *error = NULL;
+    MMBroadbandModemUblox *self;
+    CreateBearerContext   *ctx;
+    GError                *error = NULL;
 
-    ctx = (CreateBearerContext *) g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     g_assert (!ctx->bearer);
     ctx->bearer = mm_broadband_bearer_ublox_new_finish (res, &error);
@@ -1565,74 +1559,76 @@
         return;
     }
 
-    mm_dbg ("u-blox: new u-blox broadband bearer created at DBus path '%s'", mm_base_bearer_get_path (ctx->bearer));
+    mm_obj_dbg (self, "new u-blox broadband bearer created at DBus path '%s'", mm_base_bearer_get_path (ctx->bearer));
     ctx->step++;
     create_bearer_step (task);
 }
 
 static void
-mode_check_ready (MMBaseModem  *self,
+mode_check_ready (MMBaseModem  *_self,
                   GAsyncResult *res,
                   GTask        *task)
 {
-    const gchar *response;
-    GError *error = NULL;
-    CreateBearerContext *ctx;
+    MMBroadbandModemUblox *self = MM_BROADBAND_MODEM_UBLOX (_self);
+    const gchar           *response;
+    GError                *error = NULL;
+    CreateBearerContext   *ctx;
 
-    ctx = (CreateBearerContext *) g_task_get_task_data (task);
+    ctx = g_task_get_task_data (task);
 
-    response = mm_base_modem_at_command_finish (self, res, &error);
+    response = mm_base_modem_at_command_finish (_self, res, &error);
     if (!response) {
-        mm_dbg ("u-blox: couldn't load current networking mode: %s", error->message);
+        mm_obj_dbg (self, "couldn't load current networking mode: %s", error->message);
         g_error_free (error);
-    } else if (!mm_ublox_parse_ubmconf_response (response, &ctx->self->priv->mode, &error)) {
-        mm_dbg ("u-blox: couldn't parse current networking mode response '%s': %s", response, error->message);
+    } else if (!mm_ublox_parse_ubmconf_response (response, &self->priv->mode, &error)) {
+        mm_obj_dbg (self, "couldn't parse current networking mode response '%s': %s", response, error->message);
         g_error_free (error);
     } else {
-        g_assert (ctx->self->priv->mode != MM_UBLOX_NETWORKING_MODE_UNKNOWN);
-        mm_dbg ("u-blox: networking mode loaded: %s", mm_ublox_networking_mode_get_string (ctx->self->priv->mode));
+        g_assert (self->priv->mode != MM_UBLOX_NETWORKING_MODE_UNKNOWN);
+        mm_obj_dbg (self, "networking mode loaded: %s", mm_ublox_networking_mode_get_string (self->priv->mode));
     }
 
     /* If checking networking mode isn't supported, we'll fallback to
      * assume the device is in router mode, which is the mode asking for
      * less connection setup rules from our side (just request DHCP).
      */
-    if (ctx->self->priv->mode == MM_UBLOX_NETWORKING_MODE_UNKNOWN && ctx->has_net) {
-        mm_dbg ("u-blox: fallback to default networking mode: router");
-        ctx->self->priv->mode = MM_UBLOX_NETWORKING_MODE_ROUTER;
+    if (self->priv->mode == MM_UBLOX_NETWORKING_MODE_UNKNOWN && ctx->has_net) {
+        mm_obj_dbg (self, "fallback to default networking mode: router");
+        self->priv->mode = MM_UBLOX_NETWORKING_MODE_ROUTER;
     }
 
-    ctx->self->priv->mode_checked = TRUE;
+    self->priv->mode_checked = TRUE;
 
     ctx->step++;
     create_bearer_step (task);
 }
 
 static void
-profile_check_ready (MMBaseModem  *self,
+profile_check_ready (MMBaseModem  *_self,
                      GAsyncResult *res,
                      GTask        *task)
 {
-    const gchar *response;
-    GError *error = NULL;
-    CreateBearerContext *ctx;
+    MMBroadbandModemUblox *self = MM_BROADBAND_MODEM_UBLOX (_self);
+    const gchar           *response;
+    GError                *error = NULL;
+    CreateBearerContext   *ctx;
 
-    ctx = (CreateBearerContext *) g_task_get_task_data (task);
+    ctx = g_task_get_task_data (task);
 
-    response = mm_base_modem_at_command_finish (self, res, &error);
+    response = mm_base_modem_at_command_finish (_self, res, &error);
     if (!response) {
-        mm_dbg ("u-blox: couldn't load current usb profile: %s", error->message);
+        mm_obj_dbg (self, "couldn't load current usb profile: %s", error->message);
         g_error_free (error);
-    } else if (!mm_ublox_parse_uusbconf_response (response, &ctx->self->priv->profile, &error)) {
-        mm_dbg ("u-blox: couldn't parse current usb profile response '%s': %s", response, error->message);
+    } else if (!mm_ublox_parse_uusbconf_response (response, &self->priv->profile, &error)) {
+        mm_obj_dbg (self, "couldn't parse current usb profile response '%s': %s", response, error->message);
         g_error_free (error);
     } else {
-        g_assert (ctx->self->priv->profile != MM_UBLOX_USB_PROFILE_UNKNOWN);
-        mm_dbg ("u-blox: usb profile loaded: %s", mm_ublox_usb_profile_get_string (ctx->self->priv->profile));
+        g_assert (self->priv->profile != MM_UBLOX_USB_PROFILE_UNKNOWN);
+        mm_obj_dbg (self, "usb profile loaded: %s", mm_ublox_usb_profile_get_string (self->priv->profile));
     }
 
     /* Assume the operation has been performed, even if it may have failed */
-    ctx->self->priv->profile_checked = TRUE;
+    self->priv->profile_checked = TRUE;
 
     ctx->step++;
     create_bearer_step (task);
@@ -1641,19 +1637,22 @@
 static void
 create_bearer_step (GTask *task)
 {
-    CreateBearerContext *ctx;
+    MMBroadbandModemUblox *self;
+    CreateBearerContext   *ctx;
 
-    ctx = (CreateBearerContext *) g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
+
     switch (ctx->step) {
     case CREATE_BEARER_STEP_FIRST:
         ctx->step++;
         /* fall through */
 
     case CREATE_BEARER_STEP_CHECK_PROFILE:
-        if (!ctx->self->priv->profile_checked) {
-            mm_dbg ("u-blox: checking current USB profile...");
+        if (!self->priv->profile_checked) {
+            mm_obj_dbg (self, "checking current USB profile...");
             mm_base_modem_at_command (
-                MM_BASE_MODEM (ctx->self),
+                MM_BASE_MODEM (self),
                 "+UUSBCONF?",
                 3,
                 FALSE,
@@ -1665,10 +1664,10 @@
         /* fall through */
 
     case CREATE_BEARER_STEP_CHECK_MODE:
-        if (!ctx->self->priv->mode_checked) {
-            mm_dbg ("u-blox: checking current networking mode...");
+        if (!self->priv->mode_checked) {
+            mm_obj_dbg (self, "checking current networking mode...");
             mm_base_modem_at_command (
-                MM_BASE_MODEM (ctx->self),
+                MM_BASE_MODEM (self),
                 "+UBMCONF?",
                 3,
                 FALSE,
@@ -1682,16 +1681,16 @@
     case CREATE_BEARER_STEP_CREATE_BEARER:
         /* If we have a net interface, we'll create a u-blox bearer, unless for
          * any reason we have the back-compatible profile selected. */
-        if ((ctx->self->priv->profile != MM_UBLOX_USB_PROFILE_BACK_COMPATIBLE) && ctx->has_net) {
+        if ((self->priv->profile != MM_UBLOX_USB_PROFILE_BACK_COMPATIBLE) && ctx->has_net) {
             /* whenever there is a net port, we should have loaded a valid networking mode */
-            g_assert (ctx->self->priv->mode != MM_UBLOX_NETWORKING_MODE_UNKNOWN);
-            mm_dbg ("u-blox: creating u-blox broadband bearer (%s profile, %s mode)...",
-                    mm_ublox_usb_profile_get_string (ctx->self->priv->profile),
-                    mm_ublox_networking_mode_get_string (ctx->self->priv->mode));
+            g_assert (self->priv->mode != MM_UBLOX_NETWORKING_MODE_UNKNOWN);
+            mm_obj_dbg (self, "creating u-blox broadband bearer (%s profile, %s mode)...",
+                        mm_ublox_usb_profile_get_string (self->priv->profile),
+                        mm_ublox_networking_mode_get_string (self->priv->mode));
             mm_broadband_bearer_ublox_new (
-                MM_BROADBAND_MODEM (ctx->self),
-                ctx->self->priv->profile,
-                ctx->self->priv->mode,
+                MM_BROADBAND_MODEM (self),
+                self->priv->profile,
+                self->priv->mode,
                 ctx->properties,
                 NULL, /* cancellable */
                 (GAsyncReadyCallback) broadband_bearer_ublox_new_ready,
@@ -1701,8 +1700,8 @@
 
         /* If usb profile is back-compatible already, or if there is no NET port
          * available, create default generic bearer */
-        mm_dbg ("u-blox: creating generic broadband bearer...");
-        mm_broadband_bearer_new (MM_BROADBAND_MODEM (ctx->self),
+        mm_obj_dbg (self, "creating generic broadband bearer...");
+        mm_broadband_bearer_new (MM_BROADBAND_MODEM (self),
                                  ctx->properties,
                                  NULL, /* cancellable */
                                  (GAsyncReadyCallback) broadband_bearer_new_ready,
@@ -1733,7 +1732,6 @@
 
     ctx = g_slice_new0 (CreateBearerContext);
     ctx->step = CREATE_BEARER_STEP_FIRST;
-    ctx->self = g_object_ref (self);
     ctx->properties = g_object_ref (properties);
 
     /* Flag whether this modem has exposed a network interface */
diff --git a/plugins/ublox/mm-modem-helpers-ublox.c b/plugins/ublox/mm-modem-helpers-ublox.c
index df6b6a2..fe1719c 100644
--- a/plugins/ublox/mm-modem-helpers-ublox.c
+++ b/plugins/ublox/mm-modem-helpers-ublox.c
@@ -365,6 +365,7 @@
 
 GArray *
 mm_ublox_parse_urat_test_response (const gchar  *response,
+                                   gpointer      log_object,
                                    GError      **error)
 {
     GArray *combinations = NULL;
@@ -415,7 +416,7 @@
 
         selected_value = g_array_index (selected, guint, i);
         if (selected_value >= G_N_ELEMENTS (ublox_combinations)) {
-            mm_warn ("Unexpected AcT value: %u", selected_value);
+            mm_obj_warn (log_object, "unexpected AcT value: %u", selected_value);
             continue;
         }
 
@@ -435,12 +436,12 @@
 
             preferred_value = g_array_index (preferred, guint, j);
             if (preferred_value >= G_N_ELEMENTS (ublox_combinations)) {
-                mm_warn ("Unexpected AcT preferred value: %u", preferred_value);
+                mm_obj_warn (log_object, "unexpected AcT preferred value: %u", preferred_value);
                 continue;
             }
             combination.preferred = ublox_combinations[preferred_value];
             if (mm_count_bits_set (combination.preferred) != 1) {
-                mm_warn ("AcT preferred value should be a single AcT: %u", preferred_value);
+                mm_obj_warn (log_object, "AcT preferred value should be a single AcT: %u", preferred_value);
                 continue;
             }
             if (!(combination.allowed & combination.preferred))
@@ -980,6 +981,7 @@
 GArray *
 mm_ublox_filter_supported_modes (const gchar  *model,
                                  GArray       *combinations,
+                                 gpointer      logger,
                                  GError      **error)
 {
     MMModemModeCombination mode;
@@ -1002,7 +1004,7 @@
 
     all = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 1);
     g_array_append_val (all, mode);
-    filtered = mm_filter_supported_modes (all, combinations);
+    filtered = mm_filter_supported_modes (all, combinations, logger);
     g_array_unref (all);
     g_array_unref (combinations);
 
@@ -1022,6 +1024,7 @@
 
 GArray *
 mm_ublox_get_supported_bands (const gchar  *model,
+                              gpointer      log_object,
                               GError      **error)
 {
     MMModemMode  mode;
@@ -1033,13 +1036,13 @@
 
     for (i = 0; i < G_N_ELEMENTS (band_configuration); i++) {
         if (g_str_has_prefix (model, band_configuration[i].model)) {
-            mm_dbg("Found Model (Supported Bands): %s", band_configuration[i].model);
+            mm_obj_dbg (log_object, "known supported bands found for model: %s", band_configuration[i].model);
             break;
         }
     }
 
     if (i == G_N_ELEMENTS (band_configuration)) {
-        mm_warn ("Unknown model name given: %s", model);
+        mm_obj_warn (log_object, "unknown model name given when looking for supported bands: %s", model);
         return NULL;
     }
 
@@ -1174,19 +1177,22 @@
 append_bands (GArray      *bands,
               guint        ubandsel_value,
               MMModemMode  mode,
-              const gchar *model)
+              const gchar *model,
+              gpointer     log_object)
 {
     guint i, j, k, x;
     MMModemBand band;
 
     /* Find Modem Model Index in band_configuration */
     for (i = 0; i < G_N_ELEMENTS (band_configuration); i++) {
-        if (g_str_has_prefix (model, band_configuration[i].model))
+        if (g_str_has_prefix (model, band_configuration[i].model)) {
+            mm_obj_dbg (log_object, "known bands found for model: %s", band_configuration[i].model);
             break;
+        }
     }
 
     if (i == G_N_ELEMENTS (band_configuration)) {
-        mm_warn ("Unknown Modem Model given: %s", model);
+        mm_obj_warn (log_object, "unknown model name given when looking for bands: %s", model);
         return;
     }
 
@@ -1241,6 +1247,7 @@
 GArray *
 mm_ublox_parse_ubandsel_response (const gchar  *response,
                                   const gchar  *model,
+                                  gpointer      log_object,
                                   GError      **error)
 {
     GArray      *array_values = NULL;
@@ -1269,7 +1276,7 @@
     mode = supported_modes_per_model (model);
     array = g_array_new (FALSE, FALSE, sizeof (MMModemBand));
     for (i = 0; i < array_values->len; i++)
-        append_bands (array, g_array_index (array_values, guint, i), mode, model);
+        append_bands (array, g_array_index (array_values, guint, i), mode, model, log_object);
 
     if (!array->len) {
         inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
@@ -1590,7 +1597,8 @@
 
 static GArray *
 parse_bands_from_string (const gchar *str,
-                         const gchar *group)
+                         const gchar *group,
+                         gpointer     log_object)
 {
     GArray *bands = NULL;
     GError *inner_error = NULL;
@@ -1602,12 +1610,12 @@
 
         bands = uact_num_array_to_band_array (nums);
         tmpstr = mm_common_build_bands_string ((MMModemBand *)(bands->data), bands->len);
-        mm_dbg ("modem reports support for %s bands: %s", group, tmpstr);
+        mm_obj_dbg (log_object, "modem reports support for %s bands: %s", group, tmpstr);
         g_free (tmpstr);
 
         g_array_unref (nums);
     } else if (inner_error) {
-        mm_warn ("couldn't parse list of supported %s bands: %s", group, inner_error->message);
+        mm_obj_warn (log_object, "couldn't parse list of supported %s bands: %s", group, inner_error->message);
         g_clear_error (&inner_error);
     }
 
@@ -1616,6 +1624,7 @@
 
 gboolean
 mm_ublox_parse_uact_test (const gchar  *response,
+                          gpointer      log_object,
                           GArray      **bands2g_out,
                           GArray      **bands3g_out,
                           GArray      **bands4g_out,
@@ -1668,9 +1677,9 @@
         goto out;
     }
 
-    bands2g = parse_bands_from_string (bands2g_str, "2G");
-    bands3g = parse_bands_from_string (bands3g_str, "3G");
-    bands4g = parse_bands_from_string (bands4g_str, "4G");
+    bands2g = parse_bands_from_string (bands2g_str, "2G", log_object);
+    bands3g = parse_bands_from_string (bands3g_str, "3G", log_object);
+    bands4g = parse_bands_from_string (bands4g_str, "4G", log_object);
 
     if (!bands2g->len && !bands3g->len && !bands4g->len) {
         inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
@@ -1744,6 +1753,7 @@
 
 gboolean
 mm_ublox_parse_urat_read_response (const gchar  *response,
+                                   gpointer      log_object,
                                    MMModemMode  *out_allowed,
                                    MMModemMode  *out_preferred,
                                    GError      **error)
@@ -1782,7 +1792,7 @@
         }
         allowed = ublox_combinations[value];
         allowed_str = mm_modem_mode_build_string_from_mask (allowed);
-        mm_dbg ("current allowed modes retrieved: %s", allowed_str);
+        mm_obj_dbg (log_object, "current allowed modes retrieved: %s", allowed_str);
 
         /* Preferred item is optional */
         if (mm_get_uint_from_match_info (match_info, 2, &value)) {
@@ -1793,7 +1803,7 @@
             }
             preferred = ublox_combinations[value];
             preferred_str = mm_modem_mode_build_string_from_mask (preferred);
-            mm_dbg ("current preferred modes retrieved: %s", preferred_str);
+            mm_obj_dbg (log_object, "current preferred modes retrieved: %s", preferred_str);
             if (mm_count_bits_set (preferred) != 1) {
                 inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
                                            "AcT preferred value should be a single AcT: %s", preferred_str);
@@ -1883,6 +1893,7 @@
 
 MMUbloxBearerAllowedAuth
 mm_ublox_parse_uauthreq_test (const char  *response,
+                              gpointer     log_object,
                               GError     **error)
 {
     MMUbloxBearerAllowedAuth   mask = MM_UBLOX_BEARER_ALLOWED_AUTH_UNKNOWN;
@@ -1930,7 +1941,7 @@
                     mask |= MM_UBLOX_BEARER_ALLOWED_AUTH_AUTO;
                     break;
                 default:
-                    mm_warn ("Unexpected +UAUTHREQ value: %u", val);
+                    mm_obj_warn (log_object, "unexpected +UAUTHREQ value: %u", val);
                     break;
             }
         }
diff --git a/plugins/ublox/mm-modem-helpers-ublox.h b/plugins/ublox/mm-modem-helpers-ublox.h
index 121a983..06bba00 100644
--- a/plugins/ublox/mm-modem-helpers-ublox.h
+++ b/plugins/ublox/mm-modem-helpers-ublox.h
@@ -101,6 +101,7 @@
 /* URAT=? response parser */
 
 GArray *mm_ublox_parse_urat_test_response (const gchar  *response,
+                                           gpointer      log_object,
                                            GError      **error);
 
 /*****************************************************************************/
@@ -115,12 +116,14 @@
 
 GArray *mm_ublox_filter_supported_modes (const gchar  *model,
                                          GArray       *combinations,
+                                         gpointer      logger,
                                          GError      **error);
 
 /*****************************************************************************/
 /* Model-based supported bands loading */
 
 GArray *mm_ublox_get_supported_bands (const gchar *model,
+                                      gpointer     log_object,
                                       GError     **error);
 
 /*****************************************************************************/
@@ -128,6 +131,7 @@
 
 GArray *mm_ublox_parse_ubandsel_response (const gchar  *response,
                                           const gchar  *model,
+                                          gpointer      log_object,
                                           GError      **error);
 
 /*****************************************************************************/
@@ -147,6 +151,7 @@
 /* UACT=? test parser */
 
 gboolean mm_ublox_parse_uact_test (const gchar  *response,
+                                   gpointer      log_object,
                                    GArray      **bands_2g,
                                    GArray      **bands_3g,
                                    GArray      **bands_4g,
@@ -167,6 +172,7 @@
 /* URAT? response parser */
 
 gboolean mm_ublox_parse_urat_read_response (const gchar  *response,
+                                            gpointer      log_object,
                                             MMModemMode  *out_allowed,
                                             MMModemMode  *out_preferred,
                                             GError      **error);
@@ -190,6 +196,7 @@
 } MMUbloxBearerAllowedAuth;
 
 MMUbloxBearerAllowedAuth mm_ublox_parse_uauthreq_test (const char  *response,
+                                                       gpointer     log_object,
                                                        GError     **error);
 
 /*****************************************************************************/
diff --git a/plugins/ublox/mm-plugin-ublox.c b/plugins/ublox/mm-plugin-ublox.c
index 6a0d140..569054b 100644
--- a/plugins/ublox/mm-plugin-ublox.c
+++ b/plugins/ublox/mm-plugin-ublox.c
@@ -19,7 +19,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-serial-parsers.h"
 #include "mm-broadband-modem-ublox.h"
 #include "mm-plugin-ublox.h"
@@ -88,9 +88,7 @@
     mm_port_serial_at_add_unsolicited_msg_handler (ctx->port, ctx->ready_regex,
                                                    NULL, NULL, NULL);
 
-    mm_dbg ("(%s/%s) timed out waiting for READY unsolicited message",
-            mm_port_probe_get_port_subsys (probe),
-            mm_port_probe_get_port_name   (probe));
+    mm_obj_dbg (probe, "timed out waiting for READY unsolicited message");
 
     /* not an error really, we didn't probe anything yet, that's all */
     g_task_return_boolean (task, TRUE);
@@ -113,9 +111,7 @@
     g_source_remove (ctx->timeout_id);
     ctx->timeout_id = 0;
 
-    mm_dbg ("(%s/%s) READY received: port is AT",
-            mm_port_probe_get_port_subsys (probe),
-            mm_port_probe_get_port_name   (probe));
+    mm_obj_dbg (probe, "received READY: port is AT");
 
     /* Flag as an AT port right away */
     mm_port_probe_set_result_at (probe, TRUE);
@@ -133,9 +129,7 @@
     ctx   = g_task_get_task_data     (task);
     probe = g_task_get_source_object (task);
 
-    mm_dbg ("(%s/%s) waiting for READY unsolicited message...",
-            mm_port_probe_get_port_subsys (probe),
-            mm_port_probe_get_port_name   (probe));
+    mm_obj_dbg (probe, "waiting for READY unsolicited message...");
 
     /* Configure a regex on the TTY, so that we stop the custom init
      * as soon as +READY URC is received */
@@ -145,10 +139,7 @@
                                                    task,
                                                    NULL);
 
-    mm_dbg ("(%s/%s) waiting %d seconds for init timeout",
-            mm_port_probe_get_port_subsys (probe),
-            mm_port_probe_get_port_name   (probe),
-            ctx->wait_timeout_secs);
+    mm_obj_dbg (probe, "waiting %d seconds for init timeout", ctx->wait_timeout_secs);
 
     /* Otherwise, let the custom init timeout in some seconds. */
     ctx->timeout_id = g_timeout_add_seconds (ctx->wait_timeout_secs, (GSourceFunc) ready_timeout, task);
@@ -160,7 +151,7 @@
                 GTask          *task)
 {
     MMPortProbe       *probe;
-    GError            *error = NULL;
+    g_autoptr(GError)  error = NULL;
 
     probe = g_task_get_source_object (task);
 
@@ -169,28 +160,21 @@
         /* On a timeout error, wait for READY URC */
         if (g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_RESPONSE_TIMEOUT)) {
             wait_for_ready (task);
-            goto out;
+            return;
         }
         /* On an unknown error, make it fatal */
         if (!mm_serial_parser_v1_is_known_error (error)) {
-            mm_warn ("(%s/%s) custom port initialization logic failed: %s",
-                    mm_port_probe_get_port_subsys (probe),
-                    mm_port_probe_get_port_name   (probe),
-                    error->message);
-            goto out_complete;
+            mm_obj_warn (probe, "custom port initialization logic failed: %s", error->message);
+            goto out;
         }
     }
 
-    mm_dbg ("(%s/%s) port is AT",
-            mm_port_probe_get_port_subsys (probe),
-            mm_port_probe_get_port_name   (probe));
+    mm_obj_dbg (probe, "port is AT");
     mm_port_probe_set_result_at (probe, TRUE);
 
-out_complete:
+out:
     g_task_return_boolean (task, TRUE);
     g_object_unref (task);
-out:
-    g_clear_error (&error);
 }
 
 static void
@@ -256,7 +240,7 @@
     };
 
     return MM_PLUGIN (g_object_new (MM_TYPE_PLUGIN_UBLOX,
-                                    MM_PLUGIN_NAME,                   "u-blox",
+                                    MM_PLUGIN_NAME,                   MM_MODULE_NAME,
                                     MM_PLUGIN_ALLOWED_SUBSYSTEMS,     subsystems,
                                     MM_PLUGIN_ALLOWED_VENDOR_IDS,     vendor_ids,
                                     MM_PLUGIN_ALLOWED_VENDOR_STRINGS, vendor_strings,
diff --git a/plugins/ublox/tests/test-modem-helpers-ublox.c b/plugins/ublox/tests/test-modem-helpers-ublox.c
index 17a4641..2d66287 100644
--- a/plugins/ublox/tests/test-modem-helpers-ublox.c
+++ b/plugins/ublox/tests/test-modem-helpers-ublox.c
@@ -22,7 +22,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-test.h"
 #include "mm-modem-helpers.h"
 #include "mm-modem-helpers-ublox.h"
 
@@ -290,11 +290,11 @@
     GError *error = NULL;
     guint i;
 
-    combinations = mm_ublox_parse_urat_test_response (response, &error);
+    combinations = mm_ublox_parse_urat_test_response (response, NULL, &error);
     g_assert_no_error (error);
     g_assert (combinations);
 
-    combinations = mm_ublox_filter_supported_modes (model, combinations, &error);
+    combinations = mm_ublox_filter_supported_modes (model, combinations, NULL, &error);
     g_assert_no_error (error);
     g_assert (combinations);
 
@@ -461,7 +461,7 @@
         GError      *error = NULL;
         gboolean     success;
 
-        success = mm_ublox_parse_urat_read_response (urat_tests[i].response,
+        success = mm_ublox_parse_urat_read_response (urat_tests[i].response, NULL,
                                                      &allowed, &preferred, &error);
         g_assert_no_error (error);
         g_assert (success);
@@ -498,7 +498,7 @@
     GError *error = NULL;
     GArray *bands;
 
-    bands = mm_ublox_parse_ubandsel_response (str, model, &error);
+    bands = mm_ublox_parse_ubandsel_response (str, model, NULL, &error);
     g_assert_no_error (error);
     g_assert (bands);
 
@@ -701,7 +701,7 @@
     GArray   *bands_3g = NULL;
     GArray   *bands_4g = NULL;
 
-    result = mm_ublox_parse_uact_test (str, &bands_2g, &bands_3g, &bands_4g, &error);
+    result = mm_ublox_parse_uact_test (str, NULL, &bands_2g, &bands_3g, &bands_4g, &error);
     g_assert_no_error (error);
     g_assert (result);
 
@@ -858,7 +858,7 @@
     GError                   *error = NULL;
     MMUbloxBearerAllowedAuth  allowed_auths;
 
-    allowed_auths = mm_ublox_parse_uauthreq_test (str, &error);
+    allowed_auths = mm_ublox_parse_uauthreq_test (str, NULL, &error);
     g_assert_no_error (error);
     g_assert_cmpuint (allowed_auths, ==, expected_allowed_auths);
 }
@@ -979,26 +979,6 @@
 
 /*****************************************************************************/
 
-void
-_mm_log (const char *loc,
-         const char *func,
-         guint32 level,
-         const char *fmt,
-         ...)
-{
-    va_list args;
-    gchar *msg;
-
-    if (!g_test_verbose ())
-        return;
-
-    va_start (args, fmt);
-    msg = g_strdup_vprintf (fmt, args);
-    va_end (args);
-    g_print ("%s\n", msg);
-    g_free (msg);
-}
-
 int main (int argc, char **argv)
 {
     setlocale (LC_ALL, "");
diff --git a/plugins/via/mm-broadband-modem-via.c b/plugins/via/mm-broadband-modem-via.c
index 6e2cfe6..24ea6d0 100644
--- a/plugins/via/mm-broadband-modem-via.c
+++ b/plugins/via/mm-broadband-modem-via.c
@@ -24,7 +24,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-modem-helpers.h"
 #include "mm-errors-types.h"
 #include "mm-base-modem-at.h"
@@ -199,7 +199,7 @@
     /* Try to parse the results */
     g_regex_match (r, response, 0, &match_info);
     if (g_match_info_get_match_count (match_info) < 6) {
-        mm_warn ("Via: failed to parse ^SYSINFO response: '%s'", response);
+        mm_obj_warn (self, "failed to parse ^SYSINFO response: '%s'", response);
         goto out;
     }
 
@@ -232,7 +232,7 @@
         }
     } else {
         /* Say we're registered to something even though sysmode parsing failed */
-        mm_dbg ("SYSMODE parsing failed: assuming registered at least in CDMA1x");
+        mm_obj_dbg (self, "SYSMODE parsing failed: assuming registered at least in CDMA1x");
         results->detailed_cdma1x_state = reg_state;
     }
 
@@ -282,7 +282,7 @@
 
     if (mm_get_uint_from_match_info (match_info, 1, &quality)) {
         quality = MM_CLAMP_HIGH (quality, 100);
-        mm_dbg ("EVDO signal quality: %u", quality);
+        mm_obj_dbg (self, "EVDO signal quality: %u", quality);
         mm_iface_modem_update_signal_quality (MM_IFACE_MODEM (self), quality);
     }
 }
diff --git a/plugins/via/mm-plugin-via.c b/plugins/via/mm-plugin-via.c
index 2e9e704..f12c650 100644
--- a/plugins/via/mm-plugin-via.c
+++ b/plugins/via/mm-plugin-via.c
@@ -27,7 +27,6 @@
 
 #include "mm-broadband-modem-via.h"
 #include "mm-plugin-via.h"
-#include "mm-log.h"
 
 G_DEFINE_TYPE (MMPluginVia, mm_plugin_via, MM_TYPE_PLUGIN)
 
@@ -62,7 +61,7 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_VIA,
-                      MM_PLUGIN_NAME,                    "Via CBP7",
+                      MM_PLUGIN_NAME,                    MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS,      subsystems,
                       MM_PLUGIN_ALLOWED_PRODUCT_STRINGS, product_strings,
                       MM_PLUGIN_ALLOWED_AT,              TRUE,
diff --git a/plugins/wavecom/mm-broadband-modem-wavecom.c b/plugins/wavecom/mm-broadband-modem-wavecom.c
index 47980d8..8362055 100644
--- a/plugins/wavecom/mm-broadband-modem-wavecom.c
+++ b/plugins/wavecom/mm-broadband-modem-wavecom.c
@@ -27,7 +27,7 @@
 #include <libmm-glib.h>
 
 #include "ModemManager.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-serial-parsers.h"
 #include "mm-modem-helpers.h"
 #include "mm-iface-modem.h"
@@ -176,7 +176,7 @@
     g_array_append_val (combinations, mode);
 
     /* Filter out those unsupported modes */
-    filtered = mm_filter_supported_modes (all, combinations);
+    filtered = mm_filter_supported_modes (all, combinations, self);
     g_array_unref (all);
     g_array_unref (combinations);
 
@@ -341,7 +341,7 @@
     if (strncmp (response,
                  WAVECOM_MS_CLASS_A_IDSTR,
                  strlen (WAVECOM_MS_CLASS_A_IDSTR)) == 0) {
-        mm_dbg ("Modem configured as a Class A mobile station");
+        mm_obj_dbg (self, "configured as a Class A mobile station");
         /* For 3G devices, query WWSM status */
         mm_base_modem_at_command (self,
                                   "+WWSM?",
@@ -358,19 +358,19 @@
     if (strncmp (response,
                  WAVECOM_MS_CLASS_B_IDSTR,
                  strlen (WAVECOM_MS_CLASS_B_IDSTR)) == 0) {
-        mm_dbg ("Modem configured as a Class B mobile station");
+        mm_obj_dbg (self, "configured as a Class B mobile station");
         result.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_CS);
         result.preferred = MM_MODEM_MODE_2G;
     } else if (strncmp (response,
                         WAVECOM_MS_CLASS_CG_IDSTR,
                         strlen (WAVECOM_MS_CLASS_CG_IDSTR)) == 0) {
-        mm_dbg ("Modem configured as a Class CG mobile station");
+        mm_obj_dbg (self, "configured as a Class CG mobile station");
         result.allowed = MM_MODEM_MODE_2G;
         result.preferred = MM_MODEM_MODE_NONE;
     } else if (strncmp (response,
                         WAVECOM_MS_CLASS_CC_IDSTR,
                         strlen (WAVECOM_MS_CLASS_CC_IDSTR)) == 0) {
-        mm_dbg ("Modem configured as a Class CC mobile station");
+        mm_obj_dbg (self, "configured as a Class CC mobile station");
         result.allowed = MM_MODEM_MODE_CS;
         result.preferred = MM_MODEM_MODE_NONE;
     }
@@ -812,7 +812,6 @@
         return;
     }
 
-    mm_dbg ("Setting new bands to use: '%s'", bands_string);
     cmd = g_strdup_printf ("+WMBS=\"%u\",1", wavecom_band);
     mm_base_modem_at_command (MM_BASE_MODEM (self),
                               cmd,
@@ -885,7 +884,6 @@
         return;
     }
 
-    mm_dbg ("Setting new bands to use: '%s'", bands_string);
     cmd = g_strdup_printf ("+WMBS=%c,1", wavecom_band);
     mm_base_modem_at_command (MM_BASE_MODEM (self),
                               cmd,
@@ -1090,7 +1088,7 @@
         return;
     }
 
-    mm_dbg ("Device is already in automatic registration mode, not requesting it again");
+    mm_obj_dbg (self, "device is already in automatic registration mode, not requesting it again");
 
 out:
     if (error)
@@ -1181,8 +1179,8 @@
                 GAsyncReadyCallback callback,
                 gpointer user_data)
 {
-    mm_warn ("Not in full functionality status, power-up command is needed. "
-             "Note that it may reboot the modem.");
+    mm_obj_warn (self, "not in full functionality status, power-up command is needed");
+    mm_obj_warn (self, "the device maybe rebooted");
 
     /* Try to go to full functionality mode without rebooting the system.
      * Works well if we previously switched off the power with CFUN=4
@@ -1258,7 +1256,7 @@
     MM_BROADBAND_MODEM_CLASS (mm_broadband_modem_wavecom_parent_class)->setup_ports (self);
 
     /* Set 9600 baudrate by default in the AT port */
-    mm_dbg ("Baudrate will be set to 9600 bps...");
+    mm_obj_dbg (self, "baudrate will be set to 9600 bps...");
     primary = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));
     if (!primary)
         return;
diff --git a/plugins/wavecom/mm-plugin-wavecom.c b/plugins/wavecom/mm-plugin-wavecom.c
index 8ed217b..22b1ba4 100644
--- a/plugins/wavecom/mm-plugin-wavecom.c
+++ b/plugins/wavecom/mm-plugin-wavecom.c
@@ -65,7 +65,7 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_WAVECOM,
-                      MM_PLUGIN_NAME,               "Wavecom",
+                      MM_PLUGIN_NAME,               MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems,
                       MM_PLUGIN_ALLOWED_VENDOR_IDS, vendor_ids,
                       MM_PLUGIN_FORBIDDEN_DRIVERS,  forbidden_drivers,
diff --git a/plugins/x22x/mm-broadband-modem-x22x.c b/plugins/x22x/mm-broadband-modem-x22x.c
index 0d7794a..dcd1add 100644
--- a/plugins/x22x/mm-broadband-modem-x22x.c
+++ b/plugins/x22x/mm-broadband-modem-x22x.c
@@ -90,7 +90,7 @@
     g_array_append_val (combinations, mode);
 
     /* Filter out those unsupported modes */
-    filtered = mm_filter_supported_modes (all, combinations);
+    filtered = mm_filter_supported_modes (all, combinations, self);
     g_array_unref (all);
     g_array_unref (combinations);
 
@@ -300,7 +300,6 @@
                           GAsyncReadyCallback callback,
                           gpointer user_data)
 {
-    mm_dbg ("loading access technology (x22x)...");
     mm_base_modem_at_command (MM_BASE_MODEM (self),
                               "+SSND?",
                               3,
diff --git a/plugins/x22x/mm-plugin-x22x.c b/plugins/x22x/mm-plugin-x22x.c
index 795d30a..248d5fd 100644
--- a/plugins/x22x/mm-plugin-x22x.c
+++ b/plugins/x22x/mm-plugin-x22x.c
@@ -21,7 +21,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-modem-helpers.h"
 #include "mm-plugin-x22x.h"
 #include "mm-broadband-modem-x22x.h"
@@ -62,12 +62,15 @@
 
 static void
 gmr_ready (MMPortSerialAt *port,
-           GAsyncResult *res,
-           GTask *task)
+           GAsyncResult   *res,
+           GTask          *task)
 {
+    MMPortProbe *probe;
     const gchar *p;
     const gchar *response;
-    GError *error = NULL;
+    GError      *error = NULL;
+
+    probe = g_task_get_source_object (task);
 
     response = mm_port_serial_at_command_finish (port, res, &error);
     if (error) {
@@ -90,7 +93,7 @@
                                  MM_CORE_ERROR_UNSUPPORTED,
                                  "Not supported with the X22X plugin");
     } else {
-        mm_dbg ("(X22X) device is supported by this plugin");
+        mm_obj_dbg (probe, "(X22X) device is supported by this plugin");
         g_task_return_boolean (task, TRUE);
     }
     g_object_unref (task);
@@ -99,16 +102,17 @@
 static void
 x22x_custom_init_step (GTask *task)
 {
+    MMPortProbe           *probe;
     X22xCustomInitContext *ctx;
-    GCancellable *cancellable;
+    GCancellable          *cancellable;
 
-    ctx = g_task_get_task_data (task);
+    probe       = g_task_get_source_object (task);
+    ctx         = g_task_get_task_data (task);
     cancellable = g_task_get_cancellable (task);
 
     /* If cancelled, end */
     if (g_cancellable_is_cancelled (cancellable)) {
-        mm_dbg ("(X22X) no need to keep on running custom init in (%s)",
-                mm_port_get_device (MM_PORT (ctx->port)));
+        mm_obj_dbg (probe, "(X22X) no need to keep on running custom init");
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
         return;
@@ -190,7 +194,7 @@
 {
 #if defined WITH_QMI
     if (mm_port_probe_list_has_qmi_port (probes)) {
-        mm_dbg ("QMI-powered X22X modem found...");
+        mm_obj_dbg (self, "QMI-powered X22X modem found...");
         return MM_BASE_MODEM (mm_broadband_modem_qmi_new (uid,
                                                           drivers,
                                                           mm_plugin_get_name (self),
@@ -226,7 +230,7 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_X22X,
-                      MM_PLUGIN_NAME,               "X22X",
+                      MM_PLUGIN_NAME,               MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems,
                       MM_PLUGIN_ALLOWED_VENDOR_IDS, vendor_ids,
                       MM_PLUGIN_ALLOWED_AT,         TRUE,
diff --git a/plugins/xmm/mm-broadband-modem-mbim-xmm.c b/plugins/xmm/mm-broadband-modem-mbim-xmm.c
index 1aa8b7b..781d7e4 100644
--- a/plugins/xmm/mm-broadband-modem-mbim-xmm.c
+++ b/plugins/xmm/mm-broadband-modem-mbim-xmm.c
@@ -22,7 +22,6 @@
 #include <ctype.h>
 
 #include "ModemManager.h"
-#include "mm-log.h"
 #include "mm-iface-modem.h"
 #include "mm-iface-modem-location.h"
 #include "mm-broadband-modem-mbim-xmm.h"
diff --git a/plugins/xmm/mm-broadband-modem-xmm.c b/plugins/xmm/mm-broadband-modem-xmm.c
index ab32216..35103d8 100644
--- a/plugins/xmm/mm-broadband-modem-xmm.c
+++ b/plugins/xmm/mm-broadband-modem-xmm.c
@@ -22,7 +22,6 @@
 #include <ctype.h>
 
 #include "ModemManager.h"
-#include "mm-log.h"
 #include "mm-iface-modem.h"
 #include "mm-iface-modem-location.h"
 #include "mm-broadband-modem-xmm.h"
diff --git a/plugins/xmm/mm-modem-helpers-xmm.c b/plugins/xmm/mm-modem-helpers-xmm.c
index 4ccbc74..9b3933d 100644
--- a/plugins/xmm/mm-modem-helpers-xmm.c
+++ b/plugins/xmm/mm-modem-helpers-xmm.c
@@ -172,6 +172,7 @@
 
 gboolean
 mm_xmm_parse_xact_test_response (const gchar  *response,
+                                 gpointer      log_object,
                                  GArray      **modes_out,
                                  GArray      **bands_out,
                                  GError      **error)
@@ -231,7 +232,7 @@
         supported_value = g_array_index (supported, guint, i);
 
         if (supported_value >= G_N_ELEMENTS (xmm_modes)) {
-            mm_warn ("Unexpected AcT supported value: %u", supported_value);
+            mm_obj_warn (log_object, "unexpected AcT supported value: %u", supported_value);
             continue;
         }
 
@@ -251,12 +252,12 @@
 
             preferred_value = g_array_index (preferred, guint, j);
             if (preferred_value >= G_N_ELEMENTS (xmm_modes)) {
-                mm_warn ("Unexpected AcT preferred value: %u", preferred_value);
+                mm_obj_warn (log_object, "unexpected AcT preferred value: %u", preferred_value);
                 continue;
             }
             combination.preferred = xmm_modes[preferred_value];
             if (mm_count_bits_set (combination.preferred) != 1) {
-                mm_warn ("AcT preferred value should be a single AcT: %u", preferred_value);
+                mm_obj_warn (log_object, "AcT preferred value should be a single AcT: %u", preferred_value);
                 continue;
             }
             if (!(combination.allowed & combination.preferred))
@@ -283,7 +284,7 @@
         guint       num;
 
         if (!mm_get_uint_from_str (split[i], &num)) {
-            mm_warn ("Unexpected band value: %s", split[i]);
+            mm_obj_warn (log_object, "unexpected band value: %s", split[i]);
             continue;
         }
 
@@ -292,7 +293,7 @@
 
         band = xact_num_to_band (num);
         if (band == MM_MODEM_BAND_UNKNOWN) {
-            mm_warn ("Unsupported band value: %s", split[i]);
+            mm_obj_warn (log_object, "unsupported band value: %s", split[i]);
             continue;
         }
 
@@ -318,7 +319,7 @@
     all_modes = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 1);
     g_array_append_val (all_modes, all);
 
-    filtered = mm_filter_supported_modes (all_modes, modes);
+    filtered = mm_filter_supported_modes (all_modes, modes, log_object);
     if (!filtered || filtered->len == 0) {
         inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
                                    "Empty supported mode list after frequency band filtering");
@@ -696,8 +697,9 @@
 }
 
 static gboolean
-rssnr_level_to_rssnr (gint     rssnr_level,
-                      gdouble *out_rssnr)
+rssnr_level_to_rssnr (gint      rssnr_level,
+                      gpointer  log_object,
+                      gdouble  *out_rssnr)
 {
     if (rssnr_level <= 100 &&
         rssnr_level >= -100) {
@@ -706,7 +708,7 @@
     }
 
     if (rssnr_level != 255)
-        mm_warn ("unexpected RSSNR level: %u", rssnr_level);
+        mm_obj_warn (log_object, "unexpected RSSNR level: %u", rssnr_level);
     return FALSE;
 }
 
@@ -715,6 +717,7 @@
 
 gboolean
 mm_xmm_xcesq_response_to_signal_info (const gchar  *response,
+                                      gpointer      log_object,
                                       MMSignal    **out_gsm,
                                       MMSignal    **out_umts,
                                       MMSignal    **out_lte,
@@ -745,7 +748,7 @@
         return FALSE;
 
     /* GERAN RSSI */
-    if (mm_3gpp_rxlev_to_rssi (rxlev, &rssi)) {
+    if (mm_3gpp_rxlev_to_rssi (rxlev, log_object, &rssi)) {
         gsm = mm_signal_new ();
         mm_signal_set_rssi (gsm, rssi);
     }
@@ -753,13 +756,13 @@
     /* ignore BER */
 
     /* UMTS RSCP */
-    if (mm_3gpp_rscp_level_to_rscp (rscp_level, &rscp)) {
+    if (mm_3gpp_rscp_level_to_rscp (rscp_level, log_object, &rscp)) {
         umts = mm_signal_new ();
         mm_signal_set_rscp (umts, rscp);
     }
 
     /* UMTS EcIo (assumed EcN0) */
-    if (mm_3gpp_ecn0_level_to_ecio (ecn0_level, &ecio)) {
+    if (mm_3gpp_ecn0_level_to_ecio (ecn0_level, log_object, &ecio)) {
         if (!umts)
             umts = mm_signal_new ();
         mm_signal_set_ecio (umts, ecio);
@@ -771,20 +774,20 @@
     }
 
     /* LTE RSRQ */
-    if (mm_3gpp_rsrq_level_to_rsrq (rsrq_level, &rsrq)) {
+    if (mm_3gpp_rsrq_level_to_rsrq (rsrq_level, log_object, &rsrq)) {
         lte = mm_signal_new ();
         mm_signal_set_rsrq (lte, rsrq);
     }
 
     /* LTE RSRP */
-    if (mm_3gpp_rsrp_level_to_rsrp (rsrp_level, &rsrp)) {
+    if (mm_3gpp_rsrp_level_to_rsrp (rsrp_level, log_object, &rsrp)) {
         if (!lte)
             lte = mm_signal_new ();
         mm_signal_set_rsrp (lte, rsrp);
     }
 
     /* LTE RSSNR */
-    if (rssnr_level_to_rssnr (rssnr_level, &rssnr)) {
+    if (rssnr_level_to_rssnr (rssnr_level, log_object, &rssnr)) {
         if (!lte)
             lte = mm_signal_new ();
         mm_signal_set_snr (lte, rssnr);
diff --git a/plugins/xmm/mm-modem-helpers-xmm.h b/plugins/xmm/mm-modem-helpers-xmm.h
index f70fc34..a18f066 100644
--- a/plugins/xmm/mm-modem-helpers-xmm.h
+++ b/plugins/xmm/mm-modem-helpers-xmm.h
@@ -21,6 +21,7 @@
 
 /* AT+XACT=? response parser */
 gboolean mm_xmm_parse_xact_test_response (const gchar  *response,
+                                          gpointer      logger,
                                           GArray      **modes_out,
                                           GArray      **bands_out,
                                           GError      **error);
@@ -50,6 +51,7 @@
                                             GError      **error);
 
 gboolean mm_xmm_xcesq_response_to_signal_info (const gchar  *response,
+                                               gpointer      log_object,
                                                MMSignal    **out_gsm,
                                                MMSignal    **out_umts,
                                                MMSignal    **out_lte,
diff --git a/plugins/xmm/mm-shared-xmm.c b/plugins/xmm/mm-shared-xmm.c
index 2f40d78..6045758 100644
--- a/plugins/xmm/mm-shared-xmm.c
+++ b/plugins/xmm/mm-shared-xmm.c
@@ -22,7 +22,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-iface-modem.h"
 #include "mm-iface-modem-signal.h"
 #include "mm-iface-modem-location.h"
@@ -154,6 +154,7 @@
     response = mm_base_modem_at_command_finish (self, res, &error);
     if (!response ||
         !mm_xmm_parse_xact_test_response (response,
+                                          self,
                                           &priv->supported_modes,
                                           &priv->supported_bands,
                                           &error))
@@ -419,7 +420,8 @@
 }
 
 static gchar *
-validate_and_build_command_set_current_bands (const GArray *bands_array,
+validate_and_build_command_set_current_bands (MMSharedXmm  *self,
+                                              const GArray *bands_array,
                                               const GArray *supported_modes,
                                               MMModemMode   allowed_modes,
                                               GError      **error)
@@ -444,11 +446,10 @@
          */
         unapplied = mm_xmm_get_modem_mode_any (supported_modes) & ~(allowed_modes);
         if (unapplied != MM_MODEM_MODE_NONE) {
-            gchar *str;
+            g_autofree gchar *str = NULL;
 
             str = mm_modem_mode_build_string_from_mask (unapplied);
-            mm_warn ("Automatic band selection not applied to non-current modes %s", str);
-            g_free (str);
+            mm_obj_warn (self, "automatic band selection not applied to non-current modes %s", str);
         }
 
         /* Nothing else to validate, go build the command right away */
@@ -549,7 +550,8 @@
         goto out;
     }
 
-    command = validate_and_build_command_set_current_bands (bands_array,
+    command = validate_and_build_command_set_current_bands (MM_SHARED_XMM (self),
+                                                            bands_array,
                                                             priv->supported_modes,
                                                             priv->allowed_modes,
                                                             &error);
@@ -764,7 +766,7 @@
     const gchar *response;
 
     response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);
-    if (!response || !mm_xmm_xcesq_response_to_signal_info (response, gsm, umts, lte, error))
+    if (!response || !mm_xmm_xcesq_response_to_signal_info (response, self, gsm, umts, lte, error))
         return FALSE;
 
     if (cdma)
@@ -839,28 +841,28 @@
                                              &loc_response_type_nmea_supported,
                                              &gnss_type_gps_glonass_supported,
                                              &error)) {
-        mm_dbg ("XLCSLSR based GPS control unsupported: %s", error->message);
+        mm_obj_dbg (self, "XLCSLSR based GPS control unsupported: %s", error->message);
         g_clear_error (&error);
     } else if (!transport_protocol_invalid_supported ||
                !standalone_position_mode_supported ||
                !loc_response_type_nmea_supported ||
                !gnss_type_gps_glonass_supported) {
-        mm_dbg ("XLCSLSR based GPS control unsupported: protocol invalid %s, standalone %s, nmea %s, gps/glonass %s",
-                transport_protocol_invalid_supported ? "supported" : "unsupported",
-                standalone_position_mode_supported   ? "supported" : "unsupported",
-                loc_response_type_nmea_supported     ? "supported" : "unsupported",
-                gnss_type_gps_glonass_supported      ? "supported" : "unsupported");
+        mm_obj_dbg (self, "XLCSLSR based GPS control unsupported: protocol invalid %s, standalone %s, nmea %s, gps/glonass %s",
+                    transport_protocol_invalid_supported ? "supported" : "unsupported",
+                    standalone_position_mode_supported   ? "supported" : "unsupported",
+                    loc_response_type_nmea_supported     ? "supported" : "unsupported",
+                    gnss_type_gps_glonass_supported      ? "supported" : "unsupported");
     } else {
-        mm_dbg ("XLCSLSR based GPS control supported");
+        mm_obj_dbg (self, "XLCSLSR based GPS control supported");
         priv->supported_sources |= (MM_MODEM_LOCATION_SOURCE_GPS_NMEA | MM_MODEM_LOCATION_SOURCE_GPS_RAW);
 
         if (transport_protocol_supl_supported && ms_assisted_based_position_mode_supported) {
-            mm_dbg ("XLCSLSR based A-GPS control supported");
+            mm_obj_dbg (self, "XLCSLSR based A-GPS control supported");
             priv->supported_sources |= (MM_MODEM_LOCATION_SOURCE_AGPS_MSA | MM_MODEM_LOCATION_SOURCE_AGPS_MSB);
         } else {
-            mm_dbg ("XLCSLSR based A-GPS control unsupported: protocol supl %s, ms assisted/based %s",
-                    transport_protocol_supl_supported         ? "supported" : "unsupported",
-                    ms_assisted_based_position_mode_supported ? "supported" : "unsupported");
+            mm_obj_dbg (self, "XLCSLSR based A-GPS control unsupported: protocol supl %s, ms assisted/based %s",
+                        transport_protocol_supl_supported         ? "supported" : "unsupported",
+                        ms_assisted_based_position_mode_supported ? "supported" : "unsupported");
         }
 
         sources |= priv->supported_sources;
@@ -902,7 +904,7 @@
 
     /* If parent already supports GPS sources, we won't do anything else */
     if (sources & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA | MM_MODEM_LOCATION_SOURCE_GPS_RAW)) {
-        mm_dbg ("No need to run XLCSLSR based location gathering");
+        mm_obj_dbg (self, "no need to run XLCSLSR based location gathering");
         g_task_return_int (task, sources);
         g_object_unref (task);
         return;
diff --git a/plugins/xmm/tests/test-modem-helpers-xmm.c b/plugins/xmm/tests/test-modem-helpers-xmm.c
index b4a8b2b..e40ffca 100644
--- a/plugins/xmm/tests/test-modem-helpers-xmm.c
+++ b/plugins/xmm/tests/test-modem-helpers-xmm.c
@@ -22,7 +22,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-test.h"
 #include "mm-modem-helpers.h"
 #include "mm-modem-helpers-xmm.h"
 
@@ -45,7 +45,7 @@
     gboolean  ret;
     guint     i;
 
-    ret = mm_xmm_parse_xact_test_response (response, &modes, &bands, &error);
+    ret = mm_xmm_parse_xact_test_response (response, NULL, &modes, &bands, &error);
     g_assert_no_error (error);
     g_assert (ret);
 
@@ -617,6 +617,7 @@
         MMSignal *lte  = NULL;
 
         success = mm_xmm_xcesq_response_to_signal_info (xcesq_response_tests[i].str,
+                                                        NULL,
                                                         &gsm, &umts, &lte,
                                                         &error);
         g_assert_no_error (error);
@@ -753,26 +754,6 @@
 
 /*****************************************************************************/
 
-void
-_mm_log (const char *loc,
-         const char *func,
-         guint32     level,
-         const char *fmt,
-         ...)
-{
-    va_list args;
-    gchar *msg;
-
-    if (!g_test_verbose ())
-        return;
-
-    va_start (args, fmt);
-    msg = g_strdup_vprintf (fmt, args);
-    va_end (args);
-    g_print ("%s\n", msg);
-    g_free (msg);
-}
-
 int main (int argc, char **argv)
 {
     setlocale (LC_ALL, "");
diff --git a/plugins/zte/mm-broadband-modem-zte-icera.c b/plugins/zte/mm-broadband-modem-zte-icera.c
index fe8448e..c0befa5 100644
--- a/plugins/zte/mm-broadband-modem-zte-icera.c
+++ b/plugins/zte/mm-broadband-modem-zte-icera.c
@@ -29,7 +29,6 @@
 #include "mm-common-zte.h"
 #include "mm-broadband-modem-zte-icera.h"
 #include "mm-modem-helpers.h"
-#include "mm-log.h"
 
 static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface);
 
diff --git a/plugins/zte/mm-broadband-modem-zte.c b/plugins/zte/mm-broadband-modem-zte.c
index a1b24bc..64549cd 100644
--- a/plugins/zte/mm-broadband-modem-zte.c
+++ b/plugins/zte/mm-broadband-modem-zte.c
@@ -24,7 +24,6 @@
 #include <ctype.h>
 
 #include "ModemManager.h"
-#include "mm-log.h"
 #include "mm-errors-types.h"
 #include "mm-modem-helpers.h"
 #include "mm-base-modem-at.h"
@@ -70,7 +69,6 @@
 
     response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
     if (!response) {
-        mm_dbg ("Couldn't query unlock retries: '%s'", error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -303,7 +301,7 @@
     }
 
     /* Filter out those unsupported modes */
-    filtered = mm_filter_supported_modes (all, combinations);
+    filtered = mm_filter_supported_modes (all, combinations, self);
     g_array_unref (all);
     g_array_unref (combinations);
 
diff --git a/plugins/zte/mm-plugin-zte.c b/plugins/zte/mm-plugin-zte.c
index 7b0849f..195ff56 100644
--- a/plugins/zte/mm-plugin-zte.c
+++ b/plugins/zte/mm-plugin-zte.c
@@ -21,7 +21,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-plugin-zte.h"
 #include "mm-broadband-modem-zte.h"
 #include "mm-broadband-modem-zte-icera.h"
@@ -70,7 +70,7 @@
 {
 #if defined WITH_QMI
     if (mm_port_probe_list_has_qmi_port (probes)) {
-        mm_dbg ("QMI-powered ZTE modem found...");
+        mm_obj_dbg (self, "QMI-powered ZTE modem found...");
         return MM_BASE_MODEM (mm_broadband_modem_qmi_new (uid,
                                                           drivers,
                                                           mm_plugin_get_name (self),
@@ -81,7 +81,7 @@
 
 #if defined WITH_MBIM
     if (mm_port_probe_list_has_mbim_port (probes)) {
-        mm_dbg ("MBIM-powered ZTE modem found...");
+        mm_obj_dbg (self, "MBIM-powered ZTE modem found...");
         return MM_BASE_MODEM (mm_broadband_modem_mbim_new (uid,
                                                            drivers,
                                                            mm_plugin_get_name (self),
@@ -126,7 +126,7 @@
     }
 
     if (mm_kernel_device_get_global_property_as_boolean (port, "ID_MM_ZTE_ICERA_DHCP")) {
-        mm_dbg ("ZTE: Icera-based modem will use DHCP");
+        mm_obj_dbg (self, "icera-based modem will use DHCP");
         g_object_set (modem,
                       MM_BROADBAND_MODEM_ICERA_DEFAULT_IP_METHOD, MM_BEARER_IP_METHOD_DHCP,
                       NULL);
@@ -149,7 +149,7 @@
 
     return MM_PLUGIN (
         g_object_new (MM_TYPE_PLUGIN_ZTE,
-                      MM_PLUGIN_NAME,               "ZTE",
+                      MM_PLUGIN_NAME,               MM_MODULE_NAME,
                       MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems,
                       MM_PLUGIN_ALLOWED_VENDOR_IDS, vendor_ids,
                       MM_PLUGIN_CUSTOM_AT_PROBE,    custom_at_probe,
diff --git a/po/LINGUAS b/po/LINGUAS
index 68225ab..d09b7cc 100644
--- a/po/LINGUAS
+++ b/po/LINGUAS
@@ -9,6 +9,7 @@
 lt
 pl
 pt_BR
+ru
 sk
 sv
 tr
diff --git a/po/cs.po b/po/cs.po
index 568e43f..205d21f 100644
--- a/po/cs.po
+++ b/po/cs.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: ModemManager master\n"
 "Report-Msgid-Bugs-To: modemmanager-devel@lists.freedesktop.org\n"
-"POT-Creation-Date: 2019-09-25 12:48+0200\n"
+"POT-Creation-Date: 2020-04-08 16:23+0200\n"
 "PO-Revision-Date: 2017-10-21 15:32+0200\n"
 "Last-Translator: Marek Černocký <marek@manet.cz>\n"
 "Language-Team: čeština <gnome-cs-list@gnome.org>\n"
@@ -114,6 +114,6 @@
 "Systémová zásada brání v dotázání na firmware nebo brání v jeho správě na "
 "tomto zařízení."
 
-#: src/mm-sleep-monitor.c:114
+#: src/mm-sleep-monitor.c:125
 msgid "ModemManager needs to reset devices"
 msgstr "Správa modemů potřebuje resetovat zařízení"
diff --git a/po/da.po b/po/da.po
index 9473d0a..dc89d55 100644
--- a/po/da.po
+++ b/po/da.po
@@ -6,7 +6,7 @@
 msgstr ""
 "Project-Id-Version: ModemManager master\n"
 "Report-Msgid-Bugs-To: modemmanager-devel@lists.freedesktop.org\n"
-"POT-Creation-Date: 2019-09-25 12:48+0200\n"
+"POT-Creation-Date: 2020-04-08 16:23+0200\n"
 "PO-Revision-Date: 2019-02-10 16:46+0200\n"
 "Last-Translator: scootergrisen\n"
 "Language-Team: Danish\n"
@@ -107,6 +107,6 @@
 msgstr ""
 "Systempolitikken forhindrer forespørgsel og håndtering af enhedens firmware."
 
-#: src/mm-sleep-monitor.c:114
+#: src/mm-sleep-monitor.c:125
 msgid "ModemManager needs to reset devices"
 msgstr "ModemManager har brug for at nulstille enhederne"
diff --git a/po/de.po b/po/de.po
index 7e0281f..4f8661e 100644
--- a/po/de.po
+++ b/po/de.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: ModemManager\n"
 "Report-Msgid-Bugs-To: modemmanager-devel@lists.freedesktop.org\n"
-"POT-Creation-Date: 2019-09-25 12:48+0200\n"
+"POT-Creation-Date: 2020-04-08 16:23+0200\n"
 "PO-Revision-Date: 2014-01-06 21:23+0100\n"
 "Last-Translator: Mario Blättermann <mario.blaettermann@gmail.com>\n"
 "Language-Team: German <debian-l10n-german@lists.debian.org>\n"
@@ -115,6 +115,6 @@
 "Die Systemrichtlinien verhindern die Abfrage oder Verwaltung der Firmware "
 "dieses Gerätes."
 
-#: src/mm-sleep-monitor.c:114
+#: src/mm-sleep-monitor.c:125
 msgid "ModemManager needs to reset devices"
 msgstr ""
diff --git a/po/fr.po b/po/fr.po
index c86ecd1..928a795 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: ModemManager master\n"
 "Report-Msgid-Bugs-To: modemmanager-devel@lists.freedesktop.org\n"
-"POT-Creation-Date: 2019-09-25 12:48+0200\n"
+"POT-Creation-Date: 2020-04-08 16:23+0200\n"
 "PO-Revision-Date: 2018-08-18 16:17+0200\n"
 "Last-Translator: Claude Paroz <claude@2xlibre.net>\n"
 "Language-Team: French <gnomefr@traduc.org>\n"
@@ -111,6 +111,6 @@
 "La politique système empêche l’interrogation et la gestion du matériel de ce "
 "périphérique."
 
-#: src/mm-sleep-monitor.c:114
+#: src/mm-sleep-monitor.c:125
 msgid "ModemManager needs to reset devices"
 msgstr "ModemManager a besoin de réinitialiser les périphériques"
diff --git a/po/fur.po b/po/fur.po
index 536e482..4b59615 100644
--- a/po/fur.po
+++ b/po/fur.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: ModemManager master\n"
 "Report-Msgid-Bugs-To: modemmanager-devel@lists.freedesktop.org\n"
-"POT-Creation-Date: 2019-09-25 12:48+0200\n"
+"POT-Creation-Date: 2020-04-08 16:23+0200\n"
 "PO-Revision-Date: 2018-03-25 17:20+0200\n"
 "Last-Translator: Fabio Tomat <f.t.public@gmail.com>\n"
 "Language-Team: Friulian <f.t.public@gmail.com>\n"
@@ -114,6 +114,6 @@
 "La politiche dal sisteme e impedìs di interogâ o gjestî il firmware di chest "
 "dispositîf."
 
-#: src/mm-sleep-monitor.c:114
+#: src/mm-sleep-monitor.c:125
 msgid "ModemManager needs to reset devices"
 msgstr "ModemManager al à bisugne di ristabilî/azerâ i dispositîfs"
diff --git a/po/hu.po b/po/hu.po
index 6b204c2..a07a5bd 100644
--- a/po/hu.po
+++ b/po/hu.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: modemmanager master\n"
 "Report-Msgid-Bugs-To: modemmanager-devel@lists.freedesktop.org\n"
-"POT-Creation-Date: 2019-09-25 12:48+0200\n"
+"POT-Creation-Date: 2020-04-08 16:23+0200\n"
 "PO-Revision-Date: 2017-09-26 22:02+0000\n"
 "Last-Translator: Gabor Kelemen <kelemeng@openscope.org>\n"
 "Language-Team: Hungarian <hu@li.org>\n"
@@ -110,6 +110,6 @@
 "A rendszer lekérdezése és használata lehetővé a firmware lekérdezését és "
 "kezelését az eszközön."
 
-#: src/mm-sleep-monitor.c:114
+#: src/mm-sleep-monitor.c:125
 msgid "ModemManager needs to reset devices"
 msgstr "A Modemkezelőnek alapállapotba kell állítania eszközöket"
diff --git a/po/id.po b/po/id.po
index a6142a5..afa8b65 100644
--- a/po/id.po
+++ b/po/id.po
@@ -7,19 +7,19 @@
 msgstr ""
 "Project-Id-Version: ModemManager master\n"
 "Report-Msgid-Bugs-To: modemmanager-devel@lists.freedesktop.org\n"
-"POT-Creation-Date: 2019-09-25 12:48+0200\n"
-"PO-Revision-Date: 2018-03-04 20:31+0700\n"
+"POT-Creation-Date: 2020-04-08 16:23+0200\n"
+"PO-Revision-Date: 2020-03-31 18:14+0700\n"
 "Last-Translator: Andika Triwidada <andika@gmail.com>\n"
 "Language-Team: Indonesian <gnome-l10n-id@googlegroups.com>\n"
 "Language: id\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 1.8.11\n"
+"X-Generator: Poedit 2.3\n"
 
 #: data/org.freedesktop.ModemManager1.policy.in.in:13
 msgid "Control the Modem Manager daemon"
-msgstr "Kendalikan daemon Manajer Modem"
+msgstr "Mengendalikan daemon Manajer Modem"
 
 #: data/org.freedesktop.ModemManager1.policy.in.in:14
 msgid "System policy prevents controlling the Modem Manager."
@@ -68,14 +68,11 @@
 
 #: data/org.freedesktop.ModemManager1.policy.in.in:58
 msgid "Query network time and timezone information"
-msgstr ""
+msgstr "Tanyakan waktu jaringan dan informasi zona waktu"
 
 #: data/org.freedesktop.ModemManager1.policy.in.in:59
-#, fuzzy
 msgid "System policy prevents querying network time information."
-msgstr ""
-"Kebijakan sistem mencegah kueri atau pemanfaatan layanan dan informasi "
-"jaringan."
+msgstr "Kebijakan sistem mencegah kuiri informasi waktu jaringan."
 
 #: data/org.freedesktop.ModemManager1.policy.in.in:67
 msgid "Enable and view geographic location and positioning information"
@@ -90,24 +87,24 @@
 
 #: data/org.freedesktop.ModemManager1.policy.in.in:76
 msgid "Query and utilize network information and services"
-msgstr "Kueri dan manfaatkan layanan dan informasi jaringan"
+msgstr "Kuiri dan manfaatkan layanan dan informasi jaringan"
 
 #: data/org.freedesktop.ModemManager1.policy.in.in:77
 msgid ""
 "System policy prevents querying or utilizing network information and "
 "services."
 msgstr ""
-"Kebijakan sistem mencegah kueri atau pemanfaatan layanan dan informasi "
+"Kebijakan sistem mencegah kuiri atau pemanfaatan layanan dan informasi "
 "jaringan."
 
 #: data/org.freedesktop.ModemManager1.policy.in.in:85
 msgid "Query and manage firmware on a mobile broadband device"
-msgstr "Kueri dan kelola firmware pada suatu peranti data seluler"
+msgstr "Kuiri dan kelola firmware pada suatu peranti data seluler"
 
 #: data/org.freedesktop.ModemManager1.policy.in.in:86
 msgid "System policy prevents querying or managing this device's firmware."
-msgstr "Kebijakan sistem mencegah kueri atau pengelolaan firmware peranti ini."
+msgstr "Kebijakan sistem mencegah kuiri atau pengelolaan firmware peranti ini."
 
-#: src/mm-sleep-monitor.c:114
+#: src/mm-sleep-monitor.c:125
 msgid "ModemManager needs to reset devices"
 msgstr "ModemManager perlu mereset peranti"
diff --git a/po/it.po b/po/it.po
index a15f503..6655593 100644
--- a/po/it.po
+++ b/po/it.po
@@ -1,14 +1,14 @@
 # Italian translation for ModemManager.
-# Copyright (C) 2018 ModemManager's COPYRIGHT HOLDER
+# Copyright (C) 2018, 2020 ModemManager's COPYRIGHT HOLDER
 # This file is distributed under the same license as the ModemManager package.
-# Milo Casagrande <milo@ubuntu.com>, 2018.
+# Milo Casagrande <milo@milo.name>, 2018, 2020.
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: ModemManager master\n"
 "Report-Msgid-Bugs-To: modemmanager-devel@lists.freedesktop.org\n"
-"POT-Creation-Date: 2019-09-25 12:48+0200\n"
-"PO-Revision-Date: 2018-09-11 11:25+0200\n"
+"POT-Creation-Date: 2020-04-08 16:23+0200\n"
+"PO-Revision-Date: 2020-03-10 20:15+0100\n"
 "Last-Translator: Milo Casagrande <milo@milo.name>\n"
 "Language-Team: Italian <gnome-it-list@gnome.org>\n"
 "Language: it\n"
@@ -16,7 +16,7 @@
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 2.1.1\n"
+"X-Generator: Poedit 2.2.4\n"
 
 #: data/org.freedesktop.ModemManager1.policy.in.in:13
 msgid "Control the Modem Manager daemon"
@@ -69,14 +69,13 @@
 
 #: data/org.freedesktop.ModemManager1.policy.in.in:58
 msgid "Query network time and timezone information"
-msgstr ""
+msgstr "Interroga le informazioni sull'ora di rete e sul fuso orario"
 
 #: data/org.freedesktop.ModemManager1.policy.in.in:59
-#, fuzzy
 msgid "System policy prevents querying network time information."
 msgstr ""
-"La politica di sistema impedisce di interrogare o di utilizzare le "
-"informazioni e i servizi della rete."
+"La politica di sistema impedisce di interrogare le informazioni sull'ora di "
+"rete"
 
 #: data/org.freedesktop.ModemManager1.policy.in.in:67
 msgid "Enable and view geographic location and positioning information"
@@ -113,6 +112,6 @@
 "La politica di sistema impedisce di interrogare o gestire il firmware di "
 "questo dispositivo."
 
-#: src/mm-sleep-monitor.c:114
+#: src/mm-sleep-monitor.c:125
 msgid "ModemManager needs to reset devices"
 msgstr "ModemManager deve reimpostare i dispositivi"
diff --git a/po/lt.po b/po/lt.po
index d238b02..303cd50 100644
--- a/po/lt.po
+++ b/po/lt.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: \n"
 "Report-Msgid-Bugs-To: modemmanager-devel@lists.freedesktop.org\n"
-"POT-Creation-Date: 2019-09-25 12:48+0200\n"
+"POT-Creation-Date: 2020-04-08 16:23+0200\n"
 "PO-Revision-Date: 2019-04-13 22:08+0300\n"
 "Last-Translator: \n"
 "Language-Team: \n"
@@ -116,6 +116,6 @@
 "Sistemos politika neleidžia užklausti ar tvarkyti šio įrenginio programinę "
 "aparatinę įrangą."
 
-#: src/mm-sleep-monitor.c:114
+#: src/mm-sleep-monitor.c:125
 msgid "ModemManager needs to reset devices"
 msgstr "ModemManager turi atstatyti įrenginius"
diff --git a/po/pl.po b/po/pl.po
index 928c378..63849e5 100644
--- a/po/pl.po
+++ b/po/pl.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: ModemManager\n"
 "Report-Msgid-Bugs-To: modemmanager-devel@lists.freedesktop.org\n"
-"POT-Creation-Date: 2019-09-26 03:26+0000\n"
+"POT-Creation-Date: 2020-04-08 16:23+0200\n"
 "PO-Revision-Date: 2019-09-28 15:02+0200\n"
 "Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
 "Language-Team: Polish <community-poland@mozilla.org>\n"
@@ -113,6 +113,6 @@
 "Ustawienia systemu uniemożliwiają odpytywanie lub zarządzanie "
 "oprogramowaniem sprzętowym tego urządzenia."
 
-#: src/mm-sleep-monitor.c:114
+#: src/mm-sleep-monitor.c:125
 msgid "ModemManager needs to reset devices"
 msgstr "Usługa ModemManager musi ponownie uruchomić urządzenia"
diff --git a/po/pt_BR.po b/po/pt_BR.po
index 944a37f..487d7e2 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: ModemManager master\n"
 "Report-Msgid-Bugs-To: modemmanager-devel@lists.freedesktop.org\n"
-"POT-Creation-Date: 2019-11-27 09:33+0100\n"
+"POT-Creation-Date: 2020-04-08 16:23+0200\n"
 "PO-Revision-Date: 2019-11-25 00:17-0300\n"
 "Last-Translator: Rafael Fontenelle <rafaelff@gnome.org>\n"
 "Language-Team: Brazilian Portuguese <gnome-pt_br-list@gnome.org>\n"
@@ -109,6 +109,6 @@
 "A política de sistema impede de consultar ou gerenciar o firmware do "
 "dispositivo."
 
-#: src/mm-sleep-monitor.c:114
+#: src/mm-sleep-monitor.c:125
 msgid "ModemManager needs to reset devices"
 msgstr "O ModemManager precisa reiniciar os dispositivos"
diff --git a/po/ru.po b/po/ru.po
new file mode 100644
index 0000000..ef98b67
--- /dev/null
+++ b/po/ru.po
@@ -0,0 +1,117 @@
+# Russian translation for ModemManager.
+# Copyright (C) 2020 ModemManager's COPYRIGHT HOLDER
+# This file is distributed under the same license as the ModemManager package.
+# Артемий Судаков <finziyr@yandex.ru>, 2020.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: ModemManager master\n"
+"Report-Msgid-Bugs-To: modemmanager-devel@lists.freedesktop.org\n"
+"POT-Creation-Date: 2020-04-08 16:23+0200\n"
+"PO-Revision-Date: 2020-04-04 21:26+0300\n"
+"Last-Translator: Артемий Судаков <finziyr@yandex.ru>\n"
+"Language-Team: Russian <gnome-cyr@gnome.org>\n"
+"Language: ru\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
+"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+"X-Generator: Poedit 2.3\n"
+
+#: data/org.freedesktop.ModemManager1.policy.in.in:13
+msgid "Control the Modem Manager daemon"
+msgstr "Настроить сервис Modem Manager"
+
+#: data/org.freedesktop.ModemManager1.policy.in.in:14
+msgid "System policy prevents controlling the Modem Manager."
+msgstr "Системная политика не позволяет управлять Modem Manager'ом."
+
+#: data/org.freedesktop.ModemManager1.policy.in.in:22
+msgid "Unlock and control a mobile broadband device"
+msgstr "Разблокировка и управление мобильным широкополосным устройством"
+
+#: data/org.freedesktop.ModemManager1.policy.in.in:23
+msgid ""
+"System policy prevents unlocking or controlling the mobile broadband device."
+msgstr ""
+"Системная политика предотвращает разблокировку или управление мобильным "
+"широкополосным устройством."
+
+#: data/org.freedesktop.ModemManager1.policy.in.in:31
+msgid "Add, modify, and delete mobile broadband contacts"
+msgstr "Добавить, изменить и удалить мобильные широкополосные контакты"
+
+#: data/org.freedesktop.ModemManager1.policy.in.in:32
+msgid ""
+"System policy prevents adding, modifying, or deleting this device's contacts."
+msgstr ""
+"Системная политика запрещает добавление, изменение или удаление контактов "
+"этого устройства."
+
+#: data/org.freedesktop.ModemManager1.policy.in.in:40
+msgid "Send, save, modify, and delete text messages"
+msgstr "Отправить, сохранить, изменить и удалить текстовые сообщения"
+
+#: data/org.freedesktop.ModemManager1.policy.in.in:41
+msgid ""
+"System policy prevents sending or manipulating this device's text messages."
+msgstr ""
+"Системная политика запрещает отправку или манипулирование текстовыми "
+"сообщениями этого устройства."
+
+#: data/org.freedesktop.ModemManager1.policy.in.in:49
+msgid "Accept incoming voice calls or start outgoing voice calls."
+msgstr ""
+"Принимать входящие голосовые звонки или начать исходящие голосовые звонки."
+
+#: data/org.freedesktop.ModemManager1.policy.in.in:50
+msgid "System policy prevents voice calls."
+msgstr "Системная политика запрещает голосовые звонки."
+
+#: data/org.freedesktop.ModemManager1.policy.in.in:58
+msgid "Query network time and timezone information"
+msgstr "Запрос информации о времени и часовых поясах в сети"
+
+#: data/org.freedesktop.ModemManager1.policy.in.in:59
+msgid "System policy prevents querying network time information."
+msgstr "Системная политика запрещает запрашивать информацию о времени в сети."
+
+#: data/org.freedesktop.ModemManager1.policy.in.in:67
+msgid "Enable and view geographic location and positioning information"
+msgstr ""
+"Включить и просмотреть географическое местоположение и информацию о "
+"местоположении"
+
+#: data/org.freedesktop.ModemManager1.policy.in.in:68
+msgid ""
+"System policy prevents enabling or viewing geographic location information."
+msgstr ""
+"Системная политика запрещает включение или просмотр информации о "
+"географическом местоположении."
+
+#: data/org.freedesktop.ModemManager1.policy.in.in:76
+msgid "Query and utilize network information and services"
+msgstr "Запрос, использование сетевой информации и услуг"
+
+#: data/org.freedesktop.ModemManager1.policy.in.in:77
+msgid ""
+"System policy prevents querying or utilizing network information and "
+"services."
+msgstr ""
+"Системная политика не позволяет запрашивать или использовать сетевую "
+"информацию и сервисы."
+
+#: data/org.freedesktop.ModemManager1.policy.in.in:85
+msgid "Query and manage firmware on a mobile broadband device"
+msgstr "Запрос и управление прошивкой на мобильном широкополосном устройстве"
+
+#: data/org.freedesktop.ModemManager1.policy.in.in:86
+msgid "System policy prevents querying or managing this device's firmware."
+msgstr ""
+"Системная политика не позволяет запрашивать или управлять прошивкой этого "
+"устройства."
+
+#: src/mm-sleep-monitor.c:125
+msgid "ModemManager needs to reset devices"
+msgstr "ModemManager'у необходимо перезагрузить устройства"
diff --git a/po/sk.po b/po/sk.po
index a8e342f..c5534ca 100644
--- a/po/sk.po
+++ b/po/sk.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: ModemManager master\n"
 "Report-Msgid-Bugs-To: modemmanager-devel@lists.freedesktop.org\n"
-"POT-Creation-Date: 2019-09-25 12:48+0200\n"
+"POT-Creation-Date: 2020-04-08 16:23+0200\n"
 "PO-Revision-Date: 2017-09-16 08:51+0200\n"
 "Last-Translator: Dušan Kazik <prescott66@gmail.com>\n"
 "Language-Team: Slovak <gnome-sk-list@gnome.org>\n"
@@ -114,6 +114,6 @@
 "Politika systému zabraňuje požadovaniu, alebo správe firmvéru tohto "
 "zariadenia."
 
-#: src/mm-sleep-monitor.c:114
+#: src/mm-sleep-monitor.c:125
 msgid "ModemManager needs to reset devices"
 msgstr "Služba ModemManager vyžaduje obnovenie zariadení"
diff --git a/po/sv.po b/po/sv.po
index c6f0fcf..059c998 100644
--- a/po/sv.po
+++ b/po/sv.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: ModemManager master\n"
 "Report-Msgid-Bugs-To: modemmanager-devel@lists.freedesktop.org\n"
-"POT-Creation-Date: 2019-09-25 12:48+0200\n"
+"POT-Creation-Date: 2020-04-08 16:23+0200\n"
 "PO-Revision-Date: 2017-12-04 20:28+0100\n"
 "Last-Translator: Josef Andersson <l10nl18nsweja@gmail.com>\n"
 "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
@@ -111,6 +111,6 @@
 "En systempolicy förhindrar att fråga och hantera denna enhets fasta "
 "programvara."
 
-#: src/mm-sleep-monitor.c:114
+#: src/mm-sleep-monitor.c:125
 msgid "ModemManager needs to reset devices"
 msgstr "ModemManager behöver starta om enheter"
diff --git a/po/tr.po b/po/tr.po
index fd34123..737f6d6 100644
--- a/po/tr.po
+++ b/po/tr.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: ModemManager master\n"
 "Report-Msgid-Bugs-To: modemmanager-devel@lists.freedesktop.org\n"
-"POT-Creation-Date: 2019-11-11 10:01+0100\n"
+"POT-Creation-Date: 2020-04-08 16:23+0200\n"
 "PO-Revision-Date: 2019-11-10 09:05+0300\n"
 "Last-Translator: Emin Tufan Çetin <etcetin@gmail.com>\n"
 "Language-Team: Türkçe <gnome-turk@gnome.org>\n"
@@ -108,6 +108,6 @@
 "Sistem ilkesi bu aygıtın donanım yazılımını sorgulamayı veya yönetmeyi "
 "engelliyor."
 
-#: src/mm-sleep-monitor.c:114
+#: src/mm-sleep-monitor.c:125
 msgid "ModemManager needs to reset devices"
 msgstr "ModemManager'in aygıtları sıfırlaması gerekiyor"
diff --git a/po/uk.po b/po/uk.po
index 0be8149..ba2d9e0 100644
--- a/po/uk.po
+++ b/po/uk.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: Modem Manager\n"
 "Report-Msgid-Bugs-To: modemmanager-devel@lists.freedesktop.org\n"
-"POT-Creation-Date: 2019-11-11 10:09+0100\n"
+"POT-Creation-Date: 2020-04-08 16:23+0200\n"
 "PO-Revision-Date: 2019-11-10 14:35+0200\n"
 "Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
 "Language-Team: Ukrainian <kde-i18n-uk@kde.org>\n"
@@ -15,8 +15,8 @@
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
-"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
+"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
 "X-Generator: Lokalize 19.11.70\n"
 
 #: data/org.freedesktop.ModemManager1.policy.in.in:13
@@ -114,6 +114,6 @@
 "Правила системи перешкоджають опитуванню або керування мікропрограмою цього "
 "пристрою."
 
-#: src/mm-sleep-monitor.c:114
+#: src/mm-sleep-monitor.c:125
 msgid "ModemManager needs to reset devices"
 msgstr "ModemManager потребує відновлення початкового стану пристроїв"
diff --git a/po/zh_CN.po b/po/zh_CN.po
index 1b576a2..2e939f9 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: ModemManager master\n"
 "Report-Msgid-Bugs-To: modemmanager-devel@lists.freedesktop.org\n"
-"POT-Creation-Date: 2019-09-25 12:48+0200\n"
+"POT-Creation-Date: 2020-04-08 16:23+0200\n"
 "PO-Revision-Date: 2019-05-03 00:10+0800\n"
 "Last-Translator: 王滋涵 <i@wi24rd.ml>\n"
 "Language-Team: Chinese (China) <i18n-zh@googlegroups.com>\n"
@@ -97,6 +97,6 @@
 msgid "System policy prevents querying or managing this device's firmware."
 msgstr "系统策略禁止在移动宽带设备上查询和管理固件。"
 
-#: src/mm-sleep-monitor.c:114
+#: src/mm-sleep-monitor.c:125
 msgid "ModemManager needs to reset devices"
 msgstr "调制解调器管理器需要重置设备"
diff --git a/src/Makefile.am b/src/Makefile.am
index 84c810d..e80c10a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -97,6 +97,11 @@
 		$(HELPER_ENUMS_INPUTS) > $@
 
 libhelpers_la_SOURCES = \
+	mm-log-object.h \
+	mm-log-object.c \
+	mm-log.c \
+	mm-log.h \
+	mm-log-test.h \
 	mm-error-helpers.c \
 	mm-error-helpers.h \
 	mm-modem-helpers.c \
@@ -131,7 +136,6 @@
 BUILT_SOURCES += $(HELPER_ENUMS_GENERATED)
 CLEANFILES    += $(HELPER_ENUMS_GENERATED)
 
-
 ################################################################################
 # kerneldevice library
 ################################################################################
@@ -160,6 +164,7 @@
 
 libkerneldevice_la_LIBADD = \
 	$(top_builddir)/libmm-glib/libmm-glib.la \
+	$(builddir)/libhelpers.la \
 	$(NULL)
 
 ################################################################################
@@ -225,7 +230,6 @@
 libport_la_LIBADD = \
 	$(top_builddir)/libqcdm/src/libqcdm.la \
 	$(top_builddir)/libmm-glib/libmm-glib.la \
-	$(builddir)/libhelpers.la \
 	$(builddir)/libkerneldevice.la \
 	$(NULL)
 
@@ -283,8 +287,6 @@
 	main.c \
 	mm-context.h \
 	mm-context.c \
-	mm-log.c \
-	mm-log.h \
 	mm-utils.h \
 	mm-private-boxed-types.h \
 	mm-private-boxed-types.c \
diff --git a/src/kerneldevice/mm-kernel-device-generic-rules.c b/src/kerneldevice/mm-kernel-device-generic-rules.c
index 1d87445..2e955a8 100644
--- a/src/kerneldevice/mm-kernel-device-generic-rules.c
+++ b/src/kerneldevice/mm-kernel-device-generic-rules.c
@@ -316,7 +316,6 @@
     gchar            *line;
     guint             first_rule_index;
 
-    mm_dbg ("[rules] loading rules from: %s", path);
     first_rule_index = rules->len;
 
     file = g_file_new_for_path (path);
@@ -406,8 +405,6 @@
     GArray *rules;
     GError *inner_error = NULL;
 
-    mm_dbg ("[rules] rules directory set to '%s'...", rules_dir);
-
     rules = g_array_new (FALSE, FALSE, sizeof (MMUdevRule));
     g_array_set_clear_func (rules, (GDestroyNotify) udev_rule_clear);
 
@@ -431,8 +428,6 @@
         goto out;
     }
 
-    mm_dbg ("[rules] %u loaded", rules->len);
-
 out:
     if (rule_files)
         g_list_free_full (rule_files, g_free);
diff --git a/src/kerneldevice/mm-kernel-device-generic.c b/src/kerneldevice/mm-kernel-device-generic.c
index c32831d..254c505 100644
--- a/src/kerneldevice/mm-kernel-device-generic.c
+++ b/src/kerneldevice/mm-kernel-device-generic.c
@@ -25,7 +25,7 @@
 
 #include "mm-kernel-device-generic.h"
 #include "mm-kernel-device-generic-rules.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 #if !defined UDEVRULESDIR
 # error UDEVRULESDIR is not defined
@@ -59,6 +59,7 @@
     guint8   interface_subclass;
     guint8   interface_protocol;
     guint8   interface_number;
+    gchar   *interface_description;
     gchar   *physdev_sysfs_path;
     guint16  physdev_vid;
     guint16  physdev_pid;
@@ -125,19 +126,16 @@
 
     self->priv->sysfs_path = realpath (tmp, NULL);
     if (!self->priv->sysfs_path || !g_file_test (self->priv->sysfs_path, G_FILE_TEST_EXISTS)) {
-        mm_warn ("Invalid sysfs path read for %s/%s",
-                 mm_kernel_event_properties_get_subsystem (self->priv->properties),
-                 mm_kernel_event_properties_get_name      (self->priv->properties));
+        mm_obj_warn (self, "invalid sysfs path read for %s/%s",
+                     mm_kernel_event_properties_get_subsystem (self->priv->properties),
+                     mm_kernel_event_properties_get_name      (self->priv->properties));
         g_clear_pointer (&self->priv->sysfs_path, g_free);
     }
 
     if (self->priv->sysfs_path) {
         const gchar *devpath;
 
-        mm_dbg ("(%s/%s) sysfs path: %s",
-                mm_kernel_event_properties_get_subsystem (self->priv->properties),
-                mm_kernel_event_properties_get_name      (self->priv->properties),
-                self->priv->sysfs_path);
+        mm_obj_dbg (self, "sysfs path: %s", self->priv->sysfs_path);
         devpath = (g_str_has_prefix (self->priv->sysfs_path, "/sys") ?
                    &self->priv->sysfs_path[4] :
                    self->priv->sysfs_path);
@@ -209,10 +207,7 @@
     }
 
     if (self->priv->interface_sysfs_path)
-        mm_dbg ("(%s/%s) interface sysfs path: %s",
-                mm_kernel_event_properties_get_subsystem (self->priv->properties),
-                mm_kernel_event_properties_get_name      (self->priv->properties),
-                self->priv->interface_sysfs_path);
+        mm_obj_dbg (self, "interface sysfs path: %s", self->priv->interface_sysfs_path);
 }
 
 static void
@@ -228,10 +223,7 @@
         self->priv->physdev_sysfs_path = g_path_get_dirname (self->priv->interface_sysfs_path);
 
     if (self->priv->physdev_sysfs_path)
-        mm_dbg ("(%s/%s) physdev sysfs path: %s",
-                mm_kernel_event_properties_get_subsystem (self->priv->properties),
-                mm_kernel_event_properties_get_name      (self->priv->properties),
-                self->priv->physdev_sysfs_path);
+        mm_obj_dbg (self, "physdev sysfs path: %s", self->priv->physdev_sysfs_path);
 }
 
 static void
@@ -250,10 +242,7 @@
     }
 
     if (self->priv->driver)
-        mm_dbg ("(%s/%s) driver: %s",
-                mm_kernel_event_properties_get_subsystem (self->priv->properties),
-                mm_kernel_event_properties_get_name      (self->priv->properties),
-                self->priv->driver);
+        mm_obj_dbg (self, "driver: %s", self->priv->driver);
 }
 
 static void
@@ -268,15 +257,10 @@
     }
 
     if (self->priv->physdev_vid) {
-        mm_dbg ("(%s/%s) vid (ID_VENDOR_ID): 0x%04x",
-                mm_kernel_event_properties_get_subsystem (self->priv->properties),
-                mm_kernel_event_properties_get_name      (self->priv->properties),
-                self->priv->physdev_vid);
+        mm_obj_dbg (self, "vid (ID_VENDOR_ID): 0x%04x", self->priv->physdev_vid);
         g_object_set_data_full (G_OBJECT (self), "ID_VENDOR_ID", g_strdup_printf ("%04x", self->priv->physdev_vid), g_free);
     } else
-        mm_dbg ("(%s/%s) vid: unknown",
-                mm_kernel_event_properties_get_subsystem (self->priv->properties),
-                mm_kernel_event_properties_get_name      (self->priv->properties));
+        mm_obj_dbg (self, "vid: unknown");
 
 }
 
@@ -292,15 +276,10 @@
     }
 
     if (self->priv->physdev_pid) {
-        mm_dbg ("(%s/%s) pid (ID_MODEL_ID): 0x%04x",
-                mm_kernel_event_properties_get_subsystem (self->priv->properties),
-                mm_kernel_event_properties_get_name      (self->priv->properties),
-                self->priv->physdev_pid);
+        mm_obj_dbg (self, "pid (ID_MODEL_ID): 0x%04x", self->priv->physdev_pid);
         g_object_set_data_full (G_OBJECT (self), "ID_MODEL_ID", g_strdup_printf ("%04x", self->priv->physdev_pid), g_free);
     } else
-        mm_dbg ("(%s/%s) pid: unknown",
-                mm_kernel_event_properties_get_subsystem (self->priv->properties),
-                mm_kernel_event_properties_get_name      (self->priv->properties));
+        mm_obj_dbg (self, "pid: unknown");
 }
 
 static void
@@ -315,15 +294,10 @@
     }
 
     if (self->priv->physdev_revision) {
-        mm_dbg ("(%s/%s) revision (ID_REVISION): 0x%04x",
-                mm_kernel_event_properties_get_subsystem (self->priv->properties),
-                mm_kernel_event_properties_get_name      (self->priv->properties),
-                self->priv->physdev_revision);
+        mm_obj_dbg (self, "revision (ID_REVISION): 0x%04x", self->priv->physdev_revision);
         g_object_set_data_full (G_OBJECT (self), "ID_REVISION", g_strdup_printf ("%04x", self->priv->physdev_revision), g_free);
     } else
-        mm_dbg ("(%s/%s) revision: unknown",
-                mm_kernel_event_properties_get_subsystem (self->priv->properties),
-                mm_kernel_event_properties_get_name      (self->priv->properties));
+        mm_obj_dbg (self, "revision: unknown");
 }
 
 static void
@@ -340,10 +314,7 @@
         g_free (aux);
     }
 
-    mm_dbg ("(%s/%s) subsystem: %s",
-            mm_kernel_event_properties_get_subsystem (self->priv->properties),
-            mm_kernel_event_properties_get_name      (self->priv->properties),
-            self->priv->physdev_subsystem ? self->priv->physdev_subsystem : "unknown");
+    mm_obj_dbg (self, "subsystem: %s", self->priv->physdev_subsystem ? self->priv->physdev_subsystem : "unknown");
 }
 
 static void
@@ -353,15 +324,10 @@
         self->priv->physdev_manufacturer = (self->priv->physdev_sysfs_path ? read_sysfs_property_as_string (self->priv->physdev_sysfs_path, "manufacturer") : NULL);
 
     if (self->priv->physdev_manufacturer) {
-        mm_dbg ("(%s/%s) manufacturer (ID_VENDOR): %s",
-                mm_kernel_event_properties_get_subsystem (self->priv->properties),
-                mm_kernel_event_properties_get_name      (self->priv->properties),
-                self->priv->physdev_manufacturer);
+        mm_obj_dbg (self, "manufacturer (ID_VENDOR): %s", self->priv->physdev_manufacturer);
         g_object_set_data_full (G_OBJECT (self), "ID_VENDOR", g_strdup (self->priv->physdev_manufacturer), g_free);
     } else
-        mm_dbg ("(%s/%s) manufacturer: unknown",
-                mm_kernel_event_properties_get_subsystem (self->priv->properties),
-                mm_kernel_event_properties_get_name      (self->priv->properties));
+        mm_obj_dbg (self, "manufacturer: unknown");
 }
 
 static void
@@ -371,15 +337,10 @@
         self->priv->physdev_product = (self->priv->physdev_sysfs_path ? read_sysfs_property_as_string (self->priv->physdev_sysfs_path, "product") : NULL);
 
     if (self->priv->physdev_product) {
-        mm_dbg ("(%s/%s) product (ID_MODEL): %s",
-                mm_kernel_event_properties_get_subsystem (self->priv->properties),
-                mm_kernel_event_properties_get_name      (self->priv->properties),
-                self->priv->physdev_product);
+        mm_obj_dbg (self, "product (ID_MODEL): %s", self->priv->physdev_product);
         g_object_set_data_full (G_OBJECT (self), "ID_MODEL", g_strdup (self->priv->physdev_product), g_free);
     } else
-        mm_dbg ("(%s/%s) product: unknown",
-                mm_kernel_event_properties_get_subsystem (self->priv->properties),
-                mm_kernel_event_properties_get_name      (self->priv->properties));
+        mm_obj_dbg (self, "product: unknown");
 
 }
 
@@ -387,60 +348,56 @@
 preload_interface_class (MMKernelDeviceGeneric *self)
 {
     self->priv->interface_class = (self->priv->interface_sysfs_path ? read_sysfs_property_as_hex (self->priv->interface_sysfs_path, "bInterfaceClass") : 0x00);
-    mm_dbg ("(%s/%s) interface class: 0x%02x",
-                mm_kernel_event_properties_get_subsystem (self->priv->properties),
-                mm_kernel_event_properties_get_name      (self->priv->properties),
-                self->priv->interface_class);
+    mm_obj_dbg (self, "interface class: 0x%02x", self->priv->interface_class);
 }
 
 static void
 preload_interface_subclass (MMKernelDeviceGeneric *self)
 {
     self->priv->interface_subclass = (self->priv->interface_sysfs_path ? read_sysfs_property_as_hex (self->priv->interface_sysfs_path, "bInterfaceSubClass") : 0x00);
-    mm_dbg ("(%s/%s) interface subclass: 0x%02x",
-                mm_kernel_event_properties_get_subsystem (self->priv->properties),
-                mm_kernel_event_properties_get_name      (self->priv->properties),
-                self->priv->interface_subclass);
+    mm_obj_dbg (self, "interface subclass: 0x%02x", self->priv->interface_subclass);
 }
 
 static void
 preload_interface_protocol (MMKernelDeviceGeneric *self)
 {
     self->priv->interface_protocol = (self->priv->interface_sysfs_path ? read_sysfs_property_as_hex (self->priv->interface_sysfs_path, "bInterfaceProtocol") : 0x00);
-    mm_dbg ("(%s/%s) interface protocol: 0x%02x",
-            mm_kernel_event_properties_get_subsystem (self->priv->properties),
-            mm_kernel_event_properties_get_name      (self->priv->properties),
-            self->priv->interface_protocol);
+    mm_obj_dbg (self, "interface protocol: 0x%02x", self->priv->interface_protocol);
 }
 
 static void
 preload_interface_number (MMKernelDeviceGeneric *self)
 {
     self->priv->interface_number = (self->priv->interface_sysfs_path ? read_sysfs_property_as_hex (self->priv->interface_sysfs_path, "bInterfaceNumber") : 0x00);
-    mm_dbg ("(%s/%s) interface number (ID_USB_INTERFACE_NUM): 0x%02x",
-            mm_kernel_event_properties_get_subsystem (self->priv->properties),
-            mm_kernel_event_properties_get_name      (self->priv->properties),
-            self->priv->interface_number);
+    mm_obj_dbg (self, "interface number (ID_USB_INTERFACE_NUM): 0x%02x", self->priv->interface_number);
     g_object_set_data_full (G_OBJECT (self), "ID_USB_INTERFACE_NUM", g_strdup_printf ("%02x", self->priv->interface_number), g_free);
 }
 
 static void
+preload_interface_description (MMKernelDeviceGeneric *self)
+{
+    self->priv->interface_description = (self->priv->interface_sysfs_path ? read_sysfs_property_as_string (self->priv->interface_sysfs_path, "interface") : NULL);
+    mm_obj_dbg (self, "interface description: %s", self->priv->interface_description ? self->priv->interface_description : "unknown");
+}
+
+static void
 preload_contents (MMKernelDeviceGeneric *self)
 {
-    preload_sysfs_path           (self);
-    preload_interface_sysfs_path (self);
-    preload_interface_class      (self);
-    preload_interface_subclass   (self);
-    preload_interface_protocol   (self);
-    preload_interface_number     (self);
-    preload_physdev_sysfs_path   (self);
-    preload_manufacturer         (self);
-    preload_product              (self);
-    preload_driver               (self);
-    preload_physdev_vid          (self);
-    preload_physdev_pid          (self);
-    preload_physdev_revision     (self);
-    preload_physdev_subsystem    (self);
+    preload_sysfs_path            (self);
+    preload_interface_sysfs_path  (self);
+    preload_interface_class       (self);
+    preload_interface_subclass    (self);
+    preload_interface_protocol    (self);
+    preload_interface_number      (self);
+    preload_interface_description (self);
+    preload_physdev_sysfs_path    (self);
+    preload_manufacturer          (self);
+    preload_product               (self);
+    preload_driver                (self);
+    preload_physdev_vid           (self);
+    preload_physdev_pid           (self);
+    preload_physdev_revision      (self);
+    preload_physdev_subsystem     (self);
 }
 
 /*****************************************************************************/
@@ -502,6 +459,14 @@
 }
 
 static const gchar *
+kernel_device_get_interface_description (MMKernelDevice *self)
+{
+    g_return_val_if_fail (MM_IS_KERNEL_DEVICE_GENERIC (self), NULL);
+
+    return MM_KERNEL_DEVICE_GENERIC (self)->priv->interface_description;
+}
+
+static const gchar *
 kernel_device_get_physdev_uid (MMKernelDevice *self)
 {
     const gchar *uid;
@@ -748,7 +713,7 @@
             result = (g_str_equal (match->value, "?*") || ((mm_get_uint_from_hex_str (match->value, &val)) &&
                                                            ((self->priv->interface_number == val) == condition_equal)));
         else
-            mm_warn ("Unknown attribute: %s", attribute);
+            mm_obj_warn (self, "unknown attribute: %s", attribute);
 
         g_free (contents);
         g_free (attribute);
@@ -770,7 +735,7 @@
         return result;
     }
 
-    mm_warn ("Unknown match condition parameter: %s", match->parameter);
+    mm_obj_warn (self, "unknown match condition parameter: %s", match->parameter);
     return FALSE;
 }
 
@@ -813,11 +778,9 @@
                 property_value_read = g_strdup_printf ("%02x", self->priv->interface_number);
 
             /* add new property */
-            mm_dbg ("(%s/%s) property added: %s=%s",
-                    mm_kernel_event_properties_get_subsystem (self->priv->properties),
-                    mm_kernel_event_properties_get_name      (self->priv->properties),
-                    rule->result.content.property.name,
-                    property_value_read ? property_value_read : rule->result.content.property.value);
+            mm_obj_dbg (self, "property added: %s=%s",
+                        rule->result.content.property.name,
+                        property_value_read ? property_value_read : rule->result.content.property.value);
 
             if (!property_value_read)
                 /* NOTE: we keep a reference to the list of rules ourselves, so it isn't
@@ -886,9 +849,7 @@
     if (g_strcmp0 (mm_kernel_event_properties_get_subsystem (self->priv->properties), "virtual") == 0)
         return;
 
-    mm_dbg ("(%s/%s) preloading contents and properties...",
-            mm_kernel_event_properties_get_subsystem (self->priv->properties),
-            mm_kernel_event_properties_get_name      (self->priv->properties));
+    mm_obj_dbg (self, "preloading contents and properties...");
     preload_contents (self);
     preload_properties (self);
 }
@@ -1115,28 +1076,29 @@
     object_class->get_property = get_property;
     object_class->set_property = set_property;
 
-    kernel_device_class->get_subsystem            = kernel_device_get_subsystem;
-    kernel_device_class->get_name                 = kernel_device_get_name;
-    kernel_device_class->get_driver               = kernel_device_get_driver;
-    kernel_device_class->get_sysfs_path           = kernel_device_get_sysfs_path;
-    kernel_device_class->get_physdev_uid          = kernel_device_get_physdev_uid;
-    kernel_device_class->get_physdev_vid          = kernel_device_get_physdev_vid;
-    kernel_device_class->get_physdev_pid          = kernel_device_get_physdev_pid;
-    kernel_device_class->get_physdev_revision     = kernel_device_get_physdev_revision;
-    kernel_device_class->get_physdev_sysfs_path   = kernel_device_get_physdev_sysfs_path;
-    kernel_device_class->get_physdev_subsystem    = kernel_device_get_physdev_subsystem;
-    kernel_device_class->get_physdev_manufacturer = kernel_device_get_physdev_manufacturer;
-    kernel_device_class->get_physdev_product      = kernel_device_get_physdev_product;
-    kernel_device_class->get_interface_class      = kernel_device_get_interface_class;
-    kernel_device_class->get_interface_subclass   = kernel_device_get_interface_subclass;
-    kernel_device_class->get_interface_protocol   = kernel_device_get_interface_protocol;
-    kernel_device_class->get_interface_sysfs_path = kernel_device_get_interface_sysfs_path;
-    kernel_device_class->cmp                      = kernel_device_cmp;
-    kernel_device_class->has_property             = kernel_device_has_property;
-    kernel_device_class->get_property             = kernel_device_get_property;
-    kernel_device_class->get_property_as_boolean  = kernel_device_get_property_as_boolean;
-    kernel_device_class->get_property_as_int      = kernel_device_get_property_as_int;
-    kernel_device_class->get_property_as_int_hex  = kernel_device_get_property_as_int_hex;
+    kernel_device_class->get_subsystem             = kernel_device_get_subsystem;
+    kernel_device_class->get_name                  = kernel_device_get_name;
+    kernel_device_class->get_driver                = kernel_device_get_driver;
+    kernel_device_class->get_sysfs_path            = kernel_device_get_sysfs_path;
+    kernel_device_class->get_physdev_uid           = kernel_device_get_physdev_uid;
+    kernel_device_class->get_physdev_vid           = kernel_device_get_physdev_vid;
+    kernel_device_class->get_physdev_pid           = kernel_device_get_physdev_pid;
+    kernel_device_class->get_physdev_revision      = kernel_device_get_physdev_revision;
+    kernel_device_class->get_physdev_sysfs_path    = kernel_device_get_physdev_sysfs_path;
+    kernel_device_class->get_physdev_subsystem     = kernel_device_get_physdev_subsystem;
+    kernel_device_class->get_physdev_manufacturer  = kernel_device_get_physdev_manufacturer;
+    kernel_device_class->get_physdev_product       = kernel_device_get_physdev_product;
+    kernel_device_class->get_interface_class       = kernel_device_get_interface_class;
+    kernel_device_class->get_interface_subclass    = kernel_device_get_interface_subclass;
+    kernel_device_class->get_interface_protocol    = kernel_device_get_interface_protocol;
+    kernel_device_class->get_interface_sysfs_path  = kernel_device_get_interface_sysfs_path;
+    kernel_device_class->get_interface_description = kernel_device_get_interface_description;
+    kernel_device_class->cmp                       = kernel_device_cmp;
+    kernel_device_class->has_property              = kernel_device_has_property;
+    kernel_device_class->get_property              = kernel_device_get_property;
+    kernel_device_class->get_property_as_boolean   = kernel_device_get_property_as_boolean;
+    kernel_device_class->get_property_as_int       = kernel_device_get_property_as_int;
+    kernel_device_class->get_property_as_int_hex   = kernel_device_get_property_as_int_hex;
 
     /* Device-wide properties are stored per-port in the generic backend */
     kernel_device_class->has_global_property            = kernel_device_has_property;
diff --git a/src/kerneldevice/mm-kernel-device-udev.c b/src/kerneldevice/mm-kernel-device-udev.c
index 6ca50dc..f07c46b 100644
--- a/src/kerneldevice/mm-kernel-device-udev.c
+++ b/src/kerneldevice/mm-kernel-device-udev.c
@@ -21,7 +21,7 @@
 #include <ModemManager-tags.h>
 
 #include "mm-kernel-device-udev.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 static void initable_iface_init (GInitableIface *iface);
 
@@ -39,7 +39,7 @@
 
 struct _MMKernelDeviceUdevPrivate {
     GUdevDevice *device;
-    GUdevDevice *parent;
+    GUdevDevice *interface;
     GUdevDevice *physdev;
     guint16      vendor;
     guint16      product;
@@ -177,9 +177,7 @@
         return;
 
     if (!get_device_ids (self->priv->device, &self->priv->vendor, &self->priv->product, &self->priv->revision))
-        mm_dbg ("(%s/%s) could not get vendor/product id",
-                g_udev_device_get_subsystem (self->priv->device),
-                g_udev_device_get_name      (self->priv->device));
+        mm_obj_dbg (self, "could not get vendor/product id");
 }
 
 /*****************************************************************************/
@@ -263,12 +261,42 @@
 /*****************************************************************************/
 
 static void
-ensure_parent (MMKernelDeviceUdev *self)
+ensure_interface (MMKernelDeviceUdev *self)
 {
-    if (self->priv->parent)
+    GUdevDevice *new_parent;
+    GUdevDevice *parent;
+
+    if (self->priv->interface)
         return;
-    if (self->priv->device)
-        self->priv->parent = g_udev_device_get_parent (self->priv->device);
+
+    if (!self->priv->device)
+        return;
+
+    ensure_physdev (self);
+
+    parent = g_udev_device_get_parent (self->priv->device);
+    while (1) {
+        /* Abort if no parent found */
+        if (!parent)
+            break;
+
+        /* Look for the first parent that is a USB interface (i.e. has
+         * bInterfaceClass) */
+        if (g_udev_device_has_sysfs_attr (parent, "bInterfaceClass")) {
+            self->priv->interface = parent;
+            break;
+        }
+
+        /* If unknown physdev, just stop right away */
+        if (!self->priv->physdev || parent == self->priv->physdev) {
+            g_object_unref (parent);
+            break;
+        }
+
+        new_parent = g_udev_device_get_parent (parent);
+        g_object_unref (parent);
+        parent = new_parent;
+    }
 }
 
 /*****************************************************************************/
@@ -494,8 +522,8 @@
     g_return_val_if_fail (MM_IS_KERNEL_DEVICE_UDEV (_self), -1);
 
     self = MM_KERNEL_DEVICE_UDEV (_self);
-    ensure_parent (self);
-    return (self->priv->parent ? g_udev_device_get_sysfs_attr_as_int (self->priv->parent, "bInterfaceClass") : -1);
+    ensure_interface (self);
+    return (self->priv->interface ? g_udev_device_get_sysfs_attr_as_int (self->priv->interface, "bInterfaceClass") : -1);
 }
 
 static gint
@@ -506,8 +534,8 @@
     g_return_val_if_fail (MM_IS_KERNEL_DEVICE_UDEV (_self), -1);
 
     self = MM_KERNEL_DEVICE_UDEV (_self);
-    ensure_parent (self);
-    return (self->priv->parent ? g_udev_device_get_sysfs_attr_as_int (self->priv->parent, "bInterfaceSubClass") : -1);
+    ensure_interface (self);
+    return (self->priv->interface ? g_udev_device_get_sysfs_attr_as_int (self->priv->interface, "bInterfaceSubClass") : -1);
 }
 
 static gint
@@ -518,8 +546,8 @@
     g_return_val_if_fail (MM_IS_KERNEL_DEVICE_UDEV (_self), -1);
 
     self = MM_KERNEL_DEVICE_UDEV (_self);
-    ensure_parent (self);
-    return (self->priv->parent ? g_udev_device_get_sysfs_attr_as_int (self->priv->parent, "bInterfaceProtocol") : -1);
+    ensure_interface (self);
+    return (self->priv->interface ? g_udev_device_get_sysfs_attr_as_int (self->priv->interface, "bInterfaceProtocol") : -1);
 }
 
 static const gchar *
@@ -530,8 +558,20 @@
     g_return_val_if_fail (MM_IS_KERNEL_DEVICE_UDEV (_self), NULL);
 
     self = MM_KERNEL_DEVICE_UDEV (_self);
-    ensure_parent (self);
-    return (self->priv->parent ? g_udev_device_get_sysfs_path (self->priv->parent) : NULL);
+    ensure_interface (self);
+    return (self->priv->interface ? g_udev_device_get_sysfs_path (self->priv->interface) : NULL);
+}
+
+static const gchar *
+kernel_device_get_interface_description (MMKernelDevice *_self)
+{
+    MMKernelDeviceUdev *self;
+
+    g_return_val_if_fail (MM_IS_KERNEL_DEVICE_UDEV (_self), NULL);
+
+    self = MM_KERNEL_DEVICE_UDEV (_self);
+    ensure_interface (self);
+    return (self->priv->interface ? g_udev_device_get_sysfs_attr (self->priv->interface, "interface") : NULL);
 }
 
 static gboolean
@@ -894,7 +934,7 @@
     MMKernelDeviceUdev *self = MM_KERNEL_DEVICE_UDEV (object);
 
     g_clear_object (&self->priv->physdev);
-    g_clear_object (&self->priv->parent);
+    g_clear_object (&self->priv->interface);
     g_clear_object (&self->priv->device);
     g_clear_object (&self->priv->properties);
 
@@ -935,6 +975,7 @@
     kernel_device_class->get_interface_subclass         = kernel_device_get_interface_subclass;
     kernel_device_class->get_interface_protocol         = kernel_device_get_interface_protocol;
     kernel_device_class->get_interface_sysfs_path       = kernel_device_get_interface_sysfs_path;
+    kernel_device_class->get_interface_description      = kernel_device_get_interface_description;
     kernel_device_class->cmp                            = kernel_device_cmp;
     kernel_device_class->has_property                   = kernel_device_has_property;
     kernel_device_class->get_property                   = kernel_device_get_property;
diff --git a/src/kerneldevice/mm-kernel-device.c b/src/kerneldevice/mm-kernel-device.c
index 35c840a..abe0ddd 100644
--- a/src/kerneldevice/mm-kernel-device.c
+++ b/src/kerneldevice/mm-kernel-device.c
@@ -16,10 +16,13 @@
 #include <config.h>
 #include <string.h>
 
-#include "mm-log.h"
 #include "mm-kernel-device.h"
+#include "mm-log-object.h"
 
-G_DEFINE_ABSTRACT_TYPE (MMKernelDevice, mm_kernel_device, G_TYPE_OBJECT)
+static void log_object_iface_init (MMLogObjectInterface *iface);
+
+G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MMKernelDevice, mm_kernel_device, G_TYPE_OBJECT,
+                                  G_IMPLEMENT_INTERFACE (MM_TYPE_LOG_OBJECT, log_object_iface_init))
 
 /*****************************************************************************/
 
@@ -183,6 +186,16 @@
             NULL);
 }
 
+const gchar *
+mm_kernel_device_get_interface_description (MMKernelDevice *self)
+{
+    g_return_val_if_fail (MM_IS_KERNEL_DEVICE (self), NULL);
+
+    return (MM_KERNEL_DEVICE_GET_CLASS (self)->get_interface_description ?
+            MM_KERNEL_DEVICE_GET_CLASS (self)->get_interface_description (self) :
+            NULL);
+}
+
 gboolean
 mm_kernel_device_cmp (MMKernelDevice *a,
                       MMKernelDevice *b)
@@ -307,12 +320,29 @@
 
 /*****************************************************************************/
 
+static gchar *
+log_object_build_id (MMLogObject *_self)
+{
+    MMKernelDevice *self;
+
+    self = MM_KERNEL_DEVICE (_self);
+    return g_strdup (mm_kernel_device_get_name (self));
+}
+
+/*****************************************************************************/
+
 static void
 mm_kernel_device_init (MMKernelDevice *self)
 {
 }
 
 static void
+log_object_iface_init (MMLogObjectInterface *iface)
+{
+    iface->build_id = log_object_build_id;
+}
+
+static void
 mm_kernel_device_class_init (MMKernelDeviceClass *klass)
 {
 }
diff --git a/src/kerneldevice/mm-kernel-device.h b/src/kerneldevice/mm-kernel-device.h
index 6e66d4d..c66b23d 100644
--- a/src/kerneldevice/mm-kernel-device.h
+++ b/src/kerneldevice/mm-kernel-device.h
@@ -41,10 +41,11 @@
     const gchar * (* get_driver)      (MMKernelDevice *self);
     const gchar * (* get_sysfs_path)  (MMKernelDevice *self);
 
-    gint          (* get_interface_class)      (MMKernelDevice *self);
-    gint          (* get_interface_subclass)   (MMKernelDevice *self);
-    gint          (* get_interface_protocol)   (MMKernelDevice *self);
-    const gchar * (* get_interface_sysfs_path) (MMKernelDevice *self);
+    gint          (* get_interface_class)       (MMKernelDevice *self);
+    gint          (* get_interface_subclass)    (MMKernelDevice *self);
+    gint          (* get_interface_protocol)    (MMKernelDevice *self);
+    const gchar * (* get_interface_sysfs_path)  (MMKernelDevice *self);
+    const gchar * (* get_interface_description) (MMKernelDevice *self);
 
     const gchar * (* get_physdev_uid) (MMKernelDevice *self);
     guint16       (* get_physdev_vid) (MMKernelDevice *self);
@@ -77,10 +78,11 @@
 const gchar *mm_kernel_device_get_driver      (MMKernelDevice *self);
 const gchar *mm_kernel_device_get_sysfs_path  (MMKernelDevice *self);
 
-gint         mm_kernel_device_get_interface_class      (MMKernelDevice *self);
-gint         mm_kernel_device_get_interface_subclass   (MMKernelDevice *self);
-gint         mm_kernel_device_get_interface_protocol   (MMKernelDevice *self);
-const gchar *mm_kernel_device_get_interface_sysfs_path (MMKernelDevice *self);
+gint         mm_kernel_device_get_interface_class       (MMKernelDevice *self);
+gint         mm_kernel_device_get_interface_subclass    (MMKernelDevice *self);
+gint         mm_kernel_device_get_interface_protocol    (MMKernelDevice *self);
+const gchar *mm_kernel_device_get_interface_sysfs_path  (MMKernelDevice *self);
+const gchar *mm_kernel_device_get_interface_description (MMKernelDevice *self);
 
 const gchar *mm_kernel_device_get_physdev_uid          (MMKernelDevice *self);
 guint16      mm_kernel_device_get_physdev_vid          (MMKernelDevice *self);
diff --git a/src/main.c b/src/main.c
index 7a6b4b1..9963c7c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -26,8 +26,9 @@
 
 #include "ModemManager.h"
 
-#include "mm-base-manager.h"
+#define MM_LOG_NO_OBJECT
 #include "mm-log.h"
+#include "mm-base-manager.h"
 #include "mm-context.h"
 
 #if defined WITH_SYSTEMD_SUSPEND_RESUME
@@ -43,7 +44,7 @@
 static gboolean
 quit_cb (gpointer user_data)
 {
-    mm_info ("Caught signal, shutting down...");
+    mm_info ("caught signal, shutting down...");
 
     if (manager)
         g_object_set (manager, MM_BASE_MANAGER_CONNECTION, NULL, NULL);
@@ -60,14 +61,14 @@
 static void
 sleeping_cb (MMSleepMonitor *sleep_monitor)
 {
-    mm_dbg ("Removing devices... (sleeping)");
+    mm_dbg ("removing devices... (sleeping)");
     mm_base_manager_shutdown (manager, FALSE);
 }
 
 static void
 resuming_cb (MMSleepMonitor *sleep_monitor)
 {
-    mm_dbg ("Re-scanning (resuming)");
+    mm_dbg ("re-scanning (resuming)");
     mm_base_manager_start (manager, FALSE);
 }
 
@@ -80,7 +81,7 @@
 {
     GError *error = NULL;
 
-    mm_dbg ("Bus acquired, creating manager...");
+    mm_dbg ("bus acquired, creating manager...");
 
     /* Create Manager object */
     g_assert (!manager);
@@ -92,7 +93,7 @@
                                    mm_context_get_test_enable (),
                                    &error);
     if (!manager) {
-        mm_warn ("Could not create manager: %s", error->message);
+        mm_warn ("could not create manager: %s", error->message);
         g_error_free (error);
         g_main_loop_quit (loop);
         return;
@@ -104,7 +105,7 @@
                   const gchar *name,
                   gpointer user_data)
 {
-    mm_dbg ("Service name '%s' was acquired", name);
+    mm_dbg ("service name '%s' was acquired", name);
 
     /* Launch automatic scan for devices */
     g_assert (manager);
@@ -119,10 +120,9 @@
     /* Note that we're not allowing replacement, so once the name acquired, the
      * process won't lose it. */
     if (!name)
-        mm_warn ("Could not get the system bus. Make sure "
-                 "the message bus daemon is running!");
+        mm_warn ("could not get the system bus; make sure the message bus daemon is running!");
     else
-        mm_warn ("Could not acquire the '%s' service name", name);
+        mm_warn ("could not acquire the '%s' service name", name);
 
     if (manager)
         g_object_set (manager, MM_BASE_MANAGER_CONNECTION, NULL, NULL);
@@ -156,8 +156,8 @@
 main (int argc, char *argv[])
 {
     GMainLoop *inner;
-    GError *err = NULL;
-    guint name_id;
+    GError    *error = NULL;
+    guint      name_id;
 
     /* Setup application context */
     mm_context_init (argc, argv);
@@ -167,9 +167,9 @@
                        mm_context_get_log_journal (),
                        mm_context_get_log_timestamps (),
                        mm_context_get_log_relative_timestamps (),
-                       &err)) {
-        g_warning ("Failed to set up logging: %s", err->message);
-        g_error_free (err);
+                       &error)) {
+        g_warning ("failed to set up logging: %s", error->message);
+        g_error_free (error);
         exit (1);
     }
 
@@ -228,8 +228,7 @@
         }
 
         if (mm_base_manager_num_modems (manager))
-            mm_warn ("Disabling modems took too long, "
-                     "shutting down with '%u' modems around",
+            mm_warn ("disabling modems took too long, shutting down with %u modems around",
                      mm_base_manager_num_modems (manager));
 
         g_object_unref (manager);
diff --git a/src/mm-auth-provider.c b/src/mm-auth-provider.c
index bea27d0..5b4b13f 100644
--- a/src/mm-auth-provider.c
+++ b/src/mm-auth-provider.c
@@ -19,7 +19,7 @@
 
 #include <ModemManager.h>
 #include "mm-errors-types.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-utils.h"
 #include "mm-auth-provider.h"
 
@@ -38,7 +38,10 @@
     GObjectClass parent;
 };
 
-G_DEFINE_TYPE (MMAuthProvider, mm_auth_provider, G_TYPE_OBJECT)
+static void log_object_iface_init (MMLogObjectInterface *iface);
+
+G_DEFINE_TYPE_EXTENDED (MMAuthProvider, mm_auth_provider, G_TYPE_OBJECT, 0,
+                        G_IMPLEMENT_INTERFACE (MM_TYPE_LOG_OBJECT, log_object_iface_init))
 
 /*****************************************************************************/
 
@@ -163,6 +166,14 @@
 
 /*****************************************************************************/
 
+static gchar *
+log_object_build_id (MMLogObject *_self)
+{
+    return g_strdup ("auth-provider");
+}
+
+/*****************************************************************************/
+
 static void
 mm_auth_provider_init (MMAuthProvider *self)
 {
@@ -174,8 +185,8 @@
         if (!self->authority) {
             /* NOTE: we failed to create the polkit authority, but we still create
              * our AuthProvider. Every request will fail, though. */
-            mm_warn ("failed to create PolicyKit authority: '%s'",
-                     error ? error->message : "unknown");
+            mm_obj_warn (self, "failed to create PolicyKit authority: '%s'",
+                         error ? error->message : "unknown");
             g_clear_error (&error);
         }
     }
@@ -193,6 +204,12 @@
 }
 
 static void
+log_object_iface_init (MMLogObjectInterface *iface)
+{
+    iface->build_id = log_object_build_id;
+}
+
+static void
 mm_auth_provider_class_init (MMAuthProviderClass *class)
 {
     GObjectClass *object_class = G_OBJECT_CLASS (class);
diff --git a/src/mm-base-bearer.c b/src/mm-base-bearer.c
index 81c281b..163f0bd 100644
--- a/src/mm-base-bearer.c
+++ b/src/mm-base-bearer.c
@@ -35,7 +35,7 @@
 #include "mm-base-bearer.h"
 #include "mm-base-modem-at.h"
 #include "mm-base-modem.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-modem-helpers.h"
 #include "mm-bearer-stats.h"
 
@@ -50,7 +50,10 @@
 #define BEARER_CONNECTION_MONITOR_INITIAL_TIMEOUT 30
 #define BEARER_CONNECTION_MONITOR_TIMEOUT          5
 
-G_DEFINE_TYPE (MMBaseBearer, mm_base_bearer, MM_GDBUS_TYPE_BEARER_SKELETON)
+static void log_object_iface_init (MMLogObjectInterface *iface);
+
+G_DEFINE_TYPE_EXTENDED (MMBaseBearer, mm_base_bearer, MM_GDBUS_TYPE_BEARER_SKELETON, 0,
+                        G_IMPLEMENT_INTERFACE (MM_TYPE_LOG_OBJECT, log_object_iface_init))
 
 typedef enum {
     CONNECTION_FORBIDDEN_REASON_NONE,
@@ -76,6 +79,8 @@
 struct _MMBaseBearerPrivate {
     /* The connection to the system bus */
     GDBusConnection *connection;
+    guint            dbus_id;
+
     /* The modem which owns this BEARER */
     MMBaseModem *modem;
     /* The path where the BEARER object is exported */
@@ -139,10 +144,9 @@
 void
 mm_base_bearer_export (MMBaseBearer *self)
 {
-    static guint id = 0;
     gchar *path;
 
-    path = g_strdup_printf (MM_DBUS_BEARER_PREFIX "/%d", id++);
+    path = g_strdup_printf (MM_DBUS_BEARER_PREFIX "/%d", self->priv->dbus_id);
     g_object_set (self,
                   MM_BASE_BEARER_PATH, path,
                   NULL);
@@ -171,14 +175,14 @@
     if (status == MM_BEARER_CONNECTION_STATUS_UNKNOWN) {
         /* Only warn if not reporting an "unsupported" error */
         if (!g_error_matches (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED)) {
-            mm_warn ("checking if connected failed: %s", error->message);
+            mm_obj_warn (self, "checking if connected failed: %s", error->message);
             g_error_free (error);
             return;
         }
 
         /* If we're being told that connection monitoring is unsupported, just
          * ignore the error and remove the timeout. */
-        mm_dbg ("Connection monitoring is unsupported by the device");
+        mm_obj_dbg (self, "connection monitoring is unsupported by the device");
         self->priv->load_connection_status_unsupported = TRUE;
         connection_monitor_stop (self);
         g_error_free (error);
@@ -187,7 +191,7 @@
 
     /* Report connection or disconnection */
     g_assert (status == MM_BEARER_CONNECTION_STATUS_CONNECTED || status == MM_BEARER_CONNECTION_STATUS_DISCONNECTED);
-    mm_dbg ("connection status loaded: %s", mm_bearer_connection_status_get_string (status));
+    mm_obj_dbg (self, "connection status loaded: %s", mm_bearer_connection_status_get_string (status));
     mm_base_bearer_report_connection_status (self, status);
 }
 
@@ -250,18 +254,73 @@
 }
 
 static void
-bearer_reset_interface_stats (MMBaseBearer *self)
+bearer_reset_ongoing_interface_stats (MMBaseBearer *self)
 {
-    g_clear_object (&self->priv->stats);
-    mm_gdbus_bearer_set_stats (MM_GDBUS_BEARER (self), NULL);
+    mm_bearer_stats_set_duration (self->priv->stats, 0);
+    mm_bearer_stats_set_tx_bytes (self->priv->stats, 0);
+    mm_bearer_stats_set_rx_bytes (self->priv->stats, 0);
+    bearer_update_interface_stats (self);
+}
+
+static void
+bearer_set_ongoing_interface_stats (MMBaseBearer *self,
+                                    guint         duration,
+                                    guint64       rx_bytes,
+                                    guint64       tx_bytes)
+{
+    guint n_updates = 0;
+
+    /* Make sure we don't reset to 0 these values if we had ever set them
+     * before. Just ignore the update if we're reported 0 */
+
+    if (duration) {
+        gint delta_duration;
+
+        delta_duration = duration - mm_bearer_stats_get_duration (self->priv->stats);
+        if (delta_duration > 0) {
+            mm_bearer_stats_set_duration (self->priv->stats, duration);
+            mm_bearer_stats_set_total_duration (self->priv->stats,
+                                                mm_bearer_stats_get_total_duration (self->priv->stats) + delta_duration);
+            n_updates++;
+        }
+    }
+
+    if (rx_bytes) {
+        gint64 delta_rx_bytes;
+
+        delta_rx_bytes = rx_bytes - mm_bearer_stats_get_rx_bytes (self->priv->stats);
+        if (delta_rx_bytes > 0) {
+            mm_bearer_stats_set_rx_bytes (self->priv->stats, rx_bytes);
+            mm_bearer_stats_set_total_rx_bytes (self->priv->stats,
+                                                mm_bearer_stats_get_total_rx_bytes (self->priv->stats) + delta_rx_bytes);
+            n_updates++;
+        }
+    }
+
+    if (tx_bytes) {
+        gint64 delta_tx_bytes;
+
+        delta_tx_bytes = tx_bytes - mm_bearer_stats_get_tx_bytes (self->priv->stats);
+        if (delta_tx_bytes > 0) {
+            mm_bearer_stats_set_tx_bytes (self->priv->stats, tx_bytes);
+            mm_bearer_stats_set_total_tx_bytes (self->priv->stats,
+                                                mm_bearer_stats_get_total_tx_bytes (self->priv->stats) + delta_tx_bytes);
+            n_updates++;
+        }
+    }
+
+    if (n_updates)
+        bearer_update_interface_stats (self);
 }
 
 static void
 bearer_stats_stop (MMBaseBearer *self)
 {
     if (self->priv->duration_timer) {
-        if (self->priv->stats)
-            mm_bearer_stats_set_duration (self->priv->stats, (guint64) g_timer_elapsed (self->priv->duration_timer, NULL));
+        bearer_set_ongoing_interface_stats (self,
+                                            (guint64) g_timer_elapsed (self->priv->duration_timer, NULL),
+                                            0,
+                                            0);
         g_timer_destroy (self->priv->duration_timer);
         self->priv->duration_timer = NULL;
     }
@@ -283,14 +342,14 @@
     if (!MM_BASE_BEARER_GET_CLASS (self)->reload_stats_finish (self, &rx_bytes, &tx_bytes, res, &error)) {
         /* If reloading stats fails, warn about it and don't update anything */
         if (!g_error_matches (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED)) {
-            mm_warn ("Reloading stats failed: %s", error->message);
+            mm_obj_warn (self, "reloading stats failed: %s", error->message);
             g_error_free (error);
             return;
         }
 
         /* If we're being told that reloading stats is unsupported, just ignore
          * the error and update oly the duration timer. */
-        mm_dbg ("Reloading stats is unsupported by the device");
+        mm_obj_dbg (self, "reloading stats is unsupported by the device");
         self->priv->reload_stats_unsupported = TRUE;
         rx_bytes = 0;
         tx_bytes = 0;
@@ -298,10 +357,10 @@
     }
 
     /* We only update stats if they were retrieved properly */
-    mm_bearer_stats_set_duration (self->priv->stats, (guint32) g_timer_elapsed (self->priv->duration_timer, NULL));
-    mm_bearer_stats_set_tx_bytes (self->priv->stats, tx_bytes);
-    mm_bearer_stats_set_rx_bytes (self->priv->stats, rx_bytes);
-    bearer_update_interface_stats (self);
+    bearer_set_ongoing_interface_stats (self,
+                                        (guint32) g_timer_elapsed (self->priv->duration_timer, NULL),
+                                        rx_bytes,
+                                        tx_bytes);
 }
 
 static gboolean
@@ -323,21 +382,16 @@
     }
 
     /* Otherwise, just update duration and we're done */
-    mm_bearer_stats_set_duration (self->priv->stats, (guint32) g_timer_elapsed (self->priv->duration_timer, NULL));
-    mm_bearer_stats_set_tx_bytes (self->priv->stats, 0);
-    mm_bearer_stats_set_rx_bytes (self->priv->stats, 0);
-    bearer_update_interface_stats (self);
+    bearer_set_ongoing_interface_stats (self,
+                                        (guint32) g_timer_elapsed (self->priv->duration_timer, NULL),
+                                        0,
+                                        0);
     return G_SOURCE_CONTINUE;
 }
 
 static void
 bearer_stats_start (MMBaseBearer *self)
 {
-    /* Allocate new stats object. If there was one already created from a
-     * previous run, deallocate it */
-    g_assert (!self->priv->stats);
-    self->priv->stats = mm_bearer_stats_new ();
-
     /* Start duration timer */
     g_assert (!self->priv->duration_timer);
     self->priv->duration_timer = g_timer_new ();
@@ -374,6 +428,10 @@
     /* NOTE: we do allow status 'CONNECTED' here; it may happen if we go into
      * DISCONNECTING and we cannot disconnect */
 
+    /* Do nothing if the status is the same */
+    if (self->priv->status == status)
+        return;
+
     /* Update the property value */
     self->priv->status = status;
     g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_STATUS]);
@@ -381,6 +439,8 @@
     /* Ensure that we don't expose any connection related data in the
      * interface when going into disconnected state. */
     if (self->priv->status == MM_BEARER_STATUS_DISCONNECTED) {
+        g_autoptr(GString) report = NULL;
+
         bearer_reset_interface_status (self);
         /* Cleanup flag to ignore disconnection reports */
         self->priv->ignore_disconnection_reports = FALSE;
@@ -388,6 +448,19 @@
         bearer_stats_stop (self);
         /* Stop connection monitoring */
         connection_monitor_stop (self);
+
+        /* Build and log report */
+        report = g_string_new (NULL);
+        g_string_append_printf (report,
+                                "connection #%u finished: duration %us",
+                                mm_bearer_stats_get_attempts (self->priv->stats),
+                                mm_bearer_stats_get_duration (self->priv->stats));
+        if (!self->priv->reload_stats_unsupported)
+            g_string_append_printf (report,
+                                    ", tx: %" G_GUINT64_FORMAT " bytes, rx :%" G_GUINT64_FORMAT " bytes",
+                                    mm_bearer_stats_get_tx_bytes (self->priv->stats),
+                                    mm_bearer_stats_get_rx_bytes (self->priv->stats));
+        mm_obj_info (self, "%s", report->str);
     }
 }
 
@@ -413,7 +486,7 @@
      * the bearer when ownership of the TTY is given back to MM. */
     if ((ipv4_config && mm_bearer_ip_config_get_method (ipv4_config) == MM_BEARER_IP_METHOD_PPP) ||
         (ipv6_config && mm_bearer_ip_config_get_method (ipv6_config) == MM_BEARER_IP_METHOD_PPP)) {
-        mm_dbg ("PPP is required for connection, will ignore disconnection reports");
+        mm_obj_dbg (self, "PPP is required for connection, will ignore disconnection reports");
         self->priv->ignore_disconnection_reports = TRUE;
     }
 
@@ -450,7 +523,7 @@
     g_warn_if_fail (self->priv->reason_3gpp == CONNECTION_FORBIDDEN_REASON_UNREGISTERED);
     self->priv->deferred_3gpp_unregistration_id = 0;
 
-    mm_dbg ("Forcing bearer disconnection, not registered in 3GPP network");
+    mm_obj_dbg (self, "forcing bearer disconnection, not registered in 3GPP network");
     mm_base_bearer_disconnect_force (self);
     return G_SOURCE_REMOVE;
 }
@@ -476,6 +549,7 @@
     case MM_MODEM_3GPP_REGISTRATION_STATE_HOME_SMS_ONLY:
     case MM_MODEM_3GPP_REGISTRATION_STATE_HOME_CSFB_NOT_PREFERRED:
     case MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING:
+    case MM_MODEM_3GPP_REGISTRATION_STATE_ATTACHED_RLOS:
         self->priv->reason_3gpp = CONNECTION_FORBIDDEN_REASON_NONE;
         break;
     case MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING:
@@ -504,7 +578,7 @@
 
     /* Modem is roaming and roaming not allowed, report right away */
     if (self->priv->reason_3gpp == CONNECTION_FORBIDDEN_REASON_ROAMING) {
-        mm_dbg ("Bearer not allowed to connect, registered in roaming 3GPP network");
+        mm_obj_dbg (self, "bearer not allowed to connect, registered in roaming 3GPP network");
         reset_deferred_unregistration (self);
         mm_base_bearer_disconnect_force (self);
         return;
@@ -512,7 +586,7 @@
 
     /* Modem is registered under emergency services only? */
     if (self->priv->reason_3gpp == CONNECTION_FORBIDDEN_REASON_EMERGENCY_ONLY) {
-        mm_dbg ("Bearer not allowed to connect, emergency services only");
+        mm_obj_dbg (self, "bearer not allowed to connect, emergency services only");
         reset_deferred_unregistration (self);
         mm_base_bearer_disconnect_force (self);
         return;
@@ -526,13 +600,13 @@
 
         /* If the bearer is not connected, report right away */
         if (self->priv->status != MM_BEARER_STATUS_CONNECTED) {
-            mm_dbg ("Bearer not allowed to connect, not registered in 3GPP network");
+            mm_obj_dbg (self, "bearer not allowed to connect, not registered in 3GPP network");
             mm_base_bearer_disconnect_force (self);
             return;
         }
 
         /* Otherwise, setup the new timeout */
-        mm_dbg ("Connected bearer not registered in 3GPP network");
+        mm_obj_dbg (self, "connected bearer not registered in 3GPP network");
         self->priv->deferred_3gpp_unregistration_id =
             g_timeout_add_seconds (BEARER_DEFERRED_UNREGISTRATION_TIMEOUT,
                                    (GSourceFunc) deferred_3gpp_unregistration_cb,
@@ -549,7 +623,7 @@
     g_warn_if_fail (self->priv->reason_cdma == CONNECTION_FORBIDDEN_REASON_UNREGISTERED);
     self->priv->deferred_cdma_unregistration_id = 0;
 
-    mm_dbg ("Forcing bearer disconnection, not registered in CDMA network");
+    mm_obj_dbg (self, "forcing bearer disconnection, not registered in CDMA network");
     mm_base_bearer_disconnect_force (self);
     return G_SOURCE_REMOVE;
 }
@@ -591,7 +665,7 @@
 
     /* Modem is roaming and roaming not allowed, report right away */
     if (self->priv->reason_cdma == CONNECTION_FORBIDDEN_REASON_ROAMING) {
-        mm_dbg ("Bearer not allowed to connect, registered in roaming CDMA network");
+        mm_obj_dbg (self, "bearer not allowed to connect, registered in roaming CDMA network");
         reset_deferred_unregistration (self);
         mm_base_bearer_disconnect_force (self);
         return;
@@ -605,13 +679,13 @@
 
         /* If the bearer is not connected, report right away */
         if (self->priv->status != MM_BEARER_STATUS_CONNECTED) {
-            mm_dbg ("Bearer not allowed to connect, not registered in CDMA network");
+            mm_obj_dbg (self, "bearer not allowed to connect, not registered in CDMA network");
             mm_base_bearer_disconnect_force (self);
             return;
         }
 
         /* Otherwise, setup the new timeout */
-        mm_dbg ("Connected bearer not registered in CDMA network");
+        mm_obj_dbg (self, "connected bearer not registered in CDMA network");
         self->priv->deferred_cdma_unregistration_id =
             g_timeout_add_seconds (BEARER_DEFERRED_UNREGISTRATION_TIMEOUT,
                                    (GSourceFunc) deferred_cdma_unregistration_cb,
@@ -700,14 +774,11 @@
     GError *error = NULL;
 
     if (!MM_BASE_BEARER_GET_CLASS (self)->disconnect_finish (self, res, &error)) {
-        mm_warn ("Error disconnecting bearer '%s': '%s'. "
-                 "Will assume disconnected anyway.",
-                 self->priv->path,
-                 error->message);
+        mm_obj_warn (self, "error disconnecting: %s; will assume disconnected anyway", error->message);
         g_error_free (error);
     }
     else
-        mm_dbg ("Disconnected bearer '%s'", self->priv->path);
+        mm_obj_dbg (self, "disconnected bearer '%s'", self->priv->path);
 
     /* Report disconnection to the bearer object using class method
      * mm_bearer_report_connection_status. This gives subclass implementations a
@@ -729,9 +800,15 @@
     /* NOTE: connect() implementations *MUST* handle cancellations themselves */
     result = MM_BASE_BEARER_GET_CLASS (self)->connect_finish (self, res, &error);
     if (!result) {
-        mm_dbg ("Couldn't connect bearer '%s': '%s'",
-                self->priv->path,
-                error->message);
+        mm_obj_warn (self, "connection attempt #%u failed: %s",
+                     mm_bearer_stats_get_attempts (self->priv->stats),
+                     error->message);
+
+        /* Update failed attempts */
+        mm_bearer_stats_set_failed_attempts (self->priv->stats,
+                                             mm_bearer_stats_get_failed_attempts (self->priv->stats) + 1);
+        bearer_update_interface_stats (self);
+
         if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
             /* Will launch disconnection */
             launch_disconnect = TRUE;
@@ -740,14 +817,14 @@
     }
     /* Handle cancellations detected after successful connection */
     else if (g_cancellable_is_cancelled (self->priv->connect_cancellable)) {
-        mm_dbg ("Connected bearer '%s', but need to disconnect", self->priv->path);
+        mm_obj_dbg (self, "connected, but need to disconnect");
         mm_bearer_connect_result_unref (result);
         error = g_error_new (G_IO_ERROR, G_IO_ERROR_CANCELLED,
                              "Bearer got connected, but had to disconnect after cancellation request");
         launch_disconnect = TRUE;
     }
     else {
-        mm_dbg ("Connected bearer '%s'", self->priv->path);
+        mm_obj_dbg (self, "connected");
 
         /* Update bearer and interface status */
         bearer_update_status_connected (
@@ -862,11 +939,15 @@
         return;
     }
 
+    /* Update total attempts */
+    mm_bearer_stats_set_attempts (self->priv->stats,
+                                  mm_bearer_stats_get_attempts (self->priv->stats) + 1);
+    bearer_reset_ongoing_interface_stats (self);
+
     /* Connecting! */
-    mm_dbg ("Connecting bearer '%s'", self->priv->path);
+    mm_obj_dbg (self, "connecting...");
     self->priv->connect_cancellable = g_cancellable_new ();
     bearer_update_status (self, MM_BEARER_STATUS_CONNECTING);
-    bearer_reset_interface_stats (self);
     MM_BASE_BEARER_GET_CLASS (self)->connect (
         self,
         self->priv->connect_cancellable,
@@ -935,7 +1016,7 @@
                   MM_BASE_BEARER_MODEM, &ctx->modem,
                   NULL);
 
-    mm_dbg ("User request to connect bearer '%s'", self->priv->path);
+    mm_obj_dbg (self, "user request to connect");
 
     mm_base_modem_authorize (ctx->modem,
                              invocation,
@@ -964,12 +1045,12 @@
     GError *error = NULL;
 
     if (!MM_BASE_BEARER_GET_CLASS (self)->disconnect_finish (self, res, &error)) {
-        mm_dbg ("Couldn't disconnect bearer '%s': %s", self->priv->path, error->message);
+        mm_obj_dbg (self, "couldn't disconnect: %s", error->message);
         bearer_update_status (self, MM_BEARER_STATUS_CONNECTED);
         g_task_return_error (task, error);
     }
     else {
-        mm_dbg ("Disconnected bearer '%s'", self->priv->path);
+        mm_obj_dbg (self, "disconnected");
         bearer_update_status (self, MM_BEARER_STATUS_DISCONNECTED);
         g_task_return_boolean (task, TRUE);
     }
@@ -987,8 +1068,7 @@
     if (self->priv->status != MM_BEARER_STATUS_DISCONNECTED)
         return;
 
-    mm_dbg ("Disconnected bearer '%s' after cancelling previous connect request",
-            self->priv->path);
+    mm_obj_dbg (self, "disconnected after cancelling previous connect request");
     g_signal_handler_disconnect (self,
                                  self->priv->disconnect_signal_handler);
     self->priv->disconnect_signal_handler = 0;
@@ -1037,7 +1117,7 @@
         return;
     }
 
-    mm_dbg ("Disconnecting bearer '%s'", self->priv->path);
+    mm_obj_dbg (self, "disconnecting...");
 
     /* If currently connecting, try to cancel that operation, and wait to get
      * disconnected. */
@@ -1128,7 +1208,7 @@
                   MM_BASE_BEARER_MODEM, &ctx->modem,
                   NULL);
 
-    mm_dbg ("User request to disconnect bearer '%s'", self->priv->path);
+    mm_obj_dbg (self, "user request to disconnect");
 
     mm_base_modem_authorize (ctx->modem,
                              invocation,
@@ -1159,9 +1239,7 @@
                                            self->priv->connection,
                                            self->priv->path,
                                            &error)) {
-        mm_warn ("couldn't export BEARER at '%s': '%s'",
-                 self->priv->path,
-                 error->message);
+        mm_obj_warn (self, "couldn't export to bus: %s", error->message);
         g_error_free (error);
     }
 }
@@ -1174,7 +1252,7 @@
     path = g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (self));
     /* Only unexport if currently exported */
     if (path) {
-        mm_dbg ("Removing from DBus bearer at '%s'", path);
+        mm_obj_dbg (self, "removing from bus");
         g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (self));
     }
 }
@@ -1222,14 +1300,11 @@
     GError *error = NULL;
 
     if (!MM_BASE_BEARER_GET_CLASS (self)->disconnect_finish (self, res, &error)) {
-        mm_warn ("Error disconnecting bearer '%s': '%s'. "
-                 "Will assume disconnected anyway.",
-                 self->priv->path,
-                 error->message);
+        mm_obj_warn (self, "error disconnecting: %s; will assume disconnected anyway", error->message);
         g_error_free (error);
     }
     else
-        mm_dbg ("Disconnected bearer '%s'", self->priv->path);
+        mm_obj_dbg (self, "disconnected");
 
     /* Report disconnection to the bearer object using class method
      * mm_bearer_report_connection_status. This gives subclass implementations a
@@ -1246,7 +1321,7 @@
         self->priv->status == MM_BEARER_STATUS_DISCONNECTED)
         return;
 
-    mm_dbg ("Forcing disconnection of bearer '%s'", self->priv->path);
+    mm_obj_dbg (self, "forcing disconnection");
 
     /* If currently connecting, try to cancel that operation. */
     if (self->priv->status == MM_BEARER_STATUS_CONNECTING) {
@@ -1310,7 +1385,7 @@
                                          MMBearerConnectionStatus  status)
 {
     if ((status == MM_BEARER_CONNECTION_STATUS_DISCONNECTED) && self->priv->ignore_disconnection_reports) {
-        mm_dbg ("ignoring disconnection report for bearer '%s'", self->priv->path);
+        mm_obj_dbg (self, "ignoring disconnection report");
         return;
     }
 
@@ -1319,6 +1394,17 @@
 
 /*****************************************************************************/
 
+static gchar *
+log_object_build_id (MMLogObject *_self)
+{
+    MMBaseBearer *self;
+
+    self = MM_BASE_BEARER (_self);
+    return g_strdup_printf ("bearer%u", self->priv->dbus_id);
+}
+
+/*****************************************************************************/
+
 static void
 set_property (GObject *object,
               guint prop_id,
@@ -1351,6 +1437,8 @@
         g_clear_object (&self->priv->modem);
         self->priv->modem = g_value_dup_object (value);
         if (self->priv->modem) {
+            /* Set owner ID */
+            mm_log_object_set_owner_id (MM_LOG_OBJECT (self), mm_log_object_get_id (MM_LOG_OBJECT (self->priv->modem)));
             /* Bind the modem's connection (which is set when it is exported,
              * and unset when unexported) to the BEARER's connection */
             g_object_bind_property (self->priv->modem, MM_BASE_MODEM_CONNECTION,
@@ -1429,14 +1517,21 @@
 static void
 mm_base_bearer_init (MMBaseBearer *self)
 {
+    static guint id = 0;
+
     /* Initialize private data */
     self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
                                               MM_TYPE_BASE_BEARER,
                                               MMBaseBearerPrivate);
+
+    /* Each bearer is given a unique id to build its own DBus path */
+    self->priv->dbus_id = id++;
+
     self->priv->status = MM_BEARER_STATUS_DISCONNECTED;
     self->priv->reason_3gpp = CONNECTION_FORBIDDEN_REASON_NONE;
     self->priv->reason_cdma = CONNECTION_FORBIDDEN_REASON_NONE;
     self->priv->default_ip_family = MM_BEARER_IP_FAMILY_IPV4;
+    self->priv->stats = mm_bearer_stats_new ();
 
     /* Set defaults */
     mm_gdbus_bearer_set_interface   (MM_GDBUS_BEARER (self), NULL);
@@ -1449,6 +1544,7 @@
                                      mm_bearer_ip_config_get_dictionary (NULL));
     mm_gdbus_bearer_set_ip6_config  (MM_GDBUS_BEARER (self),
                                      mm_bearer_ip_config_get_dictionary (NULL));
+    bearer_update_interface_stats (self);
 }
 
 static void
@@ -1485,6 +1581,12 @@
 }
 
 static void
+log_object_iface_init (MMLogObjectInterface *iface)
+{
+    iface->build_id = log_object_build_id;
+}
+
+static void
 mm_base_bearer_class_init (MMBaseBearerClass *klass)
 {
     GObjectClass *object_class = G_OBJECT_CLASS (klass);
diff --git a/src/mm-base-call.c b/src/mm-base-call.c
index 6966e94..149cfbd 100644
--- a/src/mm-base-call.c
+++ b/src/mm-base-call.c
@@ -32,11 +32,14 @@
 #include "mm-iface-modem-voice.h"
 #include "mm-base-modem-at.h"
 #include "mm-base-modem.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-modem-helpers.h"
 #include "mm-error-helpers.h"
 
-G_DEFINE_TYPE (MMBaseCall, mm_base_call, MM_GDBUS_TYPE_CALL_SKELETON)
+static void log_object_iface_init (MMLogObjectInterface *iface);
+
+G_DEFINE_TYPE_EXTENDED (MMBaseCall, mm_base_call, MM_GDBUS_TYPE_CALL_SKELETON, 0,
+                        G_IMPLEMENT_INTERFACE (MM_TYPE_LOG_OBJECT, log_object_iface_init))
 
 enum {
     PROP_0,
@@ -54,6 +57,8 @@
 struct _MMBaseCallPrivate {
     /* The connection to the system bus */
     GDBusConnection *connection;
+    guint            dbus_id;
+
     /* The modem which owns this call */
     MMBaseModem *modem;
     /* The path where the call object is exported */
@@ -92,7 +97,7 @@
 incoming_timeout_cb (MMBaseCall *self)
 {
     self->priv->incoming_timeout = 0;
-    mm_info ("incoming call timed out: no response");
+    mm_obj_info (self, "incoming call timed out: no response");
     mm_base_call_change_state (self, MM_CALL_STATE_TERMINATED, MM_CALL_STATE_REASON_TERMINATED);
     return G_SOURCE_REMOVE;
 }
@@ -157,14 +162,14 @@
     g_clear_object (&ctx->self->priv->start_cancellable);
 
     if (!MM_BASE_CALL_GET_CLASS (self)->start_finish (self, res, &error)) {
-        mm_warn ("Couldn't start call : '%s'", error->message);
+        mm_obj_warn (self, "couldn't start call: %s", error->message);
 
         /* When cancelled via the start cancellable, it's because we got an early in-call error
          * before the call attempt was reported as started. */
         if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) ||
             g_error_matches (error, MM_CORE_ERROR, MM_CORE_ERROR_CANCELLED)) {
             g_clear_error (&error);
-            error = mm_connection_error_for_code (MM_CONNECTION_ERROR_NO_DIALTONE);
+            error = mm_connection_error_for_code (MM_CONNECTION_ERROR_NO_DIALTONE, self);
         }
 
         /* Convert errors into call state updates */
@@ -182,7 +187,7 @@
         return;
     }
 
-    mm_info ("call is started");
+    mm_obj_info (self, "call is started");
 
     /* If dialing to ringing supported, leave it dialing */
     if (!ctx->self->priv->supports_dialing_to_ringing) {
@@ -224,7 +229,7 @@
         return;
     }
 
-    mm_info ("user request to start call");
+    mm_obj_info (ctx->self, "user request to start call");
 
     /* Disallow non-emergency calls when in emergency-only state */
     if (!mm_iface_modem_voice_authorize_outgoing_call (MM_IFACE_MODEM_VOICE (modem), ctx->self, &error)) {
@@ -311,7 +316,7 @@
         return;
     }
 
-    mm_info ("call is accepted");
+    mm_obj_info (self, "call is accepted");
 
     if (ctx->self->priv->incoming_timeout) {
         g_source_remove (ctx->self->priv->incoming_timeout);
@@ -348,7 +353,7 @@
         return;
     }
 
-    mm_info ("user request to accept call");
+    mm_obj_info (ctx->self, "user request to accept call");
 
     /* Check if we do support doing it */
     if (!MM_BASE_CALL_GET_CLASS (ctx->self)->accept ||
@@ -421,7 +426,7 @@
         return;
     }
 
-    mm_info ("call is deflected to '%s'", ctx->number);
+    mm_obj_info (self, "call is deflected to '%s'", ctx->number);
     mm_base_call_change_state (ctx->self, MM_CALL_STATE_TERMINATED, MM_CALL_STATE_REASON_DEFLECTED);
     mm_gdbus_call_complete_deflect (MM_GDBUS_CALL (ctx->self), ctx->invocation);
     handle_deflect_context_free (ctx);
@@ -453,7 +458,7 @@
         return;
     }
 
-    mm_info ("user request to deflect call");
+    mm_obj_info (ctx->self, "user request to deflect call");
 
     /* Check if we do support doing it */
     if (!MM_BASE_CALL_GET_CLASS (ctx->self)->deflect ||
@@ -710,7 +715,7 @@
         return;
     }
 
-    mm_info ("user request to hangup call");
+    mm_obj_info (ctx->self, "user request to hangup call");
 
     /* Check if we do support doing it */
     if (!MM_BASE_CALL_GET_CLASS (ctx->self)->hangup ||
@@ -856,10 +861,9 @@
 void
 mm_base_call_export (MMBaseCall *self)
 {
-    static guint id = 0;
     gchar *path;
 
-    path = g_strdup_printf (MM_DBUS_CALL_PREFIX "/%d", id++);
+    path = g_strdup_printf (MM_DBUS_CALL_PREFIX "/%d", self->priv->dbus_id);
     g_object_set (self,
                   MM_BASE_CALL_PATH, path,
                   NULL);
@@ -896,9 +900,7 @@
                                            self->priv->connection,
                                            self->priv->path,
                                            &error)) {
-        mm_warn ("couldn't export call at '%s': '%s'",
-                 self->priv->path,
-                 error->message);
+        mm_obj_warn (self, "couldn't export call: %s", error->message);
         g_error_free (error);
     }
 }
@@ -989,10 +991,10 @@
     if (old_state == new_state)
         return;
 
-    mm_info ("Call state changed: %s -> %s (%s)",
-             mm_call_state_get_string (old_state),
-             mm_call_state_get_string (new_state),
-             mm_call_state_reason_get_string (reason));
+    mm_obj_info (self, "call state changed: %s -> %s (%s)",
+                 mm_call_state_get_string (old_state),
+                 mm_call_state_get_string (new_state),
+                 mm_call_state_reason_get_string (reason));
 
     /* Setup/cleanup unsolicited events  based on state transitions to/from ACTIVE */
     if (new_state == MM_CALL_STATE_TERMINATED) {
@@ -1235,8 +1237,8 @@
 
     mm_base_modem_at_command_finish (modem, res, &error);
     if (error) {
-        mm_warn ("couldn't hangup single call with call id '%u': %s",
-                 self->priv->index, error->message);
+        mm_obj_warn (self, "couldn't hangup single call with call id '%u': %s",
+                     self->priv->index, error->message);
         g_error_free (error);
         chup_fallback (task);
         return;
@@ -1286,15 +1288,18 @@
 }
 
 static void
-call_send_dtmf_ready (MMBaseModem *modem,
+call_send_dtmf_ready (MMBaseModem  *modem,
                       GAsyncResult *res,
-                      GTask *task)
+                      GTask        *task)
 {
-    GError *error = NULL;
+    MMBaseCall *self;
+    GError     *error = NULL;
+
+    self = g_task_get_source_object (task);
 
     mm_base_modem_at_command_finish (modem, res, &error);
     if (error) {
-        mm_dbg ("Couldn't send_dtmf: '%s'", error->message);
+        mm_obj_dbg (self, "couldn't send dtmf: %s", error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -1328,6 +1333,17 @@
 
 /*****************************************************************************/
 
+static gchar *
+log_object_build_id (MMLogObject *_self)
+{
+    MMBaseCall *self;
+
+    self = MM_BASE_CALL (_self);
+    return g_strdup_printf ("call%u", self->priv->dbus_id);
+}
+
+/*****************************************************************************/
+
 MMBaseCall *
 mm_base_call_new (MMBaseModem     *modem,
                   MMCallDirection  direction,
@@ -1381,6 +1397,8 @@
         g_clear_object (&self->priv->modem);
         self->priv->modem = g_value_dup_object (value);
         if (self->priv->modem) {
+            /* Set owner ID */
+            mm_log_object_set_owner_id (MM_LOG_OBJECT (self), mm_log_object_get_id (MM_LOG_OBJECT (self->priv->modem)));
             /* Bind the modem's connection (which is set when it is exported,
              * and unset when unexported) to the call's connection */
             g_object_bind_property (self->priv->modem, MM_BASE_MODEM_CONNECTION,
@@ -1439,8 +1457,13 @@
 static void
 mm_base_call_init (MMBaseCall *self)
 {
+    static guint id = 0;
+
     /* Initialize private data */
     self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, MM_TYPE_BASE_CALL, MMBaseCallPrivate);
+
+    /* Each call is given a unique id to build its own DBus path */
+    self->priv->dbus_id = id++;
 }
 
 static void
@@ -1479,6 +1502,12 @@
 }
 
 static void
+log_object_iface_init (MMLogObjectInterface *iface)
+{
+    iface->build_id = log_object_build_id;
+}
+
+static void
 mm_base_call_class_init (MMBaseCallClass *klass)
 {
     GObjectClass *object_class = G_OBJECT_CLASS (klass);
diff --git a/src/mm-base-manager.c b/src/mm-base-manager.c
index 5ff0c05..653adb5 100644
--- a/src/mm-base-manager.c
+++ b/src/mm-base-manager.c
@@ -44,13 +44,14 @@
 #include "mm-auth-provider.h"
 #include "mm-plugin.h"
 #include "mm-filter.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
-static void initable_iface_init (GInitableIface *iface);
+static void initable_iface_init   (GInitableIface       *iface);
+static void log_object_iface_init (MMLogObjectInterface *iface);
 
 G_DEFINE_TYPE_EXTENDED (MMBaseManager, mm_base_manager, MM_GDBUS_TYPE_ORG_FREEDESKTOP_MODEM_MANAGER1_SKELETON, 0,
-                        G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
-                                               initable_iface_init));
+                        G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init)
+                        G_IMPLEMENT_INTERFACE (MM_TYPE_LOG_OBJECT, log_object_iface_init))
 
 enum {
     PROP_0,
@@ -180,8 +181,8 @@
     /* Receive plugin result from the plugin manager */
     plugin = mm_plugin_manager_device_support_check_finish (plugin_manager, res, &error);
     if (!plugin) {
-        mm_info ("Couldn't check support for device '%s': %s",
-                 mm_device_get_uid (ctx->device), error->message);
+        mm_obj_info (ctx->self, "couldn't check support for device '%s': %s",
+                     mm_device_get_uid (ctx->device), error->message);
         g_error_free (error);
         g_hash_table_remove (ctx->self->priv->devices, mm_device_get_uid (ctx->device));
         find_device_support_context_free (ctx);
@@ -193,8 +194,8 @@
     g_object_unref (plugin);
 
     if (!mm_device_create_modem (ctx->device, &error)) {
-        mm_warn ("Couldn't create modem for device '%s': %s",
-                 mm_device_get_uid (ctx->device), error->message);
+        mm_obj_warn (ctx->self, "couldn't create modem for device '%s': %s",
+                     mm_device_get_uid (ctx->device), error->message);
         g_error_free (error);
         g_hash_table_remove (ctx->self->priv->devices, mm_device_get_uid (ctx->device));
         find_device_support_context_free (ctx);
@@ -202,8 +203,8 @@
     }
 
     /* Modem now created */
-    mm_info ("Modem for device '%s' successfully created",
-             mm_device_get_uid (ctx->device));
+    mm_obj_info (ctx->self, "modem for device '%s' successfully created",
+                 mm_device_get_uid (ctx->device));
     find_device_support_context_free (ctx);
 }
 
@@ -220,7 +221,7 @@
 device_removed (MMBaseManager  *self,
                 MMKernelDevice *kernel_device)
 {
-    MMDevice *device;
+    MMDevice    *device;
     const gchar *subsys;
     const gchar *name;
 
@@ -241,14 +242,14 @@
              * ourselves. */
             g_object_ref (device);
             {
-                mm_info ("(%s/%s): released by device '%s'", subsys, name, mm_device_get_uid (device));
+                mm_obj_info (self, "port %s released by device '%s'", name, mm_device_get_uid (device));
                 mm_device_release_port (device, kernel_device);
 
                 /* If port probe list gets empty, remove the device object iself */
                 if (!mm_device_peek_port_probe_list (device)) {
-                    mm_dbg ("Removing empty device '%s'", mm_device_get_uid (device));
+                    mm_obj_dbg (self, "removing empty device '%s'", mm_device_get_uid (device));
                     if (mm_plugin_manager_device_support_check_cancel (self->priv->plugin_manager, device))
-                        mm_dbg ("Device support check has been cancelled");
+                        mm_obj_dbg (self, "device support check has been cancelled");
 
                     /* The device may have already been removed from the tracking HT, we
                      * just try to remove it and if it fails, we ignore it */
@@ -291,7 +292,7 @@
      */
     device = find_device_by_kernel_device (self, kernel_device);
     if (device) {
-        mm_dbg ("Removing device '%s'", mm_device_get_uid (device));
+        mm_obj_dbg (self, "removing device '%s'", mm_device_get_uid (device));
         mm_device_remove_modem (device);
         g_hash_table_remove (self->priv->devices, mm_device_get_uid (device));
         return;
@@ -299,23 +300,21 @@
 }
 
 static void
-device_added (MMBaseManager  *manager,
+device_added (MMBaseManager  *self,
               MMKernelDevice *port,
               gboolean        hotplugged,
               gboolean        manual_scan)
 {
     MMDevice    *device;
     const gchar *physdev_uid;
-    const gchar *subsys;
     const gchar *name;
 
     g_return_if_fail (port != NULL);
 
-    subsys = mm_kernel_device_get_subsystem (port);
     name = mm_kernel_device_get_name (port);
 
-    mm_dbg ("(%s/%s): adding device at sysfs path: %s",
-            subsys, name, mm_kernel_device_get_sysfs_path (port));
+    mm_obj_dbg (self, "adding port %s at sysfs path: %s",
+                name, mm_kernel_device_get_sysfs_path (port));
 
     /* Ignore devices that aren't completely configured by udev yet.  If
      * ModemManager is started in parallel with udev, explicitly requesting
@@ -330,8 +329,8 @@
         /* This could mean that device changed, losing its candidate
          * flags (such as Bluetooth RFCOMM devices upon disconnect.
          * Try to forget it. */
-        device_removed (manager, port);
-        mm_dbg ("(%s/%s): port not candidate", subsys, name);
+        device_removed (self, port);
+        mm_obj_dbg (self, "port %s not candidate", name);
         return;
     }
 
@@ -341,50 +340,48 @@
     g_assert (physdev_uid);
 
     /* If the device is inhibited, do nothing else */
-    if (is_device_inhibited (manager, physdev_uid)) {
+    if (is_device_inhibited (self, physdev_uid)) {
         /* Note: we will not report as hotplugged an inhibited device port
          * because we don't know what was done with the port out of our
          * context. */
-        device_inhibited_track_port (manager, physdev_uid, port, manual_scan);
+        device_inhibited_track_port (self, physdev_uid, port, manual_scan);
         return;
     }
 
     /* Run port filter */
-    if (!mm_filter_port (manager->priv->filter, port, manual_scan))
+    if (!mm_filter_port (self->priv->filter, port, manual_scan))
         return;
 
     /* If already added, ignore new event */
-    if (find_device_by_port (manager, port)) {
-        mm_dbg ("(%s/%s): port already added", subsys, name);
+    if (find_device_by_port (self, port)) {
+        mm_obj_dbg (self, "port %s already added", name);
         return;
     }
 
     /* See if we already created an object to handle ports in this device */
-    device = find_device_by_physdev_uid (manager, physdev_uid);
+    device = find_device_by_physdev_uid (self, physdev_uid);
     if (!device) {
         FindDeviceSupportContext *ctx;
 
-        mm_dbg ("(%s/%s): first port in device %s",
-                subsys, name, physdev_uid);
+        mm_obj_dbg (self, "port %s is first in device %s", name, physdev_uid);
 
         /* Keep the device listed in the Manager */
-        device = mm_device_new (physdev_uid, hotplugged, FALSE, manager->priv->object_manager);
-        g_hash_table_insert (manager->priv->devices,
+        device = mm_device_new (physdev_uid, hotplugged, FALSE, self->priv->object_manager);
+        g_hash_table_insert (self->priv->devices,
                              g_strdup (physdev_uid),
                              device);
 
         /* Launch device support check */
         ctx = g_slice_new (FindDeviceSupportContext);
-        ctx->self = g_object_ref (manager);
+        ctx->self = g_object_ref (self);
         ctx->device = g_object_ref (device);
         mm_plugin_manager_device_support_check (
-            manager->priv->plugin_manager,
+            self->priv->plugin_manager,
             device,
             (GAsyncReadyCallback) device_support_check_ready,
             ctx);
     } else
-        mm_dbg ("(%s/%s): additional port in device %s",
-                subsys, name, physdev_uid);
+        mm_obj_dbg (self, "additional port %s in device %s", name, physdev_uid);
 
     /* Grab the port in the existing device. */
     mm_device_grab_port (device, port);
@@ -425,11 +422,11 @@
 
     uid = mm_kernel_event_properties_get_uid (properties);
 
-    mm_dbg ("Kernel event reported:");
-    mm_dbg ("  action:    %s", action);
-    mm_dbg ("  subsystem: %s", subsystem);
-    mm_dbg ("  name:      %s", name);
-    mm_dbg ("  uid:       %s", uid ? uid : "n/a");
+    mm_obj_dbg (self, "kernel event reported:");
+    mm_obj_dbg (self, "  action:    %s", action);
+    mm_obj_dbg (self, "  subsystem: %s", subsystem);
+    mm_obj_dbg (self, "  name:      %s", name);
+    mm_obj_dbg (self, "  uid:       %s", uid ? uid : "n/a");
 
 #if defined WITH_UDEV
     kernel_device = mm_kernel_device_udev_new_from_properties (properties, error);
@@ -455,15 +452,16 @@
 
 static void
 handle_uevent (GUdevClient *client,
-               const char *action,
+               const gchar *action,
                GUdevDevice *device,
-               gpointer user_data)
+               gpointer     user_data)
 {
-    MMBaseManager *self = MM_BASE_MANAGER (user_data);
-    const gchar *subsys;
-    const gchar *name;
+    MMBaseManager  *self;
+    const gchar    *subsys;
+    const gchar    *name;
     MMKernelDevice *kernel_device;
 
+    self = MM_BASE_MANAGER (user_data);
     g_return_if_fail (action != NULL);
 
     /* A bit paranoid */
@@ -629,11 +627,11 @@
     }
 
 #if defined WITH_UDEV
-    mm_dbg ("Starting %s device scan...", manual_scan ? "manual" : "automatic");
+    mm_obj_dbg (self, "starting %s device scan...", manual_scan ? "manual" : "automatic");
     process_scan (self, manual_scan);
-    mm_dbg ("Finished device scan...");
+    mm_obj_dbg (self, "finished device scan...");
 #else
-    mm_dbg ("Unsupported %s device scan...", manual_scan ? "manual" : "automatic");
+    mm_obj_dbg (self, "unsupported %s device scan...", manual_scan ? "manual" : "automatic");
 #endif
 }
 
@@ -745,8 +743,8 @@
 }
 
 static void
-set_logging_auth_ready (MMAuthProvider *authp,
-                        GAsyncResult *res,
+set_logging_auth_ready (MMAuthProvider    *authp,
+                        GAsyncResult      *res,
                         SetLoggingContext *ctx)
 {
     GError *error = NULL;
@@ -756,7 +754,7 @@
     else if (!mm_log_set_level (ctx->level, &error))
         g_dbus_method_invocation_take_error (ctx->invocation, error);
     else {
-        mm_info ("logging: level '%s'", ctx->level);
+        mm_obj_info (ctx->self, "logging: level '%s'", ctx->level);
         mm_gdbus_org_freedesktop_modem_manager1_complete_set_logging (
             MM_GDBUS_ORG_FREEDESKTOP_MODEM_MANAGER1 (ctx->self),
             ctx->invocation);
@@ -985,9 +983,7 @@
 
             port_info = (InhibitedDevicePortInfo *)(l->data);
             if (mm_kernel_device_cmp (port_info->kernel_port, kernel_port)) {
-                mm_dbg ("(%s/%s): released while inhibited",
-                        mm_kernel_device_get_subsystem (kernel_port),
-                        mm_kernel_device_get_name (kernel_port));
+                mm_obj_dbg (self, "released port %s while inhibited", mm_kernel_device_get_name (kernel_port));
                 inhibited_device_port_info_free (port_info);
                 info->port_infos = g_list_delete_link (info->port_infos, l);
                 return;
@@ -1018,9 +1014,7 @@
         }
     }
 
-    mm_dbg ("(%s/%s): added while inhibited",
-            mm_kernel_device_get_subsystem (kernel_port),
-            mm_kernel_device_get_name (kernel_port));
+    mm_obj_dbg (self, "added port %s while inhibited", mm_kernel_device_get_name (kernel_port));
 
     port_info = g_slice_new0 (InhibitedDevicePortInfo);
     port_info->kernel_port = g_object_ref (kernel_port);
@@ -1085,7 +1079,7 @@
 
         /* Uninhibit device, which will create and expose the modem object */
         if (!mm_device_uninhibit (device, &error)) {
-            mm_warn ("Couldn't uninhibit device: %s", error->message);
+            mm_obj_warn (self, "couldn't uninhibit device: %s", error->message);
             g_error_free (error);
         }
     }
@@ -1096,7 +1090,7 @@
                      const gchar              *sender_name,
                      InhibitSenderLostContext *lost_ctx)
 {
-    mm_info ("Device inhibition teardown for uid '%s' (owner disappeared from bus)", lost_ctx->uid);
+    mm_obj_info (lost_ctx->self, "device inhibition teardown for uid '%s' (owner disappeared from bus)", lost_ctx->uid);
     remove_device_inhibition (lost_ctx->self, lost_ctx->uid);
 }
 
@@ -1151,7 +1145,7 @@
 
     g_hash_table_insert (ctx->self->priv->inhibited_devices, g_strdup (ctx->uid), info);
 
-    mm_info ("Device inhibition setup for uid '%s'", ctx->uid);
+    mm_obj_info (ctx->self, "device inhibition setup for uid '%s'", ctx->uid);
 
     mm_gdbus_org_freedesktop_modem_manager1_complete_inhibit_device (
         MM_GDBUS_ORG_FREEDESKTOP_MODEM_MANAGER1 (ctx->self),
@@ -1200,7 +1194,7 @@
         return;
     }
 
-    mm_info ("Device inhibition teardown for uid '%s'", ctx->uid);
+    mm_obj_info (ctx->self, "device inhibition teardown for uid '%s'", ctx->uid);
     remove_device_inhibition (ctx->self, ctx->uid);
 
     mm_gdbus_org_freedesktop_modem_manager1_complete_inhibit_device (
@@ -1267,7 +1261,7 @@
     gchar *physdev_uid;
     GError *error = NULL;
 
-    mm_info ("Test profile set to: '%s'", id);
+    mm_obj_info (self, "test profile set to: '%s'", id);
 
     /* Create device and keep it listed in the Manager */
     physdev_uid = g_strdup_printf ("/virtual/%s", id);
@@ -1284,23 +1278,23 @@
                              MM_CORE_ERROR_NOT_FOUND,
                              "Requested plugin '%s' not found",
                              plugin_name);
-        mm_warn ("Couldn't set plugin for virtual device '%s': %s",
-                 mm_device_get_uid (device),
-                 error->message);
+        mm_obj_warn (self, "couldn't set plugin for virtual device '%s': %s",
+                     mm_device_get_uid (device),
+                     error->message);
         goto out;
     }
     mm_device_set_plugin (device, G_OBJECT (plugin));
 
     /* Create modem */
     if (!mm_device_create_modem (device, &error)) {
-        mm_warn ("Couldn't create modem for virtual device '%s': %s",
-                 mm_device_get_uid (device),
-                 error->message);
+        mm_obj_warn (self, "couldn't create modem for virtual device '%s': %s",
+                     mm_device_get_uid (device),
+                     error->message);
         goto out;
     }
 
-    mm_info ("Modem for virtual device '%s' successfully created",
-             mm_device_get_uid (device));
+    mm_obj_info (self, "modem for virtual device '%s' successfully created",
+                 mm_device_get_uid (device));
 
 out:
 
@@ -1317,6 +1311,14 @@
 
 /*****************************************************************************/
 
+static gchar *
+log_object_build_id (MMLogObject *_self)
+{
+    return g_strdup ("base-manager");
+}
+
+/*****************************************************************************/
+
 MMBaseManager *
 mm_base_manager_new (GDBusConnection  *connection,
                      const gchar      *plugin_dir,
@@ -1342,52 +1344,52 @@
 }
 
 static void
-set_property (GObject *object,
-              guint prop_id,
+set_property (GObject      *object,
+              guint         prop_id,
               const GValue *value,
-              GParamSpec *pspec)
+              GParamSpec   *pspec)
 {
-    MMBaseManagerPrivate *priv = MM_BASE_MANAGER (object)->priv;
+    MMBaseManager *self = MM_BASE_MANAGER (object);
 
     switch (prop_id) {
     case PROP_CONNECTION: {
         gboolean had_connection = FALSE;
 
-        if (priv->connection) {
+        if (self->priv->connection) {
             had_connection = TRUE;
-            g_object_unref (priv->connection);
+            g_object_unref (self->priv->connection);
         }
-        priv->connection = g_value_dup_object (value);
+        self->priv->connection = g_value_dup_object (value);
         /* Propagate connection loss to subobjects */
-        if (had_connection && !priv->connection) {
-            if (priv->object_manager) {
-                mm_dbg ("Stopping connection in object manager server");
-                g_dbus_object_manager_server_set_connection (priv->object_manager, NULL);
+        if (had_connection && !self->priv->connection) {
+            if (self->priv->object_manager) {
+                mm_obj_dbg (self, "stopping connection in object manager server");
+                g_dbus_object_manager_server_set_connection (self->priv->object_manager, NULL);
             }
-            if (priv->test_skeleton &&
-                g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (priv->test_skeleton))) {
-                mm_dbg ("Stopping connection in test skeleton");
-                g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (priv->test_skeleton));
+            if (self->priv->test_skeleton &&
+                g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (self->priv->test_skeleton))) {
+                mm_obj_dbg (self, "stopping connection in test skeleton");
+                g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (self->priv->test_skeleton));
             }
         }
         break;
     }
     case PROP_AUTO_SCAN:
-        priv->auto_scan = g_value_get_boolean (value);
+        self->priv->auto_scan = g_value_get_boolean (value);
         break;
     case PROP_FILTER_POLICY:
-        priv->filter_policy = g_value_get_flags (value);
+        self->priv->filter_policy = g_value_get_flags (value);
         break;
     case PROP_ENABLE_TEST:
-        priv->enable_test = g_value_get_boolean (value);
+        self->priv->enable_test = g_value_get_boolean (value);
         break;
     case PROP_PLUGIN_DIR:
-        g_free (priv->plugin_dir);
-        priv->plugin_dir = g_value_dup_string (value);
+        g_free (self->priv->plugin_dir);
+        self->priv->plugin_dir = g_value_dup_string (value);
         break;
     case PROP_INITIAL_KERNEL_EVENTS:
-        g_free (priv->initial_kernel_events);
-        priv->initial_kernel_events = g_value_dup_string (value);
+        g_free (self->priv->initial_kernel_events);
+        self->priv->initial_kernel_events = g_value_dup_string (value);
         break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -1396,31 +1398,31 @@
 }
 
 static void
-get_property (GObject *object,
-              guint prop_id,
-              GValue *value,
+get_property (GObject    *object,
+              guint       prop_id,
+              GValue     *value,
               GParamSpec *pspec)
 {
-    MMBaseManagerPrivate *priv = MM_BASE_MANAGER (object)->priv;
+    MMBaseManager *self = MM_BASE_MANAGER (object);
 
     switch (prop_id) {
     case PROP_CONNECTION:
-        g_value_set_object (value, priv->connection);
+        g_value_set_object (value, self->priv->connection);
         break;
     case PROP_AUTO_SCAN:
-        g_value_set_boolean (value, priv->auto_scan);
+        g_value_set_boolean (value, self->priv->auto_scan);
         break;
     case PROP_FILTER_POLICY:
-        g_value_set_flags (value, priv->filter_policy);
+        g_value_set_flags (value, self->priv->filter_policy);
         break;
     case PROP_ENABLE_TEST:
-        g_value_set_boolean (value, priv->enable_test);
+        g_value_set_boolean (value, self->priv->enable_test);
         break;
     case PROP_PLUGIN_DIR:
-        g_value_set_string (value, priv->plugin_dir);
+        g_value_set_string (value, self->priv->plugin_dir);
         break;
     case PROP_INITIAL_KERNEL_EVENTS:
-        g_value_set_string (value, priv->initial_kernel_events);
+        g_value_set_string (value, self->priv->initial_kernel_events);
         break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -1429,45 +1431,41 @@
 }
 
 static void
-mm_base_manager_init (MMBaseManager *manager)
+mm_base_manager_init (MMBaseManager *self)
 {
-    MMBaseManagerPrivate *priv;
-
     /* Setup private data */
-    manager->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE (manager,
-                                                        MM_TYPE_BASE_MANAGER,
-                                                        MMBaseManagerPrivate);
+    self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, MM_TYPE_BASE_MANAGER, MMBaseManagerPrivate);
 
     /* Setup authorization provider */
-    priv->authp = mm_auth_provider_get ();
-    priv->authp_cancellable = g_cancellable_new ();
+    self->priv->authp = mm_auth_provider_get ();
+    self->priv->authp_cancellable = g_cancellable_new ();
 
     /* Setup internal lists of device objects */
-    priv->devices = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
+    self->priv->devices = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
 
     /* Setup internal list of inhibited devices */
-    priv->inhibited_devices = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)inhibited_device_info_free);
+    self->priv->inhibited_devices = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)inhibited_device_info_free);
 
 #if defined WITH_UDEV
     {
         const gchar *subsys[5] = { "tty", "net", "usb", "usbmisc", NULL };
 
         /* Setup UDev client */
-        priv->udev = g_udev_client_new (subsys);
+        self->priv->udev = g_udev_client_new (subsys);
     }
 #endif
 
     /* By default, enable autoscan */
-    priv->auto_scan = TRUE;
+    self->priv->auto_scan = TRUE;
 
     /* By default, no test interface */
-    priv->enable_test = FALSE;
+    self->priv->enable_test = FALSE;
 
     /* Setup Object Manager Server */
-    priv->object_manager = g_dbus_object_manager_server_new (MM_DBUS_PATH);
+    self->priv->object_manager = g_dbus_object_manager_server_new (MM_DBUS_PATH);
 
     /* Enable processing of input DBus messages */
-    g_object_connect (manager,
+    g_object_connect (self,
                       "signal::handle-set-logging",         G_CALLBACK (handle_set_logging),         NULL,
                       "signal::handle-scan-devices",        G_CALLBACK (handle_scan_devices),        NULL,
                       "signal::handle-report-kernel-event", G_CALLBACK (handle_report_kernel_event), NULL,
@@ -1476,48 +1474,48 @@
 }
 
 static gboolean
-initable_init (GInitable *initable,
-               GCancellable *cancellable,
-               GError **error)
+initable_init (GInitable     *initable,
+               GCancellable  *cancellable,
+               GError       **error)
 {
-    MMBaseManagerPrivate *priv = MM_BASE_MANAGER (initable)->priv;
+    MMBaseManager *self = MM_BASE_MANAGER (initable);
 
 #if defined WITH_UDEV
     /* If autoscan enabled, list for udev events */
-    if (priv->auto_scan)
-        g_signal_connect (priv->udev, "uevent", G_CALLBACK (handle_uevent), initable);
+    if (self->priv->auto_scan)
+        g_signal_connect (self->priv->udev, "uevent", G_CALLBACK (handle_uevent), initable);
 #endif
 
     /* Create filter */
-    priv->filter = mm_filter_new (priv->filter_policy, error);
-    if (!priv->filter)
+    self->priv->filter = mm_filter_new (self->priv->filter_policy, error);
+    if (!self->priv->filter)
         return FALSE;
 
     /* Create plugin manager */
-    priv->plugin_manager = mm_plugin_manager_new (priv->plugin_dir, priv->filter, error);
-    if (!priv->plugin_manager)
+    self->priv->plugin_manager = mm_plugin_manager_new (self->priv->plugin_dir, self->priv->filter, error);
+    if (!self->priv->plugin_manager)
         return FALSE;
 
     /* Export the manager interface */
     if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (initable),
-                                           priv->connection,
+                                           self->priv->connection,
                                            MM_DBUS_PATH,
                                            error))
         return FALSE;
 
     /* Export the Object Manager interface */
-    g_dbus_object_manager_server_set_connection (priv->object_manager,
-                                                 priv->connection);
+    g_dbus_object_manager_server_set_connection (self->priv->object_manager,
+                                                 self->priv->connection);
 
     /* Setup the Test skeleton and export the interface */
-    if (priv->enable_test) {
-        priv->test_skeleton = mm_gdbus_test_skeleton_new ();
-        g_signal_connect (priv->test_skeleton,
+    if (self->priv->enable_test) {
+        self->priv->test_skeleton = mm_gdbus_test_skeleton_new ();
+        g_signal_connect (self->priv->test_skeleton,
                           "handle-set-profile",
                           G_CALLBACK (handle_set_profile),
                           initable);
-        if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (priv->test_skeleton),
-                                               priv->connection,
+        if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (self->priv->test_skeleton),
+                                               self->priv->connection,
                                                MM_DBUS_PATH,
                                                error))
             return FALSE;
@@ -1530,38 +1528,38 @@
 static void
 finalize (GObject *object)
 {
-    MMBaseManagerPrivate *priv = MM_BASE_MANAGER (object)->priv;
+    MMBaseManager *self = MM_BASE_MANAGER (object);
 
-    g_free (priv->initial_kernel_events);
-    g_free (priv->plugin_dir);
+    g_free (self->priv->initial_kernel_events);
+    g_free (self->priv->plugin_dir);
 
-    g_hash_table_destroy (priv->inhibited_devices);
-    g_hash_table_destroy (priv->devices);
+    g_hash_table_destroy (self->priv->inhibited_devices);
+    g_hash_table_destroy (self->priv->devices);
 
 #if defined WITH_UDEV
-    if (priv->udev)
-        g_object_unref (priv->udev);
+    if (self->priv->udev)
+        g_object_unref (self->priv->udev);
 #endif
 
-    if (priv->filter)
-        g_object_unref (priv->filter);
+    if (self->priv->filter)
+        g_object_unref (self->priv->filter);
 
-    if (priv->plugin_manager)
-        g_object_unref (priv->plugin_manager);
+    if (self->priv->plugin_manager)
+        g_object_unref (self->priv->plugin_manager);
 
-    if (priv->object_manager)
-        g_object_unref (priv->object_manager);
+    if (self->priv->object_manager)
+        g_object_unref (self->priv->object_manager);
 
-    if (priv->test_skeleton)
-        g_object_unref (priv->test_skeleton);
+    if (self->priv->test_skeleton)
+        g_object_unref (self->priv->test_skeleton);
 
-    if (priv->connection)
-        g_object_unref (priv->connection);
+    if (self->priv->connection)
+        g_object_unref (self->priv->connection);
 
     /* note: authp is a singleton, we don't keep a full reference */
 
-    if (priv->authp_cancellable)
-        g_object_unref (priv->authp_cancellable);
+    if (self->priv->authp_cancellable)
+        g_object_unref (self->priv->authp_cancellable);
 
     G_OBJECT_CLASS (mm_base_manager_parent_class)->finalize (object);
 }
@@ -1573,6 +1571,12 @@
 }
 
 static void
+log_object_iface_init (MMLogObjectInterface *iface)
+{
+    iface->build_id = log_object_build_id;
+}
+
+static void
 mm_base_manager_class_init (MMBaseManagerClass *manager_class)
 {
     GObjectClass *object_class = G_OBJECT_CLASS (manager_class);
diff --git a/src/mm-base-modem.c b/src/mm-base-modem.c
index 322fb89..0805ced 100644
--- a/src/mm-base-modem.c
+++ b/src/mm-base-modem.c
@@ -31,12 +31,15 @@
 #include "mm-context.h"
 #include "mm-base-modem.h"
 
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-port-enums-types.h"
 #include "mm-serial-parsers.h"
 #include "mm-modem-helpers.h"
 
-G_DEFINE_ABSTRACT_TYPE (MMBaseModem, mm_base_modem, MM_GDBUS_TYPE_OBJECT_SKELETON);
+static void log_object_iface_init (MMLogObjectInterface *iface);
+
+G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MMBaseModem, mm_base_modem, MM_GDBUS_TYPE_OBJECT_SKELETON,
+                                  G_IMPLEMENT_INTERFACE (MM_TYPE_LOG_OBJECT, log_object_iface_init))
 
 /* If we get 10 consecutive timeouts in a serial port, we consider the modem
  * invalid and we request re-probing. */
@@ -61,6 +64,7 @@
 struct _MMBaseModemPrivate {
     /* The connection to the system bus */
     GDBusConnection *connection;
+    guint            dbus_id;
 
     /* Modem-wide cancellable. If it ever gets cancelled, no further operations
      * should be done by the modem. */
@@ -113,6 +117,12 @@
 #endif
 };
 
+guint
+mm_base_modem_get_dbus_id (MMBaseModem *self)
+{
+    return self->priv->dbus_id;
+}
+
 static gchar *
 get_hash_key (const gchar *subsys,
               const gchar *name)
@@ -127,22 +137,17 @@
 {
     /* If reached the maximum number of timeouts, invalidate modem */
     if (n_consecutive_timeouts >= self->priv->max_timeouts) {
-        mm_err ("(%s/%s) %s port timed out %u consecutive times, marking modem '%s' as invalid",
-                 mm_port_subsys_get_string (mm_port_get_subsys (MM_PORT (port))),
-                 mm_port_get_device (MM_PORT (port)),
-                 mm_port_type_get_string (mm_port_get_port_type (MM_PORT (port))),
-                 n_consecutive_timeouts,
-                 g_dbus_object_get_object_path (G_DBUS_OBJECT (self)));
+        mm_obj_err (self, "port %s timed out %u consecutive times, marking modem as invalid",
+                    mm_port_get_device (MM_PORT (port)),
+                    n_consecutive_timeouts);
         g_cancellable_cancel (self->priv->cancellable);
         return;
     }
 
     if (n_consecutive_timeouts > 1)
-        mm_warn ("(%s/%s) %s port timed out %u consecutive times",
-                 mm_port_subsys_get_string (mm_port_get_subsys (MM_PORT (port))),
-                 mm_port_get_device (MM_PORT (port)),
-                 mm_port_type_get_string (mm_port_get_port_type (MM_PORT (port))),
-                 n_consecutive_timeouts);
+        mm_obj_warn (self, "port %s timed out %u consecutive times",
+                     mm_port_get_device (MM_PORT (port)),
+                     n_consecutive_timeouts);
 }
 
 gboolean
@@ -221,13 +226,13 @@
             /* Prefer plugin-provided flags to the generic ones */
             if (at_pflags == MM_PORT_SERIAL_AT_FLAG_NONE) {
                 if (mm_kernel_device_get_property_as_boolean (kernel_device, ID_MM_PORT_TYPE_AT_PRIMARY)) {
-                    mm_dbg ("AT port '%s/%s' flagged as primary", subsys, name);
+                    mm_obj_dbg (self, "AT port '%s/%s' flagged as primary", subsys, name);
                     at_pflags = MM_PORT_SERIAL_AT_FLAG_PRIMARY;
                 } else if (mm_kernel_device_get_property_as_boolean (kernel_device, ID_MM_PORT_TYPE_AT_SECONDARY)) {
-                    mm_dbg ("AT port '%s/%s' flagged as secondary", subsys, name);
+                    mm_obj_dbg (self, "AT port '%s/%s' flagged as secondary", subsys, name);
                     at_pflags = MM_PORT_SERIAL_AT_FLAG_SECONDARY;
                 } else if (mm_kernel_device_get_property_as_boolean (kernel_device, ID_MM_PORT_TYPE_AT_PPP)) {
-                    mm_dbg ("AT port '%s/%s' flagged as PPP", subsys, name);
+                    mm_obj_dbg (self, "AT port '%s/%s' flagged as PPP", subsys, name);
                     at_pflags = MM_PORT_SERIAL_AT_FLAG_PPP;
                 }
             }
@@ -269,8 +274,8 @@
 
             flow_control = mm_flow_control_from_string (flow_control_tag, &inner_error);
             if (flow_control == MM_FLOW_CONTROL_UNKNOWN) {
-                mm_warn ("(%s/%s) unsupported flow control settings in port: %s",
-                         subsys, name, inner_error->message);
+                mm_obj_warn (self, "unsupported flow control settings in port %s: %s",
+                             name, inner_error->message);
                 g_error_free (inner_error);
             } else {
                 g_object_set (port,
@@ -339,10 +344,7 @@
         /* We already filter out before all non-tty, non-net, non-cdc-wdm ports */
         g_assert_not_reached ();
 
-    mm_dbg ("(%s) type '%s' claimed by %s",
-            name,
-            mm_port_type_get_string (ptype),
-            mm_base_modem_get_device (self));
+    mm_obj_dbg (self, "grabbed port '%s/%s'", name, mm_port_type_get_string (ptype));
 
     /* Add it to the tracking HT.
      * Note: 'key' and 'port' now owned by the HT. */
@@ -353,6 +355,9 @@
                   MM_PORT_KERNEL_DEVICE, kernel_device,
                   NULL);
 
+    /* Set owner ID */
+    mm_log_object_set_owner_id (MM_LOG_OBJECT (port), mm_log_object_get_id (MM_LOG_OBJECT (self)));
+
     return TRUE;
 }
 
@@ -1015,7 +1020,7 @@
     GError *error = NULL;
 
     if (mm_base_modem_initialize_finish (self, res, &error)) {
-        mm_dbg ("modem properly initialized");
+        mm_obj_dbg (self, "modem initialized");
         mm_base_modem_set_valid (self, TRUE);
         return;
     }
@@ -1025,8 +1030,7 @@
         /* Even with initialization errors, we do set the state to valid, so
          * that the modem gets exported and the failure notified to the user.
          */
-        mm_dbg ("Couldn't finish initialization in the current state: '%s'",
-                error->message);
+        mm_obj_dbg (self, "couldn't finish initialization in the current state: '%s'", error->message);
         g_error_free (error);
         mm_base_modem_set_valid (self, TRUE);
         return;
@@ -1034,7 +1038,7 @@
 
     /* Really fatal, we cannot even export the failed modem (e.g. error before
      * even trying to enable the Modem interface */
-    mm_warn ("couldn't initialize the modem: '%s'", error->message);
+    mm_obj_warn (self, "couldn't initialize: '%s'", error->message);
     g_error_free (error);
 }
 
@@ -1042,11 +1046,10 @@
 log_port (MMBaseModem *self, MMPort *port, const char *desc)
 {
     if (port) {
-        mm_dbg ("(%s) %s/%s %s",
-                self->priv->device,
-                mm_port_subsys_get_string (mm_port_get_subsys (port)),
-                mm_port_get_device (port),
-                desc);
+        mm_obj_dbg (self, "%s/%s %s",
+                    mm_port_subsys_get_string (mm_port_get_subsys (port)),
+                    mm_port_get_device (port),
+                    desc);
     }
 }
 
@@ -1467,9 +1470,9 @@
 cleanup_modem_port (MMBaseModem *self,
                     MMPort      *port)
 {
-    mm_dbg ("cleaning up port '%s/%s'...",
-            mm_port_subsys_get_string (mm_port_get_subsys (MM_PORT (port))),
-            mm_port_get_device (MM_PORT (port)));
+    mm_obj_dbg (self, "cleaning up port '%s/%s'...",
+                mm_port_subsys_get_string (mm_port_get_subsys (MM_PORT (port))),
+                mm_port_get_device (MM_PORT (port)));
 
     /* Cleanup for serial ports */
     if (MM_IS_PORT_SERIAL (port)) {
@@ -1515,14 +1518,30 @@
 
 /*****************************************************************************/
 
+static gchar *
+log_object_build_id (MMLogObject *_self)
+{
+    MMBaseModem *self;
+
+    self = MM_BASE_MODEM (_self);
+    return g_strdup_printf ("modem%u", self->priv->dbus_id);
+}
+
+/*****************************************************************************/
+
 static void
 mm_base_modem_init (MMBaseModem *self)
 {
+    static guint id = 0;
+
     /* Initialize private data */
     self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
                                               MM_TYPE_BASE_MODEM,
                                               MMBaseModemPrivate);
 
+    /* Each modem is given a unique id to build its own DBus path */
+    self->priv->dbus_id = id++;
+
     /* Setup authorization provider */
     self->priv->authp = mm_auth_provider_get ();
     self->priv->authp_cancellable = g_cancellable_new ();
@@ -1640,9 +1659,7 @@
     g_assert (!self->priv->enable_tasks);
     g_assert (!self->priv->disable_tasks);
 
-    mm_dbg ("Modem (%s) '%s' completely disposed",
-            self->priv->plugin,
-            self->priv->device);
+    mm_obj_dbg (self, "completely disposed");
 
     g_free (self->priv->device);
     g_strfreev (self->priv->drivers);
@@ -1692,6 +1709,12 @@
 }
 
 static void
+log_object_iface_init (MMLogObjectInterface *iface)
+{
+    iface->build_id = log_object_build_id;
+}
+
+static void
 mm_base_modem_class_init (MMBaseModemClass *klass)
 {
     GObjectClass *object_class = G_OBJECT_CLASS (klass);
diff --git a/src/mm-base-modem.h b/src/mm-base-modem.h
index e4001f2..0c4b95f 100644
--- a/src/mm-base-modem.h
+++ b/src/mm-base-modem.h
@@ -105,6 +105,8 @@
 
 GType mm_base_modem_get_type (void);
 
+guint     mm_base_modem_get_dbus_id  (MMBaseModem *self);
+
 gboolean  mm_base_modem_grab_port    (MMBaseModem         *self,
                                       MMKernelDevice      *kernel_device,
                                       MMPortType           ptype,
diff --git a/src/mm-base-sim.c b/src/mm-base-sim.c
index 7eca8e4..2775953 100644
--- a/src/mm-base-sim.c
+++ b/src/mm-base-sim.c
@@ -30,14 +30,15 @@
 #include "mm-base-sim.h"
 #include "mm-base-modem-at.h"
 #include "mm-base-modem.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-modem-helpers.h"
 
 static void async_initable_iface_init (GAsyncInitableIface *iface);
+static void log_object_iface_init     (MMLogObjectInterface *iface);
 
 G_DEFINE_TYPE_EXTENDED (MMBaseSim, mm_base_sim, MM_GDBUS_TYPE_SIM_SKELETON, 0,
-                        G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE,
-                                               async_initable_iface_init))
+                        G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, async_initable_iface_init)
+                        G_IMPLEMENT_INTERFACE (MM_TYPE_LOG_OBJECT, log_object_iface_init))
 
 enum {
     PROP_0,
@@ -57,6 +58,8 @@
 struct _MMBaseSimPrivate {
     /* The connection to the system bus */
     GDBusConnection *connection;
+    guint            dbus_id;
+
     /* The modem which owns this SIM */
     MMBaseModem *modem;
     /* The path where the SIM object is exported */
@@ -70,10 +73,9 @@
 void
 mm_base_sim_export (MMBaseSim *self)
 {
-    static guint id = 0;
     gchar *path;
 
-    path = g_strdup_printf (MM_DBUS_SIM_PREFIX "/%d", id++);
+    path = g_strdup_printf (MM_DBUS_SIM_PREFIX "/%d", self->priv->dbus_id);
     g_object_set (self,
                   MM_BASE_SIM_PATH, path,
                   NULL);
@@ -912,9 +914,7 @@
                                            self->priv->connection,
                                            self->priv->path,
                                            &error)) {
-        mm_warn ("couldn't export SIM at '%s': '%s'",
-                 self->priv->path,
-                 error->message);
+        mm_obj_warn (self, "couldn't export SIM: %s", error->message);
         g_error_free (error);
     }
 }
@@ -1031,7 +1031,7 @@
         return NULL;
 
     for (i = 0; emergency_numbers[i]; i++)
-        mm_dbg ("loaded emergency number: %s", emergency_numbers[i]);
+        mm_obj_dbg (self, "loaded emergency number: %s", emergency_numbers[i]);
 
     return emergency_numbers;
 }
@@ -1043,7 +1043,7 @@
                         GAsyncReadyCallback  callback,
                         gpointer             user_data)
 {
-    mm_dbg ("loading emergency numbers...");
+    mm_obj_dbg (self, "loading emergency numbers...");
 
     /* READ BINARY of EF_ECC (Emergency Call Codes) ETSI TS 51.011 section 10.3.27 */
     mm_base_modem_at_command (
@@ -1109,7 +1109,7 @@
     if (!sim_identifier)
         return NULL;
 
-    mm_dbg ("loaded SIM identifier: %s", sim_identifier);
+    mm_obj_dbg (self, "loaded SIM identifier: %s", sim_identifier);
     return sim_identifier;
 }
 
@@ -1120,7 +1120,7 @@
                      GAsyncReadyCallback callback,
                      gpointer user_data)
 {
-    mm_dbg ("loading SIM identifier...");
+    mm_obj_dbg (self, "loading SIM identifier...");
 
     /* READ BINARY of EFiccid (ICC Identification) ETSI TS 102.221 section 13.2 */
     mm_base_modem_at_command (
@@ -1177,7 +1177,7 @@
     if (!imsi)
         return NULL;
 
-    mm_dbg ("loaded IMSI: %s", imsi);
+    mm_obj_dbg (self, "loaded IMSI: %s", imsi);
     return imsi;
 }
 
@@ -1188,7 +1188,7 @@
            GAsyncReadyCallback callback,
            gpointer user_data)
 {
-    mm_dbg ("loading IMSI...");
+    mm_obj_dbg (self, "loading IMSI...");
 
     mm_base_modem_at_command (
         self->priv->modem,
@@ -1306,7 +1306,7 @@
                           GAsyncReadyCallback callback,
                           gpointer user_data)
 {
-    mm_dbg ("loading Operator ID...");
+    mm_obj_dbg (self, "loading operator ID...");
 
     /* READ BINARY of EFad (Administrative Data) ETSI 51.011 section 10.3.18 */
     mm_base_modem_at_command (
@@ -1401,7 +1401,7 @@
                     GAsyncReadyCallback callback,
                     gpointer user_data)
 {
-    mm_dbg ("loading Operator Name...");
+    mm_obj_dbg (self, "loading operator name...");
 
     /* READ BINARY of EFspn (Service Provider Name) ETSI 51.011 section 10.3.11 */
     mm_base_modem_at_command (
@@ -1485,8 +1485,7 @@
             return;
         }
 
-        mm_warn ("couldn't load SIM identifier: '%s'",
-                 error ? error->message : "unknown error");
+        mm_obj_warn (self, "couldn't load SIM identifier: %s", error ? error->message : "unknown error");
         g_clear_error (&error);
     }
 
@@ -1509,7 +1508,7 @@
 
     str_list = MM_BASE_SIM_GET_CLASS (self)->load_emergency_numbers_finish (self, res, &error);
     if (error) {
-        mm_warn ("couldn't load list of Emergency Numbers: '%s'", error->message);
+        mm_obj_warn (self, "couldn't load list of emergency numbers: %s", error->message);
         g_error_free (error);
     }
 
@@ -1540,7 +1539,7 @@
         g_free (val);                                                   \
                                                                         \
         if (error) {                                                    \
-            mm_warn ("couldn't load %s: '%s'", DISPLAY, error->message); \
+            mm_obj_warn (self, "couldn't load %s: %s", DISPLAY, error->message); \
             g_error_free (error);                                       \
         }                                                               \
                                                                         \
@@ -1551,8 +1550,8 @@
     }
 
 STR_REPLY_READY_FN (imsi, "IMSI")
-STR_REPLY_READY_FN (operator_identifier, "Operator identifier")
-STR_REPLY_READY_FN (operator_name, "Operator name")
+STR_REPLY_READY_FN (operator_identifier, "operator identifier")
+STR_REPLY_READY_FN (operator_name, "operator name")
 
 static void
 interface_initialization_step (GTask *task)
@@ -1739,6 +1738,19 @@
                        user_data);
 }
 
+/*****************************************************************************/
+
+static gchar *
+log_object_build_id (MMLogObject *_self)
+{
+    MMBaseSim *self;
+
+    self = MM_BASE_SIM (_self);
+    return g_strdup_printf ("sim%u", self->priv->dbus_id);
+}
+
+/*****************************************************************************/
+
 static void
 set_property (GObject *object,
               guint prop_id,
@@ -1771,6 +1783,8 @@
         g_clear_object (&self->priv->modem);
         self->priv->modem = g_value_dup_object (value);
         if (self->priv->modem) {
+            /* Set owner ID */
+            mm_log_object_set_owner_id (MM_LOG_OBJECT (self), mm_log_object_get_id (MM_LOG_OBJECT (self->priv->modem)));
             /* Bind the modem's connection (which is set when it is exported,
              * and unset when unexported) to the SIM's connection */
             g_object_bind_property (self->priv->modem, MM_BASE_MODEM_CONNECTION,
@@ -1811,8 +1825,13 @@
 static void
 mm_base_sim_init (MMBaseSim *self)
 {
+    static guint id = 0;
+
     /* Initialize private data */
     self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, MM_TYPE_BASE_SIM, MMBaseSimPrivate);
+
+    /* Each SIM is given a unique id to build its own DBus path */
+    self->priv->dbus_id = id++;
 }
 
 static void
@@ -1850,6 +1869,12 @@
 }
 
 static void
+log_object_iface_init (MMLogObjectInterface *iface)
+{
+    iface->build_id = log_object_build_id;
+}
+
+static void
 mm_base_sim_class_init (MMBaseSimClass *klass)
 {
     GObjectClass *object_class = G_OBJECT_CLASS (klass);
diff --git a/src/mm-base-sms.c b/src/mm-base-sms.c
index 4d306e7..ad6bba2 100644
--- a/src/mm-base-sms.c
+++ b/src/mm-base-sms.c
@@ -1,4 +1,3 @@
-
 /* -*- 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
@@ -34,10 +33,13 @@
 #include "mm-sms-part-3gpp.h"
 #include "mm-base-modem-at.h"
 #include "mm-base-modem.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-modem-helpers.h"
 
-G_DEFINE_TYPE (MMBaseSms, mm_base_sms, MM_GDBUS_TYPE_SMS_SKELETON)
+static void log_object_iface_init (MMLogObjectInterface *iface);
+
+G_DEFINE_TYPE_EXTENDED (MMBaseSms, mm_base_sms, MM_GDBUS_TYPE_SMS_SKELETON, 0,
+                        G_IMPLEMENT_INTERFACE (MM_TYPE_LOG_OBJECT, log_object_iface_init))
 
 enum {
     PROP_0,
@@ -55,6 +57,8 @@
 struct _MMBaseSmsPrivate {
     /* The connection to the system bus */
     GDBusConnection *connection;
+    guint            dbus_id;
+
     /* The modem which owns this SMS */
     MMBaseModem *modem;
     /* The path where the SMS object is exported */
@@ -125,7 +129,7 @@
     g_assert (!(text != NULL && data != NULL));
 
     if (text) {
-        split_text = mm_sms_part_3gpp_util_split_text (text, &encoding);
+        split_text = mm_sms_part_3gpp_util_split_text (text, &encoding, self);
         if (!split_text) {
             g_set_error (error,
                          MM_CORE_ERROR,
@@ -174,14 +178,14 @@
             if (!split_text[i])
                 break;
             part_text = split_text[i];
-            mm_dbg ("  Processing chunk '%u' of text with '%u' bytes",
-                    i, (guint) strlen (part_text));
+            mm_obj_dbg (self, "  processing chunk '%u' of text with '%u' bytes",
+                        i, (guint) strlen (part_text));
         } else if (split_data) {
             if (!split_data[i])
                 break;
             part_data = split_data[i];
-            mm_dbg ("  Processing chunk '%u' of data with '%u' bytes",
-                    i, part_data->len);
+            mm_obj_dbg (self, "  processing chunk '%u' of data with '%u' bytes",
+                        i, part_data->len);
 
         } else
             g_assert_not_reached ();
@@ -201,11 +205,9 @@
             mm_sms_part_set_concat_reference (part, 0); /* We don't set a concat reference here */
             mm_sms_part_set_concat_sequence (part, i + 1);
             mm_sms_part_set_concat_max (part, n_parts);
-
-            mm_dbg ("Created SMS part '%u' for multipart SMS ('%u' parts expected)",
-                    i + 1, n_parts);
+            mm_obj_dbg (self, "created SMS part '%u' for multipart SMS ('%u' parts expected)", i + 1, n_parts);
         } else {
-            mm_dbg ("Created SMS part for singlepart SMS");
+            mm_obj_dbg (self, "created SMS part for singlepart SMS");
         }
 
         /* Add to the list of parts */
@@ -271,14 +273,14 @@
 
     /* If creating a CDMA SMS part but we don't have a Teleservice ID, we default to WMT */
     if (mm_gdbus_sms_get_teleservice_id (MM_GDBUS_SMS (self)) == MM_SMS_CDMA_TELESERVICE_ID_UNKNOWN) {
-        mm_dbg ("Defaulting to WMT teleservice ID when creating SMS part");
+        mm_obj_dbg (self, "defaulting to WMT teleservice ID when creating SMS part");
         mm_sms_part_set_cdma_teleservice_id (part, MM_SMS_CDMA_TELESERVICE_ID_WMT);
     } else
         mm_sms_part_set_cdma_teleservice_id (part, mm_gdbus_sms_get_teleservice_id (MM_GDBUS_SMS (self)));
 
     mm_sms_part_set_cdma_service_category (part, mm_gdbus_sms_get_service_category (MM_GDBUS_SMS (self)));
 
-    mm_dbg ("Created SMS part for CDMA SMS");
+    mm_obj_dbg (self, "created SMS part for CDMA SMS");
 
     /* Add to the list of parts */
     self->priv->parts = g_list_append (self->priv->parts, part);
@@ -651,10 +653,9 @@
 void
 mm_base_sms_export (MMBaseSms *self)
 {
-    static guint id = 0;
     gchar *path;
 
-    path = g_strdup_printf (MM_DBUS_SMS_PREFIX "/%d", id++);
+    path = g_strdup_printf (MM_DBUS_SMS_PREFIX "/%d", self->priv->dbus_id);
     g_object_set (self,
                   MM_BASE_SMS_PATH, path,
                   NULL);
@@ -690,9 +691,7 @@
                                            self->priv->connection,
                                            self->priv->path,
                                            &error)) {
-        mm_warn ("couldn't export SMS at '%s': '%s'",
-                 self->priv->path,
-                 error->message);
+        mm_obj_warn (self, "couldn't export SMS: %s", error->message);
         g_error_free (error);
     }
 }
@@ -772,12 +771,13 @@
 /*****************************************************************************/
 
 static gboolean
-sms_get_store_or_send_command (MMSmsPart *part,
-                               gboolean text_or_pdu,   /* TRUE for PDU */
-                               gboolean store_or_send, /* TRUE for send */
-                               gchar **out_cmd,
-                               gchar **out_msg_data,
-                               GError **error)
+sms_get_store_or_send_command (MMBaseSms  *self,
+                               MMSmsPart  *part,
+                               gboolean    text_or_pdu,   /* TRUE for PDU */
+                               gboolean    store_or_send, /* TRUE for send */
+                               gchar     **out_cmd,
+                               gchar     **out_msg_data,
+                               GError    **error)
 {
     g_assert (out_cmd != NULL);
     g_assert (out_msg_data != NULL);
@@ -796,7 +796,7 @@
 
         /* AT+CMGW=<length>[, <stat>]<CR> PDU can be entered. <CTRL-Z>/<ESC> */
 
-        pdu = mm_sms_part_3gpp_get_submit_pdu (part, &pdulen, &msgstart, error);
+        pdu = mm_sms_part_3gpp_get_submit_pdu (part, &pdulen, &msgstart, self, error);
         if (!pdu)
             /* 'error' should already be set */
             return FALSE;
@@ -930,10 +930,12 @@
 static void
 sms_store_next_part (GTask *task)
 {
+    MMBaseSms *self;
     SmsStoreContext *ctx;
     gchar *cmd;
     GError *error = NULL;
 
+    self = g_task_get_source_object (task);
     ctx = g_task_get_task_data (task);
 
     if (!ctx->current) {
@@ -945,7 +947,8 @@
 
     g_clear_pointer (&ctx->msg_data, g_free);
 
-    if (!sms_get_store_or_send_command ((MMSmsPart *)ctx->current->data,
+    if (!sms_get_store_or_send_command (self,
+                                        (MMSmsPart *)ctx->current->data,
                                         ctx->use_pdu_mode,
                                         FALSE,
                                         &cmd,
@@ -1153,12 +1156,14 @@
                          GAsyncResult *res,
                          GTask *task)
 {
+    MMBaseSms *self;
     SmsSendContext *ctx;
     GError *error = NULL;
     const gchar *response;
     gint message_reference;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     response = mm_base_modem_at_command_finish (modem, res, &error);
     if (error) {
@@ -1168,8 +1173,7 @@
             return;
         }
 
-        mm_dbg ("Couldn't send SMS from storage: '%s'; trying generic send...",
-                error->message);
+        mm_obj_dbg (self, "couldn't send SMS from storage: %s; trying generic send...", error->message);
         g_error_free (error);
 
         ctx->from_storage = FALSE;
@@ -1194,10 +1198,12 @@
 static void
 sms_send_next_part (GTask *task)
 {
+    MMBaseSms *self;
     SmsSendContext *ctx;
     GError *error = NULL;
     gchar *cmd;
 
+    self = g_task_get_source_object (task);
     ctx = g_task_get_task_data (task);
 
     if (!ctx->current) {
@@ -1225,7 +1231,8 @@
 
     g_clear_pointer (&ctx->msg_data, g_free);
 
-    if (!sms_get_store_or_send_command ((MMSmsPart *)ctx->current->data,
+    if (!sms_get_store_or_send_command (self,
+                                        (MMSmsPart *)ctx->current->data,
                                         ctx->use_pdu_mode,
                                         TRUE,
                                         &cmd,
@@ -1345,17 +1352,19 @@
                    GAsyncResult *res,
                    GTask *task)
 {
+    MMBaseSms *self;
     SmsDeletePartsContext *ctx;
     GError *error = NULL;
 
+    self = g_task_get_source_object (task);
     ctx = g_task_get_task_data (task);
 
     mm_base_modem_at_command_finish (modem, res, &error);
     if (error) {
         ctx->n_failed++;
-        mm_dbg ("Couldn't delete SMS part with index %u: '%s'",
-                mm_sms_part_get_index ((MMSmsPart *)ctx->current->data),
-                error->message);
+        mm_obj_dbg (self, "couldn't delete SMS part with index %u: %s",
+                    mm_sms_part_get_index ((MMSmsPart *)ctx->current->data),
+                    error->message);
         g_error_free (error);
     }
 
@@ -1447,7 +1456,7 @@
     g_task_set_task_data (task, ctx, (GDestroyNotify)sms_delete_parts_context_free);
 
     if (mm_base_sms_get_storage (self) == MM_SMS_STORAGE_UNKNOWN) {
-        mm_dbg ("Not removing parts from non-stored SMS");
+        mm_obj_dbg (self, "not removing parts from non-stored SMS");
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
         return;
@@ -1569,12 +1578,12 @@
             idx = mm_sms_part_get_concat_sequence ((MMSmsPart *)l->data);
 
             if (idx < 1 || idx > self->priv->max_parts) {
-                mm_warn ("Invalid part index (%u) found, ignoring", idx);
+                mm_obj_warn (self, "invalid part index (%u) found, ignoring", idx);
                 continue;
             }
 
             if (sorted_parts[idx - 1]) {
-                mm_warn ("Duplicate part index (%u) found, ignoring", idx);
+                mm_obj_warn (self, "duplicate part index (%u) found, ignoring", idx);
                 continue;
             }
 
@@ -1723,8 +1732,7 @@
         if (!assemble_sms (self, &inner_error)) {
             /* We DO NOT propagate the error. The part was properly taken
              * so ownership passed to the MMBaseSms object. */
-            mm_warn ("Couldn't assemble SMS: '%s'",
-                     inner_error->message);
+            mm_obj_warn (self, "couldn't assemble SMS: %s", inner_error->message);
             g_error_free (inner_error);
         } else {
             /* Completed AND assembled
@@ -1898,6 +1906,17 @@
 
 /*****************************************************************************/
 
+static gchar *
+log_object_build_id (MMLogObject *_self)
+{
+    MMBaseSms *self;
+
+    self = MM_BASE_SMS (_self);
+    return g_strdup_printf ("sms%u", self->priv->dbus_id);
+}
+
+/*****************************************************************************/
+
 static void
 set_property (GObject *object,
               guint prop_id,
@@ -1931,6 +1950,8 @@
         g_clear_object (&self->priv->modem);
         self->priv->modem = g_value_dup_object (value);
         if (self->priv->modem) {
+            /* Set owner ID */
+            mm_log_object_set_owner_id (MM_LOG_OBJECT (self), mm_log_object_get_id (MM_LOG_OBJECT (self->priv->modem)));
             /* Bind the modem's connection (which is set when it is exported,
              * and unset when unexported) to the SMS's connection */
             g_object_bind_property (self->priv->modem, MM_BASE_MODEM_CONNECTION,
@@ -1989,10 +2010,15 @@
 static void
 mm_base_sms_init (MMBaseSms *self)
 {
+    static guint id = 0;
+
     /* Initialize private data */
     self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, MM_TYPE_BASE_SMS, MMBaseSmsPrivate);
     /* Defaults */
     self->priv->max_parts = 1;
+
+    /* Each SMS is given a unique id to build its own DBus path */
+    self->priv->dbus_id = id++;
 }
 
 static void
@@ -2024,6 +2050,12 @@
 }
 
 static void
+log_object_iface_init (MMLogObjectInterface *iface)
+{
+    iface->build_id = log_object_build_id;
+}
+
+static void
 mm_base_sms_class_init (MMBaseSmsClass *klass)
 {
     GObjectClass *object_class = G_OBJECT_CLASS (klass);
diff --git a/src/mm-bearer-list.c b/src/mm-bearer-list.c
index 4ae446b..504b99a 100644
--- a/src/mm-bearer-list.c
+++ b/src/mm-bearer-list.c
@@ -268,10 +268,6 @@
 mm_bearer_list_new (guint max_bearers,
                     guint max_active_bearers)
 {
-    mm_dbg ("Creating bearer list (max: %u, max active: %u)",
-            max_bearers,
-            max_active_bearers);
-
     /* Create the object */
     return g_object_new  (MM_TYPE_BEARER_LIST,
                           MM_BEARER_LIST_MAX_BEARERS, max_bearers,
diff --git a/src/mm-bearer-mbim.c b/src/mm-bearer-mbim.c
index 392ddde..57f10cb 100644
--- a/src/mm-bearer-mbim.c
+++ b/src/mm-bearer-mbim.c
@@ -30,7 +30,7 @@
 #include "mm-modem-helpers-mbim.h"
 #include "mm-port-enums-types.h"
 #include "mm-bearer-mbim.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 G_DEFINE_TYPE (MMBearerMbim, mm_bearer_mbim, MM_TYPE_BASE_BEARER)
 
@@ -253,6 +253,7 @@
                               GAsyncResult *res,
                               GTask *task)
 {
+    MMBearerMbim *self;
     ConnectContext *ctx;
     GError *error = NULL;
     MbimMessage *response;
@@ -271,7 +272,8 @@
     guint32 ipv4mtu;
     guint32 ipv6mtu;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     response = mbim_device_command_finish (device, res, &error);
     if (response &&
@@ -302,17 +304,17 @@
         /* IPv4 info */
 
         str = mbim_ip_configuration_available_flag_build_string_from_mask (ipv4configurationavailable);
-        mm_dbg ("IPv4 configuration available: '%s'", str);
+        mm_obj_dbg (self, "IPv4 configuration available: '%s'", str);
         g_free (str);
 
         if ((ipv4configurationavailable & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_ADDRESS) && ipv4addresscount) {
             guint i;
 
-            mm_dbg ("  IP addresses (%u)", ipv4addresscount);
+            mm_obj_dbg (self, "  IP addresses (%u)", ipv4addresscount);
             for (i = 0; i < ipv4addresscount; i++) {
                 addr = g_inet_address_new_from_bytes ((guint8 *)&ipv4address[i]->ipv4_address, G_SOCKET_FAMILY_IPV4);
                 str = g_inet_address_to_string (addr);
-                mm_dbg ("    IP [%u]: '%s/%u'", i, str, ipv4address[i]->on_link_prefix_length);
+                mm_obj_dbg (self, "    IP [%u]: '%s/%u'", i, str, ipv4address[i]->on_link_prefix_length);
                 g_free (str);
                 g_object_unref (addr);
             }
@@ -321,7 +323,7 @@
         if ((ipv4configurationavailable & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_GATEWAY) && ipv4gateway) {
             addr = g_inet_address_new_from_bytes ((guint8 *)ipv4gateway, G_SOCKET_FAMILY_IPV4);
             str = g_inet_address_to_string (addr);
-            mm_dbg ("  Gateway: '%s'", str);
+            mm_obj_dbg (self, "  gateway: '%s'", str);
             g_free (str);
             g_object_unref (addr);
         }
@@ -329,12 +331,12 @@
         if ((ipv4configurationavailable & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_DNS) && ipv4dnsservercount) {
             guint i;
 
-            mm_dbg ("  DNS addresses (%u)", ipv4dnsservercount);
+            mm_obj_dbg (self, "  DNS addresses (%u)", ipv4dnsservercount);
             for (i = 0; i < ipv4dnsservercount; i++) {
                 addr = g_inet_address_new_from_bytes ((guint8 *)&ipv4dnsserver[i], G_SOCKET_FAMILY_IPV4);
                 if (!g_inet_address_get_is_any (addr)) {
                     str = g_inet_address_to_string (addr);
-                    mm_dbg ("    DNS [%u]: '%s'", i, str);
+                    mm_obj_dbg (self, "    DNS [%u]: '%s'", i, str);
                     g_free (str);
                 }
                 g_object_unref (addr);
@@ -342,23 +344,23 @@
         }
 
         if ((ipv4configurationavailable & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_MTU) && ipv4mtu) {
-            mm_dbg ("  MTU: '%u'", ipv4mtu);
+            mm_obj_dbg (self, "  MTU: '%u'", ipv4mtu);
         }
 
         /* IPv6 info */
 
         str = mbim_ip_configuration_available_flag_build_string_from_mask (ipv6configurationavailable);
-        mm_dbg ("IPv6 configuration available: '%s'", str);
+        mm_obj_dbg (self, "IPv6 configuration available: '%s'", str);
         g_free (str);
 
         if ((ipv6configurationavailable & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_ADDRESS) && ipv6addresscount) {
             guint i;
 
-            mm_dbg ("  IP addresses (%u)", ipv6addresscount);
+            mm_obj_dbg (self, "  IP addresses (%u)", ipv6addresscount);
             for (i = 0; i < ipv6addresscount; i++) {
                 addr = g_inet_address_new_from_bytes ((guint8 *)&ipv6address[i]->ipv6_address, G_SOCKET_FAMILY_IPV6);
                 str = g_inet_address_to_string (addr);
-                mm_dbg ("    IP [%u]: '%s/%u'", i, str, ipv6address[i]->on_link_prefix_length);
+                mm_obj_dbg (self, "    IP [%u]: '%s/%u'", i, str, ipv6address[i]->on_link_prefix_length);
                 g_free (str);
                 g_object_unref (addr);
             }
@@ -367,7 +369,7 @@
         if ((ipv6configurationavailable & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_GATEWAY) && ipv6gateway) {
             addr = g_inet_address_new_from_bytes ((guint8 *)ipv6gateway, G_SOCKET_FAMILY_IPV6);
             str = g_inet_address_to_string (addr);
-            mm_dbg ("  Gateway: '%s'", str);
+            mm_obj_dbg (self, "  gateway: '%s'", str);
             g_free (str);
             g_object_unref (addr);
         }
@@ -375,12 +377,12 @@
         if ((ipv6configurationavailable & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_DNS) && ipv6dnsservercount) {
             guint i;
 
-            mm_dbg ("  DNS addresses (%u)", ipv6dnsservercount);
+            mm_obj_dbg (self, "  DNS addresses (%u)", ipv6dnsservercount);
             for (i = 0; i < ipv6dnsservercount; i++) {
                 addr = g_inet_address_new_from_bytes ((guint8 *)&ipv6dnsserver[i], G_SOCKET_FAMILY_IPV6);
                 if (!g_inet_address_get_is_any (addr)) {
                     str = g_inet_address_to_string (addr);
-                    mm_dbg ("    DNS [%u]: '%s'", i, str);
+                    mm_obj_dbg (self, "    DNS [%u]: '%s'", i, str);
                     g_free (str);
                 }
                 g_object_unref (addr);
@@ -388,7 +390,7 @@
         }
 
         if ((ipv6configurationavailable & MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_MTU) && ipv6mtu) {
-            mm_dbg ("  MTU: '%u'", ipv6mtu);
+            mm_obj_dbg (self, "  MTU: '%u'", ipv6mtu);
         }
 
         /* Build connection results */
@@ -563,6 +565,7 @@
                    GAsyncResult *res,
                    GTask *task)
 {
+    MMBearerMbim *self;
     ConnectContext *ctx;
     GError *error = NULL;
     MbimMessage *response;
@@ -570,7 +573,8 @@
     MbimActivationState activation_state;
     guint32 nw_error;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     response = mbim_device_command_finish (device, res, &error);
     if (response &&
@@ -597,10 +601,10 @@
                  * MBIM_CONTEXT_IP_TYPE_DEFAULT, which MM never does.  Some
                  * devices (K5160) report the wrong type in the response.
                  */
-                mm_dbg ("Session ID '%u': %s (IP type: %s)",
-                        session_id,
-                        mbim_activation_state_get_string (activation_state),
-                        mbim_context_ip_type_get_string (ctx->ip_type));
+                mm_obj_dbg (self, "session ID '%u': %s (IP type: %s)",
+                            session_id,
+                            mbim_activation_state_get_string (activation_state),
+                            mbim_context_ip_type_get_string (ctx->ip_type));
             }
         } else {
             /* Prefer the error from the result to the parsing error */
@@ -650,13 +654,15 @@
                           GAsyncResult *res,
                           GTask        *task)
 {
+    MMBearerMbim *self;
     ConnectContext *ctx;
     GError *error = NULL;
     MbimMessage *response;
     guint32 session_id;
     MbimActivationState activation_state;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     response = mbim_device_command_finish (device, res, &error);
     if (response &&
@@ -670,7 +676,7 @@
             NULL, /* context_type */
             NULL, /* nw_error */
             &error)) {
-        mm_dbg ("Session ID '%u': %s", session_id, mbim_activation_state_get_string (activation_state));
+        mm_obj_dbg (self, "session ID '%u': %s", session_id, mbim_activation_state_get_string (activation_state));
     } else
         activation_state = MBIM_ACTIVATION_STATE_UNKNOWN;
 
@@ -697,13 +703,15 @@
                                   GAsyncResult *res,
                                   GTask *task)
 {
+    MMBearerMbim *self;
     ConnectContext *ctx;
     GError *error = NULL;
     MbimMessage *response;
     guint32 provisioned_contexts_count;
     MbimProvisionedContextElement **provisioned_contexts;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     response = mbim_device_command_finish (device, res, &error);
     if (response &&
@@ -715,25 +723,25 @@
             &error)) {
         guint32 i;
 
-        mm_dbg ("Provisioned contexts found (%u):", provisioned_contexts_count);
+        mm_obj_dbg (self, "provisioned contexts found (%u):", provisioned_contexts_count);
         for (i = 0; i < provisioned_contexts_count; i++) {
             MbimProvisionedContextElement *el = provisioned_contexts[i];
             gchar *uuid_str;
 
             uuid_str = mbim_uuid_get_printable (&el->context_type);
-            mm_dbg ("[%u] context type: %s", el->context_id, mbim_context_type_get_string (mbim_uuid_to_context_type (&el->context_type)));
-            mm_dbg ("             uuid: %s", uuid_str);
-            mm_dbg ("    access string: %s", el->access_string ? el->access_string : "");
-            mm_dbg ("         username: %s", el->user_name ? el->user_name : "");
-            mm_dbg ("         password: %s", el->password ? el->password : "");
-            mm_dbg ("      compression: %s", mbim_compression_get_string (el->compression));
-            mm_dbg ("             auth: %s", mbim_auth_protocol_get_string (el->auth_protocol));
+            mm_obj_dbg (self, "[%u] context type: %s", el->context_id, mbim_context_type_get_string (mbim_uuid_to_context_type (&el->context_type)));
+            mm_obj_dbg (self, "             uuid: %s", uuid_str);
+            mm_obj_dbg (self, "    access string: %s", el->access_string ? el->access_string : "");
+            mm_obj_dbg (self, "         username: %s", el->user_name ? el->user_name : "");
+            mm_obj_dbg (self, "         password: %s", el->password ? el->password : "");
+            mm_obj_dbg (self, "      compression: %s", mbim_compression_get_string (el->compression));
+            mm_obj_dbg (self, "             auth: %s", mbim_auth_protocol_get_string (el->auth_protocol));
             g_free (uuid_str);
         }
 
         mbim_provisioned_context_element_array_free (provisioned_contexts);
     } else {
-        mm_dbg ("Error listing provisioned contexts: %s", error->message);
+        mm_obj_dbg (self, "error listing provisioned contexts: %s", error->message);
         g_error_free (error);
     }
 
@@ -750,6 +758,7 @@
                           GAsyncResult *res,
                           GTask *task)
 {
+    MMBearerMbim *self;
     ConnectContext *ctx;
     GError *error = NULL;
     MbimMessage *response;
@@ -759,6 +768,7 @@
     guint64 uplink_speed;
     guint64 downlink_speed;
 
+    self = g_task_get_source_object (task);
     ctx = g_task_get_task_data (task);
 
     response = mbim_device_command_finish (device, res, &error);
@@ -783,11 +793,11 @@
                 gchar *str;
 
                 str = mbim_data_class_build_string_from_mask (highest_available_data_class);
-                mm_dbg ("Packet service update:");
-                mm_dbg ("         state: '%s'", mbim_packet_service_state_get_string (packet_service_state));
-                mm_dbg ("    data class: '%s'", str);
-                mm_dbg ("        uplink: '%" G_GUINT64_FORMAT "' bps", uplink_speed);
-                mm_dbg ("      downlink: '%" G_GUINT64_FORMAT "' bps", downlink_speed);
+                mm_obj_dbg (self, "packet service update:");
+                mm_obj_dbg (self, "         state: '%s'", mbim_packet_service_state_get_string (packet_service_state));
+                mm_obj_dbg (self, "    data class: '%s'", str);
+                mm_obj_dbg (self, "        uplink: '%" G_GUINT64_FORMAT "' bps", uplink_speed);
+                mm_obj_dbg (self, "      downlink: '%" G_GUINT64_FORMAT "' bps", downlink_speed);
                 g_free (str);
             }
         } else {
@@ -806,7 +816,7 @@
         /* Don't make NoDeviceSupport errors fatal; just try to keep on the
          * connection sequence even with this error. */
         if (g_error_matches (error, MBIM_STATUS_ERROR, MBIM_STATUS_ERROR_NO_DEVICE_SUPPORT)) {
-            mm_dbg ("Device doesn't support packet service attach");
+            mm_obj_dbg (self, "device doesn't support packet service attach");
             g_error_free (error);
         } else {
             /* All other errors are fatal */
@@ -845,7 +855,7 @@
     case CONNECT_STEP_PACKET_SERVICE: {
         GError *error = NULL;
 
-        mm_dbg ("Activating packet service...");
+        mm_obj_dbg (self, "activating packet service...");
         message = (mbim_message_packet_service_set_new (
                        MBIM_PACKET_SERVICE_ACTION_ATTACH,
                        &error));
@@ -866,7 +876,7 @@
     }
 
     case CONNECT_STEP_PROVISIONED_CONTEXTS:
-        mm_dbg ("Listing provisioned contexts...");
+        mm_obj_dbg (self, "listing provisioned contexts...");
         message = mbim_message_provisioned_contexts_query_new (NULL);
         mbim_device_command (ctx->device,
                              message,
@@ -954,7 +964,7 @@
             MMBearerAllowedAuth bearer_auth;
 
             bearer_auth = mm_bearer_properties_get_allowed_auth (ctx->properties);
-            auth = mm_bearer_allowed_auth_to_mbim_auth_protocol (bearer_auth, &error);
+            auth = mm_bearer_allowed_auth_to_mbim_auth_protocol (bearer_auth, self, &error);
             if (error) {
                 g_task_return_error (task, error);
                 g_object_unref (task);
@@ -969,7 +979,7 @@
 
             ip_family = mm_base_bearer_get_default_ip_family (MM_BASE_BEARER (self));
             str = mm_bearer_ip_family_build_string_from_mask (ip_family);
-            mm_dbg ("No specific IP family requested, defaulting to %s", str);
+            mm_obj_dbg (self, "no specific IP family requested, defaulting to %s", str);
             g_free (str);
         }
 
@@ -980,7 +990,7 @@
             return;
         }
 
-        mm_dbg ("Launching %s connection with APN '%s'...", mbim_context_ip_type_get_string (ctx->ip_type), apn);
+        mm_obj_dbg (self, "launching %s connection with APN '%s'...", mbim_context_ip_type_get_string (ctx->ip_type), apn);
         message = (mbim_message_connect_set_new (
                        self->priv->session_id,
                        MBIM_ACTIVATION_COMMAND_ACTIVATE,
@@ -1011,7 +1021,7 @@
     case CONNECT_STEP_IP_CONFIGURATION: {
         GError *error = NULL;
 
-        mm_dbg ("Querying IP configuration...");
+        mm_obj_dbg (self, "querying IP configuration...");
         message = (mbim_message_ip_configuration_query_new (
                        self->priv->session_id,
                        MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_NONE, /* ipv4configurationavailable */
@@ -1108,7 +1118,7 @@
 
     g_object_unref (modem);
 
-    mm_dbg ("Launching connection with data port (%s/%s)",
+    mm_obj_dbg (self, "launching connection with data port (%s/%s)",
             mm_port_subsys_get_string (mm_port_get_subsys (data)),
             mm_port_get_device (data));
 
@@ -1174,6 +1184,7 @@
                       GAsyncResult *res,
                       GTask *task)
 {
+    MMBearerMbim *self;
     DisconnectContext *ctx;
     GError *error = NULL;
     MbimMessage *response;
@@ -1183,7 +1194,8 @@
     GError *inner_error = NULL;
     gboolean result = FALSE, parsed_result = FALSE;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     response = mbim_device_command_finish (device, res, &error);
     if (!response)
@@ -1211,16 +1223,16 @@
     if (result && parsed_result) {
         g_assert (!error);
         g_assert (!inner_error);
-        mm_dbg ("Session ID '%u': %s", session_id, mbim_activation_state_get_string (activation_state));
+        mm_obj_dbg (self, "session ID '%u': %s", session_id, mbim_activation_state_get_string (activation_state));
         /* success */
         goto out;
     }
 
     if (g_error_matches (error, MBIM_STATUS_ERROR, MBIM_STATUS_ERROR_CONTEXT_NOT_ACTIVATED)) {
         if (parsed_result)
-            mm_dbg ("Context not activated: session ID '%u' already disconnected", session_id);
+            mm_obj_dbg (self, "context not activated: session ID '%u' already disconnected", session_id);
         else
-            mm_dbg ("Context not activated: already disconnected");
+            mm_obj_dbg (self, "context not activated: already disconnected");
 
         g_clear_error (&error);
         g_clear_error (&inner_error);
@@ -1331,15 +1343,15 @@
     task = g_task_new (self, NULL, callback, user_data);
 
     if (!self->priv->data) {
-        mm_dbg ("No need to disconnect: MBIM bearer is already disconnected");
+        mm_obj_dbg (self, "no need to disconnect: MBIM bearer is already disconnected");
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
         return;
     }
 
-    mm_dbg ("Launching disconnection on data port (%s/%s)",
-            mm_port_subsys_get_string (mm_port_get_subsys (self->priv->data)),
-            mm_port_get_device (self->priv->data));
+    mm_obj_dbg (self, "launching disconnection on data port (%s/%s)",
+                mm_port_subsys_get_string (mm_port_get_subsys (self->priv->data)),
+                mm_port_get_device (self->priv->data));
 
     ctx = g_slice_new0 (DisconnectContext);
     ctx->device = g_object_ref (device);
diff --git a/src/mm-bearer-qmi.c b/src/mm-bearer-qmi.c
index ece9227..4ec93d7 100644
--- a/src/mm-bearer-qmi.c
+++ b/src/mm-bearer-qmi.c
@@ -31,7 +31,7 @@
 #include "mm-bearer-qmi.h"
 #include "mm-modem-helpers-qmi.h"
 #include "mm-port-enums-types.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-modem-helpers.h"
 
 G_DEFINE_TYPE (MMBearerQmi, mm_bearer_qmi, MM_TYPE_BASE_BEARER)
@@ -537,11 +537,14 @@
                      GAsyncResult *res,
                      GTask *task)
 {
+    MMBearerQmi *self;
     ConnectContext *ctx;
     GError *error = NULL;
     QmiMessageWdsStartNetworkOutput *output;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_task_data (task);
+    ctx  = g_task_get_task_data (task);
+
     g_assert (ctx->running_ipv4 || ctx->running_ipv6);
     g_assert (!(ctx->running_ipv4 && ctx->running_ipv6));
 
@@ -565,7 +568,7 @@
 
             /* Fall down to a successful connection */
         } else {
-            mm_info ("error: couldn't start network: %s", error->message);
+            mm_obj_info (self, "couldn't start network: %s", error->message);
             if (g_error_matches (error,
                                  QMI_PROTOCOL_ERROR,
                                  QMI_PROTOCOL_ERROR_CALL_FAILED)) {
@@ -577,20 +580,18 @@
                         output,
                         &cer,
                         NULL))
-                    mm_info ("call end reason (%u): '%s'",
-                             cer,
-                             qmi_wds_call_end_reason_get_string (cer));
+                    mm_obj_info (self, "call end reason (%u): %s", cer, qmi_wds_call_end_reason_get_string (cer));
 
                 if (qmi_message_wds_start_network_output_get_verbose_call_end_reason (
                         output,
                         &verbose_cer_type,
                         &verbose_cer_reason,
                         NULL))
-                    mm_info ("verbose call end reason (%u,%d): [%s] %s",
-                             verbose_cer_type,
-                             verbose_cer_reason,
-                             qmi_wds_verbose_call_end_reason_type_get_string (verbose_cer_type),
-                             qmi_wds_verbose_call_end_reason_get_string (verbose_cer_type, verbose_cer_reason));
+                    mm_obj_info (self, "verbose call end reason (%u,%d): [%s] %s",
+                                 verbose_cer_type,
+                                 verbose_cer_reason,
+                                 qmi_wds_verbose_call_end_reason_type_get_string (verbose_cer_type),
+                                 qmi_wds_verbose_call_end_reason_get_string (verbose_cer_type, verbose_cer_reason));
             }
         }
     }
@@ -693,7 +694,7 @@
 
     /* IPv4 subnet mask */
     if (!qmi_message_wds_get_current_settings_output_get_ipv4_gateway_subnet_mask (output, &addr, &error)) {
-        mm_warn ("Failed to read IPv4 netmask (%s)", error->message);
+        mm_obj_warn (self, "failed to read IPv4 netmask: %s", error->message);
         g_clear_error (&error);
         return NULL;
     }
@@ -702,12 +703,12 @@
 
     /* IPv4 address */
     if (!qmi_message_wds_get_current_settings_output_get_ipv4_address (output, &addr, &error)) {
-        mm_warn ("IPv4 family but no IPv4 address (%s)", error->message);
+        mm_obj_warn (self, "IPv4 family but no IPv4 address: %s", error->message);
         g_clear_error (&error);
         return NULL;
     }
 
-    mm_info ("QMI IPv4 Settings:");
+    mm_obj_info (self, "QMI IPv4 Settings:");
 
     config = mm_bearer_ip_config_new ();
     mm_bearer_ip_config_set_method (config, ip_method);
@@ -716,15 +717,15 @@
     qmi_inet4_ntop (addr, buf, sizeof (buf));
     mm_bearer_ip_config_set_address (config, buf);
     mm_bearer_ip_config_set_prefix (config, prefix);
-    mm_info ("    Address: %s/%d", buf, prefix);
+    mm_obj_info (self, "    address: %s/%d", buf, prefix);
 
     /* IPv4 gateway address */
     if (qmi_message_wds_get_current_settings_output_get_ipv4_gateway_address (output, &addr, &error)) {
         qmi_inet4_ntop (addr, buf, sizeof (buf));
         mm_bearer_ip_config_set_gateway (config, buf);
-        mm_info ("    Gateway: %s", buf);
+        mm_obj_info (self, "    gateway: %s", buf);
     } else {
-        mm_info ("    Gateway: failed (%s)", error->message);
+        mm_obj_info (self, "    gateway: failed (%s)", error->message);
         g_clear_error (&error);
     }
 
@@ -732,9 +733,9 @@
     if (qmi_message_wds_get_current_settings_output_get_primary_ipv4_dns_address (output, &addr, &error)) {
         qmi_inet4_ntop (addr, buf, sizeof (buf));
         dns[dns_idx++] = buf;
-        mm_info ("    DNS #1: %s", buf);
+        mm_obj_info (self, "    DNS #1: %s", buf);
     } else {
-        mm_info ("    DNS #1: failed (%s)", error->message);
+        mm_obj_info (self, "    DNS #1: failed (%s)", error->message);
         g_clear_error (&error);
     }
 
@@ -742,9 +743,9 @@
     if (qmi_message_wds_get_current_settings_output_get_secondary_ipv4_dns_address (output, &addr, &error)) {
         qmi_inet4_ntop (addr, buf2, sizeof (buf2));
         dns[dns_idx++] = buf2;
-        mm_info ("    DNS #2: %s", buf2);
+        mm_obj_info (self, "    DNS #2: %s", buf2);
     } else {
-        mm_info ("    DNS #2: failed (%s)", error->message);
+        mm_obj_info (self, "    DNS #2: failed (%s)", error->message);
         g_clear_error (&error);
     }
 
@@ -753,7 +754,7 @@
 
     if (mtu) {
         mm_bearer_ip_config_set_mtu (config, mtu);
-        mm_info ("       MTU: %d", mtu);
+        mm_obj_info (self, "       MTU: %d", mtu);
     }
 
     return config;
@@ -795,12 +796,12 @@
 
     /* If the message has an IPv6 address, create an IPv6 bearer config */
     if (!qmi_message_wds_get_current_settings_output_get_ipv6_address (output, &array, &prefix, &error)) {
-        mm_warn ("IPv6 family but no IPv6 address (%s)", error->message);
+        mm_obj_warn (self, "IPv6 family but no IPv6 address: %s", error->message);
         g_clear_error (&error);
         return NULL;
     }
 
-    mm_info ("QMI IPv6 Settings:");
+    mm_obj_info (self, "QMI IPv6 Settings:");
 
     config = mm_bearer_ip_config_new ();
     mm_bearer_ip_config_set_method (config, ip_method);
@@ -810,15 +811,15 @@
 
     mm_bearer_ip_config_set_address (config, buf);
     mm_bearer_ip_config_set_prefix (config, prefix);
-    mm_info ("    Address: %s/%d", buf, prefix);
+    mm_obj_info (self, "    address: %s/%d", buf, prefix);
 
     /* IPv6 gateway address */
     if (qmi_message_wds_get_current_settings_output_get_ipv6_gateway_address (output, &array, &prefix, &error)) {
         qmi_inet6_ntop (array, buf, sizeof (buf));
         mm_bearer_ip_config_set_gateway (config, buf);
-        mm_info ("    Gateway: %s/%d", buf, prefix);
+        mm_obj_info (self, "    gateway: %s/%d", buf, prefix);
     } else {
-        mm_info ("    Gateway: failed (%s)", error->message);
+        mm_obj_info (self, "    gateway: failed (%s)", error->message);
         g_clear_error (&error);
     }
 
@@ -826,9 +827,9 @@
     if (qmi_message_wds_get_current_settings_output_get_ipv6_primary_dns_address (output, &array, &error)) {
         qmi_inet6_ntop (array, buf, sizeof (buf));
         dns[dns_idx++] = buf;
-        mm_info ("    DNS #1: %s", buf);
+        mm_obj_info (self, "    DNS #1: %s", buf);
     } else {
-        mm_info ("    DNS #1: failed (%s)", error->message);
+        mm_obj_info (self, "    DNS #1: failed (%s)", error->message);
         g_clear_error (&error);
     }
 
@@ -836,9 +837,9 @@
     if (qmi_message_wds_get_current_settings_output_get_ipv6_secondary_dns_address (output, &array, &error)) {
         qmi_inet6_ntop (array, buf2, sizeof (buf2));
         dns[dns_idx++] = buf2;
-        mm_info ("    DNS #2: %s", buf2);
+        mm_obj_info (self, "    DNS #2: %s", buf2);
     } else {
-        mm_info ("    DNS #2: failed (%s)", error->message);
+        mm_obj_info (self, "    DNS #2: failed (%s)", error->message);
         g_clear_error (&error);
     }
 
@@ -847,7 +848,7 @@
 
     if (mtu) {
         mm_bearer_ip_config_set_mtu (config, mtu);
-        mm_info ("       MTU: %d", mtu);
+        mm_obj_info (self, "       MTU: %d", mtu);
     }
 
     return config;
@@ -858,11 +859,13 @@
                             GAsyncResult *res,
                             GTask *task)
 {
+    MMBearerQmi *self;
     ConnectContext *ctx;
     GError *error = NULL;
     QmiMessageWdsGetCurrentSettingsOutput *output;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
     g_assert (ctx->running_ipv4 || ctx->running_ipv6);
 
     output = qmi_client_wds_get_current_settings_finish (client, res, &error);
@@ -871,7 +874,7 @@
 
         /* When we're using static IP address, the current settings are mandatory */
         if (ctx->ip_method == MM_BEARER_IP_METHOD_STATIC) {
-            mm_warn ("Failed to retrieve mandatory IP settings: %s", error->message);
+            mm_obj_warn (self, "failed to retrieve mandatory IP settings: %s", error->message);
             if (output)
                 qmi_message_wds_get_current_settings_output_unref (output);
             complete_connect (task, NULL, error);
@@ -879,7 +882,7 @@
         }
 
         /* Otherwise, just go on as we're asking for DHCP */
-        mm_dbg ("Couldn't get current settings: %s", error->message);
+        mm_obj_dbg (self, "couldn't get current settings: %s", error->message);
         g_error_free (error);
 
         config = mm_bearer_ip_config_new ();
@@ -897,16 +900,16 @@
         GArray *array;
 
         if (!qmi_message_wds_get_current_settings_output_get_ip_family (output, &ip_family, &error)) {
-            mm_dbg (" IP Family: failed (%s); assuming IPv4", error->message);
+            mm_obj_dbg (self, " IP Family: failed (%s); assuming IPv4", error->message);
             g_clear_error (&error);
             ip_family = QMI_WDS_IP_FAMILY_IPV4;
         }
-        mm_dbg (" IP Family: %s",
+        mm_obj_dbg (self, " IP Family: %s",
                 (ip_family == QMI_WDS_IP_FAMILY_IPV4) ? "IPv4" :
                    (ip_family == QMI_WDS_IP_FAMILY_IPV6) ? "IPv6" : "unknown");
 
         if (!qmi_message_wds_get_current_settings_output_get_mtu (output, &mtu, &error)) {
-            mm_dbg ("       MTU: failed (%s)", error->message);
+            mm_obj_dbg (self, "       MTU: failed (%s)", error->message);
             g_clear_error (&error);
         }
 
@@ -925,10 +928,10 @@
                     g_string_append (s, ", ");
                 g_string_append (s, g_array_index (array, const char *, i));
             }
-            mm_dbg ("   Domains: %s", s->str);
+            mm_obj_dbg (self, "   domains: %s", s->str);
             g_string_free (s, TRUE);
         } else {
-            mm_dbg ("   Domains: failed (%s)", error ? error->message : "unknown");
+            mm_obj_dbg (self, "   domains: failed (%s)", error ? error->message : "unknown");
             g_clear_error (&error);
         }
     }
@@ -975,11 +978,14 @@
                      GAsyncResult *res,
                      GTask *task)
 {
+    MMBearerQmi *self;
     ConnectContext *ctx;
     GError *error = NULL;
     QmiMessageWdsSetIpFamilyOutput *output;
 
+    self = g_task_get_source_object (task);
     ctx = g_task_get_task_data (task);
+
     g_assert (ctx->running_ipv4 || ctx->running_ipv6);
     g_assert (!(ctx->running_ipv4 && ctx->running_ipv6));
 
@@ -991,7 +997,7 @@
 
     if (error) {
         /* Ensure we add the IP family preference TLV */
-        mm_dbg ("Couldn't set IP family preference: '%s'", error->message);
+        mm_obj_dbg (self, "couldn't set IP family preference: %s", error->message);
         g_error_free (error);
         ctx->default_ip_family_set = FALSE;
     } else {
@@ -1029,20 +1035,18 @@
                     output,
                     &cer,
                     NULL))
-                mm_info ("bearer call end reason (%u): '%s'",
-                         cer,
-                         qmi_wds_call_end_reason_get_string (cer));
+                mm_obj_info (self, "bearer call end reason (%u): '%s'", cer, qmi_wds_call_end_reason_get_string (cer));
 
             if (qmi_indication_wds_packet_service_status_output_get_verbose_call_end_reason (
                     output,
                     &verbose_cer_type,
                     &verbose_cer_reason,
                     NULL))
-                mm_info ("bearer verbose call end reason (%u,%d): [%s] %s",
-                         verbose_cer_type,
-                         verbose_cer_reason,
-                         qmi_wds_verbose_call_end_reason_type_get_string (verbose_cer_type),
-                         qmi_wds_verbose_call_end_reason_get_string (verbose_cer_type, verbose_cer_reason));
+                mm_obj_info (self, "bearer verbose call end reason (%u,%d): [%s] %s",
+                             verbose_cer_type,
+                             verbose_cer_reason,
+                             qmi_wds_verbose_call_end_reason_type_get_string (verbose_cer_type),
+                             qmi_wds_verbose_call_end_reason_get_string (verbose_cer_type, verbose_cer_reason));
 
             mm_base_bearer_report_connection_status (MM_BASE_BEARER (self), MM_BEARER_CONNECTION_STATUS_DISCONNECTED);
         }
@@ -1077,7 +1081,7 @@
                             QmiIndicationWdsEventReportOutput *output,
                             MMBearerQmi *self)
 {
-    mm_dbg ("Got QMI WDS event report");
+    mm_obj_dbg (self, "got QMI WDS event report");
 }
 
 static guint
@@ -1326,7 +1330,7 @@
         else
             ctx->ip_method = MM_BEARER_IP_METHOD_DHCP;
 
-        mm_dbg ("Defaulting to use %s IP method", mm_bearer_ip_method_get_string (ctx->ip_method));
+        mm_obj_dbg (self, "defaulting to use %s IP method", mm_bearer_ip_method_get_string (ctx->ip_method));
         ctx->step++;
         /* fall through */
 
@@ -1339,7 +1343,7 @@
         }
 
         /* Start IPv4 setup */
-        mm_dbg ("Running IPv4 connection setup");
+        mm_obj_dbg (self, "running IPv4 connection setup");
         ctx->running_ipv4 = TRUE;
         ctx->running_ipv6 = FALSE;
         ctx->step++;
@@ -1352,7 +1356,7 @@
                                          QMI_SERVICE_WDS,
                                          MM_PORT_QMI_FLAG_WDS_IPV4);
         if (!client) {
-            mm_dbg ("Allocating IPv4-specific WDS client");
+            mm_obj_dbg (self, "allocating IPv4-specific WDS client");
             mm_port_qmi_allocate_client (ctx->qmi,
                                          QMI_SERVICE_WDS,
                                          MM_PORT_QMI_FLAG_WDS_IPV4,
@@ -1372,7 +1376,7 @@
             qmi_client_check_version (QMI_CLIENT (ctx->client_ipv4), 1, 9)) {
             QmiMessageWdsSetIpFamilyInput *input;
 
-            mm_dbg ("Setting default IP family to: IPv4");
+            mm_obj_dbg (self, "setting default IP family to: IPv4");
             input = qmi_message_wds_set_ip_family_input_new ();
             qmi_message_wds_set_ip_family_input_set_preference (input, QMI_WDS_IP_FAMILY_IPV4, NULL);
             qmi_client_wds_set_ip_family (ctx->client_ipv4,
@@ -1405,7 +1409,7 @@
     case CONNECT_STEP_START_NETWORK_IPV4: {
         QmiMessageWdsStartNetworkInput *input;
 
-        mm_dbg ("Starting IPv4 connection...");
+        mm_obj_dbg (self, "starting IPv4 connection...");
         input = build_start_network_input (ctx);
         qmi_client_wds_start_network (ctx->client_ipv4,
                                       input,
@@ -1420,7 +1424,7 @@
     case CONNECT_STEP_GET_CURRENT_SETTINGS_IPV4:
         /* Retrieve and print IP configuration */
         if (ctx->packet_data_handle_ipv4) {
-            mm_dbg ("Getting IPv4 configuration...");
+            mm_obj_dbg (self, "getting IPv4 configuration...");
             get_current_settings (task, ctx->client_ipv4);
             return;
         }
@@ -1436,7 +1440,7 @@
         }
 
         /* Start IPv6 setup */
-        mm_dbg ("Running IPv6 connection setup");
+        mm_obj_dbg (self, "running IPv6 connection setup");
         ctx->running_ipv4 = FALSE;
         ctx->running_ipv6 = TRUE;
         ctx->step++;
@@ -1449,7 +1453,7 @@
                                          QMI_SERVICE_WDS,
                                          MM_PORT_QMI_FLAG_WDS_IPV6);
         if (!client) {
-            mm_dbg ("Allocating IPv6-specific WDS client");
+            mm_obj_dbg (self, "allocating IPv6-specific WDS client");
             mm_port_qmi_allocate_client (ctx->qmi,
                                          QMI_SERVICE_WDS,
                                          MM_PORT_QMI_FLAG_WDS_IPV6,
@@ -1471,7 +1475,7 @@
         if (qmi_client_check_version (QMI_CLIENT (ctx->client_ipv6), 1, 9)) {
             QmiMessageWdsSetIpFamilyInput *input;
 
-            mm_dbg ("Setting default IP family to: IPv6");
+            mm_obj_dbg (self, "setting default IP family to: IPv6");
             input = qmi_message_wds_set_ip_family_input_new ();
             qmi_message_wds_set_ip_family_input_set_preference (input, QMI_WDS_IP_FAMILY_IPV6, NULL);
             qmi_client_wds_set_ip_family (ctx->client_ipv6,
@@ -1504,7 +1508,7 @@
     case CONNECT_STEP_START_NETWORK_IPV6: {
         QmiMessageWdsStartNetworkInput *input;
 
-        mm_dbg ("Starting IPv6 connection...");
+        mm_obj_dbg (self, "starting IPv6 connection...");
         input = build_start_network_input (ctx);
         qmi_client_wds_start_network (ctx->client_ipv6,
                                       input,
@@ -1519,7 +1523,7 @@
     case CONNECT_STEP_GET_CURRENT_SETTINGS_IPV6:
         /* Retrieve and print IP configuration */
         if (ctx->packet_data_handle_ipv6) {
-            mm_dbg ("Getting IPv6 configuration...");
+            mm_obj_dbg (self, "getting IPv6 configuration...");
             get_current_settings (task, ctx->client_ipv6);
             return;
         }
@@ -1677,11 +1681,9 @@
         goto out;
     }
 
-    mm_dbg ("Launching connection with QMI port (%s/%s) and data port (%s/%s)",
-            mm_port_subsys_get_string (mm_port_get_subsys (MM_PORT (qmi))),
-            mm_port_get_device (MM_PORT (qmi)),
-            mm_port_subsys_get_string (mm_port_get_subsys (data)),
-            mm_port_get_device (data));
+    mm_obj_dbg (self, "launching connection with QMI port (%s) and data port (%s)",
+                mm_port_get_device (MM_PORT (qmi)),
+                mm_port_get_device (data));
 
     ctx = g_slice_new0 (ConnectContext);
     ctx->self = g_object_ref (self);
@@ -1714,8 +1716,7 @@
 
             ip_family = mm_base_bearer_get_default_ip_family (_self);
             ip_family_str = mm_bearer_ip_family_build_string_from_mask (ip_family);
-            mm_dbg ("No specific IP family requested, defaulting to %s",
-                    ip_family_str);
+            mm_obj_dbg (self, "no specific IP family requested, defaulting to %s", ip_family_str);
             ctx->no_ip_family_preference = TRUE;
             g_free (ip_family_str);
         }
@@ -2061,7 +2062,7 @@
         (!self->priv->client_ipv4 && !self->priv->client_ipv6) ||
         !self->priv->data ||
         !self->priv->qmi) {
-        mm_dbg ("No need to disconnect: QMI bearer is already disconnected");
+        mm_obj_dbg (self, "no need to disconnect: QMI bearer is already disconnected");
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
         return;
diff --git a/src/mm-broadband-bearer.c b/src/mm-broadband-bearer.c
index 29c1d2d..004ef1f 100644
--- a/src/mm-broadband-bearer.c
+++ b/src/mm-broadband-bearer.c
@@ -32,7 +32,7 @@
 #include "mm-iface-modem-3gpp.h"
 #include "mm-iface-modem-cdma.h"
 #include "mm-base-modem-at.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-modem-helpers.h"
 #include "mm-port-enums-types.h"
 #include "mm-helper-enums-types.h"
@@ -93,7 +93,7 @@
 
         ip_family = mm_base_bearer_get_default_ip_family (MM_BASE_BEARER (self));
         default_family = mm_bearer_ip_family_build_string_from_mask (ip_family);
-        mm_dbg ("No specific IP family requested, defaulting to %s", default_family);
+        mm_obj_dbg (self, "no specific IP family requested, defaulting to %s", default_family);
         g_free (default_family);
     }
 
@@ -159,8 +159,9 @@
 /* Generic implementations (both 3GPP and CDMA) are always AT-port based */
 
 static MMPortSerialAt *
-common_get_at_data_port (MMBaseModem *modem,
-                         GError **error)
+common_get_at_data_port (MMBroadbandBearer  *self,
+                         MMBaseModem        *modem,
+                         GError            **error)
 {
     MMPort *data;
 
@@ -181,7 +182,7 @@
         return NULL;
     }
 
-    mm_dbg ("Connection through a plain serial AT port (%s)", mm_port_get_device (data));
+    mm_obj_dbg (self, "connection through a plain serial AT port: %s", mm_port_get_device (data));
 
     return MM_PORT_SERIAL_AT (g_object_ref (data));
 }
@@ -198,39 +199,39 @@
  */
 
 static void
-dial_cdma_ready (MMBaseModem *modem,
+dial_cdma_ready (MMBaseModem  *modem,
                  GAsyncResult *res,
-                 GTask *task)
+                 GTask        *task)
 {
-    MMBroadbandBearer *self;
+    MMBroadbandBearer      *self;
     DetailedConnectContext *ctx;
-    GError *error = NULL;
-    MMBearerIpConfig *config;
+    GError                 *error = NULL;
+    MMBearerIpConfig       *config;
+
+    self = g_task_get_source_object (task);
+    ctx = g_task_get_task_data (task);
 
     /* DO NOT check for cancellable here. If we got here without errors, the
      * bearer is really connected and therefore we need to reflect that in
      * the state machine. */
     mm_base_modem_at_command_full_finish (modem, res, &error);
     if (error) {
-        mm_warn ("Couldn't connect: '%s'", error->message);
+        mm_obj_warn (self, "couldn't connect: %s", error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
     }
 
-    self = g_task_get_source_object (task);
-    ctx = g_task_get_task_data (task);
-
     /* Configure flow control to use while connected */
     if (self->priv->flow_control != MM_FLOW_CONTROL_NONE) {
         gchar *flow_control_str;
 
         flow_control_str = mm_flow_control_build_string_from_mask (self->priv->flow_control);
-        mm_dbg ("[%s] Setting flow control: %s", mm_port_get_device (ctx->data), flow_control_str);
+        mm_obj_dbg (self, "setting flow control in %s: %s", mm_port_get_device (ctx->data), flow_control_str);
         g_free (flow_control_str);
 
         if (!mm_port_serial_set_flow_control (MM_PORT_SERIAL (ctx->data), self->priv->flow_control, &error)) {
-            mm_warn ("Couldn't set flow control settings: %s", error->message);
+            mm_obj_warn (self, "couldn't set flow control settings in %s: %s", mm_port_get_device (ctx->data), error->message);
             g_clear_error (&error);
         }
     }
@@ -291,7 +292,7 @@
 
     mm_base_modem_at_command_full_finish (self, res, &error);
     if (error) {
-        mm_warn ("Couldn't set RM protocol: '%s'", error->message);
+        mm_obj_warn (self, "couldn't set RM protocol: %s", error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -319,7 +320,7 @@
 
     result = mm_base_modem_at_command_full_finish (self, res, &error);
     if (error) {
-        mm_warn ("Couldn't query current RM protocol: '%s'", error->message);
+        mm_obj_warn (self, "couldn't query current RM protocol: %s", error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -329,9 +330,7 @@
     current_index = (guint) atoi (result);
     current_rm = mm_cdma_get_rm_protocol_from_index (current_index, &error);
     if (error) {
-        mm_warn ("Couldn't parse RM protocol reply (%s): '%s'",
-                 result,
-                 error->message);
+        mm_obj_warn (self, "couldn't parse RM protocol reply (%s): %s", result, error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -342,14 +341,13 @@
         guint new_index;
         gchar *command;
 
-        mm_dbg ("Setting requested RM protocol...");
+        mm_obj_dbg (self, "setting requested RM protocol...");
 
         new_index = (mm_cdma_get_index_from_rm_protocol (
                          mm_bearer_properties_get_rm_protocol (mm_base_bearer_peek_config (MM_BASE_BEARER (self))),
                          &error));
         if (error) {
-            mm_warn ("Cannot set RM protocol: '%s'",
-                     error->message);
+            mm_obj_warn (self, "cannot set RM protocol: %s", error->message);
             g_task_return_error (task, error);
             g_object_unref (task);
             return;
@@ -396,7 +394,7 @@
 
     /* Grab dial port. This gets a reference to the dial port and OPENs it.
      * If we fail, we'll need to close it ourselves. */
-    ctx->data = (MMPort *)common_get_at_data_port (ctx->modem, &error);
+    ctx->data = (MMPort *)common_get_at_data_port (self, ctx->modem, &error);
     if (!ctx->data) {
         g_task_return_error (task, error);
         g_object_unref (task);
@@ -408,7 +406,7 @@
             mm_base_bearer_peek_config (MM_BASE_BEARER (self))) !=
         MM_MODEM_CDMA_RM_PROTOCOL_UNKNOWN) {
         /* Need to query current RM protocol */
-        mm_dbg ("Querying current RM protocol set...");
+        mm_obj_dbg (self, "querying current RM protocol set...");
         mm_base_modem_at_command_full (ctx->modem,
                                        ctx->primary,
                                        "+CRM?",
@@ -531,11 +529,11 @@
         GError *error = NULL;
 
         flow_control_str = mm_flow_control_build_string_from_mask (self->priv->flow_control);
-        mm_dbg ("[%s] Setting flow control: %s", mm_port_get_device (MM_PORT (ctx->dial_port)), flow_control_str);
+        mm_obj_dbg (self, "setting flow control in %s: %s", mm_port_get_device (MM_PORT (ctx->dial_port)), flow_control_str);
         g_free (flow_control_str);
 
         if (!mm_port_serial_set_flow_control (MM_PORT_SERIAL (ctx->dial_port), self->priv->flow_control, &error)) {
-            mm_warn ("Couldn't set flow control settings: %s", error->message);
+            mm_obj_warn (self, "couldn't set flow control settings in %s: %s", mm_port_get_device (MM_PORT (ctx->dial_port)), error->message);
             g_clear_error (&error);
         }
     }
@@ -576,7 +574,7 @@
 
     /* Grab dial port. This gets a reference to the dial port and OPENs it.
      * If we fail, we'll need to close it ourselves. */
-    ctx->dial_port = common_get_at_data_port (ctx->modem, &error);
+    ctx->dial_port = common_get_at_data_port (self, ctx->modem, &error);
     if (!ctx->dial_port) {
         g_task_return_error (task, error);
         g_object_unref (task);
@@ -653,14 +651,16 @@
                    GAsyncResult *res,
                    GTask        *task)
 {
+    MMBroadbandBearer       *self;
     CidSelection3gppContext *ctx;
     GError                  *error = NULL;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     mm_base_modem_at_command_full_finish (modem, res, &error);
     if (error) {
-        mm_warn ("Couldn't initialize context: '%s'", error->message);
+        mm_obj_warn (self, "couldn't initialize context: %s", error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -686,9 +686,9 @@
 
     /* Initialize a PDP context with our APN and PDP type */
     apn = mm_bearer_properties_get_apn (mm_base_bearer_peek_config (MM_BASE_BEARER (self)));
-    mm_dbg ("%s context with APN '%s' and PDP type '%s'",
-            ctx->cid_overwritten ? "Overwriting" : "Initializing",
-            apn, ctx->pdp_type);
+    mm_obj_dbg (self, "%s context with APN '%s' and PDP type '%s'",
+                ctx->cid_overwritten ? "overwriting" : "initializing",
+                apn, ctx->pdp_type);
     quoted_apn = mm_port_serial_at_quote_string (apn);
     cmd = g_strdup_printf ("+CGDCONT=%u,\"%s\",%s", ctx->cid, ctx->pdp_type, quoted_apn);
     g_free (quoted_apn);
@@ -718,6 +718,7 @@
                                         ctx->ip_family,
                                         ctx->context_list,
                                         ctx->context_format_list,
+                                        self,
                                         &ctx->cid_reused,
                                         &ctx->cid_overwritten);
 
@@ -738,17 +739,19 @@
                      GAsyncResult *res,
                      GTask        *task)
 {
+    MMBroadbandBearer       *self;
     CidSelection3gppContext *ctx;
     GError                  *error = NULL;
     const gchar             *response;
     GList                   *l;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     response = mm_base_modem_at_command_full_finish (modem, res, &error);
     if (!response) {
         /* Ignore errors */
-        mm_dbg ("Failed checking currently defined contexts: %s", error->message);
+        mm_obj_dbg (self, "failed checking currently defined contexts: %s", error->message);
         g_clear_error (&error);
         goto out;
     }
@@ -757,24 +760,24 @@
     ctx->context_list = mm_3gpp_parse_cgdcont_read_response (response, &error);
     if (!ctx->context_list) {
         if (error) {
-            mm_dbg ("Failed parsing currently defined contexts: %s", error->message);
+            mm_obj_dbg (self, "failed parsing currently defined contexts: %s", error->message);
             g_clear_error (&error);
         } else
-            mm_dbg ("No contexts currently defined");
+            mm_obj_dbg (self, "no contexts currently defined");
         goto out;
     }
 
     /* Show all found PDP contexts in debug log */
-    mm_dbg ("Found '%u' PDP contexts", g_list_length (ctx->context_list));
+    mm_obj_dbg (self, "found %u PDP contexts", g_list_length (ctx->context_list));
     for (l = ctx->context_list; l; l = g_list_next (l)) {
         MM3gppPdpContext *pdp = l->data;
         gchar            *ip_family_str;
 
         ip_family_str = mm_bearer_ip_family_build_string_from_mask (pdp->pdp_type);
-        mm_dbg ("  PDP context [cid=%u] [type='%s'] [apn='%s']",
-                pdp->cid,
-                ip_family_str,
-                pdp->apn ? pdp->apn : "");
+        mm_obj_dbg (self, "  PDP context [cid=%u] [type='%s'] [apn='%s']",
+                    pdp->cid,
+                    ip_family_str,
+                    pdp->apn ? pdp->apn : "");
         g_free (ip_family_str);
     }
 
@@ -786,11 +789,13 @@
 static void
 cid_selection_3gpp_query_current (GTask *task)
 {
+    MMBroadbandBearer       *self;
     CidSelection3gppContext *ctx;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
-    mm_dbg ("Checking currently defined contexts...");
+    mm_obj_dbg (self, "checking currently defined contexts...");
     mm_base_modem_at_command_full (ctx->modem,
                                    ctx->primary,
                                    "+CGDCONT?",
@@ -807,23 +812,25 @@
                     GAsyncResult *res,
                     GTask        *task)
 {
+    MMBroadbandBearer       *self;
     CidSelection3gppContext *ctx;
     GError                  *error = NULL;
     const gchar             *response;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     response = mm_base_modem_at_command_full_finish (modem, res, &error);
     if (!response) {
         /* Ignore errors */
-        mm_dbg ("Failed checking context definition format: %s", error->message);
+        mm_obj_dbg (self, "failed checking context definition format: %s", error->message);
         g_clear_error (&error);
         goto out;
     }
 
-    ctx->context_format_list = mm_3gpp_parse_cgdcont_test_response (response, &error);
+    ctx->context_format_list = mm_3gpp_parse_cgdcont_test_response (response, self, &error);
     if (error) {
-        mm_dbg ("Error parsing +CGDCONT test response: '%s'", error->message);
+        mm_obj_dbg (self, "error parsing +CGDCONT test response: %s", error->message);
         g_clear_error (&error);
         goto out;
     }
@@ -836,11 +843,13 @@
 static void
 cid_selection_3gpp_query_format (GTask *task)
 {
+    MMBroadbandBearer       *self;
     CidSelection3gppContext *ctx;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
-    mm_dbg ("Checking context definition format...");
+    mm_obj_dbg (self, "checking context definition format...");
     mm_base_modem_at_command_full (ctx->modem,
                                    ctx->primary,
                                    "+CGDCONT=?",
@@ -1309,7 +1318,7 @@
 
     /* If the modem has 3GPP capabilities and an APN, launch 3GPP-based connection */
     if (mm_iface_modem_is_3gpp (MM_IFACE_MODEM (modem)) && apn) {
-        mm_dbg ("Launching 3GPP connection attempt with APN '%s'", apn);
+        mm_obj_dbg (self, "launching 3GPP connection attempt with APN '%s'", apn);
         MM_BROADBAND_BEARER_GET_CLASS (self)->connect_3gpp (
             MM_BROADBAND_BEARER (self),
             MM_BROADBAND_MODEM (modem),
@@ -1324,7 +1333,7 @@
 
     /* Otherwise, launch CDMA-specific connection. */
     if (mm_iface_modem_is_cdma (MM_IFACE_MODEM (modem)) && !apn) {
-        mm_dbg ("Launching 3GPP2 connection attempt");
+        mm_obj_dbg (self, "launching 3GPP2 connection attempt");
         MM_BROADBAND_BEARER_GET_CLASS (self)->connect_cdma (
             MM_BROADBAND_BEARER (self),
             MM_BROADBAND_MODEM (modem),
@@ -1397,9 +1406,12 @@
 static void
 data_flash_cdma_ready (MMPortSerial *data,
                        GAsyncResult *res,
-                       GTask *task)
+                       GTask        *task)
 {
-    GError *error = NULL;
+    MMBroadbandBearer *self;
+    GError            *error = NULL;
+
+    self = g_task_get_source_object (task);
 
     mm_port_serial_flash_finish (data, res, &error);
 
@@ -1426,7 +1438,7 @@
             return;
         }
 
-        mm_dbg ("Port flashing failed (not fatal): %s", error->message);
+        mm_obj_dbg (self, "port flashing failed (not fatal): %s", error->message);
         g_error_free (error);
     }
 
@@ -1442,8 +1454,12 @@
                         GAsyncResult *res,
                         GTask *task)
 {
+    MMBroadbandBearer         *self;
     DetailedDisconnectContext *ctx;
-    GError *error = NULL;
+    GError                    *error = NULL;
+
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     g_object_set (data, MM_PORT_SERIAL_AT_INIT_SEQUENCE_ENABLED, TRUE, NULL);
 
@@ -1454,10 +1470,8 @@
         return;
     }
 
-    ctx = g_task_get_task_data (task);
-
     /* Just flash the data port */
-    mm_dbg ("Flashing data port (%s)...", mm_port_get_device (MM_PORT (ctx->data)));
+    mm_obj_dbg (self, "flashing data port %s...", mm_port_get_device (MM_PORT (ctx->data)));
     mm_port_serial_flash (MM_PORT_SERIAL (ctx->data),
                           1000,
                           TRUE,
@@ -1492,7 +1506,7 @@
     g_object_set (data, MM_PORT_SERIAL_AT_INIT_SEQUENCE_ENABLED, FALSE, NULL);
 
     /* Fully reopen the port before flashing */
-    mm_dbg ("Reopening data port (%s)...", mm_port_get_device (MM_PORT (ctx->data)));
+    mm_obj_dbg (self, "reopening data port %s...", mm_port_get_device (MM_PORT (ctx->data)));
     mm_port_serial_reopen (MM_PORT_SERIAL (ctx->data),
                            1000,
                            (GAsyncReadyCallback)data_reopen_cdma_ready,
@@ -1503,17 +1517,19 @@
 /* 3GPP disconnect */
 
 static void
-cgact_data_ready (MMBaseModem *modem,
+cgact_data_ready (MMBaseModem  *modem,
                   GAsyncResult *res,
-                  GTask *task)
+                  GTask        *task)
 {
+    MMBroadbandBearer *self;
+    GError            *error = NULL;
 
-    GError *error = NULL;
+    self = g_task_get_source_object (task);
 
     /* Ignore errors for now */
     mm_base_modem_at_command_full_finish (modem, res, &error);
     if (error) {
-        mm_dbg ("PDP context deactivation failed (not fatal): %s", error->message);
+        mm_obj_dbg (self, "PDP context deactivation failed (not fatal): %s", error->message);
         g_error_free (error);
     }
 
@@ -1524,12 +1540,14 @@
 static void
 data_flash_3gpp_ready (MMPortSerial *data,
                        GAsyncResult *res,
-                       GTask *task)
+                       GTask        *task)
 {
+    MMBroadbandBearer         *self;
     DetailedDisconnectContext *ctx;
-    GError *error = NULL;
+    GError                    *error = NULL;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     mm_port_serial_flash_finish (data, res, &error);
 
@@ -1556,7 +1574,7 @@
             return;
         }
 
-        mm_dbg ("Port flashing failed (not fatal): %s", error->message);
+        mm_obj_dbg (self, "port flashing failed (not fatal): %s", error->message);
         g_error_free (error);
     }
 
@@ -1566,7 +1584,7 @@
     /* Don't bother doing the CGACT again if it was already done on the
      * primary or secondary port */
     if (ctx->cgact_sent) {
-        mm_dbg ("PDP disconnection already sent");
+        mm_obj_dbg (self, "PDP disconnection already sent");
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
         return;
@@ -1578,9 +1596,9 @@
      * port when the CGACT is sent on the separte data port.
      */
     if (MM_PORT_SERIAL (ctx->primary) == data)
-        mm_dbg ("Sending PDP context deactivation in primary/data port...");
+        mm_obj_dbg (self, "sending PDP context deactivation in primary/data port...");
     else
-        mm_dbg ("Sending PDP context deactivation in primary port again...");
+        mm_obj_dbg (self, "sending PDP context deactivation in primary port again...");
 
     mm_base_modem_at_command_full (ctx->modem,
                                    ctx->primary,
@@ -1596,10 +1614,14 @@
 static void
 data_reopen_3gpp_ready (MMPortSerial *data,
                         GAsyncResult *res,
-                        GTask *task)
+                        GTask        *task)
 {
+    MMBroadbandBearer         *self;
     DetailedDisconnectContext *ctx;
-    GError *error = NULL;
+    GError                    *error = NULL;
+
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     g_object_set (data, MM_PORT_SERIAL_AT_INIT_SEQUENCE_ENABLED, TRUE, NULL);
 
@@ -1610,10 +1632,8 @@
         return;
     }
 
-    ctx = g_task_get_task_data (task);
-
     /* Just flash the data port */
-    mm_dbg ("Flashing data port (%s)...", mm_port_get_device (MM_PORT (ctx->data)));
+    mm_obj_dbg (self, "flashing data port %s...", mm_port_get_device (MM_PORT (ctx->data)));
     mm_port_serial_flash (MM_PORT_SERIAL (ctx->data),
                           1000,
                           TRUE,
@@ -1624,16 +1644,18 @@
 static void
 data_reopen_3gpp (GTask *task)
 {
+    MMBroadbandBearer         *self;
     DetailedDisconnectContext *ctx;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     /* We don't want to run init sequence right away during the reopen, as we're
      * going to flash afterwards. */
     g_object_set (ctx->data, MM_PORT_SERIAL_AT_INIT_SEQUENCE_ENABLED, FALSE, NULL);
 
     /* Fully reopen the port before flashing */
-    mm_dbg ("Reopening data port (%s)...", mm_port_get_device (MM_PORT (ctx->data)));
+    mm_obj_dbg (self, "reopening data port %s...", mm_port_get_device (MM_PORT (ctx->data)));
     mm_port_serial_reopen (MM_PORT_SERIAL (ctx->data),
                            1000,
                            (GAsyncReadyCallback)data_reopen_3gpp_ready,
@@ -1641,20 +1663,22 @@
 }
 
 static void
-cgact_ready (MMBaseModem *modem,
+cgact_ready (MMBaseModem  *modem,
              GAsyncResult *res,
-             GTask *task)
+             GTask        *task)
 {
+    MMBroadbandBearer         *self;
     DetailedDisconnectContext *ctx;
-    GError *error = NULL;
+    GError                    *error = NULL;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     mm_base_modem_at_command_full_finish (modem, res, &error);
     if (!error)
         ctx->cgact_sent = TRUE;
     else {
-        mm_dbg ("PDP context deactivation failed (not fatal): %s", error->message);
+        mm_obj_dbg (self, "PDP context deactivation failed (not fatal): %s", error->message);
         g_error_free (error);
     }
 
@@ -1692,7 +1716,7 @@
     /* If the primary port is NOT connected (doesn't have to be the data port),
      * we'll send CGACT there */
     if (!mm_port_get_connected (MM_PORT (ctx->primary))) {
-        mm_dbg ("Sending PDP context deactivation in primary port...");
+        mm_obj_dbg (self, "sending PDP context deactivation in primary port...");
         mm_base_modem_at_command_full (ctx->modem,
                                        ctx->primary,
                                        ctx->cgact_command,
@@ -1711,7 +1735,7 @@
      * driver doesn't support it).
      */
     if (ctx->secondary) {
-        mm_dbg ("Sending PDP context deactivation in secondary port...");
+        mm_obj_dbg (self, "sending PDP context deactivation in secondary port...");
         mm_base_modem_at_command_full (ctx->modem,
                                        ctx->secondary,
                                        ctx->cgact_command,
@@ -1811,7 +1835,7 @@
     task = g_task_new (self, NULL, callback, user_data);
 
     if (!MM_BROADBAND_BEARER (self)->priv->port) {
-        mm_dbg ("No need to disconnect: bearer is already disconnected");
+        mm_obj_dbg (self, "no need to disconnect: bearer is already disconnected");
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
         return;
diff --git a/src/mm-broadband-modem-mbim.c b/src/mm-broadband-modem-mbim.c
index ba129dc..f6c7a7e 100644
--- a/src/mm-broadband-modem-mbim.c
+++ b/src/mm-broadband-modem-mbim.c
@@ -28,7 +28,7 @@
 #include "mm-sms-mbim.h"
 
 #include "ModemManager.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-errors-types.h"
 #include "mm-error-helpers.h"
 #include "mm-modem-helpers.h"
@@ -259,11 +259,11 @@
             qmi_caps_str = mm_common_build_capabilities_string ((const MMModemCapability *)&(ctx->current_qmi), 1);
 
             if ((ctx->current_mbim & ctx->current_qmi) != ctx->current_mbim)
-                mm_warn ("MBIM reported current capabilities (%s) not found in QMI-over-MBIM reported ones (%s)",
-                         mbim_caps_str, qmi_caps_str);
+                mm_obj_warn (self, "MBIM reported current capabilities (%s) not found in QMI-over-MBIM reported ones (%s)",
+                             mbim_caps_str, qmi_caps_str);
             else
-                mm_dbg ("MBIM reported current capabilities (%s) is a subset of the QMI-over-MBIM reported ones (%s)",
-                        mbim_caps_str, qmi_caps_str);
+                mm_obj_dbg (self, "MBIM reported current capabilities (%s) is a subset of the QMI-over-MBIM reported ones (%s)",
+                            mbim_caps_str, qmi_caps_str);
             g_free (mbim_caps_str);
             g_free (qmi_caps_str);
 
@@ -279,7 +279,7 @@
          * capability and mode related operations are going to be done via QMI as well, so that we
          * don't mix both logics */
         if (self->priv->qmi_capability_and_mode_switching)
-            mm_info ("QMI-based capability and mode switching support enabled");
+            mm_obj_info (self, "QMI-based capability and mode switching support enabled");
     }
 #else
     result = ctx->current_mbim;
@@ -337,12 +337,14 @@
 static void
 load_current_capabilities_mbim (GTask *task)
 {
+    MMBroadbandModemMbim           *self;
     MbimMessage                    *message;
     LoadCurrentCapabilitiesContext *ctx;
 
+    self = g_task_get_source_object (task);
     ctx = g_task_get_task_data (task);
 
-    mm_dbg ("loading current capabilities...");
+    mm_obj_dbg (self, "loading current capabilities...");
     message = mbim_message_device_caps_query_new (NULL);
     mbim_device_command (ctx->device,
                          message,
@@ -366,8 +368,8 @@
     ctx = g_task_get_task_data (task);
 
     ctx->current_qmi = mm_shared_qmi_load_current_capabilities_finish (self, res, &error);
-    if (!ctx->current_qmi) {
-        mm_dbg ("Couldn't load currrent capabilities using QMI over MBIM: %s", error->message);
+    if (error) {
+        mm_obj_dbg (self, "couldn't load currrent capabilities using QMI over MBIM: %s", error->message);
         g_clear_error (&error);
     }
 
@@ -994,12 +996,12 @@
              * The MC7710 may use this while the SIM is not ready yet. */
             break;
         case MBIM_SUBSCRIBER_READY_STATE_BAD_SIM:
-            error = mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_SIM_WRONG);
+            error = mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_SIM_WRONG, self);
             break;
         case MBIM_SUBSCRIBER_READY_STATE_FAILURE:
         case MBIM_SUBSCRIBER_READY_STATE_NOT_ACTIVATED:
         default:
-            error = mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_SIM_FAILURE);
+            error = mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_SIM_FAILURE, self);
             break;
         }
     }
@@ -1019,7 +1021,7 @@
         /* All retries consumed? issue error */
         if (ctx->last_attempt) {
             if (ready_state == MBIM_SUBSCRIBER_READY_STATE_SIM_NOT_INSERTED)
-                g_task_return_error (task, mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_SIM_NOT_INSERTED));
+                g_task_return_error (task, mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_SIM_NOT_INSERTED, self));
             else
                 g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
                                          "Error waiting for SIM to get initialized");
@@ -1402,14 +1404,17 @@
                               GAsyncResult *res,
                               GTask        *task)
 {
+    MMBroadbandModemMbim                    *self;
     PowerUpContext                          *ctx;
     QmiMessageDmsSetFccAuthenticationOutput *output;
     GError                                  *error = NULL;
 
+    self = g_task_get_source_object (task);
     ctx = g_task_get_task_data (task);
+
     output = qmi_client_dms_set_fcc_authentication_finish (qmi_client_dms, res, &error);
     if (!output || !qmi_message_dms_set_fcc_authentication_output_get_result (output, &error)) {
-        mm_dbg ("error: couldn't set FCC auth: %s", error->message);
+        mm_obj_dbg (self, "couldn't set FCC auth: %s", error->message);
         g_error_free (error);
         g_assert (ctx->saved_error);
         g_task_return_error (task, ctx->saved_error);
@@ -1456,6 +1461,7 @@
     MbimRadioSwitchState software_radio_state;
 
     ctx = g_task_get_task_data (task);
+
     response = mbim_device_command_finish (device, res, &error);
     if (response &&
         mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error) &&
@@ -1487,8 +1493,11 @@
 #if defined WITH_QMI && QMI_MBIM_QMUX_SUPPORTED
     /* Only the first attempt isn't fatal, if we have a QMI DMS client */
     if ((ctx->step == POWER_UP_CONTEXT_STEP_FIRST) && ctx->qmi_client_dms) {
+        MMBroadbandModemMbim *self;
+
         /* Warn and keep, will retry */
-        mm_warn ("%s", error->message);
+        self = g_task_get_source_object (task);
+        mm_obj_warn (self, "%s", error->message);
         g_assert (!ctx->saved_error);
         ctx->saved_error = error;
         ctx->step++;
@@ -1752,8 +1761,8 @@
                                               GAsyncResult *res,
                                               GTask        *task)
 {
-    MbimMessage *response;
-    GError      *error = NULL;
+    MbimMessage      *response;
+    GError           *error = NULL;
 
     response = mbim_device_command_finish (device, res, &error);
     if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) {
@@ -1761,7 +1770,7 @@
         /* We don't really expect the Intel firmware update service to be
          * available in QMI modems, but doesn't harm to fallback to the QMI
          * implementation here */
-        mm_dbg ("Couldn't run intel reset: %s", error->message);
+        mm_obj_dbg (g_task_get_source_object (task), "couldn't run intel reset: %s", error->message);
         g_error_free (error);
         modem_reset_shared_qmi (task);
 #else
@@ -1902,7 +1911,7 @@
     }
 
     /* We just create a MMBearerMbim */
-    mm_dbg ("Creating MBIM bearer in MBIM modem");
+    mm_obj_dbg (self, "creating MBIM bearer in MBIM modem");
     bearer = mm_bearer_mbim_new (self,
                                  properties,
                                  (guint)session_id);
@@ -1957,7 +1966,7 @@
             &error)) {
         /* Don't treat this as fatal. Parent enabling may fail if it cannot grab a primary
          * AT port, which isn't really an issue in MBIM-based modems */
-        mm_dbg ("Couldn't start parent enabling: %s", error->message);
+        mm_obj_dbg (self, "couldn't start parent enabling: %s", error->message);
         g_error_free (error);
     }
 
@@ -2020,7 +2029,7 @@
     if (error) {
         /* Don't treat this as fatal. Parent initialization may fail if it cannot grab a primary
          * AT port, which isn't really an issue in MBIM-based modems */
-        mm_dbg ("Couldn't start parent initialization: %s", error->message);
+        mm_obj_dbg (self, "couldn't start parent initialization: %s", error->message);
         g_error_free (error);
     }
 
@@ -2058,13 +2067,15 @@
                                      GAsyncResult *res,
                                      GTask        *task)
 {
+    MMBroadbandModemMbim         *self;
     InitializationStartedContext *ctx;
     GError                       *error = NULL;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     if (!mm_port_mbim_allocate_qmi_client_finish (mbim, res, &error)) {
-        mm_dbg ("Couldn't allocate QMI client for service '%s': %s",
+        mm_obj_dbg (self, "couldn't allocate QMI client for service '%s': %s",
                 qmi_service_get_string (qmi_services[ctx->qmi_service_index]),
                 error->message);
         g_error_free (error);
@@ -2129,10 +2140,10 @@
             if (service == MBIM_SERVICE_MS_BASIC_CONNECT_EXTENSIONS) {
                 for (j = 0; j < device_services[i]->cids_count; j++) {
                     if (device_services[i]->cids[j] == MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_PCO) {
-                        mm_dbg ("PCO is supported");
+                        mm_obj_dbg (self, "PCO is supported");
                         self->priv->is_pco_supported = TRUE;
                     } else if (device_services[i]->cids[j] == MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_LTE_ATTACH_STATUS) {
-                        mm_dbg ("LTE attach status is supported");
+                        mm_obj_dbg (self, "LTE attach status is supported");
                         self->priv->is_lte_attach_status_supported = TRUE;
                     }
                 }
@@ -2142,7 +2153,7 @@
             if (service == MBIM_SERVICE_USSD) {
                 for (j = 0; j < device_services[i]->cids_count; j++) {
                     if (device_services[i]->cids[j] == MBIM_CID_USSD) {
-                        mm_dbg ("USSD is supported");
+                        mm_obj_dbg (self, "USSD is supported");
                         self->priv->is_ussd_supported = TRUE;
                         break;
                     }
@@ -2153,10 +2164,10 @@
             if (service == MBIM_SERVICE_ATDS) {
                 for (j = 0; j < device_services[i]->cids_count; j++) {
                     if (device_services[i]->cids[j] == MBIM_CID_ATDS_LOCATION) {
-                        mm_dbg ("ATDS location is supported");
+                        mm_obj_dbg (self, "ATDS location is supported");
                         self->priv->is_atds_location_supported = TRUE;
                     } else if (device_services[i]->cids[j] == MBIM_CID_ATDS_SIGNAL) {
-                        mm_dbg ("ATDS signal is supported");
+                        mm_obj_dbg (self, "ATDS signal is supported");
                         self->priv->is_atds_signal_supported = TRUE;
                     }
                 }
@@ -2166,7 +2177,7 @@
             if (service == MBIM_SERVICE_INTEL_FIRMWARE_UPDATE) {
                 for (j = 0; j < device_services[i]->cids_count; j++) {
                     if (device_services[i]->cids[j] == MBIM_CID_INTEL_FIRMWARE_UPDATE_MODEM_REBOOT) {
-                        mm_dbg ("Intel reset is supported");
+                        mm_obj_dbg (self, "Intel reset is supported");
                         self->priv->is_intel_reset_supported = TRUE;
                     }
                 }
@@ -2178,7 +2189,7 @@
         mbim_device_service_element_array_free (device_services);
     } else {
         /* Ignore error */
-        mm_warn ("Couldn't query device services: %s", error->message);
+        mm_obj_warn (self, "couldn't query device services: %s", error->message);
         g_error_free (error);
     }
 
@@ -2195,15 +2206,19 @@
 static void
 query_device_services (GTask *task)
 {
+    MMBroadbandModem *self;
     InitializationStartedContext *ctx;
     MbimMessage *message;
     MbimDevice *device;
 
+    self = g_task_get_source_object (task);
     ctx = g_task_get_task_data (task);
+
     device = mm_port_mbim_peek_device (ctx->mbim);
     g_assert (device);
 
-    mm_dbg ("querying device services...");
+    mm_obj_dbg (self, "querying device services...");
+
     message = mbim_message_device_services_query_new (NULL);
     mbim_device_command (device,
                          message,
@@ -2220,8 +2235,8 @@
 {
     /* We have to do a full re-probe here because simply reopening the device
      * and restarting mbim-proxy will leave us without MBIM notifications. */
-    mm_info ("Connection to mbim-proxy for %s lost, reprobing",
-             mbim_device_get_path_display (device));
+    mm_obj_info (self, "connection to mbim-proxy for %s lost, reprobing",
+                 mbim_device_get_path_display (device));
 
     g_signal_handler_disconnect (device,
                                  self->priv->mbim_device_removed_id);
@@ -2765,6 +2780,7 @@
                                                  GAsyncResult *res,
                                                  GTask        *task)
 {
+    MMBroadbandModemMbim        *self;
     MbimMessage                 *request;
     MbimMessage                 *response;
     GError                      *error = NULL;
@@ -2773,6 +2789,7 @@
     MbimLteAttachConfiguration **configurations = NULL;
     guint                        i;
 
+    self   = g_task_get_source_object (task);
     config = g_task_get_task_data (task);
 
     response = mbim_device_command_finish (device, res, &error);
@@ -2805,7 +2822,7 @@
             configurations[i]->ip_type = mm_bearer_ip_family_to_mbim_context_ip_type (ip_family, &error);
             if (error) {
                 configurations[i]->ip_type = MBIM_CONTEXT_IP_TYPE_DEFAULT;
-                mm_warn ("unexpected IP type settings requested: %s", error->message);
+                mm_obj_warn (self, "unexpected IP type settings requested: %s", error->message);
                 g_clear_error (&error);
             }
         }
@@ -2814,10 +2831,10 @@
         if (auth == MM_BEARER_ALLOWED_AUTH_UNKNOWN)
             configurations[i]->auth_protocol = MBIM_AUTH_PROTOCOL_NONE;
         else {
-            configurations[i]->auth_protocol = mm_bearer_allowed_auth_to_mbim_auth_protocol (auth, &error);
+            configurations[i]->auth_protocol = mm_bearer_allowed_auth_to_mbim_auth_protocol (auth, self, &error);
             if (error) {
                 configurations[i]->auth_protocol = MBIM_AUTH_PROTOCOL_NONE;
-                mm_warn ("unexpected auth settings requested: %s", error->message);
+                mm_obj_warn (self, "unexpected auth settings requested: %s", error->message);
                 g_clear_error (&error);
             }
         }
@@ -2919,7 +2936,7 @@
         /* Normalize the quality. 99 means unknown, we default it to 0 */
         quality = MM_CLAMP_HIGH (rssi == 99 ? 0 : rssi, 31) * 100 / 31;
 
-        mm_dbg ("Signal state indication: %u --> %u%%", rssi, quality);
+        mm_obj_dbg (self, "signal state indication: %u --> %u%%", rssi, quality);
         mm_iface_modem_update_signal_quality (MM_IFACE_MODEM (self), quality);
     }
 }
@@ -2944,6 +2961,7 @@
                           gchar *operator_name_take)
 {
     MMModem3gppRegistrationState reg_state;
+    gboolean                     operator_updated = FALSE;
 
     reg_state = mm_modem_3gpp_registration_state_from_mbim_register_state (state);
 
@@ -2953,6 +2971,7 @@
             g_str_equal (self->priv->current_operator_id, operator_id_take)) {
             g_free (operator_id_take);
         } else {
+            operator_updated = TRUE;
             g_free (self->priv->current_operator_id);
             self->priv->current_operator_id = operator_id_take;
         }
@@ -2961,10 +2980,13 @@
             g_str_equal (self->priv->current_operator_name, operator_name_take)) {
             g_free (operator_name_take);
         } else {
+            operator_updated = TRUE;
             g_free (self->priv->current_operator_name);
             self->priv->current_operator_name = operator_name_take;
         }
     } else {
+        if (self->priv->current_operator_id || self->priv->current_operator_name)
+            operator_updated = TRUE;
         g_clear_pointer (&self->priv->current_operator_id, g_free);
         g_clear_pointer (&self->priv->current_operator_name, g_free);
         g_free (operator_id_take);
@@ -2977,6 +2999,11 @@
 
     self->priv->available_data_classes = available_data_classes;
     update_access_technologies (self);
+
+    /* request to reload operator info explicitly, so that the new
+     * operator name and code is propagated to the DBus interface */
+    if (operator_updated)
+        mm_iface_modem_3gpp_reload_current_registration_info (MM_IFACE_MODEM_3GPP (self), NULL, NULL);
 }
 
 static void
@@ -3009,7 +3036,8 @@
 }
 
 typedef struct {
-    guint32 session_id;
+    MMBroadbandModemMbim *self;
+    guint32               session_id;
 } ReportDisconnectedStatusContext;
 
 static void
@@ -3020,7 +3048,7 @@
 
     if (MM_IS_BEARER_MBIM (bearer) &&
         mm_bearer_mbim_get_session_id (MM_BEARER_MBIM (bearer)) == ctx->session_id) {
-        mm_dbg ("Bearer '%s' was disconnected.", mm_base_bearer_get_path (bearer));
+        mm_obj_dbg (ctx->self, "bearer '%s' was disconnected.", mm_base_bearer_get_path (bearer));
         mm_base_bearer_report_connection_status (bearer, MM_BEARER_CONNECTION_STATUS_DISCONNECTED);
     }
 }
@@ -3057,7 +3085,8 @@
         activation_state == MBIM_ACTIVATION_STATE_DEACTIVATED) {
       ReportDisconnectedStatusContext ctx;
 
-      mm_dbg ("Session ID '%u' was deactivated.", session_id);
+      mm_obj_dbg (self, "session ID '%u' was deactivated.", session_id);
+      ctx.self = self;
       ctx.session_id = session_id;
       mm_bearer_list_foreach (bearer_list,
                               (MMBearerListForeachFunc)bearer_list_report_disconnected_status,
@@ -3094,7 +3123,7 @@
         (self->priv->last_ready_state == MBIM_SUBSCRIBER_READY_STATE_SIM_NOT_INSERTED &&
                ready_state != MBIM_SUBSCRIBER_READY_STATE_SIM_NOT_INSERTED)) {
         /* SIM has been removed or reinserted, re-probe to ensure correct interfaces are exposed */
-        mm_dbg ("SIM hot swap detected");
+        mm_obj_dbg (self, "SIM hot swap detected");
         mm_broadband_modem_update_sim_hot_swap_detected (MM_BROADBAND_MODEM (self));
     }
 
@@ -3122,8 +3151,8 @@
     }
 
     str = mbim_data_class_build_string_from_mask (highest_available_data_class);
-    mm_dbg ("Packet service state: '%s', data class: '%s'",
-            mbim_packet_service_state_get_string (packet_service_state), str);
+    mm_obj_dbg (self, "packet service state: '%s', data class: '%s'",
+                mbim_packet_service_state_get_string (packet_service_state), str);
     g_free (str);
 
     if (packet_service_state == MBIM_PACKET_SERVICE_STATE_ATTACHED) {
@@ -3252,7 +3281,7 @@
     }
 
     if (error) {
-        mm_dbg ("Flash message reading failed: %s", error->message);
+        mm_obj_dbg (self, "flash message reading failed: %s", error->message);
         g_error_free (error);
     }
 
@@ -3277,7 +3306,7 @@
     if (!device)
         return;
 
-    mm_dbg ("Reading new SMS at index '%u'", index);
+    mm_obj_dbg (self, "reading new SMS at index '%u'", index);
     message = mbim_message_sms_read_query_new (MBIM_SMS_FORMAT_PDU,
                                                MBIM_SMS_FLAG_INDEX,
                                                index,
@@ -3312,7 +3341,7 @@
                 &flag,
                 &index,
                 NULL)) {
-            mm_dbg ("Received SMS store status update: '%s'", mbim_sms_status_flag_get_string (flag));
+            mm_obj_dbg (self, "received SMS store status update: '%s'", mbim_sms_status_flag_get_string (flag));
             if (flag == MBIM_SMS_STATUS_FLAG_NEW_MESSAGE)
                 sms_notification_read_stored_sms (self, index);
         }
@@ -3338,18 +3367,18 @@
             notification,
             &pco_value,
             &error)) {
-        mm_warn ("Couldn't parse PCO notification: %s", error->message);
+        mm_obj_warn (self, "couldn't parse PCO notification: %s", error->message);
         g_error_free (error);
         return;
     }
 
     pco_data_hex = mm_utils_bin2hexstr (pco_value->pco_data_buffer,
                                         pco_value->pco_data_size);
-    mm_dbg ("Received PCO: session ID=%u type=%s size=%u data=%s",
-             pco_value->session_id,
-             mbim_pco_type_get_string (pco_value->pco_data_type),
-             pco_value->pco_data_size,
-             pco_data_hex);
+    mm_obj_dbg (self, "received PCO: session ID=%u type=%s size=%u data=%s",
+                pco_value->session_id,
+                mbim_pco_type_get_string (pco_value->pco_data_type),
+                pco_value->pco_data_size,
+                pco_data_hex);
     g_free (pco_data_hex);
 
     pco = mm_pco_new ();
@@ -3379,7 +3408,7 @@
             notification,
             &status,
             &error)) {
-        mm_warn ("Couldn't parse LTE attach status notification: %s", error->message);
+        mm_obj_warn (self, "couldn't parse LTE attach status notification: %s", error->message);
         g_error_free (error);
         return;
     }
@@ -3419,7 +3448,7 @@
                    MbimMessage          *notification)
 {
     if (mbim_message_indicate_status_get_cid (notification) != MBIM_CID_USSD) {
-        mm_warn ("unexpected USSD notification (cid %u)", mbim_message_indicate_status_get_cid (notification));
+        mm_obj_warn (self, "unexpected USSD notification (cid %u)", mbim_message_indicate_status_get_cid (notification));
         return;
     }
 
@@ -3437,10 +3466,10 @@
     MbimService service;
 
     service = mbim_message_indicate_status_get_service (notification);
-    mm_dbg ("Received notification (service '%s', command '%s')",
-            mbim_service_get_string (service),
-            mbim_cid_get_printable (service,
-                                    mbim_message_indicate_status_get_cid (notification)));
+    mm_obj_dbg (self, "received notification (service '%s', command '%s')",
+                mbim_service_get_string (service),
+                mbim_cid_get_printable (service,
+                                        mbim_message_indicate_status_get_cid (notification)));
 
     switch (service) {
     case MBIM_SERVICE_BASIC_CONNECT:
@@ -3480,17 +3509,17 @@
     if (!device)
         return;
 
-    mm_dbg ("Supported notifications: signal (%s), registration (%s), sms (%s), connect (%s), subscriber (%s), packet (%s), pco (%s), ussd (%s), lte attach status (%s), provisioned contexts (%s)",
-            self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_SIGNAL_QUALITY ? "yes" : "no",
-            self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_REGISTRATION_UPDATES ? "yes" : "no",
-            self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_SMS_READ ? "yes" : "no",
-            self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_CONNECT ? "yes" : "no",
-            self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_SUBSCRIBER_INFO ? "yes" : "no",
-            self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_PACKET_SERVICE ? "yes" : "no",
-            self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_PCO ? "yes" : "no",
-            self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_USSD ? "yes" : "no",
-            self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_LTE_ATTACH_STATUS ? "yes" : "no",
-            self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_PROVISIONED_CONTEXTS ? "yes" : "no");
+    mm_obj_dbg (self, "supported notifications: signal (%s), registration (%s), sms (%s), connect (%s), subscriber (%s), packet (%s), pco (%s), ussd (%s), lte attach status (%s), provisioned contexts (%s)",
+                self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_SIGNAL_QUALITY ? "yes" : "no",
+                self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_REGISTRATION_UPDATES ? "yes" : "no",
+                self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_SMS_READ ? "yes" : "no",
+                self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_CONNECT ? "yes" : "no",
+                self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_SUBSCRIBER_INFO ? "yes" : "no",
+                self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_PACKET_SERVICE ? "yes" : "no",
+                self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_PCO ? "yes" : "no",
+                self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_USSD ? "yes" : "no",
+                self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_LTE_ATTACH_STATUS ? "yes" : "no",
+                self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_PROVISIONED_CONTEXTS ? "yes" : "no");
 
     if (setup) {
         /* Don't re-enable it if already there */
@@ -3664,17 +3693,17 @@
     if (!peek_device (self, &device, callback, user_data))
         return;
 
-    mm_dbg ("Enabled notifications: signal (%s), registration (%s), sms (%s), connect (%s), subscriber (%s), packet (%s), pco (%s), ussd (%s), lte attach status (%s), provisioned contexts (%s)",
-            self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_SIGNAL_QUALITY ? "yes" : "no",
-            self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_REGISTRATION_UPDATES ? "yes" : "no",
-            self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_SMS_READ ? "yes" : "no",
-            self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_CONNECT ? "yes" : "no",
-            self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_SUBSCRIBER_INFO ? "yes" : "no",
-            self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_PACKET_SERVICE ? "yes" : "no",
-            self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_PCO ? "yes" : "no",
-            self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_USSD ? "yes" : "no",
-            self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_LTE_ATTACH_STATUS ? "yes" : "no",
-            self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_PROVISIONED_CONTEXTS ? "yes" : "no");
+    mm_obj_dbg (self, "enabled notifications: signal (%s), registration (%s), sms (%s), connect (%s), subscriber (%s), packet (%s), pco (%s), ussd (%s), lte attach status (%s), provisioned contexts (%s)",
+                self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_SIGNAL_QUALITY ? "yes" : "no",
+                self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_REGISTRATION_UPDATES ? "yes" : "no",
+                self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_SMS_READ ? "yes" : "no",
+                self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_CONNECT ? "yes" : "no",
+                self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_SUBSCRIBER_INFO ? "yes" : "no",
+                self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_PACKET_SERVICE ? "yes" : "no",
+                self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_PCO ? "yes" : "no",
+                self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_USSD ? "yes" : "no",
+                self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_LTE_ATTACH_STATUS ? "yes" : "no",
+                self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_PROVISIONED_CONTEXTS ? "yes" : "no");
 
     entries = g_new0 (MbimEventEntry *, 5);
 
@@ -3814,7 +3843,7 @@
     GError *error = NULL;
 
     if (!common_enable_disable_unsolicited_events_finish (self, res, &error)) {
-        mm_dbg ("Failed to enable subscriber info events: %s", error->message);
+        mm_obj_dbg (self, "failed to enable subscriber info events: %s", error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -3832,7 +3861,7 @@
     GError *error = NULL;
 
     if (!common_setup_cleanup_unsolicited_events_finish (self, res, &error)) {
-        mm_dbg ("Failed to set up subscriber info events: %s", error->message);
+        mm_obj_dbg (self, "failed to set up subscriber info events: %s", error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -4085,9 +4114,10 @@
 
 static void
 modem_3gpp_run_registration_checks (MMIfaceModem3gpp    *self,
-                                    gboolean             cs_supported,
-                                    gboolean             ps_supported,
-                                    gboolean             eps_supported,
+                                    gboolean             is_cs_supported,
+                                    gboolean             is_ps_supported,
+                                    gboolean             is_eps_supported,
+                                    gboolean             is_5gs_supported,
                                     GAsyncReadyCallback  callback,
                                     gpointer             user_data)
 {
@@ -4286,7 +4316,7 @@
 
     task = g_task_new (self, NULL, callback, user_data);
 
-    mm_dbg ("scanning networks...");
+    mm_obj_dbg (self, "scanning networks...");
     message = mbim_message_visible_providers_query_new (MBIM_VISIBLE_PROVIDERS_ACTION_FULL_SCAN, NULL);
     mbim_device_command (device,
                          message,
@@ -4300,12 +4330,21 @@
 /*****************************************************************************/
 /* Load profiles (3GPP interface) */
 
-static GList *
+static gboolean
 modem_3gpp_load_profiles_finish (MMIfaceModem3gpp *self,
                                  GAsyncResult *res,
+                                 GList **out_list,
                                  GError **error)
 {
-    return g_task_propagate_pointer (G_TASK (res), error);
+    GTask *task;
+
+    task = G_TASK (res);
+    if (!g_task_propagate_boolean (task, error))
+        return FALSE;
+
+    if (out_list)
+        *out_list = mm_3gpp_profile_list_copy (g_task_get_task_data (task));
+    return TRUE;
 }
 
 static void
@@ -4332,7 +4371,8 @@
             n_provisioned_contexts);
         mbim_provisioned_context_element_array_free (provisioned_contexts);
 
-        g_task_return_pointer (task, profiles, (GDestroyNotify)mm_3gpp_profile_list_free);
+        g_task_set_task_data (task, profiles, (GDestroyNotify)mm_3gpp_profile_list_free);
+        g_task_return_boolean (task, TRUE);
     } else
         g_task_return_error (task, error);
 
@@ -4356,7 +4396,7 @@
 
     task = g_task_new (self, NULL, callback, user_data);
 
-    mm_dbg ("loading provisioned contexts...");
+    mm_obj_dbg (self, "loading provisioned contexts...");
     message = mbim_message_provisioned_contexts_query_new (NULL);
     mbim_device_command (device,
                          message,
@@ -4650,7 +4690,7 @@
              guint32      *scheme,
              GError      **error)
 {
-    GByteArray *array;
+    g_autoptr(GByteArray) array = NULL;
 
     if (mm_charset_can_convert_to (command, MM_MODEM_CHARSET_GSM)) {
         guint8  *gsm;
@@ -4670,12 +4710,13 @@
 
         array = g_byte_array_new_take (packed, packed_len);
     } else {
+        g_autoptr(GError) inner_error = NULL;
+
         *scheme = MM_MODEM_GSM_USSD_SCHEME_UCS2;
         array = g_byte_array_sized_new (strlen (command) * 2);
-        if (!mm_modem_charset_byte_array_append (array, command, FALSE, MM_MODEM_CHARSET_UCS2)) {
+        if (!mm_modem_charset_byte_array_append (array, command, FALSE, MM_MODEM_CHARSET_UCS2, &inner_error)) {
             g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED,
-                         "Failed to encode USSD command in UCS2 charset");
-            g_byte_array_unref (array);
+                         "Failed to encode USSD command in UCS2 charset: %s", inner_error->message);
             return NULL;
         }
     }
@@ -4683,11 +4724,10 @@
     if (array->len > 160) {
         g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS,
                      "Failed to encode USSD command: encoded data too long (%u > 160)", array->len);
-        g_byte_array_unref (array);
         return NULL;
     }
 
-    return array;
+    return g_steal_pointer (&array);
 }
 
 static gchar *
@@ -4818,7 +4858,7 @@
 
     /* If no pending task, just report the error */
     if (error) {
-        mm_dbg ("Network reported USSD message: %s", error->message);
+        mm_obj_dbg (self, "network reported USSD message: %s", error->message);
         g_error_free (error);
     }
 
@@ -4842,11 +4882,11 @@
                                               &data_size,
                                               &data,
                                               NULL)) {
-        mm_dbg ("Received USSD indication: %s, session state: %s, scheme: 0x%x, data size: %u bytes",
-                mbim_ussd_response_get_string (ussd_response),
-                mbim_ussd_session_state_get_string (ussd_session_state),
-                scheme,
-                data_size);
+        mm_obj_dbg (self, "received USSD indication: %s, session state: %s, scheme: 0x%x, data size: %u bytes",
+                    mbim_ussd_response_get_string (ussd_response),
+                    mbim_ussd_session_state_get_string (ussd_session_state),
+                    scheme,
+                    data_size);
         process_ussd_message (self, ussd_response, ussd_session_state, scheme, data_size, data);
     }
 }
@@ -4982,11 +5022,11 @@
                                           &data_size,
                                           &data,
                                           &error)) {
-        mm_dbg ("Received USSD response: %s, session state: %s, scheme: 0x%x, data size: %u bytes",
-                mbim_ussd_response_get_string (ussd_response),
-                mbim_ussd_session_state_get_string (ussd_session_state),
-                scheme,
-                data_size);
+        mm_obj_dbg (self, "received USSD response: %s, session state: %s, scheme: 0x%x, data size: %u bytes",
+                    mbim_ussd_response_get_string (ussd_response),
+                    mbim_ussd_session_state_get_string (ussd_session_state),
+                    scheme,
+                    data_size);
         process_ussd_message (self, ussd_response, ussd_session_state, scheme, data_size, data);
     } else {
         /* Report error in the cached task, if any */
@@ -4998,7 +5038,7 @@
             g_task_return_error (task, error);
             g_object_unref (task);
         } else {
-            mm_dbg ("Failed to parse USSD response: %s", error->message);
+            mm_obj_dbg (self, "failed to parse USSD response: %s", error->message);
             g_clear_error (&error);
         }
     }
@@ -5187,10 +5227,10 @@
     /* We only handle 3GPP messaging (PDU based) currently */
     if (self->priv->caps_sms & MBIM_SMS_CAPS_PDU_RECEIVE &&
         self->priv->caps_sms & MBIM_SMS_CAPS_PDU_SEND) {
-        mm_dbg ("Messaging capabilities supported");
+        mm_obj_dbg (self, "messaging capabilities supported");
         g_task_return_boolean (task, TRUE);
     } else {
-        mm_dbg ("Messaging capabilities not supported by this modem");
+        mm_obj_dbg (self, "messaging capabilities not supported by this modem");
         g_task_return_boolean (task, FALSE);
     }
     g_object_unref (task);
@@ -5250,18 +5290,19 @@
     part = mm_sms_part_3gpp_new_from_binary_pdu (pdu->message_index,
                                                  pdu->pdu_data,
                                                  pdu->pdu_data_size,
+                                                 self,
                                                  &error);
     if (part) {
-        mm_dbg ("Correctly parsed PDU (%d)", pdu->message_index);
+        mm_obj_dbg (self, "correctly parsed PDU (%d)", pdu->message_index);
         mm_iface_modem_messaging_take_part (MM_IFACE_MODEM_MESSAGING (self),
                                             part,
                                             mm_sms_state_from_mbim_message_status (pdu->message_status),
                                             MM_SMS_STORAGE_MT);
     } else {
         /* Don't treat the error as critical */
-        mm_dbg ("Error parsing PDU (%d): %s",
-                pdu->message_index,
-                error->message);
+        mm_obj_dbg (self, "error parsing PDU (%d): %s",
+                    pdu->message_index,
+                    error->message);
         g_error_free (error);
     }
 }
@@ -5321,7 +5362,7 @@
 
     task = g_task_new (self, NULL, callback, user_data);
 
-    mm_dbg ("loading SMS parts...");
+    mm_obj_dbg (self, "loading SMS parts...");
     message = mbim_message_sms_read_query_new (MBIM_SMS_FORMAT_PDU,
                                                MBIM_SMS_FLAG_ALL,
                                                0, /* message index, unused */
diff --git a/src/mm-broadband-modem-qmi.c b/src/mm-broadband-modem-qmi.c
index b6ffb7d..0d86a5c 100644
--- a/src/mm-broadband-modem-qmi.c
+++ b/src/mm-broadband-modem-qmi.c
@@ -93,6 +93,10 @@
     /* New devices may not support the legacy DMS UIM commands */
     gboolean dms_uim_deprecated;
 
+    /* Whether autoconnect disabling needs to be checked up during
+     * the device enabling */
+    gboolean autoconnect_checked;
+
     /* 3GPP/CDMA registration helpers */
     gchar *current_operator_id;
     gchar *current_operator_description;
@@ -122,6 +126,12 @@
     gboolean oma_unsolicited_events_setup;
     guint oma_event_report_indication_id;
 
+    /* 3GPP USSD helpers */
+    guint ussd_indication_id;
+    gboolean ussd_unsolicited_events_enabled;
+    gboolean ussd_unsolicited_events_setup;
+    GTask *pending_ussd_action;
+
     /* Firmware helpers */
     gboolean firmware_list_preloaded;
     GList *firmware_list;
@@ -241,7 +251,7 @@
                                       callback, user_data))
         return;
 
-    mm_dbg ("loading manufacturer...");
+    mm_obj_dbg (self, "loading manufacturer...");
     qmi_client_dms_get_manufacturer (QMI_CLIENT_DMS (client),
                                      NULL,
                                      5,
@@ -301,7 +311,7 @@
                                       callback, user_data))
         return;
 
-    mm_dbg ("loading model...");
+    mm_obj_dbg (self, "loading model...");
     qmi_client_dms_get_model (QMI_CLIENT_DMS (client),
                               NULL,
                               5,
@@ -361,7 +371,7 @@
                                       callback, user_data))
         return;
 
-    mm_dbg ("loading revision...");
+    mm_obj_dbg (self, "loading revision...");
     qmi_client_dms_get_revision (QMI_CLIENT_DMS (client),
                                  NULL,
                                  5,
@@ -421,7 +431,7 @@
                                       callback, user_data))
         return;
 
-    mm_dbg ("loading hardware revision...");
+    mm_obj_dbg (self, "loading hardware revision...");
     qmi_client_dms_get_hardware_revision (QMI_CLIENT_DMS (client),
                                           NULL,
                                           5,
@@ -492,7 +502,7 @@
         else if (len == 8)
             self->priv->esn = g_strdup (str);
         else
-            mm_dbg ("Invalid ESN reported: '%s' (unexpected length)", str);
+            mm_obj_dbg (self, "invalid ESN reported: '%s' (unexpected length)", str);
     }
 
     if (qmi_message_dms_get_ids_output_get_meid (output, &str, NULL) &&
@@ -502,7 +512,7 @@
         if (len == 14)
             self->priv->meid = g_strdup (str);
         else
-            mm_dbg ("Invalid MEID reported: '%s' (unexpected length)", str);
+            mm_obj_dbg (self, "invalid MEID reported: '%s' (unexpected length)", str);
     }
 
     if (self->priv->imei)
@@ -532,7 +542,7 @@
                                       callback, user_data))
         return;
 
-    mm_dbg ("loading equipment identifier...");
+    mm_obj_dbg (self, "loading equipment identifier...");
     qmi_client_dms_get_ids (QMI_CLIENT_DMS (client),
                             NULL,
                             5,
@@ -560,7 +570,7 @@
     gchar *device_identifier;
     GTask *task;
 
-    mm_dbg ("loading device identifier...");
+    mm_obj_dbg (self, "loading device identifier...");
 
     /* Just use dummy ATI/ATI1 replies, all the other internal info should be
      * enough for uniqueness */
@@ -625,7 +635,7 @@
                                       callback, user_data))
         return;
 
-    mm_dbg ("loading own numbers...");
+    mm_obj_dbg (self, "loading own numbers...");
     qmi_client_dms_get_msisdn (QMI_CLIENT_DMS (client),
                                NULL,
                                5,
@@ -671,7 +681,8 @@
 
 /* Used also when loading unlock retries left */
 static gboolean
-uim_get_card_status_output_parse (QmiMessageUimGetCardStatusOutput  *output,
+uim_get_card_status_output_parse (MMBroadbandModemQmi               *self,
+                                  QmiMessageUimGetCardStatusOutput  *output,
                                   MMModemLock                       *o_lock,
                                   guint                             *o_pin1_retries,
                                   guint                             *o_puk1_retries,
@@ -715,7 +726,7 @@
     }
 
     if (cards->len > 1)
-        mm_dbg ("Multiple cards reported: %u", cards->len);
+        mm_obj_dbg (self, "multiple cards reported: %u", cards->len);
 
     /* All KNOWN applications in all cards will need to be in READY state for us
      * to consider UNLOCKED */
@@ -728,24 +739,24 @@
             gboolean sim_usim_found = FALSE;
 
             if (card->applications->len == 0) {
-                mm_dbg ("No applications reported in card [%u]", i);
+                mm_obj_dbg (self, "no applications reported in card [%u]", i);
                 n_invalid++;
                 break;
             }
 
             if (card->applications->len > 1)
-                mm_dbg ("Multiple applications reported in card [%u]: %u", i, card->applications->len);
+                mm_obj_dbg (self, "multiple applications reported in card [%u]: %u", i, card->applications->len);
 
             for (j = 0; j < card->applications->len; j++) {
                 app = &g_array_index (card->applications, QmiMessageUimGetCardStatusOutputCardStatusCardsElementApplicationsElement, j);
 
                 if (app->type == QMI_UIM_CARD_APPLICATION_TYPE_UNKNOWN) {
-                    mm_dbg ("Unknown application [%u] found in card [%u]: %s. Ignored.",
+                    mm_obj_dbg (self, "mnknown application [%u] found in card [%u]: %s; ignored.",
                             j, i, qmi_uim_card_application_state_get_string (app->state));
                     continue;
                 }
 
-                mm_dbg ("Application '%s' [%u] in card [%u]: %s",
+                mm_obj_dbg (self, "application '%s' [%u] in card [%u]: %s",
                         qmi_uim_card_application_type_get_string (app->type), j, i, qmi_uim_card_application_state_get_string (app->state));
 
                 if (app->type == QMI_UIM_CARD_APPLICATION_TYPE_SIM || app->type == QMI_UIM_CARD_APPLICATION_TYPE_USIM) {
@@ -761,7 +772,7 @@
             }
 
             if (!sim_usim_found) {
-                mm_dbg ("No SIM/USIM application found in card [%u]", i);
+                mm_obj_dbg (self, "no SIM/USIM application found in card [%u]", i);
                 n_invalid++;
             }
 
@@ -769,7 +780,7 @@
         }
 
         case QMI_UIM_CARD_STATE_ABSENT:
-            mm_dbg ("Card '%u' is absent", i);
+            mm_obj_dbg (self, "card '%u' is absent", i);
             n_absent++;
             break;
 
@@ -777,9 +788,9 @@
         default:
             n_error++;
             if (qmi_uim_card_error_get_string (card->error_code) != NULL)
-                mm_warn ("Card '%u' is unusable: %s", i, qmi_uim_card_error_get_string (card->error_code));
+                mm_obj_warn (self, "card '%u' is unusable: %s", i, qmi_uim_card_error_get_string (card->error_code));
             else
-                mm_warn ("Card '%u' is unusable: unknown error", i);
+                mm_obj_warn (self, "card '%u' is unusable: unknown error", i);
             break;
         }
 
@@ -819,7 +830,7 @@
         app->state != QMI_UIM_CARD_APPLICATION_STATE_PIN1_OR_UPIN_PIN_REQUIRED &&
         app->state != QMI_UIM_CARD_APPLICATION_STATE_PUK1_OR_UPIN_PUK_REQUIRED &&
         app->state != QMI_UIM_CARD_APPLICATION_STATE_PIN1_BLOCKED) {
-        mm_dbg ("Neither SIM nor USIM are ready");
+        mm_obj_dbg (self, "neither SIM nor USIM are ready");
         g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_RETRY,
                      "SIM not ready yet (retry)");
         return FALSE;
@@ -883,7 +894,7 @@
     if (lock == MM_MODEM_LOCK_NONE) {
         switch (app->pin2_state) {
         case QMI_UIM_PIN_STATE_NOT_INITIALIZED:
-            mm_warn ("SIM PIN2/PUK2 status not known yet");
+            mm_obj_warn (self, "SIM PIN2/PUK2 status not known yet");
             break;
 
         case QMI_UIM_PIN_STATE_ENABLED_NOT_VERIFIED:
@@ -891,7 +902,7 @@
             break;
 
         case QMI_UIM_PIN_STATE_PERMANENTLY_BLOCKED:
-            mm_warn ("PUK2 permanently blocked");
+            mm_obj_warn (self, "PUK2 permanently blocked");
             /* Fall through */
         case QMI_UIM_PIN_STATE_BLOCKED:
             lock = MM_MODEM_LOCK_SIM_PUK2;
@@ -902,7 +913,7 @@
             break;
 
         default:
-            mm_warn ("Unknown SIM PIN2/PUK2 status");
+            mm_obj_warn (self, "unknown SIM PIN2/PUK2 status");
             break;
         }
     }
@@ -916,11 +927,13 @@
                                            GAsyncResult *res,
                                            GTask *task)
 {
+    MMBroadbandModemQmi *self;
     LoadUnlockRequiredContext *ctx;
     QmiMessageUimGetCardStatusOutput *output;
     GError *error = NULL;
     MMModemLock lock = MM_MODEM_LOCK_UNKNOWN;
 
+    self = g_task_get_source_object (task);
     ctx = g_task_get_task_data (task);
 
     output = qmi_client_uim_get_card_status_finish (client, res, &error);
@@ -931,7 +944,8 @@
         return;
     }
 
-    if (!uim_get_card_status_output_parse (output,
+    if (!uim_get_card_status_output_parse (self,
+                                           output,
                                            &lock,
                                            NULL, NULL, NULL, NULL,
                                            &error)) {
@@ -1069,7 +1083,7 @@
     case LOAD_UNLOCK_REQUIRED_STEP_CDMA:
         /* CDMA-only modems don't need this */
         if (mm_iface_modem_is_cdma_only (MM_IFACE_MODEM (self))) {
-            mm_dbg ("Skipping unlock check in CDMA-only modem...");
+            mm_obj_dbg (self, "skipping unlock check in CDMA-only modem...");
             g_task_return_int (task, MM_MODEM_LOCK_NONE);
             g_object_unref (task);
             return;
@@ -1090,7 +1104,7 @@
                 return;
             }
 
-            mm_dbg ("loading unlock required (DMS)...");
+            mm_obj_dbg (self, "loading unlock required (DMS)...");
             qmi_client_dms_uim_get_pin_status (QMI_CLIENT_DMS (client),
                                                NULL,
                                                5,
@@ -1114,7 +1128,7 @@
             return;
         }
 
-        mm_dbg ("loading unlock required (UIM)...");
+        mm_obj_dbg (self, "loading unlock required (UIM)...");
         qmi_client_uim_get_card_status (QMI_CLIENT_UIM (client),
                                         NULL,
                                         5,
@@ -1163,6 +1177,7 @@
                                           GAsyncResult *res,
                                           GTask        *task)
 {
+    MMBroadbandModemQmi *self;
     QmiMessageUimGetCardStatusOutput *output;
     GError *error = NULL;
     guint pin1_retries = 0;
@@ -1171,6 +1186,8 @@
     guint puk2_retries = 0;
     MMUnlockRetries *retries;
 
+    self = g_task_get_source_object (task);
+
     output = qmi_client_uim_get_card_status_finish (client, res, &error);
     if (!output) {
         g_prefix_error (&error, "QMI operation failed: ");
@@ -1179,7 +1196,8 @@
         return;
     }
 
-    if (!uim_get_card_status_output_parse (output,
+    if (!uim_get_card_status_output_parse (self,
+                                           output,
                                            NULL,
                                            &pin1_retries, &puk1_retries,
                                            &pin2_retries, &puk2_retries,
@@ -1330,7 +1348,7 @@
     self = MM_BROADBAND_MODEM_QMI (_self);
     task = g_task_new (self, NULL, callback, user_data);
 
-    mm_dbg ("loading unlock retries...");
+    mm_obj_dbg (self, "loading unlock retries...");
     if (!self->priv->dms_uim_deprecated)
         dms_uim_load_unlock_retries (MM_BROADBAND_MODEM_QMI (self), task);
     else
@@ -1447,7 +1465,7 @@
      * order to report always the one with the maximum value. */
 
     if (cdma1x_rssi < 0) {
-        mm_dbg ("RSSI (CDMA): %d dBm", cdma1x_rssi);
+        mm_obj_dbg (self, "RSSI (CDMA): %d dBm", cdma1x_rssi);
         if (qmi_dbm_valid (cdma1x_rssi, QMI_NAS_RADIO_INTERFACE_CDMA_1X)) {
             rssi_max = MAX (cdma1x_rssi, rssi_max);
             signal_info_radio_interface = QMI_NAS_RADIO_INTERFACE_CDMA_1X;
@@ -1455,7 +1473,7 @@
     }
 
     if (evdo_rssi < 0) {
-        mm_dbg ("RSSI (HDR): %d dBm", evdo_rssi);
+        mm_obj_dbg (self, "RSSI (HDR): %d dBm", evdo_rssi);
         if (qmi_dbm_valid (evdo_rssi, QMI_NAS_RADIO_INTERFACE_CDMA_1XEVDO)) {
             rssi_max = MAX (evdo_rssi, rssi_max);
             signal_info_radio_interface = QMI_NAS_RADIO_INTERFACE_CDMA_1XEVDO;
@@ -1463,7 +1481,7 @@
     }
 
     if (gsm_rssi < 0) {
-        mm_dbg ("RSSI (GSM): %d dBm", gsm_rssi);
+        mm_obj_dbg (self, "RSSI (GSM): %d dBm", gsm_rssi);
         if (qmi_dbm_valid (gsm_rssi, QMI_NAS_RADIO_INTERFACE_GSM)) {
             rssi_max = MAX (gsm_rssi, rssi_max);
             signal_info_radio_interface = QMI_NAS_RADIO_INTERFACE_GSM;
@@ -1471,7 +1489,7 @@
     }
 
     if (wcdma_rssi < 0) {
-        mm_dbg ("RSSI (WCDMA): %d dBm", wcdma_rssi);
+        mm_obj_dbg (self, "RSSI (WCDMA): %d dBm", wcdma_rssi);
         if (qmi_dbm_valid (wcdma_rssi, QMI_NAS_RADIO_INTERFACE_UMTS)) {
             rssi_max = MAX (wcdma_rssi, rssi_max);
             signal_info_radio_interface = QMI_NAS_RADIO_INTERFACE_UMTS;
@@ -1479,7 +1497,7 @@
     }
 
     if (lte_rssi < 0) {
-        mm_dbg ("RSSI (LTE): %d dBm", lte_rssi);
+        mm_obj_dbg (self, "RSSI (LTE): %d dBm", lte_rssi);
         if (qmi_dbm_valid (lte_rssi, QMI_NAS_RADIO_INTERFACE_LTE)) {
             rssi_max = MAX (lte_rssi, rssi_max);
             signal_info_radio_interface = QMI_NAS_RADIO_INTERFACE_LTE;
@@ -1491,7 +1509,7 @@
         *out_quality = STRENGTH_TO_QUALITY (rssi_max);
         *out_act = mm_modem_access_technology_from_qmi_radio_interface (signal_info_radio_interface);
 
-        mm_dbg ("RSSI: %d dBm --> %u%%", rssi_max, *out_quality);
+        mm_obj_dbg (self, "RSSI: %d dBm --> %u%%", rssi_max, *out_quality);
         return TRUE;
     }
 
@@ -1587,9 +1605,9 @@
 
     /* The mandatory one is always present */
     qmi_message_nas_get_signal_strength_output_get_signal_strength (output, &signal_max, &main_interface, NULL);
-    mm_dbg ("Signal strength (%s): %d dBm",
-            qmi_nas_radio_interface_get_string (main_interface),
-            signal_max);
+    mm_obj_dbg (self, "signal strength (%s): %d dBm",
+                qmi_nas_radio_interface_get_string (main_interface),
+                signal_max);
 
     /* Treat results as invalid if main signal strength is invalid */
     if (!qmi_dbm_valid (signal_max, main_interface))
@@ -1606,9 +1624,9 @@
 
             element = &g_array_index (array, QmiMessageNasGetSignalStrengthOutputStrengthListElement, i);
 
-            mm_dbg ("Signal strength (%s): %d dBm",
-                    qmi_nas_radio_interface_get_string (element->radio_interface),
-                    element->strength);
+            mm_obj_dbg (self, "signal strength (%s): %d dBm",
+                        qmi_nas_radio_interface_get_string (element->radio_interface),
+                        element->strength);
 
             if (qmi_dbm_valid (element->strength, element->radio_interface)) {
                 signal_max = MAX (element->strength, signal_max);
@@ -1622,7 +1640,7 @@
         *o_quality = STRENGTH_TO_QUALITY (signal_max);
         *o_act = act;
 
-        mm_dbg ("Signal strength: %d dBm --> %u%%", signal_max, *o_quality);
+        mm_obj_dbg (self, "signal strength: %d dBm --> %u%%", signal_max, *o_quality);
     }
 
     return (signal_max < 0);
@@ -1693,7 +1711,7 @@
 
     task = g_task_new (self, NULL, callback, user_data);
 
-    mm_dbg ("loading signal quality...");
+    mm_obj_dbg (self, "loading signal quality...");
 
 #if defined WITH_NEWEST_QMI_COMMANDS
     /* Signal info introduced in NAS 1.8 */
@@ -1755,16 +1773,18 @@
                                   GAsyncResult *res,
                                   GTask *task)
 {
+    MMBroadbandModemQmi *self;
     SetOperatingModeContext *ctx;
     QmiMessageDmsSetFccAuthenticationOutput *output = NULL;
     GError *error = NULL;
 
+    self = g_task_get_source_object (task);
     ctx = g_task_get_task_data (task);
 
     output = qmi_client_dms_set_fcc_authentication_finish (client, res, &error);
     if (!output || !qmi_message_dms_set_fcc_authentication_output_get_result (output, &error)) {
         /* No hard errors */
-        mm_dbg ("Couldn't set FCC authentication: %s", error->message);
+        mm_obj_dbg (self, "couldn't set FCC authentication: %s", error->message);
         g_error_free (error);
     }
 
@@ -1781,17 +1801,19 @@
                               GAsyncResult *res,
                               GTask *task)
 {
+    MMBroadbandModemQmi *self;
     SetOperatingModeContext *ctx;
     QmiMessageDmsSetOperatingModeOutput *output = NULL;
     GError *error = NULL;
 
+    self = g_task_get_source_object (task);
     ctx = g_task_get_task_data (task);
 
     output = qmi_client_dms_set_operating_mode_finish (client, res, &error);
     if (!output) {
         /* If unsupported, just go out without errors */
         if (g_error_matches (error, QMI_CORE_ERROR, QMI_CORE_ERROR_UNSUPPORTED)) {
-            mm_dbg ("Device doesn't support operating mode setting. Ignoring power update.");
+            mm_obj_dbg (self, "device doesn't support operating mode setting; ignoring power update.");
             g_error_free (error);
             ctx->step = SET_OPERATING_MODE_STEP_LAST;
             set_operating_mode_context_step (task);
@@ -1847,13 +1869,15 @@
 static void
 set_operating_mode_context_step (GTask *task)
 {
+    MMBroadbandModemQmi     *self;
     SetOperatingModeContext *ctx;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     switch (ctx->step) {
     case SET_OPERATING_MODE_STEP_FIRST:
-        mm_dbg ("Setting device operating mode...");
+        mm_obj_dbg (self, "setting device operating mode...");
         qmi_client_dms_set_operating_mode (QMI_CLIENT_DMS (ctx->client),
                                            ctx->input,
                                            20,
@@ -1862,7 +1886,7 @@
                                            task);
         return;
     case SET_OPERATING_MODE_STEP_FCC_AUTH:
-        mm_dbg ("Setting FCC auth...");
+        mm_obj_dbg (self, "setting FCC auth...");
         qmi_client_dms_set_fcc_authentication (QMI_CLIENT_DMS (ctx->client),
                                                NULL,
                                                5,
@@ -1871,7 +1895,7 @@
                                                task);
         return;
     case SET_OPERATING_MODE_STEP_RETRY:
-        mm_dbg ("Setting device operating mode (retry)...");
+        mm_obj_dbg (self, "setting device operating mode (retry)...");
         qmi_client_dms_set_operating_mode (QMI_CLIENT_DMS (ctx->client),
                                            ctx->input,
                                            20,
@@ -2036,7 +2060,7 @@
                                       callback, user_data))
         return;
 
-    mm_dbg ("Getting device operating mode...");
+    mm_obj_dbg (self, "getting device operating mode...");
     qmi_client_dms_get_operating_mode (QMI_CLIENT_DMS (client),
                                        NULL,
                                        5,
@@ -2140,16 +2164,18 @@
                                           GAsyncResult *res,
                                           GTask *task)
 {
+    MMBroadbandModemQmi *self;
     LoadEnabledFacilityLocksContext *ctx;
     QmiMessageDmsUimGetPinStatusOutput *output;
     gboolean enabled;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     output = qmi_client_dms_uim_get_pin_status_finish (client, res, NULL);
     if (!output ||
         !qmi_message_dms_uim_get_pin_status_output_get_result (output, NULL)) {
-        mm_dbg ("Couldn't query PIN status, assuming SIM PIN is disabled");
+        mm_obj_dbg (self, "couldn't query PIN status, assuming SIM PIN is disabled");
         enabled = FALSE;
     } else {
         QmiDmsUimPinStatus current_status;
@@ -2161,9 +2187,9 @@
             NULL, /* unblock_retries_left */
             NULL)) {
             enabled = mm_pin_enabled_from_qmi_uim_pin_status (current_status);
-            mm_dbg ("PIN is reported %s", (enabled ? "enabled" : "disabled"));
+            mm_obj_dbg (self, "PIN is reported %s", (enabled ? "enabled" : "disabled"));
         } else {
-            mm_dbg ("Couldn't find PIN1 status in the result, assuming SIM PIN is disabled");
+            mm_obj_dbg (self, "couldn't find PIN1 status in the result, assuming SIM PIN is disabled");
             enabled = FALSE;
         }
     }
@@ -2187,11 +2213,13 @@
 static void
 get_sim_lock_status_via_pin_status (GTask *task)
 {
+    MMBroadbandModemQmi             *self;
     LoadEnabledFacilityLocksContext *ctx;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
-    mm_dbg ("Retrieving PIN status to check for enabled PIN");
+    mm_obj_dbg (self, "retrieving PIN status to check for enabled PIN");
     /* if the SIM is locked or not can only be queried by locking at
      * the PIN status */
     qmi_client_dms_uim_get_pin_status (QMI_CLIENT_DMS (ctx->client),
@@ -2207,17 +2235,20 @@
                              GAsyncResult *res,
                              GTask *task)
 {
+    MMBroadbandModemQmi *self;
     LoadEnabledFacilityLocksContext *ctx;
     gchar *facility_str;
     QmiMessageDmsUimGetCkStatusOutput *output;
 
+    self = g_task_get_source_object (task);
     ctx = g_task_get_task_data (task);
+
     facility_str = mm_modem_3gpp_facility_build_string_from_mask (1 << ctx->current);
     output = qmi_client_dms_uim_get_ck_status_finish (client, res, NULL);
     if (!output ||
         !qmi_message_dms_uim_get_ck_status_output_get_result (output, NULL)) {
         /* On errors, we'll just assume disabled */
-        mm_dbg ("Couldn't query facility '%s' status, assuming disabled", facility_str);
+        mm_obj_dbg (self, "couldn't query facility '%s' status, assuming disabled", facility_str);
         ctx->locks &= ~(1 << ctx->current);
     } else {
         QmiDmsUimFacilityState state;
@@ -2231,7 +2262,7 @@
             &unblock_retries_left,
             NULL);
 
-        mm_dbg ("Facility '%s' is: '%s'",
+        mm_obj_dbg (self, "facility '%s' is: '%s'",
                 facility_str,
                 qmi_dms_uim_facility_state_get_string (state));
 
@@ -2471,7 +2502,7 @@
                                       callback, user_data))
         return;
 
-    mm_dbg ("Scanning networks...");
+    mm_obj_dbg (self, "scanning networks...");
     qmi_client_nas_network_scan (QMI_CLIENT_NAS (client),
                                  NULL,
                                  300,
@@ -2565,12 +2596,21 @@
     g_slice_free (GetProfileListContext, ctx);
 }
 
-static GList *
+static gboolean
 modem_3gpp_load_profiles_finish (MMIfaceModem3gpp *self,
                                  GAsyncResult *res,
+                                 GList **out_list,
                                  GError **error)
 {
-    return g_task_propagate_pointer (G_TASK (res), error);
+    GTask *task;
+
+    task = G_TASK (res);
+    if (!g_task_propagate_boolean (task, error))
+        return FALSE;
+
+    if (out_list)
+        *out_list = mm_3gpp_profile_list_copy (g_task_get_task_data (task));
+    return TRUE;
 }
 
 static void get_next_profile_settings (GTask *task);
@@ -2633,9 +2673,10 @@
     ctx = g_task_get_task_data (task);
 
     if (ctx->i == ctx->profile_ids->len) {
-        g_task_return_pointer (task,
-                               mm_3gpp_profile_list_from_qmi_profile_settings (ctx->profiles),
-                               (GDestroyNotify) mm_3gpp_profile_list_free);
+        g_task_set_task_data (task,
+                              mm_3gpp_profile_list_from_qmi_profile_settings (ctx->profiles),
+                              (GDestroyNotify) mm_3gpp_profile_list_free);
+        g_task_return_boolean (task, TRUE);
         g_object_unref (task);
         return;
     }
@@ -2786,6 +2827,7 @@
     MMModemAccessTechnology mm_access_technologies;
     MMModem3gppRegistrationState mm_cs_registration_state;
     MMModem3gppRegistrationState mm_ps_registration_state;
+    gboolean operator_updated = FALSE;
 
     if (response_output)
         qmi_message_nas_get_serving_system_output_get_serving_system (
@@ -2822,15 +2864,17 @@
 
     /* Only process 3GPP info.
      * Seen the case already where 'selected_network' gives UNKNOWN but we still
-     * have valid LTE info around. */
+     * have valid LTE/5GNR info around. */
     if (selected_network == QMI_NAS_NETWORK_TYPE_3GPP ||
         (selected_network == QMI_NAS_NETWORK_TYPE_UNKNOWN &&
          (mm_access_technologies & MM_IFACE_MODEM_3GPP_ALL_ACCESS_TECHNOLOGIES_MASK))) {
-        mm_dbg ("Processing 3GPP info...");
+        mm_obj_dbg (self, "processing 3GPP info...");
     } else {
         MMModem3gppRegistrationState reg_state_3gpp;
 
-        mm_dbg ("No 3GPP info given...");
+        mm_obj_dbg (self, "no 3GPP info given...");
+        if (self->priv->current_operator_id || self->priv->current_operator_description)
+            operator_updated = TRUE;
         g_free (self->priv->current_operator_id);
         self->priv->current_operator_id = NULL;
         g_free (self->priv->current_operator_description);
@@ -2845,6 +2889,10 @@
         mm_iface_modem_3gpp_update_ps_registration_state (MM_IFACE_MODEM_3GPP (self), reg_state_3gpp);
         mm_iface_modem_3gpp_update_access_technologies (MM_IFACE_MODEM_3GPP (self), MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
         mm_iface_modem_3gpp_update_location (MM_IFACE_MODEM_3GPP (self), 0, 0, 0);
+        /* request to reload operator info explicitly, so that the new
+         * operator name and code is propagated to the DBus interface */
+        if (operator_updated)
+            mm_iface_modem_3gpp_reload_current_registration_info (MM_IFACE_MODEM_3GPP (self), NULL, NULL);
         return;
     }
 
@@ -2884,23 +2932,26 @@
              &mnc,
              &description,
              NULL))) {
-        /* When we don't have information about leading PCS digit, guess best */
-        g_free (self->priv->current_operator_id);
-        if (mnc >= 100)
-            self->priv->current_operator_id =
-                g_strdup_printf ("%.3" G_GUINT16_FORMAT "%.3" G_GUINT16_FORMAT,
-                                 mcc,
-                                 mnc);
-        else
-            self->priv->current_operator_id =
-                g_strdup_printf ("%.3" G_GUINT16_FORMAT "%.2" G_GUINT16_FORMAT,
-                                 mcc,
-                                 mnc);
+        gchar *new_operator_id;
 
-        g_clear_pointer (&self->priv->current_operator_description, g_free);
-        /* Some Telit modems apparently sometimes report non-UTF8 characters */
-        if (g_utf8_validate (description, -1, NULL))
+        /* When we don't have information about leading PCS digit, guess best */
+        if (mnc >= 100)
+            new_operator_id = g_strdup_printf ("%.3" G_GUINT16_FORMAT "%.3" G_GUINT16_FORMAT, mcc, mnc);
+        else
+            new_operator_id = g_strdup_printf ("%.3" G_GUINT16_FORMAT "%.2" G_GUINT16_FORMAT, mcc, mnc);
+
+        if (!self->priv->current_operator_id || !g_str_equal (self->priv->current_operator_id, new_operator_id)) {
+            operator_updated = TRUE;
+            g_free (self->priv->current_operator_id);
+            self->priv->current_operator_id = new_operator_id;
+        } else
+            g_free (new_operator_id);
+
+        if (!self->priv->current_operator_description || !g_str_equal (self->priv->current_operator_description, description)) {
+            operator_updated = TRUE;
+            g_free (self->priv->current_operator_description);
             self->priv->current_operator_description = g_strdup (description);
+        }
     }
 
     /* If MNC comes with PCS digit, we must make sure the additional
@@ -2920,11 +2971,15 @@
               &has_pcs_digit,
               NULL))) &&
         has_pcs_digit) {
-        g_free (self->priv->current_operator_id);
-        self->priv->current_operator_id =
-            g_strdup_printf ("%.3" G_GUINT16_FORMAT "%.3" G_GUINT16_FORMAT,
-                             mcc,
-                             mnc);
+        gchar *new_operator_id;
+
+        new_operator_id = g_strdup_printf ("%.3" G_GUINT16_FORMAT "%.3" G_GUINT16_FORMAT, mcc, mnc);
+        if (!self->priv->current_operator_id || !g_str_equal (self->priv->current_operator_id, new_operator_id)) {
+            operator_updated = TRUE;
+            g_free (self->priv->current_operator_id);
+            self->priv->current_operator_id = new_operator_id;
+        } else
+            g_free (new_operator_id);
     }
 
     /* Report new registration states */
@@ -2950,6 +3005,11 @@
     if (cid && (lac || tac))
         mm_iface_modem_3gpp_update_location (MM_IFACE_MODEM_3GPP (self), lac, tac, cid);
 
+    /* request to reload operator info explicitly, so that the new
+     * operator name and code is propagated to the DBus interface */
+    if (operator_updated)
+        mm_iface_modem_3gpp_reload_current_registration_info (MM_IFACE_MODEM_3GPP (self), NULL, NULL);
+
     /* Note: don't update access technologies with the ones retrieved here; they
      * are not really the 'current' access technologies */
 }
@@ -3132,7 +3192,7 @@
                 NULL, NULL, /* egprs support */
                 NULL, NULL, /* dtm_support */
                 NULL)) {
-            mm_dbg ("No GSM service reported");
+            mm_obj_dbg (self, "no GSM service reported");
             /* No GSM service */
             return FALSE;
         }
@@ -3156,7 +3216,7 @@
                 NULL, NULL, /* egprs support */
                 NULL, NULL, /* dtm_support */
                 NULL)) {
-            mm_dbg ("No GSM service reported");
+            mm_obj_dbg (self, "no GSM service reported");
             /* No GSM service */
             return FALSE;
         }
@@ -3176,7 +3236,7 @@
                               NULL,
                               mm_cid,
                               mm_operator_id)) {
-        mm_dbg ("No GSM service registered");
+        mm_obj_dbg (self, "no GSM service registered");
         return FALSE;
     }
 
@@ -3240,7 +3300,7 @@
                 &hs_service_valid,     &hs_service,
                 NULL, NULL, /* primary_scrambling_code */
                 NULL)) {
-            mm_dbg ("No WCDMA service reported");
+            mm_obj_dbg (self, "no WCDMA service reported");
             /* No GSM service */
             return FALSE;
         }
@@ -3265,7 +3325,7 @@
                 &hs_service_valid,     &hs_service,
                 NULL, NULL, /* primary_scrambling_code */
                 NULL)) {
-            mm_dbg ("No WCDMA service reported");
+            mm_obj_dbg (self, "no WCDMA service reported");
             /* No GSM service */
             return FALSE;
         }
@@ -3285,7 +3345,7 @@
                               NULL,
                               mm_cid,
                               mm_operator_id)) {
-        mm_dbg ("No WCDMA service registered");
+        mm_obj_dbg (self, "no WCDMA service registered");
         return FALSE;
     }
 
@@ -3349,7 +3409,7 @@
                 &network_id_valid,     &mcc, &mnc,
                 &tac_valid,            &tac,
                 NULL)) {
-            mm_dbg ("No LTE service reported");
+            mm_obj_dbg (self, "no LTE service reported");
             /* No GSM service */
             return FALSE;
         }
@@ -3372,7 +3432,7 @@
                 &network_id_valid,     &mcc, &mnc,
                 &tac_valid,            &tac,
                 NULL)) {
-            mm_dbg ("No LTE service reported");
+            mm_obj_dbg (self, "no LTE service reported");
             /* No GSM service */
             return FALSE;
         }
@@ -3392,7 +3452,7 @@
                               mm_tac,
                               mm_cid,
                               mm_operator_id)) {
-        mm_dbg ("No LTE service registered");
+        mm_obj_dbg (self, "no LTE service registered");
         return FALSE;
     }
 
@@ -3443,7 +3503,7 @@
                            &lac,
                            &cid,
                            &operator_id)) {
-        mm_dbg ("No service (GSM, WCDMA or LTE) reported");
+        mm_obj_dbg (self, "no service (GSM, WCDMA or LTE) reported");
     }
 
     /* Cache current operator ID */
@@ -3497,12 +3557,13 @@
 #endif /* WITH_NEWEST_QMI_COMMANDS */
 
 static void
-modem_3gpp_run_registration_checks (MMIfaceModem3gpp *self,
-                                    gboolean cs_supported,
-                                    gboolean ps_supported,
-                                    gboolean eps_supported,
-                                    GAsyncReadyCallback callback,
-                                    gpointer user_data)
+modem_3gpp_run_registration_checks (MMIfaceModem3gpp    *self,
+                                    gboolean             is_cs_supported,
+                                    gboolean             is_ps_supported,
+                                    gboolean             is_eps_supported,
+                                    gboolean             is_5gs_supported,
+                                    GAsyncReadyCallback  callback,
+                                    gpointer             user_data)
 {
     GTask *task;
     QmiClient *client = NULL;
@@ -3593,10 +3654,10 @@
 
     output = qmi_client_nas_register_indications_finish (client, res, &error);
     if (!output) {
-        mm_dbg ("QMI operation failed: '%s'", error->message);
+        mm_obj_dbg (self, "QMI operation failed: '%s'", error->message);
         g_error_free (error);
     } else if (!qmi_message_nas_register_indications_output_get_result (output, &error)) {
-        mm_dbg ("Couldn't register indications: '%s'", error->message);
+        mm_obj_dbg (self, "couldn't register indications: '%s'", error->message);
         g_error_free (error);
     }
 
@@ -3727,7 +3788,7 @@
     }
 
     /* Devices with NAS < 1.2 will just always issue serving system indications */
-    mm_dbg ("Assuming serving system indications are always enabled");
+    mm_obj_dbg (self, "assuming serving system indications are always enabled");
     self->priv->unsolicited_registration_events_enabled = TRUE;
     g_task_return_boolean (task, TRUE);
     g_object_unref (task);
@@ -3802,9 +3863,9 @@
     if (selected_network == QMI_NAS_NETWORK_TYPE_3GPP2 ||
         (selected_network == QMI_NAS_NETWORK_TYPE_UNKNOWN &&
          (mm_access_technologies & MM_IFACE_MODEM_CDMA_ALL_ACCESS_TECHNOLOGIES_MASK))) {
-        mm_dbg ("Processing CDMA info...");
+        mm_obj_dbg (self, "processing CDMA info...");
     } else {
-        mm_dbg ("No CDMA info given...");
+        mm_obj_dbg (self, "no CDMA info given...");
         mm_iface_modem_cdma_update_cdma1x_registration_state (MM_IFACE_MODEM_CDMA (self),
                                                               MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN,
                                                               0, 0);
@@ -4173,13 +4234,15 @@
                                   GAsyncResult *res,
                                   GTask *task)
 {
+    MMBroadbandModemQmi *self;
     CdmaActivationContext *ctx;
     QmiMessageDmsGetMsisdnOutput *output = NULL;
     GError *error = NULL;
     const gchar *current_mdn = NULL;
     const gchar *expected_mdn = NULL;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     qmi_message_dms_activate_manual_input_get_info (ctx->input_manual,
                                                     NULL, /* spc */
@@ -4193,7 +4256,7 @@
         qmi_message_dms_get_msisdn_output_get_result (output, NULL) &&
         qmi_message_dms_get_msisdn_output_get_msisdn (output, &current_mdn, NULL) &&
         g_str_equal (current_mdn, expected_mdn)) {
-        mm_dbg ("MDN successfully updated to '%s'", expected_mdn);
+        mm_obj_dbg (self, "MDN successfully updated to '%s'", expected_mdn);
         qmi_message_dms_get_msisdn_output_unref (output);
         /* And go on to next step */
         ctx->step++;
@@ -4206,7 +4269,7 @@
 
     if (ctx->n_mdn_check_retries < MAX_MDN_CHECK_RETRIES) {
         /* Retry after some time */
-        mm_dbg ("MDN not yet updated, retrying...");
+        mm_obj_dbg (self, "MDN not yet updated, retrying...");
         g_timeout_add (1, (GSourceFunc) retry_msisdn_check_cb, task);
         return;
     }
@@ -4232,15 +4295,15 @@
     if (!qmi_indication_dms_event_report_output_get_activation_state (output, &state, NULL))
         return;
 
-    mm_dbg ("Activation state update: '%s'",
+    mm_obj_dbg (self, "activation state update: '%s'",
             qmi_dms_activation_state_get_string (state));
 
     new = mm_modem_cdma_activation_state_from_qmi_activation_state (state);
 
     if (self->priv->activation_state != new)
-        mm_info ("Activation state changed: '%s'-->'%s'",
-                 mm_modem_cdma_activation_state_get_string (self->priv->activation_state),
-                 mm_modem_cdma_activation_state_get_string (new));
+        mm_obj_info (self, "activation state changed: '%s'-->'%s'",
+                     mm_modem_cdma_activation_state_get_string (self->priv->activation_state),
+                     mm_modem_cdma_activation_state_get_string (new));
 
     /* Cache the new value */
     self->priv->activation_state = new;
@@ -4280,7 +4343,7 @@
         return;
     }
 
-    mm_dbg ("Activation process still ongoing...");
+    mm_obj_dbg (self, "activation process still ongoing...");
 }
 
 static void
@@ -4425,8 +4488,7 @@
         if (ctx->input_automatic) {
             QmiMessageDmsSetEventReportInput *input;
 
-            mm_info ("Activation step [1/5]: enabling indications");
-
+            mm_obj_info (ctx->self, "activation step [1/5]: enabling indications");
             input = qmi_message_dms_set_event_report_input_new ();
             qmi_message_dms_set_event_report_input_set_activation_state_reporting (input, TRUE, NULL);
             qmi_client_dms_set_event_report (
@@ -4442,15 +4504,14 @@
 
         /* Manual activation, no indications needed */
         g_assert (ctx->input_manual != NULL);
-        mm_info ("Activation step [1/5]: indications not needed in manual activation");
+        mm_obj_info (ctx->self, "activation step [1/5]: indications not needed in manual activation");
         ctx->step++;
         /* Fall through */
 
     case CDMA_ACTIVATION_STEP_REQUEST_ACTIVATION:
         /* Automatic activation */
         if (ctx->input_automatic) {
-            mm_info ("Activation step [2/5]: requesting automatic (OTA) activation");
-
+            mm_obj_info (ctx->self, "activation step [2/5]: requesting automatic (OTA) activation");
             qmi_client_dms_activate_automatic (ctx->client,
                                                ctx->input_automatic,
                                                10,
@@ -4463,10 +4524,10 @@
         /* Manual activation */
         g_assert (ctx->input_manual != NULL);
         if (!ctx->segments)
-            mm_info ("Activation step [2/5]: requesting manual activation");
+            mm_obj_info (ctx->self, "activation step [2/5]: requesting manual activation");
         else {
-            mm_info ("Activation step [2/5]: requesting manual activation (PRL segment %u/%u)",
-                     (ctx->segment_i + 1), ctx->n_segments);
+            mm_obj_info (ctx->self, "activation step [2/5]: requesting manual activation (PRL segment %u/%u)",
+                         (ctx->segment_i + 1), ctx->n_segments);
             qmi_message_dms_activate_manual_input_set_prl (
                 ctx->input_manual,
                 (guint16)ctx->total_segments_size,
@@ -4487,14 +4548,14 @@
         /* Automatic activation */
         if (ctx->input_automatic) {
             /* State updates via unsolicited messages */
-            mm_info ("Activation step [3/5]: waiting for activation state updates");
+            mm_obj_info (ctx->self, "activation step [3/5]: waiting for activation state updates");
             return;
         }
 
         /* Manual activation; needs MSISDN checks */
         g_assert (ctx->input_manual != NULL);
         ctx->n_mdn_check_retries++;
-        mm_info ("Activation step [3/5]: checking MDN update (retry %u)", ctx->n_mdn_check_retries);
+        mm_obj_info (ctx->self, "activation step [3/5]: checking MDN update (retry %u)", ctx->n_mdn_check_retries);
         qmi_client_dms_get_msisdn (ctx->client,
                                    NULL,
                                    5,
@@ -4504,14 +4565,14 @@
         return;
 
     case CDMA_ACTIVATION_STEP_RESET:
-        mm_info ("Activation step [4/5]: power-cycling...");
+        mm_obj_info (ctx->self, "activation step [4/5]: power-cycling...");
         mm_shared_qmi_reset (MM_IFACE_MODEM (ctx->self),
                              (GAsyncReadyCallback)activation_reset_ready,
                              task);
         return;
 
     case CDMA_ACTIVATION_STEP_LAST:
-        mm_info ("Activation step [5/5]: finished");
+        mm_obj_info (ctx->self, "activation step [5/5]: finished");
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
         return;
@@ -4725,7 +4786,7 @@
     task = g_task_new (self, NULL, callback, user_data);
 
     if (enable == self->priv->unsolicited_registration_events_setup) {
-        mm_dbg ("Unsolicited registration events already %s; skipping",
+        mm_obj_dbg (self, "unsolicited registration events already %s; skipping",
                 enable ? "setup" : "cleanup");
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
@@ -4914,10 +4975,10 @@
 
     output = qmi_client_nas_set_event_report_finish (client, res, &error);
     if (!output) {
-        mm_dbg ("QMI operation failed: '%s'", error->message);
+        mm_obj_dbg (self, "QMI operation failed: '%s'", error->message);
         g_error_free (error);
     } else if (!qmi_message_nas_set_event_report_output_get_result (output, &error)) {
-        mm_dbg ("Couldn't set event report: '%s'", error->message);
+        mm_obj_dbg (self, "couldn't set event report: '%s'", error->message);
         g_error_free (error);
     }
 
@@ -4984,10 +5045,10 @@
 
     output = qmi_client_nas_register_indications_finish (client, res, &error);
     if (!output) {
-        mm_dbg ("QMI operation failed: '%s'", error->message);
+        mm_obj_dbg (self, "QMI operation failed: '%s'", error->message);
         g_error_free (error);
     } else if (!qmi_message_nas_register_indications_output_get_result (output, &error)) {
-        mm_dbg ("Couldn't register indications: '%s'", error->message);
+        mm_obj_dbg (self, "couldn't register indications: '%s'", error->message);
         g_error_free (error);
     }
 
@@ -5029,10 +5090,10 @@
 
     output = qmi_client_nas_config_signal_info_finish (client, res, &error);
     if (!output) {
-        mm_dbg ("QMI operation failed: '%s'", error->message);
+        mm_obj_dbg (self, "QMI operation failed: '%s'", error->message);
         g_error_free (error);
     } else if (!qmi_message_nas_config_signal_info_output_get_result (output, &error)) {
-        mm_dbg ("Couldn't config signal info: '%s'", error->message);
+        mm_obj_dbg (self, "couldn't config signal info: '%s'", error->message);
         g_error_free (error);
     }
 
@@ -5102,8 +5163,8 @@
     task = g_task_new (self, NULL, callback, user_data);
 
     if (enable == self->priv->unsolicited_events_enabled) {
-        mm_dbg ("Unsolicited events already %s; skipping",
-                enable ? "enabled" : "disabled");
+        mm_obj_dbg (self, "unsolicited events already %s; skipping",
+                    enable ? "enabled" : "disabled");
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
         return;
@@ -5221,10 +5282,10 @@
             /* This signal strength comes as negative dBms */
             quality = STRENGTH_TO_QUALITY (signal_strength);
 
-            mm_dbg ("Signal strength indication (%s): %d dBm --> %u%%",
-                    qmi_nas_radio_interface_get_string (signal_strength_radio_interface),
-                    signal_strength,
-                    quality);
+            mm_obj_dbg (self, "signal strength indication (%s): %d dBm --> %u%%",
+                        qmi_nas_radio_interface_get_string (signal_strength_radio_interface),
+                        signal_strength,
+                        quality);
 
             mm_iface_modem_update_signal_quality (MM_IFACE_MODEM (self), quality);
             mm_iface_modem_update_access_technologies (
@@ -5232,9 +5293,9 @@
                 mm_modem_access_technology_from_qmi_radio_interface (signal_strength_radio_interface),
                 (MM_IFACE_MODEM_3GPP_ALL_ACCESS_TECHNOLOGIES_MASK | MM_IFACE_MODEM_CDMA_ALL_ACCESS_TECHNOLOGIES_MASK));
         } else {
-            mm_dbg ("Ignoring invalid signal strength (%s): %d dBm",
-                    qmi_nas_radio_interface_get_string (signal_strength_radio_interface),
-                    signal_strength);
+            mm_obj_dbg (self, "ignoring invalid signal strength (%s): %d dBm",
+                        qmi_nas_radio_interface_get_string (signal_strength_radio_interface),
+                        signal_strength);
         }
     }
 }
@@ -5294,8 +5355,8 @@
     task = g_task_new (self, NULL, callback, user_data);
 
     if (enable == self->priv->unsolicited_events_setup) {
-        mm_dbg ("Unsolicited events already %s; skipping",
-                enable ? "setup" : "cleanup");
+        mm_obj_dbg (self, "unsolicited events already %s; skipping",
+                    enable ? "setup" : "cleanup");
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
         return;
@@ -5453,7 +5514,7 @@
         return;
     }
 
-    mm_dbg ("Messaging capabilities supported");
+    mm_obj_dbg (self, "messaging capabilities supported");
     g_task_return_boolean (task, TRUE);
     g_object_unref (task);
 }
@@ -5626,7 +5687,7 @@
     g_array_append_val (routes_array, route);
     qmi_message_wms_set_routes_input_set_route_list (input, routes_array, NULL);
 
-    mm_dbg ("setting default messaging routes...");
+    mm_obj_dbg (self, "setting default messaging routes...");
     qmi_client_wms_set_routes (QMI_CLIENT_WMS (client),
                                input,
                                5,
@@ -5713,6 +5774,7 @@
         part = mm_sms_part_cdma_new_from_binary_pdu (index,
                                                      (guint8 *)data->data,
                                                      data->len,
+                                                     self,
                                                      &error);
 
         break;
@@ -5721,25 +5783,26 @@
         part = mm_sms_part_3gpp_new_from_binary_pdu (index,
                                                      (guint8 *)data->data,
                                                      data->len,
+                                                     self,
                                                      &error);
         break;
     case QMI_WMS_MESSAGE_FORMAT_MWI:
-        mm_dbg ("Don't know how to process 'message waiting indicator' messages");
+        mm_obj_dbg (self, "don't know how to process 'message waiting indicator' messages");
         break;
     default:
-        mm_dbg ("Unhandled message format '%u'", format);
+        mm_obj_dbg (self, "unhandled message format '%u'", format);
         break;
     }
 
     if (part) {
-        mm_dbg ("Correctly parsed PDU (%d)", index);
+        mm_obj_dbg (self, "correctly parsed PDU (%d)", index);
         mm_iface_modem_messaging_take_part (self,
                                             part,
                                             mm_sms_state_from_qmi_message_tag (tag),
                                             mm_sms_storage_from_qmi_storage_type (storage));
     } else if (error) {
         /* Don't treat the error as critical */
-        mm_dbg ("Error parsing PDU (%d): %s", index, error->message);
+        mm_obj_dbg (self, "error parsing PDU (%d): %s", index, error->message);
         g_error_free (error);
     }
 }
@@ -5761,10 +5824,10 @@
 
     output = qmi_client_wms_raw_read_finish (client, res, &error);
     if (!output) {
-        mm_dbg ("QMI operation failed: %s", error->message);
+        mm_obj_dbg (self, "QMI operation failed: %s", error->message);
         g_error_free (error);
     } else if (!qmi_message_wms_raw_read_output_get_result (output, &error)) {
-        mm_dbg ("Couldn't read raw message: %s", error->message);
+        mm_obj_dbg (self, "couldn't read raw message: %s", error->message);
         g_error_free (error);
     } else {
         QmiWmsMessageTagType tag;
@@ -5861,12 +5924,14 @@
                          GAsyncResult *res,
                          GTask *task)
 {
+    MMBroadbandModemQmi *self;
     LoadInitialSmsPartsContext *ctx;
     QmiMessageWmsListMessagesOutput *output = NULL;
     GError *error = NULL;
     GArray *message_array;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     output = qmi_client_wms_list_messages_finish (client, res, &error);
     if (!output) {
@@ -5878,7 +5943,7 @@
 
     if (!qmi_message_wms_list_messages_output_get_result (output, &error)) {
         /* Ignore error, keep on */
-        mm_dbg ("Couldn't read SMS messages: %s", error->message);
+        mm_obj_dbg (self, "couldn't read SMS messages: %s", error->message);
         g_error_free (error);
         ctx->step++;
         load_initial_sms_parts_step (task);
@@ -5931,34 +5996,34 @@
         /* Fall through */
 
     case LOAD_INITIAL_SMS_PARTS_STEP_3GPP_LIST_ALL:
-        mm_dbg ("loading all 3GPP messages from storage '%s'...",
+        mm_obj_dbg (self, "loading all 3GPP messages from storage '%s'...",
                 mm_sms_storage_get_string (ctx->storage));
         mode = QMI_WMS_MESSAGE_MODE_GSM_WCDMA;
         break;
 
     case LOAD_INITIAL_SMS_PARTS_STEP_3GPP_LIST_MT_READ:
-        mm_dbg ("loading 3GPP MT-read messages from storage '%s'...",
+        mm_obj_dbg (self, "loading 3GPP MT-read messages from storage '%s'...",
                 mm_sms_storage_get_string (ctx->storage));
         tag_type = QMI_WMS_MESSAGE_TAG_TYPE_MT_READ;
         mode = QMI_WMS_MESSAGE_MODE_GSM_WCDMA;
         break;
 
     case LOAD_INITIAL_SMS_PARTS_STEP_3GPP_LIST_MT_NOT_READ:
-        mm_dbg ("loading 3GPP MT-not-read messages from storage '%s'...",
+        mm_obj_dbg (self, "loading 3GPP MT-not-read messages from storage '%s'...",
                 mm_sms_storage_get_string (ctx->storage));
         tag_type = QMI_WMS_MESSAGE_TAG_TYPE_MT_NOT_READ;
         mode = QMI_WMS_MESSAGE_MODE_GSM_WCDMA;
         break;
 
     case LOAD_INITIAL_SMS_PARTS_STEP_3GPP_LIST_MO_SENT:
-        mm_dbg ("loading 3GPP MO-sent messages from storage '%s'...",
+        mm_obj_dbg (self, "loading 3GPP MO-sent messages from storage '%s'...",
                 mm_sms_storage_get_string (ctx->storage));
         tag_type = QMI_WMS_MESSAGE_TAG_TYPE_MO_SENT;
         mode = QMI_WMS_MESSAGE_MODE_GSM_WCDMA;
         break;
 
     case LOAD_INITIAL_SMS_PARTS_STEP_3GPP_LIST_MO_NOT_SENT:
-        mm_dbg ("loading 3GPP MO-not-sent messages from storage '%s'...",
+        mm_obj_dbg (self, "loading 3GPP MO-not-sent messages from storage '%s'...",
                 mm_sms_storage_get_string (ctx->storage));
         tag_type = QMI_WMS_MESSAGE_TAG_TYPE_MO_NOT_SENT;
         mode = QMI_WMS_MESSAGE_MODE_GSM_WCDMA;
@@ -5979,34 +6044,34 @@
         /* Fall through */
 
     case LOAD_INITIAL_SMS_PARTS_STEP_CDMA_LIST_ALL:
-        mm_dbg ("loading all CDMA messages from storage '%s'...",
+        mm_obj_dbg (self, "loading all CDMA messages from storage '%s'...",
                 mm_sms_storage_get_string (ctx->storage));
         mode = QMI_WMS_MESSAGE_MODE_CDMA;
         break;
 
     case LOAD_INITIAL_SMS_PARTS_STEP_CDMA_LIST_MT_READ:
-        mm_dbg ("loading CDMA MT-read messages from storage '%s'...",
+        mm_obj_dbg (self, "loading CDMA MT-read messages from storage '%s'...",
                 mm_sms_storage_get_string (ctx->storage));
         tag_type = QMI_WMS_MESSAGE_TAG_TYPE_MT_READ;
         mode = QMI_WMS_MESSAGE_MODE_CDMA;
         break;
 
     case LOAD_INITIAL_SMS_PARTS_STEP_CDMA_LIST_MT_NOT_READ:
-        mm_dbg ("loading CDMA MT-not-read messages from storage '%s'...",
+        mm_obj_dbg (self, "loading CDMA MT-not-read messages from storage '%s'...",
                 mm_sms_storage_get_string (ctx->storage));
         tag_type = QMI_WMS_MESSAGE_TAG_TYPE_MT_NOT_READ;
         mode = QMI_WMS_MESSAGE_MODE_CDMA;
         break;
 
     case LOAD_INITIAL_SMS_PARTS_STEP_CDMA_LIST_MO_SENT:
-        mm_dbg ("loading CDMA MO-sent messages from storage '%s'...",
+        mm_obj_dbg (self, "loading CDMA MO-sent messages from storage '%s'...",
                 mm_sms_storage_get_string (ctx->storage));
         tag_type = QMI_WMS_MESSAGE_TAG_TYPE_MO_SENT;
         mode = QMI_WMS_MESSAGE_MODE_CDMA;
         break;
 
     case LOAD_INITIAL_SMS_PARTS_STEP_CDMA_LIST_MO_NOT_SENT:
-        mm_dbg ("loading CDMA MO-not-sent messages from storage '%s'...",
+        mm_obj_dbg (self, "loading CDMA MO-not-sent messages from storage '%s'...",
                 mm_sms_storage_get_string (ctx->storage));
         tag_type = QMI_WMS_MESSAGE_TAG_TYPE_MO_NOT_SENT;
         mode = QMI_WMS_MESSAGE_MODE_CDMA;
@@ -6114,10 +6179,10 @@
 
     output = qmi_client_wms_raw_read_finish (client, res, &error);
     if (!output) {
-        mm_dbg ("QMI operation failed: %s", error->message);
+        mm_obj_dbg (ctx->self, "QMI operation failed: %s", error->message);
         g_error_free (error);
     } else if (!qmi_message_wms_raw_read_output_get_result (output, &error)) {
-        mm_dbg ("Couldn't read raw message: %s", error->message);
+        mm_obj_dbg (ctx->self, "couldn't read raw message: %s", error->message);
         g_error_free (error);
     } else {
         QmiWmsMessageTagType tag;
@@ -6243,8 +6308,8 @@
     task = g_task_new (self, NULL, callback, user_data);
 
     if (enable == self->priv->messaging_unsolicited_events_setup) {
-        mm_dbg ("Messaging unsolicited events already %s; skipping",
-                enable ? "setup" : "cleanup");
+        mm_obj_dbg (self, "messaging unsolicited events already %s; skipping",
+                    enable ? "setup" : "cleanup");
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
         return;
@@ -6359,10 +6424,10 @@
 
     output = qmi_client_wms_set_event_report_finish (client, res, &error);
     if (!output) {
-        mm_dbg ("QMI operation failed: '%s'", error->message);
+        mm_obj_dbg (self, "QMI operation failed: '%s'", error->message);
         g_error_free (error);
     } else if (!qmi_message_wms_set_event_report_output_get_result (output, &error)) {
-        mm_dbg ("Couldn't set event report: '%s'", error->message);
+        mm_obj_dbg (self, "couldn't set event report: '%s'", error->message);
         g_error_free (error);
     }
 
@@ -6394,8 +6459,8 @@
     task = g_task_new (self, NULL, callback, user_data);
 
     if (enable == self->priv->messaging_unsolicited_events_enabled) {
-        mm_dbg ("Messaging unsolicited events already %s; skipping",
-                enable ? "enabled" : "disabled");
+        mm_obj_dbg (self, "messaging unsolicited events already %s; skipping",
+                    enable ? "enabled" : "disabled");
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
         return;
@@ -6696,10 +6761,10 @@
                                     QMI_SERVICE_OMA,
                                     MM_PORT_QMI_FLAG_DEFAULT,
                                     NULL)) {
-        mm_dbg ("OMA capabilities not supported");
+        mm_obj_dbg (self, "OMA capabilities not supported");
         g_task_return_boolean (task, FALSE);
     } else {
-        mm_dbg ("OMA capabilities supported");
+        mm_obj_dbg (self, "OMA capabilities supported");
         g_task_return_boolean (task, TRUE);
     }
 
@@ -7084,7 +7149,7 @@
 
         session_type = mm_oma_session_type_from_qmi_oma_session_type (network_initiated_alert_session_type);
         if (session_type == MM_OMA_SESSION_TYPE_UNKNOWN)
-            mm_warn ("Unknown QMI OMA session type '%u'", network_initiated_alert_session_type);
+            mm_obj_warn (self, "unknown QMI OMA session type '%u'", network_initiated_alert_session_type);
         else
             mm_iface_modem_oma_add_pending_network_initiated_session (
                 MM_IFACE_MODEM_OMA (self),
@@ -7118,8 +7183,8 @@
     task = g_task_new (self, NULL, callback, user_data);
 
     if (enable == self->priv->oma_unsolicited_events_setup) {
-        mm_dbg ("OMA unsolicited events already %s; skipping",
-                enable ? "setup" : "cleanup");
+        mm_obj_dbg (self, "OMA unsolicited events already %s; skipping",
+                    enable ? "setup" : "cleanup");
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
         return;
@@ -7198,10 +7263,10 @@
 
     output = qmi_client_oma_set_event_report_finish (client, res, &error);
     if (!output) {
-        mm_dbg ("QMI operation failed: '%s'", error->message);
+        mm_obj_dbg (self, "QMI operation failed: '%s'", error->message);
         g_error_free (error);
     } else if (!qmi_message_oma_set_event_report_output_get_result (output, &error)) {
-        mm_dbg ("Couldn't set event report: '%s'", error->message);
+        mm_obj_dbg (self, "couldn't set event report: '%s'", error->message);
         g_error_free (error);
     }
 
@@ -7233,8 +7298,8 @@
     task = g_task_new (self, NULL, callback, user_data);
 
     if (enable == self->priv->oma_unsolicited_events_enabled) {
-        mm_dbg ("OMA unsolicited events already %s; skipping",
-                enable ? "enabled" : "disabled");
+        mm_obj_dbg (self, "OMA unsolicited events already %s; skipping",
+                    enable ? "enabled" : "disabled");
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
         return;
@@ -7287,6 +7352,535 @@
 }
 
 /*****************************************************************************/
+/* Check support (3GPP USSD interface) */
+
+static gboolean
+modem_3gpp_ussd_check_support_finish (MMIfaceModem3gppUssd  *self,
+                                      GAsyncResult          *res,
+                                      GError               **error)
+{
+    return g_task_propagate_boolean (G_TASK (res), error);
+}
+
+static void
+modem_3gpp_ussd_check_support (MMIfaceModem3gppUssd *self,
+                               GAsyncReadyCallback   callback,
+                               gpointer              user_data)
+{
+    GTask *task;
+
+    task = g_task_new (self, NULL, callback, user_data);
+
+    /* If we have support for the Voice client, USSD is supported */
+    if (!mm_shared_qmi_peek_client (MM_SHARED_QMI (self),
+                                    QMI_SERVICE_VOICE,
+                                    MM_PORT_QMI_FLAG_DEFAULT,
+                                    NULL)) {
+        mm_obj_dbg (self, "USSD capabilities not supported");
+        g_task_return_boolean (task, FALSE);
+    } else {
+        mm_obj_dbg (self, "USSD capabilities supported");
+        g_task_return_boolean (task, TRUE);
+    }
+
+    g_object_unref (task);
+}
+
+/*****************************************************************************/
+/* USSD encode/decode helpers */
+
+static GArray *
+ussd_encode (const gchar                  *command,
+             QmiVoiceUssDataCodingScheme  *scheme,
+             GError                      **error)
+{
+    gsize                 command_len;
+    g_autoptr(GByteArray) barray = NULL;
+    g_autoptr(GError)     inner_error = NULL;
+
+    command_len = strlen (command);
+
+    if (g_str_is_ascii (command)) {
+        barray = g_byte_array_sized_new (command_len);
+        g_byte_array_append (barray, (const guint8 *)command, command_len);
+
+        *scheme = QMI_VOICE_USS_DATA_CODING_SCHEME_ASCII;
+        return (GArray *) g_steal_pointer (&barray);
+    }
+
+    barray = g_byte_array_sized_new (command_len * 2);
+    if (!mm_modem_charset_byte_array_append (barray, command, FALSE, MM_MODEM_CHARSET_UCS2, &inner_error)) {
+        g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED,
+                     "Failed to encode USSD command in UCS2 charset: %s", inner_error->message);
+        return NULL;
+    }
+
+    *scheme = QMI_VOICE_USS_DATA_CODING_SCHEME_UCS2;
+    return (GArray *) g_steal_pointer (&barray);
+}
+
+static gchar *
+ussd_decode (QmiVoiceUssDataCodingScheme   scheme,
+             GArray                       *data,
+             GError                      **error)
+{
+    gchar *decoded = NULL;
+
+    if (scheme == QMI_VOICE_USS_DATA_CODING_SCHEME_ASCII) {
+        decoded = g_strndup ((const gchar *) data->data, data->len);
+        if (!decoded)
+            g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED,
+                         "Error decoding USSD command in 0x%04x scheme (ASCII charset)",
+                         scheme);
+    } else if (scheme == QMI_VOICE_USS_DATA_CODING_SCHEME_UCS2) {
+        decoded = mm_modem_charset_byte_array_to_utf8 ((GByteArray *) data, MM_MODEM_CHARSET_UCS2);
+        if (!decoded)
+            g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED,
+                         "Error decoding USSD command in 0x%04x scheme (UCS2 charset)",
+                         scheme);
+    } else
+        g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED,
+                     "Failed to decode USSD command in unsupported 0x%04x scheme", scheme);
+
+    return decoded;
+}
+
+/*****************************************************************************/
+/* USSD indications */
+
+static void
+process_ussd_message (MMBroadbandModemQmi *self,
+                      QmiVoiceUserAction   user_action,
+                      gchar               *utf8_take,
+                      GError              *error_take)
+{
+    MMModem3gppUssdSessionState  ussd_state = MM_MODEM_3GPP_USSD_SESSION_STATE_IDLE;
+    g_autoptr(GTask)             task = NULL;
+    g_autofree gchar            *utf8 = utf8_take;
+    g_autoptr(GError)            error = error_take;
+
+    task = g_steal_pointer (&self->priv->pending_ussd_action);
+
+    if (error) {
+        g_assert (!utf8);
+        if (task)
+            g_task_return_error (task, g_steal_pointer (&error));
+        else
+            mm_obj_dbg (self, "USSD operation failed: %s", error->message);
+        return;
+    }
+
+    switch (user_action) {
+        case QMI_VOICE_USER_ACTION_NOT_REQUIRED:
+            /* no response, or a response to user's request? */
+            if (!utf8 || task)
+                break;
+            /* Network-initiated USSD-Notify */
+            mm_iface_modem_3gpp_ussd_update_network_notification (MM_IFACE_MODEM_3GPP_USSD (self), utf8);
+            g_clear_pointer (&utf8, g_free);
+            break;
+        case QMI_VOICE_USER_ACTION_REQUIRED:
+            /* further action required */
+            ussd_state = MM_MODEM_3GPP_USSD_SESSION_STATE_USER_RESPONSE;
+            /* no response, or a response to user's request? */
+            if (!utf8 || task)
+                break;
+            /* Network-initiated USSD-Request */
+            mm_iface_modem_3gpp_ussd_update_network_request (MM_IFACE_MODEM_3GPP_USSD (self), utf8);
+            g_clear_pointer (&utf8, g_free);
+            break;
+        case QMI_VOICE_USER_ACTION_UNKNOWN:
+        default:
+            /* Not an indication */
+            break;
+    }
+
+    mm_iface_modem_3gpp_ussd_update_state (MM_IFACE_MODEM_3GPP_USSD (self), ussd_state);
+
+    if (!task) {
+        if (utf8)
+            mm_obj_dbg (self, "ignoring unprocessed USSD message: %s", utf8);
+        return;
+    }
+
+    /* Complete the pending action, if any */
+    if (utf8)
+        g_task_return_pointer (task, g_steal_pointer (&utf8), g_free);
+    else
+        g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+                                 "USSD action response not processed correctly");
+}
+
+static void
+ussd_indication_cb (QmiClientVoice               *client,
+                    QmiIndicationVoiceUssdOutput *output,
+                    MMBroadbandModemQmi          *self)
+{
+    QmiVoiceUserAction           user_action = QMI_VOICE_USER_ACTION_UNKNOWN;
+    QmiVoiceUssDataCodingScheme  scheme;
+    GArray                      *uss_data = NULL;
+    gchar                       *utf8 = NULL;
+    GError                      *error = NULL;
+
+    qmi_indication_voice_ussd_output_get_user_action (output, &user_action, NULL);
+    if (qmi_indication_voice_ussd_output_get_uss_data_utf16 (output, &uss_data, NULL) && uss_data)
+        utf8 = g_convert ((const gchar *) uss_data->data, (2 * uss_data->len), "UTF-8", "UTF16-LE", NULL, NULL, &error);
+    else if (qmi_indication_voice_ussd_output_get_uss_data (output, &scheme, &uss_data, NULL) && uss_data)
+        utf8 = ussd_decode(scheme, uss_data, &error);
+
+    process_ussd_message (self, user_action, utf8, error);
+}
+
+/*****************************************************************************/
+/* Setup/cleanup unsolicited events */
+
+static gboolean
+common_3gpp_ussd_setup_cleanup_unsolicited_events_finish (MMIfaceModem3gppUssd  *self,
+                                                          GAsyncResult          *res,
+                                                          GError               **error)
+{
+    return g_task_propagate_boolean (G_TASK (res), error);
+}
+
+static void
+common_3gpp_ussd_setup_cleanup_unsolicited_events (MMBroadbandModemQmi *self,
+                                                   gboolean             setup,
+                                                   GAsyncReadyCallback  callback,
+                                                   gpointer             user_data)
+{
+    GTask     *task;
+    QmiClient *client = NULL;
+
+    if (!mm_shared_qmi_ensure_client (MM_SHARED_QMI (self),
+                                      QMI_SERVICE_VOICE, &client,
+                                      callback, user_data))
+        return;
+
+    task = g_task_new (self, NULL, callback, user_data);
+
+    if (setup == self->priv->ussd_unsolicited_events_setup) {
+        mm_obj_dbg (self, "USSD unsolicited events already %s; skipping",
+                    setup ? "setup" : "cleanup");
+        g_task_return_boolean (task, TRUE);
+        g_object_unref (task);
+        return;
+    }
+    self->priv->ussd_unsolicited_events_setup = setup;
+
+    if (setup) {
+        g_assert (self->priv->ussd_indication_id == 0);
+        self->priv->ussd_indication_id =
+            g_signal_connect (client,
+                              "ussd",
+                              G_CALLBACK (ussd_indication_cb),
+                              self);
+    } else {
+        g_assert (self->priv->ussd_indication_id != 0);
+        g_signal_handler_disconnect (client, self->priv->ussd_indication_id);
+        self->priv->ussd_indication_id = 0;
+    }
+
+    g_task_return_boolean (task, TRUE);
+    g_object_unref (task);
+}
+
+static void
+modem_3gpp_ussd_setup_unsolicited_events (MMIfaceModem3gppUssd *self,
+                                          GAsyncReadyCallback   callback,
+                                          gpointer              user_data)
+{
+    common_3gpp_ussd_setup_cleanup_unsolicited_events (MM_BROADBAND_MODEM_QMI (self), TRUE, callback, user_data);
+}
+
+static void
+modem_3gpp_ussd_cleanup_unsolicited_events (MMIfaceModem3gppUssd *self,
+                                            GAsyncReadyCallback   callback,
+                                            gpointer              user_data)
+{
+    common_3gpp_ussd_setup_cleanup_unsolicited_events (MM_BROADBAND_MODEM_QMI (self), FALSE, callback, user_data);
+}
+
+/*****************************************************************************/
+/* Enable/disable unsolicited events */
+
+static gboolean
+common_3gpp_ussd_enable_disable_unsolicited_events_finish (MMIfaceModem3gppUssd  *self,
+                                                           GAsyncResult          *res,
+                                                           GError               **error)
+{
+    return g_task_propagate_boolean (G_TASK (res), error);
+}
+
+static void
+voice_indication_register_ready (QmiClientVoice *client,
+                                 GAsyncResult   *res,
+                                 GTask          *task)
+{
+    g_autoptr(QmiMessageVoiceIndicationRegisterOutput) output = NULL;
+    GError *error = NULL;
+
+    output = qmi_client_voice_indication_register_finish (client, res, &error);
+    if (!output) {
+        g_prefix_error (&error, "QMI operation failed: ");
+        g_task_return_error (task, error);
+    } else if (!qmi_message_voice_indication_register_output_get_result (output, &error)) {
+        g_prefix_error (&error, "Couldn't register voice USSD indications: ");
+        g_task_return_error (task, error);
+    } else
+        g_task_return_boolean (task, TRUE);
+    g_object_unref (task);
+}
+
+static void
+common_3gpp_ussd_enable_disable_unsolicited_events (MMBroadbandModemQmi *self,
+                                                    gboolean             enable,
+                                                    GAsyncReadyCallback  callback,
+                                                    gpointer             user_data)
+{
+    g_autoptr(QmiMessageVoiceIndicationRegisterInput) input = NULL;
+    GTask     *task;
+    QmiClient *client;
+
+    if (!mm_shared_qmi_ensure_client (MM_SHARED_QMI (self),
+                                      QMI_SERVICE_VOICE, &client,
+                                      callback, user_data))
+        return;
+
+    task = g_task_new (self, NULL, callback, user_data);
+
+    if (enable == self->priv->ussd_unsolicited_events_enabled) {
+        mm_obj_dbg (self, "USSD unsolicited events already %s; skipping",
+                    enable ? "enabled" : "disabled");
+        g_task_return_boolean (task, TRUE);
+        g_object_unref (task);
+        return;
+    }
+    self->priv->ussd_unsolicited_events_enabled = enable;
+
+    input = qmi_message_voice_indication_register_input_new ();
+    qmi_message_voice_indication_register_input_set_ussd_notification_events (input, enable, NULL);
+    qmi_client_voice_indication_register (QMI_CLIENT_VOICE (client),
+                                          input,
+                                          10,
+                                          NULL,
+                                          (GAsyncReadyCallback) voice_indication_register_ready,
+                                          task);
+}
+
+static void
+modem_3gpp_ussd_enable_unsolicited_events (MMIfaceModem3gppUssd *self,
+                                           GAsyncReadyCallback   callback,
+                                           gpointer              user_data)
+{
+    common_3gpp_ussd_enable_disable_unsolicited_events (MM_BROADBAND_MODEM_QMI (self), TRUE, callback, user_data);
+}
+
+static void
+modem_3gpp_ussd_disable_unsolicited_events (MMIfaceModem3gppUssd *self,
+                                            GAsyncReadyCallback   callback,
+                                            gpointer              user_data)
+{
+    common_3gpp_ussd_enable_disable_unsolicited_events (MM_BROADBAND_MODEM_QMI (self), FALSE, callback, user_data);
+}
+
+/*****************************************************************************/
+/* Send command (3GPP/USSD interface) */
+
+static gchar *
+modem_3gpp_ussd_send_finish (MMIfaceModem3gppUssd  *self,
+                             GAsyncResult          *res,
+                             GError               **error)
+{
+    return g_task_propagate_pointer (G_TASK (res), error);
+}
+
+static void
+voice_answer_ussd_ready (QmiClientVoice      *client,
+                         GAsyncResult        *res,
+                         MMBroadbandModemQmi *self)
+{
+    g_autoptr(QmiMessageVoiceAnswerUssdOutput) output = NULL;
+    GError *error = NULL;
+
+    output = qmi_client_voice_answer_ussd_finish (client, res, &error);
+    if (!output)
+        g_prefix_error (&error, "QMI operation failed: ");
+    else if (!qmi_message_voice_answer_ussd_output_get_result (output, &error))
+        g_prefix_error (&error, "Couldn't answer USSD operation: ");
+
+    process_ussd_message (self, QMI_VOICE_USER_ACTION_UNKNOWN, error ? NULL : g_strdup (""), error);
+
+    /* balance out the full reference we received */
+    g_object_unref (self);
+}
+
+static void
+voice_originate_ussd_ready (QmiClientVoice      *client,
+                            GAsyncResult        *res,
+                            MMBroadbandModemQmi *self)
+{
+    g_autoptr(QmiMessageVoiceOriginateUssdOutput) output = NULL;
+    QmiVoiceUssDataCodingScheme  scheme;
+    GError                      *error = NULL;
+    GArray                      *uss_data = NULL;
+    gchar                       *utf8 = NULL;
+
+    output = qmi_client_voice_originate_ussd_finish (client, res, &error);
+    if (!output)
+        g_prefix_error (&error, "QMI operation failed: ");
+    else if (!qmi_message_voice_originate_ussd_output_get_result (output, &error))
+        g_prefix_error (&error, "Couldn't originate USSD operation: ");
+    else if (qmi_message_voice_originate_ussd_output_get_uss_data_utf16 (output, &uss_data, NULL) && uss_data)
+        utf8 = g_convert ((const gchar *) uss_data->data, (2 * uss_data->len), "UTF-8", "UTF-16LE", NULL, NULL, &error);
+    else if (qmi_message_voice_originate_ussd_output_get_uss_data (output, &scheme, &uss_data, NULL) && uss_data)
+        utf8 = ussd_decode (scheme, uss_data, &error);
+
+    process_ussd_message (self, QMI_VOICE_USER_ACTION_UNKNOWN, utf8, error);
+
+    /* balance out the full reference we received */
+    g_object_unref (self);
+}
+
+static void
+modem_3gpp_ussd_send (MMIfaceModem3gppUssd *_self,
+                      const gchar          *command,
+                      GAsyncReadyCallback   callback,
+                      gpointer              user_data)
+{
+    MMBroadbandModemQmi         *self = MM_BROADBAND_MODEM_QMI (_self);
+    GTask                       *task;
+    QmiClient                   *client;
+    QmiVoiceUssDataCodingScheme  scheme;
+    g_autoptr(GArray)            encoded = NULL;
+    GError                      *error = NULL;
+    MMModem3gppUssdSessionState  state;
+
+    if (!mm_shared_qmi_ensure_client (MM_SHARED_QMI (self),
+                                      QMI_SERVICE_VOICE, &client,
+                                      callback, user_data))
+        return;
+
+    task = g_task_new (self, NULL, callback, user_data);
+
+    /* Fail if there is an ongoing operation already */
+    if (self->priv->pending_ussd_action) {
+        g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_IN_PROGRESS,
+                                 "there is already an ongoing USSD operation");
+        g_object_unref (task);
+        return;
+    }
+
+    encoded = ussd_encode (command, &scheme, &error);
+    if (!encoded) {
+        g_task_return_error (task, error);
+        g_object_unref (task);
+        return;
+    }
+
+    state = mm_iface_modem_3gpp_ussd_get_state (MM_IFACE_MODEM_3GPP_USSD (self));
+
+    /* Cache the action, as it may be completed via URCs */
+    self->priv->pending_ussd_action = task;
+    mm_iface_modem_3gpp_ussd_update_state (_self, MM_MODEM_3GPP_USSD_SESSION_STATE_ACTIVE);
+
+    switch (state) {
+        case MM_MODEM_3GPP_USSD_SESSION_STATE_IDLE: {
+            g_autoptr(QmiMessageVoiceOriginateUssdInput) input = NULL;
+
+            input = qmi_message_voice_originate_ussd_input_new ();
+            qmi_message_voice_originate_ussd_input_set_uss_data (input, scheme, encoded, NULL);
+            qmi_client_voice_originate_ussd (QMI_CLIENT_VOICE (client), input, 100, NULL,
+                                             (GAsyncReadyCallback) voice_originate_ussd_ready,
+                                             g_object_ref (self)); /* full reference! */
+            return;
+        }
+        case MM_MODEM_3GPP_USSD_SESSION_STATE_USER_RESPONSE: {
+            g_autoptr(QmiMessageVoiceAnswerUssdInput) input = NULL;
+
+            input = qmi_message_voice_answer_ussd_input_new ();
+            qmi_message_voice_answer_ussd_input_set_uss_data (input, scheme, encoded, NULL);
+            qmi_client_voice_answer_ussd (QMI_CLIENT_VOICE (client), input, 100, NULL,
+                                          (GAsyncReadyCallback) voice_answer_ussd_ready,
+                                          g_object_ref (self)); /* full reference! */
+            return;
+        }
+        case MM_MODEM_3GPP_USSD_SESSION_STATE_UNKNOWN:
+        case MM_MODEM_3GPP_USSD_SESSION_STATE_ACTIVE:
+        default:
+            g_assert_not_reached ();
+            return;
+    }
+}
+
+/*****************************************************************************/
+/* Cancel USSD (3GPP/USSD interface) */
+
+static gboolean
+modem_3gpp_ussd_cancel_finish (MMIfaceModem3gppUssd  *self,
+                               GAsyncResult          *res,
+                               GError               **error)
+{
+    return g_task_propagate_boolean (G_TASK (res), error);
+}
+
+static void
+voice_cancel_ussd_ready (QmiClientVoice *client,
+                         GAsyncResult   *res,
+                         GTask          *task)
+{
+    g_autoptr(QmiMessageVoiceCancelUssdOutput) output = NULL;
+    MMBroadbandModemQmi *self;
+    GTask               *pending_task;
+    GError              *error = NULL;
+
+    self = g_task_get_source_object (task);
+
+    output = qmi_client_voice_cancel_ussd_finish (client, res, &error);
+    if (!output)
+        g_prefix_error (&error, "QMI operation failed: ");
+    else if (!qmi_message_voice_cancel_ussd_output_get_result (output, &error))
+        g_prefix_error (&error, "Couldn't cancel USSD operation: ");
+
+    /* Complete the pending action, regardless of the operation result */
+    pending_task = g_steal_pointer (&self->priv->pending_ussd_action);
+    if (pending_task) {
+        g_task_return_new_error (pending_task, MM_CORE_ERROR, MM_CORE_ERROR_ABORTED,
+                                 "USSD session was cancelled");
+        g_object_unref (pending_task);
+    }
+
+    mm_iface_modem_3gpp_ussd_update_state (MM_IFACE_MODEM_3GPP_USSD (self),
+                                           MM_MODEM_3GPP_USSD_SESSION_STATE_IDLE);
+
+    if (error)
+        g_task_return_error (task, error);
+    else
+        g_task_return_boolean (task, TRUE);
+    g_object_unref (task);
+}
+
+static void
+modem_3gpp_ussd_cancel (MMIfaceModem3gppUssd *_self,
+                        GAsyncReadyCallback   callback,
+                        gpointer              user_data)
+{
+    MMBroadbandModemQmi *self = MM_BROADBAND_MODEM_QMI (_self);
+    GTask               *task;
+    QmiClient           *client;
+
+    if (!mm_shared_qmi_ensure_client (MM_SHARED_QMI (self),
+                                      QMI_SERVICE_VOICE, &client,
+                                      callback, user_data))
+        return;
+
+    task = g_task_new (self, NULL, callback, user_data);
+
+    qmi_client_voice_cancel_ussd (QMI_CLIENT_VOICE (client), NULL, 100, NULL,
+                                  (GAsyncReadyCallback) voice_cancel_ussd_ready,
+                                  task);
+}
+
+/*****************************************************************************/
 /* Check firmware support (Firmware interface) */
 
 typedef struct {
@@ -7341,9 +7935,9 @@
     /* If this is is also the running image, keep an extra reference to it */
     if (running) {
         if (self->priv->current_firmware)
-            mm_warn ("A running firmware is already set (%s), not setting '%s'",
-                     mm_firmware_properties_get_unique_id (self->priv->current_firmware),
-                     mm_firmware_properties_get_unique_id (firmware));
+            mm_obj_warn (self, "a running firmware is already set (%s), not setting '%s'",
+                         mm_firmware_properties_get_unique_id (self->priv->current_firmware),
+                         mm_firmware_properties_get_unique_id (firmware));
         else
             self->priv->current_firmware = g_object_ref (firmware);
     }
@@ -7372,8 +7966,8 @@
         if (g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_INVALID_QMI_COMMAND))
             ctx->skip_image_info = TRUE;
         else
-            mm_dbg ("couldn't get detailed info for PRI image with build ID '%s': %s",
-                    ctx->current_pair->build_id, error->message);
+            mm_obj_dbg (self, "couldn't get detailed info for PRI image with build ID '%s': %s",
+                        ctx->current_pair->build_id, error->message);
         g_error_free (error);
         goto out;
     }
@@ -7551,7 +8145,8 @@
 }
 
 static GList *
-find_image_pairs (QmiMessageDmsListStoredImagesOutputListImage  *image_pri,
+find_image_pairs (MMBroadbandModemQmi                           *self,
+                  QmiMessageDmsListStoredImagesOutputListImage  *image_pri,
                   QmiMessageDmsListStoredImagesOutputListImage  *image_modem,
                   GError                                       **error)
 {
@@ -7575,7 +8170,7 @@
             if (match_images (subimage_pri->build_id, subimage_modem->build_id)) {
                 FirmwarePair *pair;
 
-                mm_dbg ("Found pairing PRI+MODEM images with build ID '%s'", subimage_pri->build_id);
+                mm_obj_dbg (self, "found pairing PRI+MODEM images with build ID '%s'", subimage_pri->build_id);
                 pair = g_slice_new (FirmwarePair);
                 pair->build_id = g_strdup (subimage_pri->build_id);
                 pair->modem_unique_id = g_array_ref (subimage_modem->unique_id);
@@ -7594,7 +8189,7 @@
         }
 
         if (j == image_modem->sublist->len)
-            mm_dbg ("Pairing for PRI image with build ID '%s' not found", subimage_pri->build_id);
+            mm_obj_dbg (self, "pairing for PRI image with build ID '%s' not found", subimage_pri->build_id);
     }
 
     if (!pairs)
@@ -7604,7 +8199,8 @@
 }
 
 static gboolean
-find_image_type_indices (GArray                                        *array,
+find_image_type_indices (MMBroadbandModemQmi                           *self,
+                         GArray                                        *array,
                          QmiMessageDmsListStoredImagesOutputListImage **image_pri,
                          QmiMessageDmsListStoredImagesOutputListImage **image_modem,
                          GError                                       **error)
@@ -7629,13 +8225,13 @@
         switch (image->type) {
         case QMI_DMS_FIRMWARE_IMAGE_TYPE_PRI:
             if (*image_pri != NULL)
-                mm_dbg ("Multiple array elements found with PRI type: ignoring additional list at index %u", i);
+                mm_obj_dbg (self, "multiple array elements found with PRI type: ignoring additional list at index %u", i);
             else
                 *image_pri = image;
             break;
         case QMI_DMS_FIRMWARE_IMAGE_TYPE_MODEM:
             if (*image_modem != NULL)
-                mm_dbg ("Multiple array elements found with MODEM type: ignoring additional list at index %u", i);
+                mm_obj_dbg (self, "multiple array elements found with MODEM type: ignoring additional list at index %u", i);
             else
                 *image_modem = image;
             break;
@@ -7660,6 +8256,7 @@
                           GAsyncResult *res,
                           GTask        *task)
 {
+    MMBroadbandModemQmi                          *self;
     FirmwareListPreloadContext                   *ctx;
     GArray                                       *array;
     QmiMessageDmsListStoredImagesOutputListImage *image_pri;
@@ -7667,7 +8264,8 @@
     QmiMessageDmsListStoredImagesOutput          *output;
     GError                                       *error = NULL;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     /* Read array from output */
     output = qmi_client_dms_list_stored_images_finish (client, res, &error);
@@ -7680,14 +8278,14 @@
     }
 
     /* Find which index corresponds to each image type */
-    if (!find_image_type_indices (array, &image_pri, &image_modem, &error)) {
+    if (!find_image_type_indices (self, array, &image_pri, &image_modem, &error)) {
         g_task_return_error (task, error);
         g_object_unref (task);
         goto out;
     }
 
     /* Build firmware PRI+MODEM pair list */
-    ctx->pairs = find_image_pairs (image_pri, image_modem, &error);
+    ctx->pairs = find_image_pairs (self, image_pri, image_modem, &error);
     if (!ctx->pairs) {
         g_task_return_error (task, error);
         g_object_unref (task);
@@ -7723,7 +8321,7 @@
     task = g_task_new (self, NULL, callback, user_data);
     g_task_set_task_data (task, ctx, (GDestroyNotify)firmware_list_preload_context_free);
 
-    mm_dbg ("loading firmware images...");
+    mm_obj_dbg (self, "loading firmware images...");
     qmi_client_dms_list_stored_images (QMI_CLIENT_DMS (client),
                                        NULL,
                                        10,
@@ -7775,7 +8373,7 @@
     GError *error = NULL;
 
     if (!firmware_list_preload_finish (self, res, &error)) {
-        mm_dbg ("firmware list loading failed: %s", error ? error->message : "unsupported");
+        mm_obj_dbg (self, "firmware list loading failed: %s", error ? error->message : "unsupported");
         g_clear_error (&error);
     }
 
@@ -8007,7 +8605,7 @@
     if (self->priv->current_firmware &&
         g_str_equal (mm_firmware_properties_get_unique_id (self->priv->current_firmware),
                      mm_firmware_properties_get_unique_id (ctx->firmware))) {
-        mm_dbg ("Modem is already running firmware image '%s'",
+        mm_obj_dbg (self, "modem is already running firmware image '%s'",
                 mm_firmware_properties_get_unique_id (self->priv->current_firmware));
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
@@ -8036,10 +8634,10 @@
         goto out;
     }
 
-    mm_dbg ("Changing Gobi firmware to MODEM '%s' and PRI '%s' with Build ID '%s'...",
-            mm_firmware_properties_get_gobi_modem_unique_id (ctx->firmware),
-            mm_firmware_properties_get_gobi_pri_unique_id (ctx->firmware),
-            unique_id);
+    mm_obj_dbg (self, "changing Gobi firmware to MODEM '%s' and PRI '%s' with Build ID '%s'...",
+                mm_firmware_properties_get_gobi_modem_unique_id (ctx->firmware),
+                mm_firmware_properties_get_gobi_pri_unique_id (ctx->firmware),
+                unique_id);
 
     /* Build array of image IDs */
     array = g_array_sized_new (FALSE, FALSE, sizeof (QmiMessageDmsSetFirmwarePreferenceInputListImage), 2);
@@ -8091,10 +8689,10 @@
                                     QMI_SERVICE_NAS,
                                     MM_PORT_QMI_FLAG_DEFAULT,
                                     NULL)) {
-        mm_dbg ("Extended signal capabilities not supported");
+        mm_obj_dbg (self, "extended signal capabilities not supported");
         g_task_return_boolean (task, FALSE);
     } else {
-        mm_dbg ("Extended signal capabilities supported");
+        mm_obj_dbg (self, "extended signal capabilities supported");
         g_task_return_boolean (task, TRUE);
     }
     g_object_unref (task);
@@ -8149,7 +8747,8 @@
 }
 
 static gdouble
-get_db_from_sinr_level (QmiNasEvdoSinrLevel level)
+get_db_from_sinr_level (MMBroadbandModemQmi *self,
+                        QmiNasEvdoSinrLevel  level)
 {
     switch (level) {
     case QMI_NAS_EVDO_SINR_LEVEL_0: return -9.0;
@@ -8162,7 +8761,7 @@
     case QMI_NAS_EVDO_SINR_LEVEL_7: return 6;
     case QMI_NAS_EVDO_SINR_LEVEL_8: return +9;
     default:
-        mm_warn ("Invalid SINR level '%u'", level);
+        mm_obj_warn (self, "invalid SINR level '%u'", level);
         return -G_MAXDOUBLE;
     }
 }
@@ -8199,6 +8798,7 @@
                                               GAsyncResult *res,
                                               GTask *task)
 {
+    MMBroadbandModemQmi *self;
     SignalLoadValuesContext *ctx;
     QmiMessageNasGetSignalStrengthOutput *output;
     GArray *array;
@@ -8208,7 +8808,9 @@
     QmiNasRadioInterface radio_interface;
     QmiNasEvdoSinrLevel sinr;
 
+    self = g_task_get_source_object (task);
     ctx = g_task_get_task_data (task);
+
     output = qmi_client_nas_get_signal_strength_finish (client, res, NULL);
     if (!output || !qmi_message_nas_get_signal_strength_output_get_result (output, NULL)) {
         /* No hard errors, go on to next step */
@@ -8338,7 +8940,7 @@
     /* SINR (EV-DO) */
     if (qmi_message_nas_get_signal_strength_output_get_sinr (output, &sinr, NULL)) {
         if (ctx->values_result->evdo)
-            mm_signal_set_sinr (ctx->values_result->evdo, get_db_from_sinr_level (sinr));
+            mm_signal_set_sinr (ctx->values_result->evdo, get_db_from_sinr_level (self, sinr));
     }
 
     qmi_message_nas_get_signal_strength_output_unref (output);
@@ -8353,6 +8955,7 @@
                                           GAsyncResult *res,
                                           GTask *task)
 {
+    MMBroadbandModemQmi *self;
     SignalLoadValuesContext *ctx;
     QmiMessageNasGetSignalInfoOutput *output;
     gint8 rssi;
@@ -8363,7 +8966,9 @@
     gint16 rsrp;
     gint16 snr;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
+
     output = qmi_client_nas_get_signal_info_finish (client, res, NULL);
     if (!output || !qmi_message_nas_get_signal_info_output_get_result (output, NULL)) {
         /* No hard errors, go on to next step */
@@ -8397,7 +9002,7 @@
         ctx->values_result->evdo = mm_signal_new ();
         mm_signal_set_rssi (ctx->values_result->evdo, (gdouble)rssi);
         mm_signal_set_ecio (ctx->values_result->evdo, ((gdouble)ecio) * (-0.5));
-        mm_signal_set_sinr (ctx->values_result->evdo, get_db_from_sinr_level (sinr_level));
+        mm_signal_set_sinr (ctx->values_result->evdo, get_db_from_sinr_level (self, sinr_level));
         mm_signal_set_io (ctx->values_result->evdo, (gdouble)io);
     }
 
@@ -8541,7 +9146,7 @@
     GTask *task;
     QmiClient *client = NULL;
 
-    mm_dbg ("loading extended signal information...");
+    mm_obj_dbg (self, "loading extended signal information...");
 
     if (!mm_shared_qmi_ensure_client (MM_SHARED_QMI (self),
                                       QMI_SERVICE_NAS, &client,
@@ -8563,39 +9168,178 @@
 /*****************************************************************************/
 /* First enabling step */
 
+typedef struct {
+    MMPortQmi    *qmi;
+    QmiClientWds *wds;
+} EnablingStartedContext;
+
+static void
+enabling_started_context_free (EnablingStartedContext *ctx)
+{
+    if (ctx->wds) {
+        mm_port_qmi_release_client (ctx->qmi, QMI_SERVICE_WDS, MM_PORT_QMI_FLAG_DEFAULT);
+        g_clear_object (&ctx->wds);
+    }
+    g_clear_object (&ctx->qmi);
+    g_slice_free (EnablingStartedContext, ctx);
+}
+
 static gboolean
-enabling_started_finish (MMBroadbandModem *self,
-                         GAsyncResult *res,
-                         GError **error)
+enabling_started_finish (MMBroadbandModem  *self,
+                         GAsyncResult      *res,
+                         GError           **error)
 {
     return g_task_propagate_boolean (G_TASK (res), error);
 }
 
 static void
-parent_enabling_started_ready (MMBroadbandModem *self,
-                               GAsyncResult *res,
-                               GTask *task)
+wds_set_autoconnect_settings_ready (QmiClientWds *client,
+                                    GAsyncResult *res,
+                                    GTask        *task)
 {
-    GError *error = NULL;
+    MMBroadbandModemQmi *self;
+    g_autoptr(GError)    error = NULL;
+    g_autoptr(QmiMessageWdsSetAutoconnectSettingsOutput) output = NULL;
 
-    if (!MM_BROADBAND_MODEM_CLASS (mm_broadband_modem_qmi_parent_class)->enabling_started_finish (
-            self,
-            res,
-            &error)) {
-        /* Don't treat this as fatal. Parent enabling may fail if it cannot grab a primary
-         * AT port, which isn't really an issue in QMI-based modems */
-        mm_dbg ("Couldn't start parent enabling: %s", error->message);
-        g_error_free (error);
-    }
+    self = g_task_get_source_object (task);
 
+    output = qmi_client_wds_set_autoconnect_settings_finish (client, res, &error);
+    if (!output || !qmi_message_wds_set_autoconnect_settings_output_get_result (output, &error))
+        mm_obj_warn (self, "failed disabling autoconnect: %s", error->message);
+    else
+        mm_obj_info (self, "autoconnect explicitly disabled");
     g_task_return_boolean (task, TRUE);
     g_object_unref (task);
 }
 
 static void
-enabling_started (MMBroadbandModem *self,
-                  GAsyncReadyCallback callback,
-                  gpointer user_data)
+wds_get_autoconnect_settings_ready (QmiClientWds *client,
+                                    GAsyncResult *res,
+                                    GTask        *task)
+{
+    MMBroadbandModemQmi      *self;
+    QmiWdsAutoconnectSetting  autoconnect_setting;
+    g_autoptr(GError)         error = NULL;
+    g_autoptr(QmiMessageWdsSetAutoconnectSettingsInput)  input  = NULL;
+    g_autoptr(QmiMessageWdsGetAutoconnectSettingsOutput) output = NULL;
+
+    self = g_task_get_source_object (task);
+
+    output = qmi_client_wds_get_autoconnect_settings_finish (client, res, &error);
+    if (!output ||
+        !qmi_message_wds_get_autoconnect_settings_output_get_result (output, &error) ||
+        !qmi_message_wds_get_autoconnect_settings_output_get_status (output, &autoconnect_setting, &error)) {
+        mm_obj_warn (self, "failed checking whether autoconnect is disabled or not: %s", error->message);
+        g_task_return_boolean (task, TRUE);
+        g_object_unref (task);
+        return;
+    }
+
+    if (autoconnect_setting != QMI_WDS_AUTOCONNECT_SETTING_ENABLED) {
+        mm_obj_dbg (self, "autoconnect is already disabled");
+        g_task_return_boolean (task, TRUE);
+        g_object_unref (task);
+        return;
+    }
+
+    mm_obj_dbg (self, "need to explicitly disable autoconnect");
+    input = qmi_message_wds_set_autoconnect_settings_input_new ();
+    qmi_message_wds_set_autoconnect_settings_input_set_status (input, QMI_WDS_AUTOCONNECT_SETTING_DISABLED, NULL);
+    qmi_client_wds_set_autoconnect_settings (client,
+                                             input,
+                                             10,
+                                             NULL,
+                                             (GAsyncReadyCallback) wds_set_autoconnect_settings_ready,
+                                             task);
+}
+
+static void
+enabling_wds_client_ready (MMPortQmi    *qmi,
+                           GAsyncResult *res,
+                           GTask        *task)
+{
+    MMBroadbandModemQmi    *self;
+    EnablingStartedContext *ctx;
+    g_autoptr(GError)       error = NULL;
+
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
+
+    if (!mm_port_qmi_allocate_client_finish (qmi, res, &error)) {
+        mm_obj_warn (self, "cannot check whether autoconnect is disabled or not: "
+                     "couldn't allocate client for WDS service: %s", error->message);
+        g_task_return_boolean (task, TRUE);
+        g_object_unref (task);
+        return;
+    }
+
+    ctx->wds = QMI_CLIENT_WDS (mm_port_qmi_get_client (ctx->qmi,
+                                                       QMI_SERVICE_WDS,
+                                                       MM_PORT_QMI_FLAG_DEFAULT));
+
+    qmi_client_wds_get_autoconnect_settings (ctx->wds,
+                                             NULL,
+                                             5,
+                                             NULL,
+                                             (GAsyncReadyCallback) wds_get_autoconnect_settings_ready,
+                                             task);
+}
+
+static void
+parent_enabling_started_ready (MMBroadbandModem *_self,
+                               GAsyncResult     *res,
+                               GTask            *task)
+{
+    MMBroadbandModemQmi    *self = MM_BROADBAND_MODEM_QMI (_self);
+    EnablingStartedContext *ctx;
+    g_autoptr(GError)       error = NULL;
+
+    if (!MM_BROADBAND_MODEM_CLASS (mm_broadband_modem_qmi_parent_class)->enabling_started_finish (_self, res, &error)) {
+        /* Don't treat this as fatal. Parent enabling may fail if it cannot grab a primary
+         * AT port, which isn't really an issue in QMI-based modems */
+        mm_obj_dbg (self, "couldn't start parent enabling: %s", error->message);
+    }
+
+    /* If the autoconnect check has already been done, we're finished */
+    if (self->priv->autoconnect_checked) {
+        g_task_return_boolean (task, TRUE);
+        g_object_unref (task);
+        return;
+    }
+
+    /* The connection logic doesn't work properly when the device is already set
+     * to autoconnect, so automatically disable autoconnect ourselves. */
+    mm_obj_dbg (self, "need to check whether autoconnect is disabled or not...");
+    self->priv->autoconnect_checked = TRUE;
+
+    /* Setup context */
+    ctx = g_slice_new0 (EnablingStartedContext);
+    g_task_set_task_data (task, ctx, (GDestroyNotify)enabling_started_context_free);
+
+    /* Keep a full port reference around */
+    ctx->qmi = mm_base_modem_get_port_qmi (MM_BASE_MODEM (self));
+    if (!ctx->qmi) {
+        mm_obj_warn (self, "cannot check whether autoconnect is disabled or not: couldn't peek QMI port");
+        /* not fatal, just assume autoconnect is disabled */
+        g_task_return_boolean (task, TRUE);
+        g_object_unref (task);
+        return;
+    }
+
+    /* By default there is no generic WDS client preallocated in the QMI port,
+     * so explicitly allocate one ourselves */
+    mm_port_qmi_allocate_client (ctx->qmi,
+                                 QMI_SERVICE_WDS,
+                                 MM_PORT_QMI_FLAG_DEFAULT,
+                                 NULL,
+                                 (GAsyncReadyCallback)enabling_wds_client_ready,
+                                 task);
+}
+
+static void
+enabling_started (MMBroadbandModem    *self,
+                  GAsyncReadyCallback  callback,
+                  gpointer             user_data)
 {
     GTask *task;
 
@@ -8619,6 +9363,7 @@
     QMI_SERVICE_UIM,
     QMI_SERVICE_LOC,
     QMI_SERVICE_PDC,
+    QMI_SERVICE_VOICE,
 };
 
 typedef struct {
@@ -8657,7 +9402,7 @@
     if (error) {
         /* Don't treat this as fatal. Parent initialization may fail if it cannot grab a primary
          * AT port, which isn't really an issue in QMI-based modems */
-        mm_dbg ("Couldn't start parent initialization: %s", error->message);
+        mm_obj_dbg (self, "couldn't start parent initialization: %s", error->message);
         g_error_free (error);
     }
 
@@ -8683,8 +9428,8 @@
                        MMBroadbandModemQmi *self)
 {
     /* Reprobe the modem here so we can get notifications back. */
-    mm_info ("Connection to qmi-proxy for %s lost, reprobing",
-             qmi_device_get_path_display (device));
+    mm_obj_info (self, "connection to qmi-proxy for %s lost, reprobing",
+                 qmi_device_get_path_display (device));
 
     g_signal_handler_disconnect (device, self->priv->qmi_device_removed_id);
     self->priv->qmi_device_removed_id = 0;
@@ -8733,15 +9478,17 @@
                                 GAsyncResult *res,
                                 GTask *task)
 {
+    MMBroadbandModemQmi *self;
     InitializationStartedContext *ctx;
     GError *error = NULL;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     if (!mm_port_qmi_allocate_client_finish (qmi, res, &error)) {
-        mm_dbg ("Couldn't allocate client for service '%s': %s",
-                qmi_service_get_string (qmi_services[ctx->service_index]),
-                error->message);
+        mm_obj_dbg (self, "couldn't allocate client for service '%s': %s",
+                    qmi_service_get_string (qmi_services[ctx->service_index]),
+                    error->message);
         g_error_free (error);
     }
 
@@ -8796,10 +9543,12 @@
                      GAsyncResult *res,
                      GTask *task)
 {
+    MMBroadbandModemQmi *self;
     InitializationStartedContext *ctx;
     GError *error = NULL;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     if (!mm_port_qmi_open_finish (qmi, res, &error)) {
         /* Really, really old devices (Gobi 1K, 2008-era firmware) may not
@@ -8807,7 +9556,7 @@
          * try without it.  The qmi_wwan driver will fix up any issues that
          * the device might have between raw-ip and 802.3 mode anyway.
          */
-        mm_dbg ("Couldn't open QMI port with data format update: %s", error->message);
+        mm_obj_dbg (self, "couldn't open QMI port with data format update: %s", error->message);
         g_error_free (error);
         mm_port_qmi_open (ctx->qmi,
                           FALSE,
@@ -9062,9 +9811,20 @@
 static void
 iface_modem_3gpp_ussd_init (MMIfaceModem3gppUssd *iface)
 {
-    /* Assume we don't have USSD support */
-    iface->check_support = NULL;
-    iface->check_support_finish = NULL;
+    iface->check_support = modem_3gpp_ussd_check_support;
+    iface->check_support_finish = modem_3gpp_ussd_check_support_finish;
+    iface->setup_unsolicited_events = modem_3gpp_ussd_setup_unsolicited_events;
+    iface->setup_unsolicited_events_finish = common_3gpp_ussd_setup_cleanup_unsolicited_events_finish;
+    iface->cleanup_unsolicited_events = modem_3gpp_ussd_cleanup_unsolicited_events;
+    iface->cleanup_unsolicited_events_finish = common_3gpp_ussd_setup_cleanup_unsolicited_events_finish;
+    iface->enable_unsolicited_events = modem_3gpp_ussd_enable_unsolicited_events;
+    iface->enable_unsolicited_events_finish = common_3gpp_ussd_enable_disable_unsolicited_events_finish;
+    iface->disable_unsolicited_events = modem_3gpp_ussd_disable_unsolicited_events;
+    iface->disable_unsolicited_events_finish = common_3gpp_ussd_enable_disable_unsolicited_events_finish;
+    iface->send = modem_3gpp_ussd_send;
+    iface->send_finish = modem_3gpp_ussd_send_finish;
+    iface->cancel = modem_3gpp_ussd_cancel;
+    iface->cancel_finish = modem_3gpp_ussd_cancel_finish;
 }
 
 static void
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c
index 6b7687f..a56ae35 100644
--- a/src/mm-broadband-modem.c
+++ b/src/mm-broadband-modem.c
@@ -48,7 +48,7 @@
 #include "mm-sms-part-3gpp.h"
 #include "mm-call-list.h"
 #include "mm-base-sim.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-modem-helpers.h"
 #include "mm-error-helpers.h"
 #include "mm-port-serial-qcdm.h"
@@ -106,6 +106,7 @@
     PROP_MODEM_3GPP_CS_NETWORK_SUPPORTED,
     PROP_MODEM_3GPP_PS_NETWORK_SUPPORTED,
     PROP_MODEM_3GPP_EPS_NETWORK_SUPPORTED,
+    PROP_MODEM_3GPP_5GS_NETWORK_SUPPORTED,
     PROP_MODEM_3GPP_IGNORED_FACILITY_LOCKS,
     PROP_MODEM_3GPP_INITIAL_EPS_BEARER,
     PROP_MODEM_CDMA_CDMA1X_REGISTRATION_STATE,
@@ -179,6 +180,7 @@
     gboolean modem_3gpp_cs_network_supported;
     gboolean modem_3gpp_ps_network_supported;
     gboolean modem_3gpp_eps_network_supported;
+    gboolean modem_3gpp_5gs_network_supported;
     /* Implementation helpers */
     GPtrArray *modem_3gpp_registration_regex;
     MMModem3gppFacility modem_3gpp_ignored_facility_locks;
@@ -427,7 +429,7 @@
     task = g_task_new (self, NULL, callback, user_data);
 
     /* We just create a MMBroadbandBearer */
-    mm_dbg ("Creating Broadband bearer in broadband modem");
+    mm_obj_dbg (self, "creating broadband bearer in broadband modem...");
     mm_broadband_bearer_new (MM_BROADBAND_MODEM (self),
                              props,
                              NULL, /* cancellable */
@@ -501,6 +503,10 @@
     const gchar *response;
     GArray      *modes;
     guint        i;
+    gboolean     is_2g = FALSE;
+    gboolean     is_3g = FALSE;
+    gboolean     is_4g = FALSE;
+    gboolean     is_5g = FALSE;
 
     ctx = g_task_get_task_data (task);
 
@@ -513,27 +519,37 @@
     if (!modes)
         goto out;
 
-    /* Add LTE caps if any of the reported modes supports 4G */
+    /* Process list of modes to gather supported ones */
     for (i = 0; i < modes->len; i++) {
-        if (g_array_index (modes, MMModemMode, i) & MM_MODEM_MODE_4G) {
-            ctx->caps |= MM_MODEM_CAPABILITY_LTE;
-            break;
-        }
+        if (g_array_index (modes, MMModemMode, i) & MM_MODEM_MODE_2G)
+            is_2g = TRUE;
+        if (g_array_index (modes, MMModemMode, i) & MM_MODEM_MODE_3G)
+            is_3g = TRUE;
+        if (g_array_index (modes, MMModemMode, i) & MM_MODEM_MODE_4G)
+            is_4g = TRUE;
+        if (g_array_index (modes, MMModemMode, i) & MM_MODEM_MODE_5G)
+            is_5g = TRUE;
     }
 
+    /* Add capabilities from modes */
+    if (is_2g || is_3g)
+        ctx->caps |= MM_MODEM_CAPABILITY_GSM_UMTS;
+    if (is_4g)
+        ctx->caps |= MM_MODEM_CAPABILITY_LTE;
+    if (is_5g)
+        ctx->caps |= MM_MODEM_CAPABILITY_5GNR;
+
     /* The +CGSM capability is saying that the modem is a 3GPP modem, but that
      * doesn't necessarily mean it's a GSM/UMTS modem, it could be a LTE-only
-     * device. We did add the GSM_UMTS capability when +CGSM was found, so now
-     * we'll check if the device only reports 4G-only mode, and remove the
-     * capability if so.
+     * or 5GNR-only device. We did add the GSM_UMTS capability when +CGSM was
+     * found, so now we'll check if the device only reports 4G or 5G modes, and
+     * remove the capability if so.
      *
      * Note that we don't change the default +CGSM -> GSM/UMTS logic, we just
      * fix it up.
      */
-    if ((modes->len == 1) && (g_array_index (modes, MMModemMode, 0) == MM_MODEM_MODE_4G)) {
-        g_assert (ctx->caps & MM_MODEM_CAPABILITY_LTE);
+    if ((is_4g || is_5g) && !is_2g && !is_3g)
         ctx->caps &= ~MM_MODEM_CAPABILITY_GSM_UMTS;
-    }
 
     g_array_unref (modes);
 
@@ -760,6 +776,7 @@
                       GAsyncResult *res,
                       GTask *task)
 {
+    MMBroadbandModem *self;
     LoadCapabilitiesContext *ctx;
     QcdmResult *result;
     gint err = QCDM_SUCCESS;
@@ -767,12 +784,13 @@
     GError *error = NULL;
     GByteArray *response;
 
+    self = g_task_get_source_object (task);
     ctx = g_task_get_task_data (task);
 
     response = mm_port_serial_qcdm_command_finish (port, res, &error);
     if (error) {
         /* Fall back to AT checking */
-        mm_dbg ("Failed to load NV ModePref: %s", error->message);
+        mm_obj_dbg (self, "failed to load NV ModePref: %s", error->message);
         g_error_free (error);
         goto at_caps;
     }
@@ -783,7 +801,7 @@
                                                &err);
     g_byte_array_unref (response);
     if (!result) {
-        mm_dbg ("Failed to parse NV ModePref result: %d", err);
+        mm_obj_dbg (self, "failed to parse NV ModePref result: %d", err);
         g_byte_array_unref (response);
         goto at_caps;
     }
@@ -791,7 +809,7 @@
     err = qcdm_result_get_u8 (result, QCDM_CMD_NV_GET_MODE_PREF_ITEM_MODE_PREF, &pref);
     qcdm_result_unref (result);
     if (err) {
-        mm_dbg ("Failed to read NV ModePref: %d", err);
+        mm_obj_dbg (self, "failed to read NV ModePref: %d", err);
         goto at_caps;
     }
 
@@ -847,8 +865,7 @@
     g_assert (ctx->qcdm_port);
 
     if (!mm_port_serial_open (MM_PORT_SERIAL (ctx->qcdm_port), &error)) {
-        mm_dbg ("Failed to open QCDM port for NV ModePref request: %s",
-                error->message);
+        mm_obj_dbg (self, "failed to open QCDM port for NV ModePref request: %s", error->message);
         g_error_free (error);
         ctx->qcdm_port = NULL;
         load_current_capabilities_at (task);
@@ -878,11 +895,10 @@
     LoadCapabilitiesContext *ctx;
     GTask *task;
 
-    mm_dbg ("loading current capabilities...");
-
-    ctx = g_slice_new0 (LoadCapabilitiesContext);
+    mm_obj_dbg (self, "loading current capabilities...");
 
     task = g_task_new (self, NULL, callback, user_data);
+    ctx = g_slice_new0 (LoadCapabilitiesContext);
     g_task_set_task_data (task, ctx, (GDestroyNotify)load_capabilities_context_free);
 
     if (mm_base_modem_peek_port_qcdm (MM_BASE_MODEM (self)))
@@ -920,7 +936,7 @@
     result = mm_base_modem_at_sequence_finish (MM_BASE_MODEM (self), res, NULL, error);
     if (result) {
         manufacturer = sanitize_info_reply (result, "GMI:");
-        mm_dbg ("loaded manufacturer: %s", manufacturer);
+        mm_obj_dbg (self, "loaded manufacturer: %s", manufacturer);
     }
     return manufacturer;
 }
@@ -936,7 +952,7 @@
                          GAsyncReadyCallback callback,
                          gpointer user_data)
 {
-    mm_dbg ("loading manufacturer...");
+    mm_obj_dbg (self, "loading manufacturer...");
     mm_base_modem_at_sequence (
         MM_BASE_MODEM (self),
         manufacturers,
@@ -960,7 +976,7 @@
     result = mm_base_modem_at_sequence_finish (MM_BASE_MODEM (self), res, NULL, error);
     if (result) {
         model = sanitize_info_reply (result, "GMM:");
-        mm_dbg ("loaded model: %s", model);
+        mm_obj_dbg (self, "loaded model: %s", model);
     }
     return model;
 }
@@ -976,7 +992,7 @@
                   GAsyncReadyCallback callback,
                   gpointer user_data)
 {
-    mm_dbg ("loading model...");
+    mm_obj_dbg (self, "loading model...");
     mm_base_modem_at_sequence (
         MM_BASE_MODEM (self),
         models,
@@ -1000,7 +1016,7 @@
     result = mm_base_modem_at_sequence_finish (MM_BASE_MODEM (self), res, NULL, error);
     if (result) {
         revision = sanitize_info_reply (result, "GMR:");
-        mm_dbg ("loaded revision: %s", revision);
+        mm_obj_dbg (self, "loaded revision: %s", revision);
     }
     return revision;
 }
@@ -1016,7 +1032,7 @@
                      GAsyncReadyCallback callback,
                      gpointer user_data)
 {
-    mm_dbg ("loading revision...");
+    mm_obj_dbg (self, "loading revision...");
     mm_base_modem_at_sequence (
         MM_BASE_MODEM (self),
         revisions,
@@ -1060,7 +1076,7 @@
         } else {
             /* Leave whatever the modem returned alone */
         }
-        mm_dbg ("loaded equipment identifier: %s", equip_id);
+        mm_obj_dbg (self, "loaded equipment identifier: %s", equip_id);
     }
     return equip_id;
 }
@@ -1078,7 +1094,7 @@
 {
     const MMBaseModemAtCommand *commands = equipment_identifiers;
 
-    mm_dbg ("loading equipment identifier...");
+    mm_obj_dbg (self, "loading equipment identifier...");
 
     /* On CDMA-only (non-3GPP) modems, just try +GSN */
     if (mm_iface_modem_is_cdma_only (self))
@@ -1129,7 +1145,7 @@
                              MM_BROADBAND_MODEM (self),
                              ((DeviceIdentifierContext *)ctx)->ati,
                              ((DeviceIdentifierContext *)ctx)->ati1));
-    mm_dbg ("loaded device identifier: %s", device_identifier);
+    mm_obj_dbg (self, "loaded device identifier: %s", device_identifier);
     return device_identifier;
 }
 
@@ -1166,7 +1182,7 @@
                               GAsyncReadyCallback callback,
                               gpointer user_data)
 {
-    mm_dbg ("loading device identifier...");
+    mm_obj_dbg (self, "loading device identifier...");
     mm_base_modem_at_sequence (
         MM_BASE_MODEM (self),
         device_identifier_steps,
@@ -1327,9 +1343,9 @@
         if (mm_port_serial_open (MM_PORT_SERIAL (ctx->qcdm), &error)) {
             ctx->qcdm = g_object_ref (ctx->qcdm);
         } else {
-            mm_dbg ("Couldn't open QCDM port: (%d) %s",
-                    error ? error->code : -1,
-                    error ? error->message : "(unknown)");
+            mm_obj_dbg (self, "couldn't open QCDM port: (%d) %s",
+                        error ? error->code : -1,
+                        error ? error->message : "(unknown)");
             ctx->qcdm = NULL;
         }
     }
@@ -1337,7 +1353,7 @@
     task = g_task_new (self, NULL, callback, user_data);
     g_task_set_task_data (task, ctx, (GDestroyNotify)own_numbers_context_free);
 
-    mm_dbg ("loading own numbers...");
+    mm_obj_dbg (self, "loading own numbers...");
     mm_base_modem_at_command (MM_BASE_MODEM (self),
                               "+CNUM",
                               3,
@@ -1448,13 +1464,13 @@
 
     /* CDMA-only modems don't need this */
     if (mm_iface_modem_is_cdma_only (self)) {
-        mm_dbg ("Skipping unlock check in CDMA-only modem...");
+        mm_obj_dbg (self, "skipping unlock check in CDMA-only modem...");
         g_task_return_int (task, MM_MODEM_LOCK_NONE);
         g_object_unref (task);
         return;
     }
 
-    mm_dbg ("checking if unlock required...");
+    mm_obj_dbg (self, "checking if unlock required...");
     mm_base_modem_at_command (MM_BASE_MODEM (self),
                               "+CPIN?",
                               10,
@@ -1514,17 +1530,17 @@
 
     response = mm_base_modem_at_command_finish (self, res, &error);
     if (!response) {
-        mm_dbg ("Couldn't load retry count for lock '%s': %s",
-                mm_modem_lock_get_string (unlock_retries_map[ctx->i].lock),
-                error->message);
+        mm_obj_dbg (self, "couldn't load retry count for lock '%s': %s",
+                    mm_modem_lock_get_string (unlock_retries_map[ctx->i].lock),
+                    error->message);
         goto next;
     }
 
     val = mm_parse_csim_response (response, &error);
     if (val < 0) {
-        mm_dbg ("Couldn't parse retry count value for lock '%s': %s",
-                mm_modem_lock_get_string (unlock_retries_map[ctx->i].lock),
-                error->message);
+        mm_obj_dbg (self, "couldn't parse retry count value for lock '%s': %s",
+                    mm_modem_lock_get_string (unlock_retries_map[ctx->i].lock),
+                    error->message);
         goto next;
     }
 
@@ -1640,7 +1656,7 @@
                     self->priv->modem_cdma_evdo_network_supported = TRUE;
                     g_object_notify (G_OBJECT (self), MM_IFACE_MODEM_CDMA_EVDO_NETWORK_SUPPORTED);
                 }
-                mm_dbg ("Device allows (CDMA) 3G network mode");
+                mm_obj_dbg (self, "device allows (CDMA) 3G network mode");
                 mode |= MM_MODEM_MODE_3G;
             }
             /* IS-707 is the 1xRTT family, which we consider as 2G */
@@ -1649,7 +1665,7 @@
                     self->priv->modem_cdma_cdma1x_network_supported = TRUE;
                     g_object_notify (G_OBJECT (self), MM_IFACE_MODEM_CDMA_CDMA1X_NETWORK_SUPPORTED);
                 }
-                mm_dbg ("Device allows (CDMA) 2G network mode");
+                mm_obj_dbg (self, "device allows (CDMA) 2G network mode");
                 mode |= MM_MODEM_MODE_2G;
             }
         }
@@ -1668,16 +1684,16 @@
     }
 
     if (error) {
-        mm_dbg ("Generic query of supported CDMA networks failed: '%s'", error->message);
+        mm_obj_dbg (self, "generic query of supported CDMA networks failed: '%s'", error->message);
         g_error_free (error);
 
         /* Use defaults */
         if (self->priv->modem_cdma_cdma1x_network_supported) {
-            mm_dbg ("Assuming device allows (CDMA) 2G network mode");
+            mm_obj_dbg (self, "assuming device allows (CDMA) 2G network mode");
             ctx->mode |= MM_MODEM_MODE_2G;
         }
         if (self->priv->modem_cdma_evdo_network_supported) {
-            mm_dbg ("Assuming device allows (CDMA) 3G network mode");
+            mm_obj_dbg (self, "assuming device allows (CDMA) 3G network mode");
             ctx->mode |= MM_MODEM_MODE_3G;
         }
     }
@@ -1702,14 +1718,14 @@
 
     response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
     if (error) {
-        mm_dbg ("Generic query of supported 3GPP networks with WS46=? failed: '%s'", error->message);
+        mm_obj_dbg (self, "generic query of supported 3GPP networks with WS46=? failed: '%s'", error->message);
         g_error_free (error);
         goto out;
     }
 
     modes = mm_3gpp_parse_ws46_test_response (response, &error);
     if (!modes) {
-        mm_dbg ("Parsing WS46=? response failed: '%s'", error->message);
+        mm_obj_dbg (self, "parsing WS46=? response failed: '%s'", error->message);
         g_error_free (error);
         goto out;
     }
@@ -1723,7 +1739,7 @@
         ctx->mode |= mode;
 
         str = mm_modem_mode_build_string_from_mask (mode);
-        mm_dbg ("Device allows (3GPP) mode combination: %s", str);
+        mm_obj_dbg (self, "device allows (3GPP) mode combination: %s", str);
         g_free (str);
     }
 
@@ -1756,7 +1772,7 @@
         if (g_strstr_len (lower, -1, "gsm") ||
             g_strstr_len (lower, -1, "gprs") ||
             g_strstr_len (lower, -1, "edge")) {
-            mm_dbg ("Device allows (3GPP) 2G networks");
+            mm_obj_dbg (self, "device allows (3GPP) 2G networks");
             mode |= MM_MODEM_MODE_2G;
         }
 
@@ -1764,12 +1780,12 @@
             g_strstr_len (lower, -1, "hsdpa") ||
             g_strstr_len (lower, -1, "hsupa") ||
             g_strstr_len (lower, -1, "hspa+")) {
-            mm_dbg ("Device allows (3GPP) 3G networks");
+            mm_obj_dbg (self, "device allows (3GPP) 3G networks");
             mode |= MM_MODEM_MODE_3G;
         }
 
         if (g_strstr_len (lower, -1, "lte")) {
-            mm_dbg ("Device allows (3GPP) 4G networks");
+            mm_obj_dbg (self, "device allows (3GPP) 4G networks");
             mode |= MM_MODEM_MODE_4G;
         }
 
@@ -1777,11 +1793,11 @@
 
         /* If no expected ID found, log error */
         if (mode == MM_MODEM_MODE_NONE)
-            mm_dbg ("Invalid list of supported networks reported by *CNTI: '%s'", response);
+            mm_obj_dbg (self, "invalid list of supported networks reported by *CNTI: '%s'", response);
         else
             ctx->mode |= mode;
     } else {
-        mm_dbg ("Generic query of supported 3GPP networks with *CNTI failed: '%s'", error->message);
+        mm_obj_dbg (self, "generic query of supported 3GPP networks with *CNTI failed: '%s'", error->message);
         g_error_free (error);
     }
 
@@ -1853,7 +1869,7 @@
     LoadSupportedModesContext *ctx;
     GTask *task;
 
-    mm_dbg ("loading supported modes...");
+    mm_obj_dbg (self, "loading supported modes...");
     ctx = g_new0 (LoadSupportedModesContext, 1);
     ctx->mode = MM_MODEM_MODE_NONE;
 
@@ -1906,7 +1922,7 @@
     if (response) {
         GList *formats, *l;
 
-        formats = mm_3gpp_parse_cgdcont_test_response (response, &error);
+        formats = mm_3gpp_parse_cgdcont_test_response (response, self, &error);
         for (l = formats; l; l = g_list_next (l))
             mask |= ((MM3gppPdpContextFormat *)(l->data))->pdp_type;
 
@@ -1928,7 +1944,7 @@
 {
     GTask *task;
 
-    mm_dbg ("loading supported IP families...");
+    mm_obj_dbg (self, "loading supported IP families...");
     task = g_task_new (self, NULL, callback, user_data);
 
     if (mm_iface_modem_is_cdma_only (self)) {
@@ -1982,7 +1998,7 @@
                                                     &pilot_pn,
                                                     &pilot_energy,
                                                     &rssi_dbm)) {
-        mm_dbg ("EVDO active pilot RSSI: %ddBm", rssi_dbm);
+        mm_obj_dbg (self, "EVDO active pilot RSSI: %ddBm", rssi_dbm);
         self->priv->evdo_pilot_rssi = rssi_dbm;
     }
 
@@ -2134,14 +2150,11 @@
                            GAsyncResult *res,
                            GTask *task)
 {
-    SignalQualityContext *ctx;
     GError *error = NULL;
     const gchar *result;
     GByteArray *indicators;
     guint quality = 0;
 
-    ctx = g_task_get_task_data (task);
-
     result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
     if (error) {
         g_clear_error (&error);
@@ -2150,19 +2163,17 @@
 
     indicators = mm_3gpp_parse_cind_read_response (result, &error);
     if (!indicators) {
-        mm_dbg ("(%s) Could not parse CIND signal quality results: %s",
-                mm_port_get_device (MM_PORT (ctx->at_port)),
-                error->message);
+        mm_obj_dbg (self, "could not parse CIND signal quality results: %s", error->message);
         g_clear_error (&error);
         goto try_csq;
     }
 
     if (indicators->len < self->priv->modem_cind_indicator_signal_quality) {
-        mm_dbg ("(%s) Could not parse CIND signal quality results; signal "
-                "index (%u) outside received range (0-%u)",
-                mm_port_get_device (MM_PORT (ctx->at_port)),
-                self->priv->modem_cind_indicator_signal_quality,
-                indicators->len);
+        mm_obj_dbg (self,
+                    "could not parse CIND signal quality results; signal "
+                    "index (%u) outside received range (0-%u)",
+                    self->priv->modem_cind_indicator_signal_quality,
+                    indicators->len);
     } else {
         quality = g_array_index (indicators,
                                  guint8,
@@ -2317,7 +2328,7 @@
     GError *error = NULL;
     GTask *task;
 
-    mm_dbg ("loading signal quality...");
+    mm_obj_dbg (self, "loading signal quality...");
     ctx = g_new0 (SignalQualityContext, 1);
 
     task = g_task_new (self, NULL, callback, user_data);
@@ -2348,7 +2359,7 @@
         }
 
         ctx->qcdm_port = NULL;
-        mm_dbg ("Couldn't open QCDM port: %s", error->message);
+        mm_obj_dbg (self, "couldn't open QCDM port: %s", error->message);
     }
 
     /* Return the error we got when getting best AT port */
@@ -2408,24 +2419,25 @@
 }
 
 static AccessTechAndMask *
-access_tech_and_mask_new (AccessTechContext *ctx)
+access_tech_and_mask_new (MMBroadbandModem  *self,
+                          AccessTechContext *ctx)
 {
     AccessTechAndMask *tech;
     MMModemAccessTechnology act = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
     guint mask = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
 
     if (ctx->fallback_mask) {
-        mm_dbg ("Fallback access technology: 0x%08x", ctx->fallback_act);
+        mm_obj_dbg (self, "fallback access technology: 0x%08x", ctx->fallback_act);
         act = ctx->fallback_act;
         mask = ctx->fallback_mask;
         goto done;
     }
 
-    mm_dbg ("QCDM operating mode: %d", ctx->opmode);
-    mm_dbg ("QCDM system mode: %d", ctx->sysmode);
-    mm_dbg ("QCDM hybrid pref: %d", ctx->hybrid);
-    mm_dbg ("QCDM WCDMA open: %d", ctx->wcdma_open);
-    mm_dbg ("QCDM EVDO open: %d", ctx->evdo_open);
+    mm_obj_dbg (self, "QCDM operating mode: %d", ctx->opmode);
+    mm_obj_dbg (self, "QCDM system mode: %d", ctx->sysmode);
+    mm_obj_dbg (self, "QCDM hybrid pref: %d", ctx->hybrid);
+    mm_obj_dbg (self, "QCDM WCDMA open: %d", ctx->wcdma_open);
+    mm_obj_dbg (self, "QCDM EVDO open: %d", ctx->evdo_open);
 
     if (ctx->opmode == QCDM_CMD_CM_SUBSYS_STATE_INFO_OPERATING_MODE_ONLINE) {
         switch (ctx->sysmode) {
@@ -2481,6 +2493,7 @@
                               GAsyncResult *res,
                               GTask *task)
 {
+    MMBroadbandModem *self;
     AccessTechContext *ctx;
     QcdmResult *result;
     gint err = QCDM_SUCCESS;
@@ -2495,6 +2508,7 @@
         return;
     }
 
+    self = g_task_get_source_object (task);
     ctx = g_task_get_task_data (task);
 
     /* Parse the response */
@@ -2513,7 +2527,9 @@
             ctx->wcdma_open = TRUE;
     }
 
-    g_task_return_pointer (task, access_tech_and_mask_new (ctx), g_free);
+    g_task_return_pointer (task,
+                           access_tech_and_mask_new (MM_BROADBAND_MODEM (self), ctx),
+                           g_free);
     g_object_unref (task);
 }
 
@@ -2581,6 +2597,7 @@
                             GAsyncResult *res,
                             GTask *task)
 {
+    MMBroadbandModem *self;
     AccessTechContext *ctx;
     QcdmResult *result;
     gint err = QCDM_SUCCESS;
@@ -2596,7 +2613,8 @@
         return;
     }
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     /* Parse the response */
     result = qcdm_cmd_hdr_subsys_state_info_result ((const gchar *) response->data,
@@ -2614,7 +2632,7 @@
             ctx->evdo_open = TRUE;
     }
 
-    g_task_return_pointer (task, access_tech_and_mask_new (ctx), g_free);
+    g_task_return_pointer (task, access_tech_and_mask_new (self, ctx), g_free);
     g_object_unref (task);
 }
 
@@ -2697,9 +2715,9 @@
         ctx->fallback_mask = MM_IFACE_MODEM_CDMA_ALL_ACCESS_TECHNOLOGIES_MASK;
     }
 
-    mm_dbg ("EVDO registration: %d", self->priv->modem_cdma_evdo_registration_state);
-    mm_dbg ("CDMA1x registration: %d", self->priv->modem_cdma_cdma1x_registration_state);
-    mm_dbg ("Fallback access tech: 0x%08x", ctx->fallback_act);
+    mm_obj_dbg (self, "EVDO registration: %d", self->priv->modem_cdma_evdo_registration_state);
+    mm_obj_dbg (self, "CDMA1x registration: %d", self->priv->modem_cdma_cdma1x_registration_state);
+    mm_obj_dbg (self, "fallback access tech: 0x%08x", ctx->fallback_act);
 }
 
 static void
@@ -2727,7 +2745,7 @@
         if (mm_port_serial_open (MM_PORT_SERIAL (ctx->port), &error)) {
             g_object_ref (ctx->port);
 
-            mm_dbg ("loading access technologies via QCDM...");
+            mm_obj_dbg (self, "loading access technologies via QCDM...");
 
             /* FIXME: we may want to run both the CDMA and 3GPP in sequence to ensure
              * that a multi-mode device that's in CDMA-mode but still has 3GPP capabilities
@@ -2768,7 +2786,7 @@
         }
 
         ctx->port = NULL;
-        mm_dbg ("Couldn't open QCDM port: %s", error->message);
+        mm_obj_dbg (self, "couldn't open QCDM port: %s", error->message);
         g_clear_error (&error);
     }
 
@@ -2778,7 +2796,9 @@
          * guess access technologies from the registration information.
          */
         access_tech_from_cdma_registration_state (MM_BROADBAND_MODEM (self), ctx);
-        g_task_return_pointer (task, access_tech_and_mask_new (ctx), g_free);
+        g_task_return_pointer (task,
+                               access_tech_and_mask_new (MM_BROADBAND_MODEM (self), ctx),
+                               g_free);
     } else {
         g_task_return_new_error (task,
                                  MM_CORE_ERROR,
@@ -2818,7 +2838,7 @@
     if (mm_base_bearer_get_status (bearer) == MM_BEARER_STATUS_DISCONNECTED)
         return;
 
-    mm_info ("Bearer %s: explicitly disconnected", mm_base_bearer_get_path (bearer));
+    mm_obj_info (bearer, "explicitly disconnected");
     mm_base_bearer_report_connection_status (bearer, MM_BEARER_CONNECTION_STATUS_DISCONNECTED);
 }
 
@@ -2845,13 +2865,13 @@
                      MM3gppCgev        type)
 {
     if (type == MM_3GPP_CGEV_NW_DETACH) {
-        mm_info ("network forced PS detach: all contexts have been deactivated");
+        mm_obj_info (self, "network forced PS detach: all contexts have been deactivated");
         bearer_list_report_disconnections (self, 0);
         return;
     }
 
     if (type == MM_3GPP_CGEV_ME_DETACH) {
-        mm_info ("mobile equipment forced PS detach: all contexts have been deactivated");
+        mm_obj_info (self, "mobile equipment forced PS detach: all contexts have been deactivated");
         bearer_list_report_disconnections (self, 0);
         return;
     }
@@ -2868,24 +2888,24 @@
     guint   cid = 0;
 
     if (!mm_3gpp_parse_cgev_indication_primary (str, type, &cid, &error)) {
-        mm_warn ("couldn't parse cid info from +CGEV indication '%s': %s", str, error->message);
+        mm_obj_warn (self, "couldn't parse cid info from +CGEV indication '%s': %s", str, error->message);
         g_error_free (error);
         return;
     }
 
     switch (type) {
     case MM_3GPP_CGEV_NW_ACT_PRIMARY:
-        mm_info ("network request to activate context (cid %u)", cid);
+        mm_obj_info (self, "network request to activate context (cid %u)", cid);
         break;
     case MM_3GPP_CGEV_ME_ACT_PRIMARY:
-        mm_info ("mobile equipment request to activate context (cid %u)", cid);
+        mm_obj_info (self, "mobile equipment request to activate context (cid %u)", cid);
         break;
     case MM_3GPP_CGEV_NW_DEACT_PRIMARY:
-        mm_info ("network request to deactivate context (cid %u)", cid);
+        mm_obj_info (self, "network request to deactivate context (cid %u)", cid);
         bearer_list_report_disconnections (self, cid);
         break;
     case MM_3GPP_CGEV_ME_DEACT_PRIMARY:
-        mm_info ("mobile equipment request to deactivate context (cid %u)", cid);
+        mm_obj_info (self, "mobile equipment request to deactivate context (cid %u)", cid);
         bearer_list_report_disconnections (self, cid);
         break;
     case MM_3GPP_CGEV_UNKNOWN:
@@ -2919,24 +2939,24 @@
     guint   cid = 0;
 
     if (!mm_3gpp_parse_cgev_indication_secondary (str, type, &p_cid, &cid, NULL, &error)) {
-        mm_warn ("couldn't parse p_cid/cid info from +CGEV indication '%s': %s", str, error->message);
+        mm_obj_warn (self, "couldn't parse p_cid/cid info from +CGEV indication '%s': %s", str, error->message);
         g_error_free (error);
         return;
     }
 
     switch (type) {
     case MM_3GPP_CGEV_NW_ACT_SECONDARY:
-        mm_info ("network request to activate secondary context (cid %u, primary cid %u)", cid, p_cid);
+        mm_obj_info (self, "network request to activate secondary context (cid %u, primary cid %u)", cid, p_cid);
         break;
     case MM_3GPP_CGEV_ME_ACT_SECONDARY:
-        mm_info ("mobile equipment request to activate secondary context (cid %u, primary cid %u)", cid, p_cid);
+        mm_obj_info (self, "mobile equipment request to activate secondary context (cid %u, primary cid %u)", cid, p_cid);
         break;
     case MM_3GPP_CGEV_NW_DEACT_SECONDARY:
-        mm_info ("network request to deactivate secondary context (cid %u, primary cid %u)", cid, p_cid);
+        mm_obj_info (self, "network request to deactivate secondary context (cid %u, primary cid %u)", cid, p_cid);
         bearer_list_report_disconnections (self, cid);
         break;
     case MM_3GPP_CGEV_ME_DEACT_SECONDARY:
-        mm_info ("mobile equipment request to deactivate secondary context (cid %u, primary cid %u)", cid, p_cid);
+        mm_obj_info (self, "mobile equipment request to deactivate secondary context (cid %u, primary cid %u)", cid, p_cid);
         bearer_list_report_disconnections (self, cid);
         break;
     case MM_3GPP_CGEV_UNKNOWN:
@@ -2971,35 +2991,35 @@
     guint   cid = 0;
 
     if (!mm_3gpp_parse_cgev_indication_pdp (str, type, &pdp_type, &pdp_addr, &cid, &error)) {
-        mm_warn ("couldn't parse PDP info from +CGEV indication '%s': %s", str, error->message);
+        mm_obj_warn (self, "couldn't parse PDP info from +CGEV indication '%s': %s", str, error->message);
         g_error_free (error);
         return;
     }
 
     switch (type) {
     case MM_3GPP_CGEV_REJECT:
-        mm_info ("network request to activate context (type %s, address %s) has been automatically rejected", pdp_type, pdp_addr);
+        mm_obj_info (self, "network request to activate context (type %s, address %s) has been automatically rejected", pdp_type, pdp_addr);
         break;
     case MM_3GPP_CGEV_NW_REACT:
         /* NOTE: we don't currently notify about automatic reconnections like this one */
         if (cid)
-            mm_info ("network request to reactivate context (type %s, address %s, cid %u)", pdp_type, pdp_addr, cid);
+            mm_obj_info (self, "network request to reactivate context (type %s, address %s, cid %u)", pdp_type, pdp_addr, cid);
         else
-            mm_info ("network request to reactivate context (type %s, address %s, cid unknown)", pdp_type, pdp_addr);
+            mm_obj_info (self, "network request to reactivate context (type %s, address %s, cid unknown)", pdp_type, pdp_addr);
         break;
     case MM_3GPP_CGEV_NW_DEACT_PDP:
         if (cid) {
-            mm_info ("network request to deactivate context (type %s, address %s, cid %u)", pdp_type, pdp_addr, cid);
+            mm_obj_info (self, "network request to deactivate context (type %s, address %s, cid %u)", pdp_type, pdp_addr, cid);
             bearer_list_report_disconnections (self, cid);
         } else
-            mm_info ("network request to deactivate context (type %s, address %s, cid unknown)", pdp_type, pdp_addr);
+            mm_obj_info (self, "network request to deactivate context (type %s, address %s, cid unknown)", pdp_type, pdp_addr);
         break;
     case MM_3GPP_CGEV_ME_DEACT_PDP:
         if (cid) {
-            mm_info ("mobile equipment request to deactivate context (type %s, address %s, cid %u)", pdp_type, pdp_addr, cid);
+            mm_obj_info (self, "mobile equipment request to deactivate context (type %s, address %s, cid %u)", pdp_type, pdp_addr, cid);
             bearer_list_report_disconnections (self, cid);
         } else
-            mm_info ("mobile equipment request to deactivate context (type %s, address %s, cid unknown)", pdp_type, pdp_addr);
+            mm_obj_info (self, "mobile equipment request to deactivate context (type %s, address %s, cid unknown)", pdp_type, pdp_addr);
         break;
     case MM_3GPP_CGEV_UNKNOWN:
     case MM_3GPP_CGEV_NW_DETACH:
@@ -3070,7 +3090,7 @@
         break;
     case MM_3GPP_CGEV_UNKNOWN:
     default:
-        mm_dbg ("unhandled +CGEV indication: %s", str);
+        mm_obj_dbg (self, "unhandled +CGEV indication: %s", str);
         break;
     }
 
@@ -3095,9 +3115,9 @@
             continue;
 
         /* Set/unset unsolicited CGEV event handler */
-        mm_dbg ("(%s) %s 3GPP +CGEV unsolicited events handlers",
-                mm_port_get_device (MM_PORT (ports[i])),
-                enable ? "Setting" : "Removing");
+        mm_obj_dbg (self, "%s 3GPP +CGEV unsolicited events handlers in %s",
+                    enable ? "setting" : "removing",
+                    mm_port_get_device (MM_PORT (ports[i])));
         mm_port_serial_at_add_unsolicited_msg_handler (
             ports[i],
             cgev_regex,
@@ -3116,7 +3136,7 @@
     guint quality;
 
     if (!mm_get_uint_from_match_info (match_info, 2, &quality)) {
-        mm_dbg ("Couldn't parse signal quality value from +CIEV");
+        mm_obj_dbg (self, "couldn't parse signal quality value from +CIEV");
         return;
     }
 
@@ -3171,9 +3191,9 @@
             continue;
 
         /* Set/unset unsolicited CIEV event handler */
-        mm_dbg ("(%s) %s 3GPP +CIEV unsolicited events handlers",
-                mm_port_get_device (MM_PORT (ports[i])),
-                enable ? "Setting" : "Removing");
+        mm_obj_dbg (self, "%s 3GPP +CIEV unsolicited events handlers in %s",
+                    enable ? "setting" : "removing",
+                    mm_port_get_device (MM_PORT (ports[i])));
         mm_port_serial_at_add_unsolicited_msg_handler (
             ports[i],
             ciev_regex,
@@ -3214,12 +3234,13 @@
 
     result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
     if (!result) {
-        mm_dbg ("+CGEREP check failed, marking packet domain event reporting as unsupported: '%s'", error->message);
+        mm_obj_dbg (self, "+CGEREP check failed: %s", error->message);
+        mm_obj_dbg (self, "packet domain event reporting is unsupported");
         g_error_free (error);
         goto out;
     }
 
-    mm_dbg ("Modem supports packet domain event reporting");
+    mm_obj_dbg (self, "packet domain event reporting is supported");
     self->priv->modem_cgerep_supported = TRUE;
 
 out:
@@ -3239,18 +3260,19 @@
     gchar          *aux;
 
     result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
-    if (error || !mm_3gpp_parse_cmer_test_response (result, &supported_modes, &supported_inds, &error)) {
-        mm_dbg ("+CMER check failed, marking indications as unsupported: '%s'", error->message);
+    if (error || !mm_3gpp_parse_cmer_test_response (result, self, &supported_modes, &supported_inds, &error)) {
+        mm_obj_dbg (self, "+CMER check failed: %s", error->message);
+        mm_obj_dbg (self, "generic indications are unsupported");
         g_error_free (error);
         goto out;
     }
 
     aux = mm_3gpp_cmer_mode_build_string_from_mask (supported_modes);
-    mm_dbg ("Supported +CMER modes: %s", aux);
+    mm_obj_dbg (self, "supported +CMER modes: %s", aux);
     g_free (aux);
 
     aux = mm_3gpp_cmer_ind_build_string_from_mask (supported_inds);
-    mm_dbg ("Supported +CMER indication settings: %s", aux);
+    mm_obj_dbg (self, "supported +CMER indication settings: %s", aux);
     g_free (aux);
 
     /* Flag +CMER supported values */
@@ -3263,14 +3285,14 @@
         self->priv->modem_cmer_enable_mode = MM_3GPP_CMER_MODE_DISCARD_URCS_IF_LINK_RESERVED;
 
     aux = mm_3gpp_cmer_mode_build_string_from_mask (self->priv->modem_cmer_enable_mode);
-    mm_dbg ("+CMER enable mode: %s", aux);
+    mm_obj_dbg (self, "+CMER enable mode: %s", aux);
     g_free (aux);
 
     if (supported_modes & MM_3GPP_CMER_MODE_DISCARD_URCS)
         self->priv->modem_cmer_disable_mode = MM_3GPP_CMER_MODE_DISCARD_URCS;
 
     aux = mm_3gpp_cmer_mode_build_string_from_mask (self->priv->modem_cmer_disable_mode);
-    mm_dbg ("+CMER disable mode: %s", aux);
+    mm_obj_dbg (self, "+CMER disable mode: %s", aux);
     g_free (aux);
 
     if (supported_inds & MM_3GPP_CMER_IND_ENABLE_NOT_CAUSED_BY_CIND)
@@ -3279,7 +3301,7 @@
         self->priv->modem_cmer_ind = MM_3GPP_CMER_IND_ENABLE_ALL;
 
     aux = mm_3gpp_cmer_ind_build_string_from_mask (self->priv->modem_cmer_ind);
-    mm_dbg ("+CMER indication setting: %s", aux);
+    mm_obj_dbg (self, "+CMER indication setting: %s", aux);
     g_free (aux);
 
 out:
@@ -3301,7 +3323,8 @@
     if (error ||
         !(indicators = mm_3gpp_parse_cind_test_response (result, &error))) {
         /* unsupported indications */
-        mm_dbg ("+CIND check failed, marking indications as unsupported: '%s'", error->message);
+        mm_obj_dbg (self, "+CIND check failed: %s", error->message);
+        mm_obj_dbg (self, "generic indications are unsupported");
         g_error_free (error);
         /* go on with remaining checks */
         check_and_setup_3gpp_urc_support (task);
@@ -3319,11 +3342,10 @@
         self->priv->modem_cind_min_signal_quality = mm_3gpp_cind_response_get_min (r);
         self->priv->modem_cind_max_signal_quality = mm_3gpp_cind_response_get_max (r);
 
-        mm_dbg ("Modem supports signal quality indications via CIND at index '%u'"
-                "(min: %u, max: %u)",
-                self->priv->modem_cind_indicator_signal_quality,
-                self->priv->modem_cind_min_signal_quality,
-                self->priv->modem_cind_max_signal_quality);
+        mm_obj_dbg (self, "signal quality indications via CIND are supported at index '%u' (min: %u, max: %u)",
+                    self->priv->modem_cind_indicator_signal_quality,
+                    self->priv->modem_cind_min_signal_quality,
+                    self->priv->modem_cind_max_signal_quality);
     } else
         self->priv->modem_cind_indicator_signal_quality = CIND_INDICATOR_INVALID;
 
@@ -3331,8 +3353,8 @@
     r = g_hash_table_lookup (indicators, "roam");
     if (r) {
         self->priv->modem_cind_indicator_roaming = mm_3gpp_cind_response_get_index (r);
-        mm_dbg ("Modem supports roaming indications via CIND at index '%u'",
-                self->priv->modem_cind_indicator_roaming);
+        mm_obj_dbg (self, "roaming indications via CIND are supported at index '%u'",
+                    self->priv->modem_cind_indicator_roaming);
     } else
         self->priv->modem_cind_indicator_roaming = CIND_INDICATOR_INVALID;
 
@@ -3340,8 +3362,8 @@
     r = g_hash_table_lookup (indicators, "service");
     if (r) {
         self->priv->modem_cind_indicator_service = mm_3gpp_cind_response_get_index (r);
-        mm_dbg ("Modem supports service indications via CIND at index '%u'",
-                self->priv->modem_cind_indicator_service);
+        mm_obj_dbg (self, "service indications via CIND are supported at index '%u'",
+                    self->priv->modem_cind_indicator_service);
     } else
         self->priv->modem_cind_indicator_service = CIND_INDICATOR_INVALID;
 
@@ -3365,7 +3387,7 @@
 
     /* Check support for +CIEV indications, managed with +CIND/+CMER */
     if (!self->priv->modem_cind_disabled && !self->priv->modem_cind_support_checked) {
-        mm_dbg ("Checking indicator support...");
+        mm_obj_dbg (self, "checking indicator support...");
         self->priv->modem_cind_support_checked = TRUE;
         mm_base_modem_at_command (MM_BASE_MODEM (self),
                                   "+CIND=?",
@@ -3378,7 +3400,7 @@
 
     /* Check support for +CGEV indications, managed with +CGEREP */
     if (!self->priv->modem_cgerep_support_checked) {
-        mm_dbg ("Checking packet domain event reporting...");
+        mm_obj_dbg (self, "checking packet domain event reporting...");
         self->priv->modem_cgerep_support_checked = TRUE;
         mm_base_modem_at_command (MM_BASE_MODEM (self),
                                   "+CGEREP=?",
@@ -3471,9 +3493,9 @@
     ctx = g_task_get_task_data (task);
 
     if (!mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error)) {
-        mm_dbg ("Couldn't %s event reporting: '%s'",
-                ctx->enable ? "enable" : "disable",
-                error->message);
+        mm_obj_dbg (self, "couldn't %s event reporting: '%s'",
+                    ctx->enable ? "enable" : "disable",
+                    error->message);
         g_error_free (error);
     }
 
@@ -3494,28 +3516,28 @@
 
     /* CMER on primary port */
     if (!ctx->cmer_primary_done && ctx->cmer_command && ctx->primary && !self->priv->modem_cind_disabled) {
-        mm_dbg ("%s +CIND event reporting in primary port...", ctx->enable ? "Enabling" : "Disabling");
+        mm_obj_dbg (self, "%s +CIND event reporting in primary port...", ctx->enable ? "enabling" : "disabling");
         ctx->cmer_primary_done = TRUE;
         command = ctx->cmer_command;
         port = ctx->primary;
     }
     /* CMER on secondary port */
     else if (!ctx->cmer_secondary_done && ctx->cmer_command && ctx->secondary && !self->priv->modem_cind_disabled) {
-        mm_dbg ("%s +CIND event reporting in secondary port...", ctx->enable ? "Enabling" : "Disabling");
+        mm_obj_dbg (self, "%s +CIND event reporting in secondary port...", ctx->enable ? "enabling" : "disabling");
         ctx->cmer_secondary_done = TRUE;
         command = ctx->cmer_command;
         port = ctx->secondary;
     }
     /* CGEREP on primary port */
     else if (!ctx->cgerep_primary_done && ctx->cgerep_command && ctx->primary) {
-        mm_dbg ("%s +CGEV event reporting in primary port...", ctx->enable ? "Enabling" : "Disabling");
+        mm_obj_dbg (self, "%s +CGEV event reporting in primary port...", ctx->enable ? "enabling" : "disabling");
         ctx->cgerep_primary_done = TRUE;
         command = ctx->cgerep_command;
         port = ctx->primary;
     }
     /* CGEREP on secondary port */
     else if (!ctx->cgerep_secondary_done && ctx->cgerep_command && ctx->secondary) {
-        mm_dbg ("%s +CGEV event reporting in secondary port...", ctx->enable ? "Enabling" : "Disabling");
+        mm_obj_dbg (self, "%s +CGEV event reporting in secondary port...", ctx->enable ? "enabling" : "disabling");
         ctx->cgerep_secondary_done = TRUE;
         port = ctx->secondary;
         command = ctx->cgerep_command;
@@ -3796,7 +3818,7 @@
 
     /* CDMA-only modems don't need this */
     if (mm_iface_modem_is_cdma_only (self)) {
-        mm_dbg ("Skipping supported charset loading in CDMA-only modem...");
+        mm_obj_dbg (self, "skipping supported charset loading in CDMA-only modem...");
         g_task_return_int (task, MM_MODEM_CHARSET_UNKNOWN);
         g_object_unref (task);
         return;
@@ -3845,7 +3867,7 @@
         goto out;
 
     /* Parse response */
-    flow_control_supported = mm_parse_ifc_test_response (response, &error);
+    flow_control_supported = mm_parse_ifc_test_response (response, self, &error);
     if (flow_control_supported == MM_FLOW_CONTROL_UNKNOWN)
         goto out;
     flow_control_supported_str = mm_flow_control_build_string_from_mask (flow_control_supported);
@@ -3872,7 +3894,7 @@
             return;
         }
 
-        mm_dbg ("Flow control settings explicitly requested (%s)", flow_control_requested_str);
+        mm_obj_dbg (self, "flow control settings explicitly requested: %s", flow_control_requested_str);
         flow_control_selected = flow_control_requested;
         flow_control_selected_str = flow_control_requested_str;
     } else {
@@ -3891,7 +3913,7 @@
         else
             g_assert_not_reached ();
         flow_control_selected_str = mm_flow_control_build_string_from_mask (flow_control_selected);
-        mm_dbg ("Flow control settings automatically selected (%s)", flow_control_selected_str);
+        mm_obj_dbg (self, "flow control settings automatically selected: %s", flow_control_selected_str);
     }
 
     /* Select flow control for all connections */
@@ -3921,7 +3943,7 @@
 
     /* Ignore errors */
     if (error) {
-        mm_dbg ("couldn't load supported flow control methods: %s", error->message);
+        mm_obj_dbg (self, "couldn't load supported flow control methods: %s", error->message);
         g_error_free (error);
     }
 
@@ -3995,13 +4017,13 @@
 
     /* CDMA-only modems don't need this */
     if (mm_iface_modem_is_cdma_only (self)) {
-        mm_dbg ("Assuming full power state in CDMA-only modem...");
+        mm_obj_dbg (self, "assuming full power state in CDMA-only modem...");
         g_task_return_int (task, MM_MODEM_POWER_STATE_ON);
         g_object_unref (task);
         return;
     }
 
-    mm_dbg ("loading power state...");
+    mm_obj_dbg (self, "loading power state...");
     mm_base_modem_at_command (MM_BASE_MODEM (self),
                               "+CFUN?",
                               3,
@@ -4033,7 +4055,7 @@
 
     /* CDMA-only modems don't need this */
     if (mm_iface_modem_is_cdma_only (self))
-        mm_dbg ("Skipping Power-up in CDMA-only modem...");
+        mm_obj_dbg (self, "skipping power-up in CDMA-only modem...");
     else
         mm_base_modem_at_command (MM_BASE_MODEM (self),
                                   "+CFUN=1",
@@ -4095,21 +4117,21 @@
         }
 
         if (ctx->retries > 0) {
-            mm_warn ("could not load SIM identifier: %s (%d retries left)",
-                     error->message, ctx->retries);
+            mm_obj_warn (self, "could not load SIM identifier: %s (%d retries left)",
+                         error->message, ctx->retries);
             --ctx->retries;
             g_clear_error (&error);
             g_timeout_add_seconds (1, (GSourceFunc) load_sim_identifier, task);
             return;
         }
 
-        mm_warn ("could not load SIM identifier: %s", error->message);
+        mm_obj_warn (self, "could not load SIM identifier: %s", error->message);
         g_task_return_error (task, error);
         goto out;
     }
 
     if (g_strcmp0 (current_simid, cached_simid) != 0) {
-        mm_info ("sim identifier has changed: possible SIM swap during power down/low");
+        mm_obj_info (self, "sim identifier has changed: possible SIM swap during power down/low");
         mm_broadband_modem_update_sim_hot_swap_detected (self);
     }
 
@@ -4141,7 +4163,7 @@
     GTask *task;
     SimSwapContext *ctx;
 
-    mm_dbg ("Checking if SIM was swapped...");
+    mm_obj_dbg (self, "checking if SIM was swapped...");
 
     task = g_task_new (self, NULL, callback, user_data);
     ctx = g_slice_new0 (SimSwapContext);
@@ -4217,7 +4239,7 @@
 
     result = mm_strip_tag (result, "+CGSN:");
     mm_parse_gsn (result, &imei, NULL, NULL);
-    mm_dbg ("loaded IMEI: %s", imei);
+    mm_obj_dbg (self, "loaded IMEI: %s", imei);
     return imei;
 }
 
@@ -4226,7 +4248,7 @@
                       GAsyncReadyCallback callback,
                       gpointer user_data)
 {
-    mm_dbg ("loading IMEI...");
+    mm_obj_dbg (self, "loading IMEI...");
     mm_base_modem_at_command (MM_BASE_MODEM (self),
                               "+CGSN",
                               3,
@@ -4360,7 +4382,7 @@
         gchar *str;
 
         str = mm_modem_3gpp_facility_build_string_from_mask (MM_BROADBAND_MODEM (self)->priv->modem_3gpp_ignored_facility_locks);
-        mm_dbg ("Ignoring facility locks: '%s'", str);
+        mm_obj_dbg (self, "ignoring facility locks: '%s'", str);
         g_free (str);
 
         ctx->facilities &= ~MM_BROADBAND_MODEM (self)->priv->modem_3gpp_ignored_facility_locks;
@@ -4386,7 +4408,7 @@
     task = g_task_new (self, NULL, callback, user_data);
     g_task_set_task_data (task, ctx, g_free);
 
-    mm_dbg ("loading enabled facility locks...");
+    mm_obj_dbg (self, "loading enabled facility locks...");
     mm_base_modem_at_command (MM_BASE_MODEM (self),
                               "+CLCK=?",
                               3,
@@ -4420,7 +4442,7 @@
 
     mm_3gpp_normalize_operator (&operator_code, MM_BROADBAND_MODEM (self)->priv->modem_current_charset);
     if (operator_code)
-        mm_dbg ("loaded Operator Code: %s", operator_code);
+        mm_obj_dbg (self, "loaded Operator Code: %s", operator_code);
     return operator_code;
 }
 
@@ -4429,7 +4451,7 @@
                                GAsyncReadyCallback callback,
                                gpointer user_data)
 {
-    mm_dbg ("loading Operator Code...");
+    mm_obj_dbg (self, "loading Operator Code...");
     mm_base_modem_at_command (MM_BASE_MODEM (self), "+COPS=3,2", 3, FALSE, NULL, NULL);
     mm_base_modem_at_command (MM_BASE_MODEM (self), "+COPS?", 3, FALSE, callback, user_data);
 }
@@ -4459,7 +4481,7 @@
 
     mm_3gpp_normalize_operator (&operator_name, MM_BROADBAND_MODEM (self)->priv->modem_current_charset);
     if (operator_name)
-        mm_dbg ("loaded Operator Name: %s", operator_name);
+        mm_obj_dbg (self, "loaded Operator Name: %s", operator_name);
     return operator_name;
 }
 
@@ -4468,7 +4490,7 @@
                                GAsyncReadyCallback callback,
                                gpointer user_data)
 {
-    mm_dbg ("loading Operator Name...");
+    mm_obj_dbg (self, "loading Operator Name...");
     mm_base_modem_at_command (MM_BASE_MODEM (self), "+COPS=3,0", 3, FALSE, NULL, NULL);
     mm_base_modem_at_command (MM_BASE_MODEM (self), "+COPS?", 3, FALSE, callback, user_data);
 }
@@ -4496,7 +4518,7 @@
                                        GAsyncReadyCallback  callback,
                                        gpointer             user_data)
 {
-    mm_dbg ("loading UE mode of operation for EPS...");
+    mm_obj_dbg (self, "loading UE mode of operation for EPS...");
     mm_base_modem_at_command (MM_BASE_MODEM (self),
                               "+CEMODE?",
                               3,
@@ -4524,7 +4546,7 @@
 {
     gchar *cmd;
 
-    mm_dbg ("updating UE mode of operation for EPS...");
+    mm_obj_dbg (self, "updating UE mode of operation for EPS...");
     cmd = mm_3gpp_build_cemode_set_request (mode);
     mm_base_modem_at_command (MM_BASE_MODEM (self),
                               cmd,
@@ -4556,18 +4578,21 @@
     MMModemAccessTechnology act = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
     gboolean cgreg = FALSE;
     gboolean cereg = FALSE;
+    gboolean c5greg = FALSE;
     GError *error = NULL;
 
     if (!mm_3gpp_parse_creg_response (match_info,
+                                      self,
                                       &state,
                                       &lac,
                                       &cell_id,
                                       &act,
                                       &cgreg,
                                       &cereg,
+                                      &c5greg,
                                       &error)) {
-        mm_warn ("error parsing unsolicited registration: %s",
-                 error && error->message ? error->message : "(unknown)");
+        mm_obj_warn (self, "error parsing unsolicited registration: %s",
+                     error && error->message ? error->message : "(unknown)");
         g_clear_error (&error);
         return;
     }
@@ -4575,7 +4600,7 @@
     /* Report new registration state and fix LAC/TAC.
      * According to 3GPP TS 27.007:
      *  - If CREG reports <AcT> 7 (LTE) then the <lac> field contains TAC
-     *  - CEREG always reports TAC
+     *  - CEREG/C5GREG always reports TAC
      */
     if (cgreg)
         mm_iface_modem_3gpp_update_ps_registration_state (MM_IFACE_MODEM_3GPP (self), state);
@@ -4583,6 +4608,10 @@
         tac = lac;
         lac = 0;
         mm_iface_modem_3gpp_update_eps_registration_state (MM_IFACE_MODEM_3GPP (self), state);
+    } else if (c5greg) {
+        tac = lac;
+        lac = 0;
+        mm_iface_modem_3gpp_update_5gs_registration_state (MM_IFACE_MODEM_3GPP (self), state);
     } else {
         if (act == MM_MODEM_ACCESS_TECHNOLOGY_LTE) {
             tac = lac;
@@ -4623,8 +4652,8 @@
         if (!ports[i])
             continue;
 
-        mm_dbg ("(%s) setting up 3GPP unsolicited registration messages handlers",
-                mm_port_get_device (MM_PORT (ports[i])));
+        mm_obj_dbg (self, "setting up 3GPP unsolicited registration messages handlers in %s",
+                    mm_port_get_device (MM_PORT (ports[i])));
         for (j = 0; j < array->len; j++) {
             mm_port_serial_at_add_unsolicited_msg_handler (
                 MM_PORT_SERIAL_AT (ports[i]),
@@ -4672,9 +4701,8 @@
         if (!ports[i])
             continue;
 
-        mm_dbg ("(%s) cleaning up unsolicited registration messages handlers",
-                mm_port_get_device (MM_PORT (ports[i])));
-
+        mm_obj_dbg (self, "cleaning up unsolicited registration messages handlers in %s",
+                    mm_port_get_device (MM_PORT (ports[i])));
         for (j = 0; j < array->len; j++) {
             mm_port_serial_at_add_unsolicited_msg_handler (
                 MM_PORT_SERIAL_AT (ports[i]),
@@ -4705,7 +4733,7 @@
     if (!result)
         return NULL;
 
-    return mm_3gpp_parse_cops_test_response (result, MM_BROADBAND_MODEM (self)->priv->modem_current_charset, error);
+    return mm_3gpp_parse_cops_test_response (result, MM_BROADBAND_MODEM (self)->priv->modem_current_charset, self, error);
 }
 
 static void
@@ -4840,36 +4868,38 @@
 /* Registration checks (3GPP interface) */
 
 typedef struct {
-    gboolean cs_supported;
-    gboolean ps_supported;
-    gboolean eps_supported;
+    gboolean is_cs_supported;
+    gboolean is_ps_supported;
+    gboolean is_eps_supported;
+    gboolean is_5gs_supported;
     gboolean run_cs;
     gboolean run_ps;
     gboolean run_eps;
+    gboolean run_5gs;
     gboolean running_cs;
     gboolean running_ps;
     gboolean running_eps;
-    GError *cs_error;
-    GError *ps_error;
-    GError *eps_error;
+    gboolean running_5gs;
+    GError *error_cs;
+    GError *error_ps;
+    GError *error_eps;
+    GError *error_5gs;
 } RunRegistrationChecksContext;
 
 static void
 run_registration_checks_context_free (RunRegistrationChecksContext *ctx)
 {
-    if (ctx->cs_error)
-        g_error_free (ctx->cs_error);
-    if (ctx->ps_error)
-        g_error_free (ctx->ps_error);
-    if (ctx->eps_error)
-        g_error_free (ctx->eps_error);
+    g_clear_error (&ctx->error_cs);
+    g_clear_error (&ctx->error_ps);
+    g_clear_error (&ctx->error_eps);
+    g_clear_error (&ctx->error_5gs);
     g_free (ctx);
 }
 
 static gboolean
-modem_3gpp_run_registration_checks_finish (MMIfaceModem3gpp *self,
-                                           GAsyncResult *res,
-                                           GError **error)
+modem_3gpp_run_registration_checks_finish (MMIfaceModem3gpp  *self,
+                                           GAsyncResult      *res,
+                                           GError           **error)
 {
     return g_task_propagate_boolean (G_TASK (res), error);
 }
@@ -4877,9 +4907,26 @@
 static void run_registration_checks_context_step (GTask *task);
 
 static void
+run_registration_checks_context_set_error (RunRegistrationChecksContext *ctx,
+                                           GError                       *error)
+{
+    g_assert (error != NULL);
+    if (ctx->running_cs)
+        ctx->error_cs = error;
+    else if (ctx->running_ps)
+        ctx->error_ps = error;
+    else if (ctx->running_eps)
+        ctx->error_eps = error;
+    else if (ctx->running_5gs)
+        ctx->error_5gs = error;
+    else
+        g_assert_not_reached ();
+}
+
+static void
 registration_status_check_ready (MMBroadbandModem *self,
-                                 GAsyncResult *res,
-                                 GTask *task)
+                                 GAsyncResult     *res,
+                                 GTask            *task)
 {
     RunRegistrationChecksContext *ctx;
     const gchar *response;
@@ -4887,31 +4934,23 @@
     GMatchInfo *match_info = NULL;
     guint i;
     gboolean parsed;
-    gboolean cgreg;
-    gboolean cereg;
-    MMModem3gppRegistrationState state;
-    MMModemAccessTechnology act;
-    gulong lac;
-    gulong tac;
-    gulong cid;
+    gboolean cgreg = FALSE;
+    gboolean cereg = FALSE;
+    gboolean c5greg = FALSE;
+    MMModem3gppRegistrationState state = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
+    MMModemAccessTechnology act = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
+    gulong lac = 0;
+    gulong tac = 0;
+    gulong cid = 0;
 
     ctx = g_task_get_task_data (task);
 
     /* Only one must be running */
-    g_assert ((ctx->running_cs ? 1 : 0) +
-              (ctx->running_ps ? 1 : 0) +
-              (ctx->running_eps ? 1 : 0) == 1);
+    g_assert ((ctx->running_cs + ctx->running_ps + ctx->running_eps + ctx->running_5gs) == 1);
 
     response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
     if (!response) {
-        g_assert (error != NULL);
-        if (ctx->running_cs)
-            ctx->cs_error = error;
-        else if (ctx->running_ps)
-            ctx->ps_error = error;
-        else
-            ctx->eps_error = error;
-
+        run_registration_checks_context_set_error (ctx, error);
         run_registration_checks_context_step (task);
         return;
     }
@@ -4929,8 +4968,7 @@
     for (i = 0;
          i < self->priv->modem_3gpp_registration_regex->len;
          i++) {
-        if (g_regex_match ((GRegex *)g_ptr_array_index (
-                               self->priv->modem_3gpp_registration_regex, i),
+        if (g_regex_match ((GRegex *)g_ptr_array_index (self->priv->modem_3gpp_registration_regex, i),
                            response,
                            0,
                            &match_info))
@@ -4944,31 +4982,20 @@
                              MM_CORE_ERROR_FAILED,
                              "Unknown registration status response: '%s'",
                              response);
-        if (ctx->running_cs)
-            ctx->cs_error = error;
-        else if (ctx->running_ps)
-            ctx->ps_error = error;
-        else
-            ctx->eps_error = error;
-
+        run_registration_checks_context_set_error (ctx, error);
         run_registration_checks_context_step (task);
         return;
     }
 
-    cgreg = FALSE;
-    cereg = FALSE;
-    state = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
-    act = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
-    tac = 0;
-    lac = 0;
-    cid = 0;
     parsed = mm_3gpp_parse_creg_response (match_info,
+                                          self,
                                           &state,
                                           &lac,
                                           &cid,
                                           &act,
                                           &cgreg,
                                           &cereg,
+                                          &c5greg,
                                           &error);
     g_match_info_free (match_info);
 
@@ -4978,12 +5005,7 @@
                                  MM_CORE_ERROR_FAILED,
                                  "Error parsing registration response: '%s'",
                                  response);
-        if (ctx->running_cs)
-            ctx->cs_error = error;
-        else if (ctx->running_ps)
-            ctx->ps_error = error;
-        else
-            ctx->eps_error = error;
+        run_registration_checks_context_set_error (ctx, error);
         run_registration_checks_context_step (task);
         return;
     }
@@ -4995,27 +5017,43 @@
      */
     if (cgreg) {
         if (ctx->running_cs)
-            mm_dbg ("Got PS registration state when checking CS registration state");
+            mm_obj_dbg (self, "got PS registration state when checking CS registration state");
         else if (ctx->running_eps)
-            mm_dbg ("Got PS registration state when checking EPS registration state");
+            mm_obj_dbg (self, "got PS registration state when checking EPS registration state");
+        else if (ctx->running_5gs)
+            mm_obj_dbg (self, "got PS registration state when checking 5GS registration state");
         mm_iface_modem_3gpp_update_ps_registration_state (MM_IFACE_MODEM_3GPP (self), state);
     } else if (cereg) {
         tac = lac;
         lac = 0;
         if (ctx->running_cs)
-            mm_dbg ("Got EPS registration state when checking CS registration state");
+            mm_obj_dbg (self, "got EPS registration state when checking CS registration state");
         else if (ctx->running_ps)
-            mm_dbg ("Got EPS registration state when checking PS registration state");
+            mm_obj_dbg (self, "got EPS registration state when checking PS registration state");
+        else if (ctx->running_5gs)
+            mm_obj_dbg (self, "got EPS registration state when checking 5GS registration state");
         mm_iface_modem_3gpp_update_eps_registration_state (MM_IFACE_MODEM_3GPP (self), state);
+    } else if (c5greg) {
+        tac = lac;
+        lac = 0;
+        if (ctx->running_cs)
+            mm_obj_dbg (self, "got 5GS registration state when checking CS registration state");
+        else if (ctx->running_ps)
+            mm_obj_dbg (self, "got 5GS registration state when checking PS registration state");
+        else if (ctx->running_eps)
+            mm_obj_dbg (self, "got 5GS registration state when checking EPS registration state");
+        mm_iface_modem_3gpp_update_5gs_registration_state (MM_IFACE_MODEM_3GPP (self), state);
     } else {
         if (act == MM_MODEM_ACCESS_TECHNOLOGY_LTE) {
             tac = lac;
             lac = 0;
         }
         if (ctx->running_ps)
-            mm_dbg ("Got CS registration state when checking PS registration state");
+            mm_obj_dbg (self, "got CS registration state when checking PS registration state");
         else if (ctx->running_eps)
-            mm_dbg ("Got CS registration state when checking EPS registration state");
+            mm_obj_dbg (self, "got CS registration state when checking EPS registration state");
+        else if (ctx->running_5gs)
+            mm_obj_dbg (self, "got CS registration state when checking 5GS registration state");
         mm_iface_modem_3gpp_update_cs_registration_state (MM_IFACE_MODEM_3GPP (self), state);
     }
 
@@ -5038,6 +5076,7 @@
     ctx->running_cs = FALSE;
     ctx->running_ps = FALSE;
     ctx->running_eps = FALSE;
+    ctx->running_5gs = FALSE;
 
     if (ctx->run_cs) {
         ctx->running_cs = TRUE;
@@ -5078,22 +5117,35 @@
         return;
     }
 
+    if (ctx->run_5gs) {
+        ctx->running_5gs = TRUE;
+        ctx->run_5gs = FALSE;
+        /* Check current 5GS-registration state. */
+        mm_base_modem_at_command (MM_BASE_MODEM (self),
+                                  "+C5GREG?",
+                                  10,
+                                  FALSE,
+                                  (GAsyncReadyCallback)registration_status_check_ready,
+                                  task);
+        return;
+    }
+
     /* If all run checks returned errors we fail */
-    if ((ctx->cs_supported || ctx->ps_supported || ctx->eps_supported) &&
-        (!ctx->cs_supported || ctx->cs_error) &&
-        (!ctx->ps_supported || ctx->ps_error) &&
-        (!ctx->eps_supported || ctx->eps_error)) {
-        /* Prefer the EPS, and then PS error if any */
-        if (ctx->eps_error) {
-            g_propagate_error (&error, ctx->eps_error);
-            ctx->eps_error = NULL;
-        } else if (ctx->ps_error) {
-            g_propagate_error (&error, ctx->ps_error);
-            ctx->ps_error = NULL;
-        } else if (ctx->cs_error) {
-            g_propagate_error (&error, ctx->cs_error);
-            ctx->cs_error = NULL;
-        } else
+    if ((ctx->is_cs_supported || ctx->is_ps_supported || ctx->is_eps_supported || ctx->is_5gs_supported) &&
+        (!ctx->is_cs_supported || ctx->error_cs) &&
+        (!ctx->is_ps_supported || ctx->error_ps) &&
+        (!ctx->is_eps_supported || ctx->error_eps) &&
+        (!ctx->is_5gs_supported || ctx->error_5gs)) {
+        /* When reporting errors, prefer the 5GS, then EPS, then PS, then CS */
+        if (ctx->error_5gs)
+            error = g_steal_pointer (&ctx->error_5gs);
+        else if (ctx->error_eps)
+            error = g_steal_pointer (&ctx->error_eps);
+        else if (ctx->error_ps)
+            error = g_steal_pointer (&ctx->error_ps);
+        else if (ctx->error_cs)
+            error = g_steal_pointer (&ctx->error_cs);
+        else
             g_assert_not_reached ();
     }
 
@@ -5105,23 +5157,26 @@
 }
 
 static void
-modem_3gpp_run_registration_checks (MMIfaceModem3gpp *self,
-                                    gboolean cs_supported,
-                                    gboolean ps_supported,
-                                    gboolean eps_supported,
-                                    GAsyncReadyCallback callback,
-                                    gpointer user_data)
+modem_3gpp_run_registration_checks (MMIfaceModem3gpp    *self,
+                                    gboolean             is_cs_supported,
+                                    gboolean             is_ps_supported,
+                                    gboolean             is_eps_supported,
+                                    gboolean             is_5gs_supported,
+                                    GAsyncReadyCallback  callback,
+                                    gpointer             user_data)
 {
     RunRegistrationChecksContext *ctx;
     GTask *task;
 
     ctx = g_new0 (RunRegistrationChecksContext, 1);
-    ctx->cs_supported = cs_supported;
-    ctx->ps_supported = ps_supported;
-    ctx->eps_supported = eps_supported;
-    ctx->run_cs = cs_supported;
-    ctx->run_ps = ps_supported;
-    ctx->run_eps = eps_supported;
+    ctx->is_cs_supported = is_cs_supported;
+    ctx->is_ps_supported = is_ps_supported;
+    ctx->is_eps_supported = is_eps_supported;
+    ctx->is_5gs_supported = is_5gs_supported;
+    ctx->run_cs = is_cs_supported;
+    ctx->run_ps = is_ps_supported;
+    ctx->run_eps = is_eps_supported;
+    ctx->run_5gs = is_5gs_supported;
 
     task = g_task_new (self, NULL, callback, user_data);
     g_task_set_task_data (task, ctx, (GDestroyNotify)run_registration_checks_context_free);
@@ -5301,9 +5356,9 @@
             mm_base_modem_at_command_full_finish (MM_BASE_MODEM (self), res, &error);
 
         if (error) {
-            mm_dbg ("%s unsolicited registration events in secondary port failed: '%s'",
-                    ctx->enable ? "Enabling" : "Disabling",
-                    error->message);
+            mm_obj_dbg (self, "%s unsolicited registration events in secondary port failed: %s",
+                        ctx->enable ? "enabling" : "disabling",
+                        error->message);
             /* Keep errors reported */
             if (ctx->running_cs && !ctx->cs_error)
                 ctx->cs_error = error;
@@ -5341,9 +5396,9 @@
             error = g_error_new (MM_CORE_ERROR,
                                  MM_CORE_ERROR_FAILED,
                                  "AT sequence failed");
-        mm_dbg ("%s unsolicited registration events in primary port failed: '%s'",
-                ctx->enable ? "Enabling" : "Disabling",
-                error->message);
+        mm_obj_dbg (self, "%s unsolicited registration events in primary port failed: %s",
+                    ctx->enable ? "enabling" : "disabling",
+                    error->message);
         /* Keep errors reported */
         if (ctx->running_cs)
             ctx->cs_error = error;
@@ -5619,7 +5674,7 @@
     response = mm_base_modem_at_command_finish (_self, res, &error);
     if (error) {
         /* Some immediate error happened when sending the USSD request */
-        mm_dbg ("Error sending USSD request: '%s'", error->message);
+        mm_obj_dbg (self, "error sending USSD request: '%s'", error->message);
         g_error_free (error);
 
         if (self->priv->pending_ussd_action) {
@@ -5629,17 +5684,17 @@
     }
 
     if (!self->priv->pending_ussd_action) {
-        mm_dbg ("USSD operation finished already via URCs");
+        mm_obj_dbg (self, "USSD operation finished already via URCs");
         return;
     }
 
     /* Cache the hint for the next time we send something */
     ctx = g_task_get_task_data (self->priv->pending_ussd_action);
     if (!self->priv->use_unencoded_ussd && ctx->current_is_unencoded) {
-        mm_dbg ("Will assume we want unencoded USSD commands");
+        mm_obj_dbg (self, "will assume we want unencoded USSD commands");
         self->priv->use_unencoded_ussd = TRUE;
     } else if (self->priv->use_unencoded_ussd && !ctx->current_is_unencoded) {
-        mm_dbg ("Will assume we want encoded USSD commands");
+        mm_obj_dbg (self, "will assume we want encoded USSD commands");
         self->priv->use_unencoded_ussd = FALSE;
     }
 
@@ -5793,14 +5848,14 @@
 /* USSD Encode/Decode (3GPP/USSD interface) */
 
 static gchar *
-modem_3gpp_ussd_encode (MMIfaceModem3gppUssd *self,
-                        const gchar *command,
-                        guint *scheme,
-                        GError **error)
+modem_3gpp_ussd_encode (MMIfaceModem3gppUssd  *self,
+                        const gchar           *command,
+                        guint                 *scheme,
+                        GError               **error)
 {
-    MMBroadbandModem *broadband = MM_BROADBAND_MODEM (self);
-    GByteArray *ussd_command;
-    gchar *hex = NULL;
+    MMBroadbandModem      *broadband = MM_BROADBAND_MODEM (self);
+    gchar                 *hex = NULL;
+    g_autoptr(GByteArray)  ussd_command = NULL;
 
     ussd_command = g_byte_array_new ();
 
@@ -5809,7 +5864,8 @@
     if (mm_modem_charset_byte_array_append (ussd_command,
                                             command,
                                             FALSE,
-                                            broadband->priv->modem_current_charset)) {
+                                            broadband->priv->modem_current_charset,
+                                            NULL)) {
         /* The scheme value does NOT represent the encoding used to encode the string
          * we're giving. This scheme reflects the encoding that the modem should use when
          * sending the data out to the network. We're hardcoding this to GSM-7 because
@@ -5820,8 +5876,6 @@
         hex = mm_utils_bin2hexstr (ussd_command->data, ussd_command->len);
     }
 
-    g_byte_array_free (ussd_command, TRUE);
-
     return hex;
 }
 
@@ -5984,7 +6038,7 @@
 
     /* If no pending task, just report the error */
     if (error) {
-        mm_warn ("Invalid USSD message: %s", error->message);
+        mm_obj_warn (self, "invalid USSD message: %s", error->message);
         g_error_free (error);
     }
 
@@ -5998,7 +6052,7 @@
 {
     gchar *str;
 
-    mm_dbg ("Unsolicited USSD URC received");
+    mm_obj_dbg (self, "unsolicited USSD URC received");
     str = g_match_info_fetch (info, 1);
     cusd_process_string (self, str);
     g_free (str);
@@ -6024,9 +6078,9 @@
         if (!ports[i])
             continue;
         /* Set/unset unsolicited CUSD event handler */
-        mm_dbg ("(%s) %s unsolicited result code handlers",
-                mm_port_get_device (MM_PORT (ports[i])),
-                enable ? "Setting" : "Removing");
+        mm_obj_dbg (self, "%s unsolicited result code handlers in %s",
+                    enable ? "setting" : "removing",
+                    mm_port_get_device (MM_PORT (ports[i])));
         mm_port_serial_at_add_unsolicited_msg_handler (
             ports[i],
             cusd_regex,
@@ -6291,13 +6345,10 @@
     if (!mm_3gpp_parse_cpms_test_response (response,
                                            &result->mem1,
                                            &result->mem2,
-                                           &result->mem3)) {
+                                           &result->mem3,
+                                           &error)) {
         supported_storages_result_free (result);
-        g_task_return_new_error (task,
-                                 MM_CORE_ERROR,
-                                 MM_CORE_ERROR_FAILED,
-                                 "Couldn't parse supported storages reply: '%s'",
-                                 response);
+        g_task_return_error (task, error);
         g_object_unref (task);
         return;
     }
@@ -6366,14 +6417,14 @@
         self->priv->current_sms_mem1_storage = mem1;
         self->priv->current_sms_mem2_storage = mem2;
 
-        mm_dbg ("Current storages initialized:");
+        mm_obj_dbg (self, "current storages initialized:");
 
         aux = mm_common_build_sms_storages_string (&mem1, 1);
-        mm_dbg ("  mem1 (list/read/delete) storages: '%s'", aux);
+        mm_obj_dbg (self, "  mem1 (list/read/delete) storages: '%s'", aux);
         g_free (aux);
 
         aux = mm_common_build_sms_storages_string (&mem2, 1);
-        mm_dbg ("  mem2 (write/send) storages:       '%s'", aux);
+        mm_obj_dbg (self, "  mem2 (write/send) storages:       '%s'", aux);
         g_free (aux);
 
         g_task_return_boolean (task, TRUE);
@@ -6532,8 +6583,8 @@
         self->priv->current_sms_mem1_storage = mem1;
         self->priv->mem1_storage_locked = TRUE;
     } else if (self->priv->current_sms_mem1_storage != MM_SMS_STORAGE_UNKNOWN) {
-        mm_dbg ("Given sms mem1 storage is unknown. Using current sms mem1 storage value '%s' instead",
-                mm_sms_storage_get_string (self->priv->current_sms_mem1_storage));
+        mm_obj_dbg (self, "given sms mem1 storage is unknown. Using current sms mem1 storage value '%s' instead",
+                    mm_sms_storage_get_string (self->priv->current_sms_mem1_storage));
     } else {
         g_task_return_new_error (task,
                                  MM_CORE_ERROR,
@@ -6557,9 +6608,8 @@
     g_assert (mem1_str != NULL);
 
     /* We don't touch 'mem3' here */
-    mm_dbg ("Locking SMS storages to: mem1 (%s), mem2 (%s)...",
-            mem1_str,
-            mem2_str ? mem2_str : "none");
+    mm_obj_dbg (self, "locking SMS storages to: mem1 (%s), mem2 (%s)...",
+                mem1_str, mem2_str ? mem2_str : "none");
 
     if (mem2_str)
         cmd = g_strdup_printf ("+CPMS=\"%s\",\"%s\"", mem1_str, mem2_str);
@@ -6668,13 +6718,12 @@
 
     mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
     if (error) {
-        mm_dbg ("Failed to set preferred SMS mode: '%s'; assuming text mode'",
-                error->message);
+        mm_obj_dbg (self, "failed to set preferred SMS mode: %s; assuming text mode'", error->message);
         g_error_free (error);
         self->priv->modem_messaging_sms_pdu_mode = FALSE;
     } else
-        mm_dbg ("Successfully set preferred SMS mode: '%s'",
-                self->priv->modem_messaging_sms_pdu_mode ? "PDU" : "text");
+        mm_obj_dbg (self, "successfully set preferred SMS mode: '%s'",
+                    self->priv->modem_messaging_sms_pdu_mode ? "PDU" : "text");
 
     g_task_return_boolean (task, TRUE);
     g_object_unref (task);
@@ -6713,8 +6762,7 @@
                                            &sms_pdu_supported,
                                            &sms_text_supported,
                                            &error)) {
-        mm_dbg ("Failed to query supported SMS modes: '%s'",
-                error->message);
+        mm_obj_dbg (self, "failed to query supported SMS modes: %s", error->message);
         g_error_free (error);
     }
 
@@ -6722,11 +6770,11 @@
     self->priv->modem_messaging_sms_pdu_mode = TRUE;
     if (!sms_pdu_supported) {
         if (sms_text_supported) {
-            mm_dbg ("PDU mode not supported, will try to use Text mode");
+            mm_obj_dbg (self, "PDU mode not supported, will try to use Text mode");
             self->priv->modem_messaging_sms_pdu_mode = FALSE;
         } else
-            mm_dbg ("Neither PDU nor Text modes are reported as supported; "
-                    "will anyway default to PDU mode");
+            mm_obj_dbg (self, "neither PDU nor Text modes are reported as supported; "
+                        "will anyway default to PDU mode");
     }
 
     self->priv->sms_supported_modes_checked = TRUE;
@@ -6792,8 +6840,7 @@
     if (error) {
         /* We're really ignoring this error afterwards, as we don't have a callback
          * passed to the async operation, so just log the error here. */
-        mm_warn ("Couldn't retrieve SMS part: '%s'",
-                 error->message);
+        mm_obj_warn (self, "couldn't retrieve SMS part: '%s'", error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -6803,23 +6850,22 @@
 
     info = mm_3gpp_parse_cmgr_read_response (response, ctx->idx, &error);
     if (!info) {
-        mm_warn ("Couldn't parse SMS part: '%s'",
-                 error->message);
+        mm_obj_warn (self, "couldn't parse SMS part: '%s'", error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
     }
 
-    part = mm_sms_part_3gpp_new_from_pdu (info->index, info->pdu, &error);
+    part = mm_sms_part_3gpp_new_from_pdu (info->index, info->pdu, self, &error);
     if (part) {
-        mm_dbg ("Correctly parsed PDU (%d)", ctx->idx);
+        mm_obj_dbg (self, "correctly parsed PDU (%d)", ctx->idx);
         mm_iface_modem_messaging_take_part (MM_IFACE_MODEM_MESSAGING (self),
                                             part,
                                             MM_SMS_STATE_RECEIVED,
                                             self->priv->modem_messaging_sms_default_storage);
     } else {
         /* Don't treat the error as critical */
-        mm_dbg ("Error parsing PDU (%d): %s", ctx->idx, error->message);
+        mm_obj_dbg (self, "error parsing PDU (%d): %s", ctx->idx, error->message);
         g_error_free (error);
     }
 
@@ -6878,7 +6924,7 @@
     str = mm_get_string_unquoted_from_match_info (info, 1);
     storage = mm_common_get_sms_storage_from_string (str, NULL);
     if (storage == MM_SMS_STORAGE_UNKNOWN) {
-        mm_dbg ("Skipping CMTI indication, unknown storage '%s' reported", str);
+        mm_obj_dbg (self, "skipping CMTI indication, unknown storage '%s' reported", str);
         g_free (str);
         return;
     }
@@ -6888,7 +6934,7 @@
     if (mm_sms_list_has_part (self->priv->modem_messaging_sms_list,
                               storage,
                               idx)) {
-        mm_dbg ("Skipping CMTI indication, part already processed");
+        mm_obj_dbg (self, "skipping CMTI indication, part already processed");
         return;
     }
 
@@ -6916,7 +6962,7 @@
     guint length;
     gchar *pdu;
 
-    mm_dbg ("Got new non-stored message indication");
+    mm_obj_dbg (self, "got new non-stored message indication");
 
     if (!mm_get_uint_from_match_info (info, 1, &length))
         return;
@@ -6925,16 +6971,16 @@
     if (!pdu)
         return;
 
-    part = mm_sms_part_3gpp_new_from_pdu (SMS_PART_INVALID_INDEX, pdu, &error);
+    part = mm_sms_part_3gpp_new_from_pdu (SMS_PART_INVALID_INDEX, pdu, self, &error);
     if (part) {
-        mm_dbg ("Correctly parsed non-stored PDU");
+        mm_obj_dbg (self, "correctly parsed non-stored PDU");
         mm_iface_modem_messaging_take_part (MM_IFACE_MODEM_MESSAGING (self),
                                             part,
                                             MM_SMS_STATE_RECEIVED,
                                             MM_SMS_STORAGE_UNKNOWN);
     } else {
         /* Don't treat the error as critical */
-        mm_dbg ("Error parsing non-stored PDU: %s", error->message);
+        mm_obj_dbg (self, "error parsing non-stored PDU: %s", error->message);
         g_error_free (error);
     }
 }
@@ -6962,9 +7008,9 @@
             continue;
 
         /* Set/unset unsolicited CMTI event handler */
-        mm_dbg ("(%s) %s messaging unsolicited events handlers",
-                mm_port_get_device (MM_PORT (ports[i])),
-                enable ? "Setting" : "Removing");
+        mm_obj_dbg (self, "%s messaging unsolicited events handlers in %s",
+                    enable ? "setting" : "removing",
+                    mm_port_get_device (MM_PORT (ports[i])));
         mm_port_serial_at_add_unsolicited_msg_handler (
             ports[i],
             cmti_regex,
@@ -7065,14 +7111,14 @@
     /* Since the secondary is not required, we don't propagate the error anywhere */
     mm_base_modem_at_sequence_full_finish (MM_BASE_MODEM (self), res, NULL, &inner_error);
     if (inner_error) {
-        mm_dbg ("(%s) Unable to enable messaging unsolicited events on modem secondary: %s",
-                mm_port_get_device (MM_PORT (secondary)),
-                inner_error->message);
+        mm_obj_dbg (self, "failed to enable messaging unsolicited events on secondary port %s: %s",
+                    mm_port_get_device (MM_PORT (secondary)),
+                    inner_error->message);
         g_error_free (inner_error);
     }
 
-    mm_dbg ("(%s) Messaging unsolicited events enabled on secondary",
-            mm_port_get_device (MM_PORT (secondary)));
+    mm_obj_dbg (self, "messaging unsolicited events enabled on secondary port %s",
+                mm_port_get_device (MM_PORT (secondary)));
 
     g_task_return_boolean (task, TRUE);
     g_object_unref (task);
@@ -7097,13 +7143,13 @@
         return;
     }
 
-    mm_dbg ("(%s) Messaging unsolicited events enabled on primary",
-            mm_port_get_device (MM_PORT (primary)));
+    mm_obj_dbg (self, "messaging unsolicited events enabled on primary port %s",
+                mm_port_get_device (MM_PORT (primary)));
 
     /* Try to enable unsolicited events for secondary port */
     if (secondary) {
-        mm_dbg ("(%s) Enabling messaging unsolicited events on secondary port",
-                mm_port_get_device (MM_PORT (secondary)));
+        mm_obj_dbg (self, "enabling messaging unsolicited events on secondary port %s",
+                    mm_port_get_device (MM_PORT (secondary)));
         mm_base_modem_at_sequence_full (
             MM_BASE_MODEM (self),
             secondary,
@@ -7132,8 +7178,8 @@
     primary = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));
 
     /* Enable unsolicited events for primary port */
-    mm_dbg ("(%s) Enabling messaging unsolicited events on primary port",
-            mm_port_get_device (MM_PORT (primary)));
+    mm_obj_dbg (self, "enabling messaging unsolicited events on primary port %s",
+                mm_port_get_device (MM_PORT (primary)));
     mm_base_modem_at_sequence_full (
         MM_BASE_MODEM (self),
         primary,
@@ -7235,26 +7281,26 @@
 
         matches = g_match_info_get_match_count (match_info);
         if (matches != 7) {
-            mm_dbg ("Failed to match entire CMGL response (count %d)", matches);
+            mm_obj_dbg (self, "failed to match entire CMGL response (count %d)", matches);
             goto next;
         }
 
         if (!mm_get_uint_from_match_info (match_info, 1, &idx)) {
-            mm_dbg ("Failed to convert message index");
+            mm_obj_dbg (self, "failed to convert message index");
             goto next;
         }
 
         /* Get part state */
         stat = mm_get_string_unquoted_from_match_info (match_info, 2);
         if (!stat) {
-            mm_dbg ("Failed to get part status");
+            mm_obj_dbg (self, "failed to get part status");
             goto next;
         }
 
         /* Get and parse number */
         number = mm_get_string_unquoted_from_match_info (match_info, 3);
         if (!number) {
-            mm_dbg ("Failed to get message sender number");
+            mm_obj_dbg (self, "failed to get message sender number");
             g_free (stat);
             goto next;
         }
@@ -7287,7 +7333,7 @@
         mm_sms_part_take_data (part, raw);
         mm_sms_part_set_class (part, -1);
 
-        mm_dbg ("Correctly parsed SMS list entry (%d)", idx);
+        mm_obj_dbg (self, "correctly parsed SMS list entry (%d)", idx);
         mm_iface_modem_messaging_take_part (MM_IFACE_MODEM_MESSAGING (self),
                                             part,
                                             sms_state_from_str (stat),
@@ -7355,16 +7401,16 @@
         MM3gppPduInfo *info = l->data;
         MMSmsPart *part;
 
-        part = mm_sms_part_3gpp_new_from_pdu (info->index, info->pdu, &error);
+        part = mm_sms_part_3gpp_new_from_pdu (info->index, info->pdu, self, &error);
         if (part) {
-            mm_dbg ("Correctly parsed PDU (%d)", info->index);
+            mm_obj_dbg (self, "correctly parsed PDU (%d)", info->index);
             mm_iface_modem_messaging_take_part (MM_IFACE_MODEM_MESSAGING (self),
                                                 part,
                                                 sms_state_from_index (info->status),
                                                 ctx->list_storage);
         } else {
             /* Don't treat the error as critical */
-            mm_dbg ("Error parsing PDU (%d): %s", info->index, error->message);
+            mm_obj_dbg (self, "error parsing PDU (%d): %s", info->index, error->message);
             g_clear_error (&error);
         }
     }
@@ -7422,8 +7468,7 @@
     task = g_task_new (self, NULL, callback, user_data);
     g_task_set_task_data (task, ctx, g_free);
 
-    mm_dbg ("Listing SMS parts in storage '%s'",
-            mm_sms_storage_get_string (storage));
+    mm_obj_dbg (self, "listing SMS parts in storage '%s'", mm_sms_storage_get_string (storage));
 
     /* First, request to set the proper storage to read from */
     mm_broadband_modem_lock_sms_storages (MM_BROADBAND_MODEM (self),
@@ -7561,7 +7606,7 @@
 }
 
 static void
-clcc_ready (MMBaseModem  *modem,
+clcc_ready (MMBaseModem  *self,
             GAsyncResult *res,
             GTask        *task)
 {
@@ -7569,8 +7614,8 @@
     GError      *error = NULL;
     GList       *call_info_list = NULL;
 
-    response = mm_base_modem_at_command_finish (modem, res, &error);
-    if (!response || !mm_3gpp_parse_clcc_response (response, &call_info_list, &error))
+    response = mm_base_modem_at_command_finish (self, res, &error);
+    if (!response || !mm_3gpp_parse_clcc_response (response, self, &call_info_list, &error))
         g_task_return_error (task, error);
     else
         g_task_return_pointer (task, call_info_list, (GDestroyNotify)mm_3gpp_call_info_list_free);
@@ -7618,7 +7663,7 @@
     call_info.number    = NULL;
 
     str = g_match_info_fetch (info, 1);
-    mm_dbg ("Call terminated: %s", str);
+    mm_obj_dbg (self, "call terminated: %s", str);
     g_free (str);
 
     mm_iface_modem_voice_report_call (MM_IFACE_MODEM_VOICE (self), &call_info);
@@ -7644,9 +7689,9 @@
         if (!ports[i])
             continue;
 
-        mm_dbg ("(%s) %s voice in-call unsolicited events handlers",
-                mm_port_get_device (MM_PORT (ports[i])),
-                enable ? "Setting" : "Removing");
+        mm_obj_dbg (self, "%s voice in-call unsolicited events handlers in %s",
+                    enable ? "setting" : "removing",
+                    mm_port_get_device (MM_PORT (ports[i])));
         mm_port_serial_at_add_unsolicited_msg_handler (
             ports[i],
             in_call_event_regex,
@@ -7671,7 +7716,7 @@
     if (!self->priv->in_call_ports_ctx)  {
         PortsContext *ctx;
 
-        mm_dbg ("Setting up in-call ports context");
+        mm_obj_dbg (self, "setting up in-call ports context");
         ctx = ports_context_new ();
         if (!ports_context_open (self, ctx, FALSE, TRUE, FALSE, &error)) {
             ports_context_unref (ctx);
@@ -7681,7 +7726,7 @@
             self->priv->in_call_ports_ctx = ctx;
         }
     } else
-        mm_dbg ("In-call ports context already set up");
+        mm_obj_dbg (self, "in-call ports context already set up");
 
     task = g_task_new (self, NULL, callback, user_data);
     if (error)
@@ -7701,11 +7746,11 @@
 
     self = MM_BROADBAND_MODEM (_self);
     if (self->priv->in_call_ports_ctx)  {
-        mm_dbg ("Cleaning up in-call ports context");
+        mm_obj_dbg (self, "cleaning up in-call ports context");
         set_voice_in_call_unsolicited_events_handlers (self, self->priv->in_call_ports_ctx, FALSE);
         g_clear_pointer (&self->priv->in_call_ports_ctx, (GDestroyNotify) ports_context_unref);
     } else
-        mm_dbg ("In-call ports context already cleaned up");
+        mm_obj_dbg (self, "in-call ports context already cleaned up");
 
     task = g_task_new (self, NULL, callback, user_data);
     g_task_return_boolean (task, TRUE);
@@ -7735,7 +7780,7 @@
     call_info.state     = MM_CALL_STATE_WAITING;
     call_info.number    = mm_get_string_unquoted_from_match_info (info, 1);
 
-    mm_dbg ("Call waiting (%s)", call_info.number);
+    mm_obj_dbg (self, "call waiting (%s)", call_info.number);
     mm_iface_modem_voice_report_call (MM_IFACE_MODEM_VOICE (self), &call_info);
 
     g_free (call_info.number);
@@ -7753,7 +7798,7 @@
     call_info.state     = MM_CALL_STATE_RINGING_IN;
     call_info.number    = NULL;
 
-    mm_dbg ("Ringing");
+    mm_obj_dbg (self, "ringing");
     mm_iface_modem_voice_report_call (MM_IFACE_MODEM_VOICE (self), &call_info);
 }
 
@@ -7767,7 +7812,7 @@
 
     /* We could have "VOICE" or "DATA". Now consider only "VOICE" */
     str = mm_get_string_unquoted_from_match_info (info, 1);
-    mm_dbg ("Ringing (%s)", str);
+    mm_obj_dbg (self, "ringing (%s)", str);
     g_free (str);
 
     call_info.index     = 0;
@@ -7790,7 +7835,7 @@
     call_info.state     = MM_CALL_STATE_RINGING_IN;
     call_info.number    = mm_get_string_unquoted_from_match_info (info, 1);
 
-    mm_dbg ("Ringing (%s)", call_info.number);
+    mm_obj_dbg (self, "ringing (%s)", call_info.number);
     mm_iface_modem_voice_report_call (MM_IFACE_MODEM_VOICE (self), &call_info);
 
     g_free (call_info.number);
@@ -7823,9 +7868,9 @@
             continue;
 
         /* Set/unset unsolicited CMTI event handler */
-        mm_dbg ("(%s) %s voice unsolicited events handlers",
-                mm_port_get_device (MM_PORT (ports[i])),
-                enable ? "Setting" : "Removing");
+        mm_obj_dbg (self, "%s voice unsolicited events handlers in %s",
+                    enable ? "setting" : "removing",
+                    mm_port_get_device (MM_PORT (ports[i])));
         mm_port_serial_at_add_unsolicited_msg_handler (
             ports[i],
             cring_regex,
@@ -7928,9 +7973,9 @@
     ctx = g_task_get_task_data (task);
 
     if (!mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error)) {
-        mm_dbg ("Couldn't %s voice event reporting: '%s'",
-                ctx->enable ? "enable" : "disable",
-                error->message);
+        mm_obj_dbg (self, "couldn't %s voice event reporting: '%s'",
+                    ctx->enable ? "enable" : "disable",
+                    error->message);
         g_error_free (error);
     }
 
@@ -7951,42 +7996,42 @@
 
     /* CLIP on primary port */
     if (!ctx->clip_primary_done && ctx->clip_command && ctx->primary) {
-        mm_dbg ("%s +CLIP calling line reporting in primary port...", ctx->enable ? "Enabling" : "Disabling");
+        mm_obj_dbg (self, "%s +CLIP calling line reporting in primary port...", ctx->enable ? "enabling" : "disabling");
         ctx->clip_primary_done = TRUE;
         command = ctx->clip_command;
         port = ctx->primary;
     }
     /* CLIP on secondary port */
     else if (!ctx->clip_secondary_done && ctx->clip_command && ctx->secondary) {
-        mm_dbg ("%s +CLIP calling line reporting in secondary port...", ctx->enable ? "Enabling" : "Disabling");
+        mm_obj_dbg (self, "%s +CLIP calling line reporting in secondary port...", ctx->enable ? "enabling" : "disabling");
         ctx->clip_secondary_done = TRUE;
         command = ctx->clip_command;
         port = ctx->secondary;
     }
     /* CRC on primary port */
     else if (!ctx->crc_primary_done && ctx->crc_command && ctx->primary) {
-        mm_dbg ("%s +CRC extended format of incoming call indications in primary port...", ctx->enable ? "Enabling" : "Disabling");
+        mm_obj_dbg (self, "%s +CRC extended format of incoming call indications in primary port...", ctx->enable ? "enabling" : "disabling");
         ctx->crc_primary_done = TRUE;
         command = ctx->crc_command;
         port = ctx->primary;
     }
     /* CRC on secondary port */
     else if (!ctx->crc_secondary_done && ctx->crc_command && ctx->secondary) {
-        mm_dbg ("%s +CRC extended format of incoming call indications in secondary port...", ctx->enable ? "Enabling" : "Disabling");
+        mm_obj_dbg (self, "%s +CRC extended format of incoming call indications in secondary port...", ctx->enable ? "enabling" : "disabling");
         ctx->crc_secondary_done = TRUE;
         command = ctx->crc_command;
         port = ctx->secondary;
     }
     /* CCWA on primary port */
     else if (!ctx->ccwa_primary_done && ctx->ccwa_command && ctx->primary) {
-        mm_dbg ("%s +CCWA call waiting indications in primary port...", ctx->enable ? "Enabling" : "Disabling");
+        mm_obj_dbg (self, "%s +CCWA call waiting indications in primary port...", ctx->enable ? "enabling" : "disabling");
         ctx->ccwa_primary_done = TRUE;
         command = ctx->ccwa_command;
         port = ctx->primary;
     }
     /* CCWA on secondary port */
     else if (!ctx->ccwa_secondary_done && ctx->ccwa_command && ctx->secondary) {
-        mm_dbg ("%s +CCWA call waiting indications in secondary port...", ctx->enable ? "Enabling" : "Disabling");
+        mm_obj_dbg (self, "%s +CCWA call waiting indications in secondary port...", ctx->enable ? "enabling" : "disabling");
         ctx->ccwa_secondary_done = TRUE;
         command = ctx->ccwa_command;
         port = ctx->secondary;
@@ -8310,7 +8355,7 @@
     if (!response)
         return FALSE;
 
-    return mm_3gpp_parse_ccwa_service_query_response (response, status, error);
+    return mm_3gpp_parse_ccwa_service_query_response (response, self, status, error);
 }
 
 static void
@@ -8346,7 +8391,7 @@
 
     result = mm_strip_tag (result, "+GSN:");
     mm_parse_gsn (result, NULL, NULL, &esn);
-    mm_dbg ("loaded ESN: %s", esn);
+    mm_obj_dbg (self, "loaded ESN: %s", esn);
     return esn;
 }
 
@@ -8355,7 +8400,7 @@
                      GAsyncReadyCallback callback,
                      gpointer user_data)
 {
-    mm_dbg ("loading ESN...");
+    mm_obj_dbg (self, "loading ESN...");
     mm_base_modem_at_command (MM_BASE_MODEM (self),
                               "+GSN",
                               3,
@@ -8381,7 +8426,7 @@
 
     result = mm_strip_tag (result, "+GSN:");
     mm_parse_gsn (result, NULL, &meid, NULL);
-    mm_dbg ("loaded MEID: %s", meid);
+    mm_obj_dbg (self, "loaded MEID: %s", meid);
     return meid;
 }
 
@@ -8391,7 +8436,7 @@
                       gpointer user_data)
 {
     /* Some devices return both the MEID and the ESN in the +GSN response */
-    mm_dbg ("loading MEID...");
+    mm_obj_dbg (self, "loading MEID...");
     mm_base_modem_at_command (MM_BASE_MODEM (self),
                               "+GSN",
                               3,
@@ -9011,6 +9056,7 @@
                         GAsyncResult *res,
                         GTask *task)
 {
+    MMBroadbandModem *self;
     QcdmResult *result = NULL;
     guint32 sid = MM_MODEM_CDMA_SID_UNKNOWN;
     guint32 nid = MM_MODEM_CDMA_NID_UNKNOWN;
@@ -9019,9 +9065,11 @@
     GError *error = NULL;
     GByteArray *response;
 
+    self = g_task_get_source_object (task);
+
     response = mm_port_serial_qcdm_command_finish (port, res, &error);
     if (error) {
-        mm_dbg ("Failed to get cdma status: %s", error->message);
+        mm_obj_dbg (self, "failed to get cdma status: %s", error->message);
         g_clear_error (&error);
 
         /* Fall back to AT+CSS */
@@ -9034,7 +9082,7 @@
                                           &err);
     if (!result) {
         if (err != QCDM_SUCCESS)
-            mm_dbg ("Failed to parse cdma status command result: %d", err);
+            mm_obj_dbg (self, "failed to parse cdma status command result: %d", err);
         g_byte_array_unref (response);
 
         /* Fall back to AT+CSS */
@@ -9055,9 +9103,9 @@
         nid = MM_MODEM_CDMA_NID_UNKNOWN;
     }
 
-    mm_dbg ("CDMA 1x Status RX state: %d", rxstate);
-    mm_dbg ("CDMA 1x Status SID: %d", sid);
-    mm_dbg ("CDMA 1x Status NID: %d", nid);
+    mm_obj_dbg (self, "CDMA 1x Status RX state: %d", rxstate);
+    mm_obj_dbg (self, "CDMA 1x Status SID: %d", sid);
+    mm_obj_dbg (self, "CDMA 1x Status NID: %d", nid);
 
     cdma1x_serving_system_complete_and_free (task,
                                              sid,
@@ -9086,7 +9134,7 @@
     }
 
     if (!mm_port_serial_open (MM_PORT_SERIAL (qcdm), &error)) {
-        mm_dbg ("Failed to open QCDM port for serving-system request: %s", error->message);
+        mm_obj_dbg (self, "failed to open QCDM port for serving-system request: %s", error->message);
         g_error_free (error);
 
         /* Fall back to AT+CSS */
@@ -9258,7 +9306,7 @@
     response = mm_strip_tag (response, "$SPERI:");
     if (!response ||
         !mm_cdma_parse_eri (response, &roaming, NULL, NULL)) {
-        mm_warn ("Couldn't parse SPERI response '%s'", response);
+        mm_obj_warn (self, "couldn't parse SPERI response '%s'", response);
         g_task_return_pointer (task,
                                detailed_registration_state_result_new (ctx),
                                g_free);
@@ -9416,7 +9464,7 @@
 
     /* Skip QCDM steps if no QCDM port */
     if (!ctx->has_qcdm_port) {
-        mm_dbg ("Will skip all QCDM-based registration checks");
+        mm_obj_dbg (self, "will skip all QCDM-based registration checks");
         results->skip_qcdm_call_manager_step = TRUE;
         results->skip_qcdm_hdr_step = TRUE;
     }
@@ -9430,14 +9478,12 @@
          * for the specific step, or subclass this setup and return
          * FALSE themselves. */
         if (ctx->has_sprint_commands) {
-            mm_dbg ("Will skip CDMA1x Serving System check, "
-                    "we do have Sprint commands");
+            mm_obj_dbg (self, "will skip CDMA1x Serving System check, we do have Sprint commands");
             results->skip_at_cdma1x_serving_system_step = TRUE;
         } else {
             /* If there aren't Sprint specific commands, and the detailed
              * registration state getter wasn't subclassed, skip the step */
-            mm_dbg ("Will skip generic detailed registration check, we "
-                    "don't have Sprint commands");
+            mm_obj_dbg (self, "will skip generic detailed registration check, we don't have Sprint commands");
             results->skip_detailed_registration_state = TRUE;
         }
     }
@@ -9640,7 +9686,7 @@
     mm_iface_modem_cdma_run_registration_checks_finish (MM_IFACE_MODEM_CDMA (self), res, &error);
 
     if (error) {
-        mm_dbg ("CDMA registration check failed: '%s'", error->message);
+        mm_obj_dbg (self, "CDMA registration check failed: %s", error->message);
         mm_iface_modem_cdma_update_cdma1x_registration_state (
             MM_IFACE_MODEM_CDMA (self),
             MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN,
@@ -9661,10 +9707,9 @@
     /* If we got registered in at least one CDMA network, end registration checks */
     if (REG_IS_DONE (self->priv->modem_cdma_cdma1x_registration_state) ||
         REG_IS_DONE (self->priv->modem_cdma_evdo_registration_state)) {
-        mm_dbg ("Modem is currently registered in a CDMA network "
-                "(CDMA1x: '%s', EV-DO: '%s')",
-                REG_IS_DONE (self->priv->modem_cdma_cdma1x_registration_state) ? "yes" : "no",
-                REG_IS_DONE (self->priv->modem_cdma_evdo_registration_state) ? "yes" : "no");
+        mm_obj_dbg (self, "registered in a CDMA network (CDMA1x: '%s', EV-DO: '%s')",
+                    REG_IS_DONE (self->priv->modem_cdma_cdma1x_registration_state) ? "yes" : "no",
+                    REG_IS_DONE (self->priv->modem_cdma_evdo_registration_state) ? "yes" : "no");
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
         return;
@@ -9672,7 +9717,7 @@
 
     /* Don't spend too much time waiting to get registered */
     if (g_timer_elapsed (ctx->timer, NULL) > ctx->max_registration_time) {
-        mm_dbg ("CDMA registration check timed out");
+        mm_obj_dbg (self, "CDMA registration check timed out");
         mm_iface_modem_cdma_update_cdma1x_registration_state (
             MM_IFACE_MODEM_CDMA (self),
             MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN,
@@ -9684,14 +9729,14 @@
         mm_iface_modem_cdma_update_access_technologies (
             MM_IFACE_MODEM_CDMA (self),
             MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
-        error = mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_NETWORK_TIMEOUT);
+        error = mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_NETWORK_TIMEOUT, self);
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
     }
 
     /* Check again in a few seconds. */
-    mm_dbg ("Modem not yet registered in a CDMA network... will recheck soon");
+    mm_obj_dbg (self, "not yet registered in a CDMA network... will recheck soon");
     g_timeout_add_seconds (3,
                            (GSourceFunc)run_cdma_registration_checks_again,
                            task);
@@ -9947,7 +9992,7 @@
     const gchar *response;
 
     response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);
-    if (!response || !mm_3gpp_cesq_response_to_signal_info (response, gsm, umts, lte, error))
+    if (!response || !mm_3gpp_cesq_response_to_signal_info (response, self, gsm, umts, lte, error))
         return FALSE;
 
     /* No 3GPP2 support */
@@ -10237,7 +10282,7 @@
     self->priv->modem_init_run = TRUE;
 
     /* After the modem init sequence, give a 500ms period for the modem to settle */
-    mm_dbg ("Giving some time to settle the modem...");
+    mm_obj_dbg (self, "giving some time to settle the modem...");
     g_timeout_add (500, (GSourceFunc)enabling_after_modem_init_timeout, task);
 }
 
@@ -10261,7 +10306,7 @@
     ctx = g_task_get_task_data (task);
 
     if (ctx->modem_init_required) {
-        mm_dbg ("Running modem initialization sequence...");
+        mm_obj_dbg (self, "running initialization sequence...");
         MM_BROADBAND_MODEM_GET_CLASS (self)->enabling_modem_init (self,
                                                                   (GAsyncReadyCallback)enabling_modem_init_ready,
                                                                   task);
@@ -10290,13 +10335,13 @@
      * did it (i.e. don't reinitialize if the modem got disabled and enabled
      * again) */
     if (self->priv->modem_init_run)
-        mm_dbg ("Skipping modem initialization: not first enabling");
+        mm_obj_dbg (self, "skipping initialization: not first enabling");
     else if (mm_base_modem_get_hotplugged (MM_BASE_MODEM (self))) {
         self->priv->modem_init_run = TRUE;
-        mm_dbg ("Skipping modem initialization: device hotplugged");
+        mm_obj_dbg (self, "skipping initialization: device hotplugged");
     } else if (!MM_BROADBAND_MODEM_GET_CLASS (self)->enabling_modem_init ||
                !MM_BROADBAND_MODEM_GET_CLASS (self)->enabling_modem_init_finish)
-        mm_dbg ("Skipping modem initialization: not required");
+        mm_obj_dbg (self, "skipping initialization: not required");
     else
         ctx->modem_init_required = TRUE;
 
@@ -10312,7 +10357,7 @@
     }
 
     /* Ports were correctly opened, now flash the primary port */
-    mm_dbg ("Flashing primary AT port before enabling...");
+    mm_obj_dbg (self, "flashing primary AT port before enabling...");
     mm_port_serial_flash (MM_PORT_SERIAL (ctx->ports->primary),
                           100,
                           FALSE,
@@ -10330,11 +10375,11 @@
     GError *error = NULL;
 
     if (!mm_iface_modem_3gpp_run_registration_checks_finish (self, res, &error)) {
-        mm_warn ("Initial 3GPP registration check failed: %s", error->message);
+        mm_obj_warn (self, "initial 3GPP registration check failed: %s", error->message);
         g_error_free (error);
         return;
     }
-    mm_dbg ("Initial 3GPP registration checks finished");
+    mm_obj_dbg (self, "initial 3GPP registration checks finished");
 }
 
 static void
@@ -10344,11 +10389,11 @@
     GError *error = NULL;
 
     if (!mm_iface_modem_cdma_run_registration_checks_finish (self, res, &error)) {
-        mm_warn ("Initial CDMA registration check failed: %s", error->message);
+        mm_obj_warn (self, "initial CDMA registration check failed: %s", error->message);
         g_error_free (error);
         return;
     }
-    mm_dbg ("Initial CDMA registration checks finished");
+    mm_obj_dbg (self, "initial CDMA registration checks finished");
 }
 
 static gboolean
@@ -10410,7 +10455,7 @@
 
     if (MM_BROADBAND_MODEM_GET_CLASS (ctx->self)->disabling_stopped &&
         !MM_BROADBAND_MODEM_GET_CLASS (ctx->self)->disabling_stopped (ctx->self, &error)) {
-        mm_warn ("Error when stopping the disabling sequence: %s", error->message);
+        mm_obj_warn (ctx->self, "error when stopping the disabling sequence: %s", error->message);
         g_error_free (error);
     }
 
@@ -10456,8 +10501,8 @@
                 return;                                                 \
             }                                                           \
                                                                         \
-            mm_dbg ("Couldn't disable interface: '%s'",                 \
-                    error->message);                                    \
+            mm_obj_dbg (self, "couldn't disable interface: %s",         \
+                        error->message);                                \
             g_error_free (error);                                       \
             return;                                                     \
         }                                                               \
@@ -10596,7 +10641,7 @@
 
     case DISABLING_STEP_IFACE_VOICE:
         if (ctx->self->priv->modem_voice_dbus_skeleton) {
-            mm_dbg ("Modem has voice capabilities, disabling the Voice interface...");
+            mm_obj_dbg (ctx->self, "modem has voice capabilities, disabling the Voice interface...");
             /* Disabling the Modem Voice interface */
             mm_iface_modem_voice_disable (MM_IFACE_MODEM_VOICE (ctx->self),
                                           (GAsyncReadyCallback)iface_modem_voice_disable_ready,
@@ -10608,7 +10653,7 @@
 
     case DISABLING_STEP_IFACE_SIGNAL:
         if (ctx->self->priv->modem_signal_dbus_skeleton) {
-            mm_dbg ("Modem has extended signal reporting capabilities, disabling the Signal interface...");
+            mm_obj_dbg (ctx->self, "modem has extended signal reporting capabilities, disabling the Signal interface...");
             /* Disabling the Modem Signal interface */
             mm_iface_modem_signal_disable (MM_IFACE_MODEM_SIGNAL (ctx->self),
                                            (GAsyncReadyCallback)iface_modem_signal_disable_ready,
@@ -10620,7 +10665,7 @@
 
     case DISABLING_STEP_IFACE_OMA:
         if (ctx->self->priv->modem_oma_dbus_skeleton) {
-            mm_dbg ("Modem has OMA capabilities, disabling the OMA interface...");
+            mm_obj_dbg (ctx->self, "modem has OMA capabilities, disabling the OMA interface...");
             /* Disabling the Modem Oma interface */
             mm_iface_modem_oma_disable (MM_IFACE_MODEM_OMA (ctx->self),
                                         (GAsyncReadyCallback)iface_modem_oma_disable_ready,
@@ -10632,7 +10677,7 @@
 
     case DISABLING_STEP_IFACE_TIME:
         if (ctx->self->priv->modem_time_dbus_skeleton) {
-            mm_dbg ("Modem has time capabilities, disabling the Time interface...");
+            mm_obj_dbg (ctx->self, "modem has time capabilities, disabling the Time interface...");
             /* Disabling the Modem Time interface */
             mm_iface_modem_time_disable (MM_IFACE_MODEM_TIME (ctx->self),
                                          (GAsyncReadyCallback)iface_modem_time_disable_ready,
@@ -10644,7 +10689,7 @@
 
     case DISABLING_STEP_IFACE_MESSAGING:
         if (ctx->self->priv->modem_messaging_dbus_skeleton) {
-            mm_dbg ("Modem has messaging capabilities, disabling the Messaging interface...");
+            mm_obj_dbg (ctx->self, "modem has messaging capabilities, disabling the Messaging interface...");
             /* Disabling the Modem Messaging interface */
             mm_iface_modem_messaging_disable (MM_IFACE_MODEM_MESSAGING (ctx->self),
                                               (GAsyncReadyCallback)iface_modem_messaging_disable_ready,
@@ -10656,7 +10701,7 @@
 
     case DISABLING_STEP_IFACE_LOCATION:
         if (ctx->self->priv->modem_location_dbus_skeleton) {
-            mm_dbg ("Modem has location capabilities, disabling the Location interface...");
+            mm_obj_dbg (ctx->self, "modem has location capabilities, disabling the Location interface...");
             /* Disabling the Modem Location interface */
             mm_iface_modem_location_disable (MM_IFACE_MODEM_LOCATION (ctx->self),
                                              (GAsyncReadyCallback)iface_modem_location_disable_ready,
@@ -10668,7 +10713,7 @@
 
     case DISABLING_STEP_IFACE_CDMA:
         if (ctx->self->priv->modem_cdma_dbus_skeleton) {
-            mm_dbg ("Modem has CDMA capabilities, disabling the Modem CDMA interface...");
+            mm_obj_dbg (ctx->self, "modem has CDMA capabilities, disabling the Modem CDMA interface...");
             /* Disabling the Modem CDMA interface */
             mm_iface_modem_cdma_disable (MM_IFACE_MODEM_CDMA (ctx->self),
                                         (GAsyncReadyCallback)iface_modem_cdma_disable_ready,
@@ -10680,7 +10725,7 @@
 
     case DISABLING_STEP_IFACE_3GPP_USSD:
         if (ctx->self->priv->modem_3gpp_ussd_dbus_skeleton) {
-            mm_dbg ("Modem has 3GPP/USSD capabilities, disabling the Modem 3GPP/USSD interface...");
+            mm_obj_dbg (ctx->self, "modem has 3GPP/USSD capabilities, disabling the Modem 3GPP/USSD interface...");
             /* Disabling the Modem 3GPP USSD interface */
             mm_iface_modem_3gpp_ussd_disable (MM_IFACE_MODEM_3GPP_USSD (ctx->self),
                                               (GAsyncReadyCallback)iface_modem_3gpp_ussd_disable_ready,
@@ -10692,7 +10737,7 @@
 
     case DISABLING_STEP_IFACE_3GPP:
         if (ctx->self->priv->modem_3gpp_dbus_skeleton) {
-            mm_dbg ("Modem has 3GPP capabilities, disabling the Modem 3GPP interface...");
+            mm_obj_dbg (ctx->self, "modem has 3GPP capabilities, disabling the Modem 3GPP interface...");
             /* Disabling the Modem 3GPP interface */
             mm_iface_modem_3gpp_disable (MM_IFACE_MODEM_3GPP (ctx->self),
                                         (GAsyncReadyCallback)iface_modem_3gpp_disable_ready,
@@ -10823,8 +10868,8 @@
                 return;                                                 \
             }                                                           \
                                                                         \
-            mm_dbg ("Couldn't enable interface: '%s'",                  \
-                    error->message);                                    \
+            mm_obj_dbg (self, "couldn't enable interface: '%s'",        \
+                        error->message);                                \
             g_error_free (error);                                       \
         }                                                               \
                                                                         \
@@ -10946,7 +10991,7 @@
 
     case ENABLING_STEP_IFACE_3GPP:
         if (ctx->self->priv->modem_3gpp_dbus_skeleton) {
-            mm_dbg ("Modem has 3GPP capabilities, enabling the Modem 3GPP interface...");
+            mm_obj_dbg (ctx->self, "modem has 3GPP capabilities, enabling the Modem 3GPP interface...");
             /* Enabling the Modem 3GPP interface */
             mm_iface_modem_3gpp_enable (MM_IFACE_MODEM_3GPP (ctx->self),
                                         g_task_get_cancellable (task),
@@ -10959,7 +11004,7 @@
 
     case ENABLING_STEP_IFACE_3GPP_USSD:
         if (ctx->self->priv->modem_3gpp_ussd_dbus_skeleton) {
-            mm_dbg ("Modem has 3GPP/USSD capabilities, enabling the Modem 3GPP/USSD interface...");
+            mm_obj_dbg (ctx->self, "modem has 3GPP/USSD capabilities, enabling the Modem 3GPP/USSD interface...");
             mm_iface_modem_3gpp_ussd_enable (MM_IFACE_MODEM_3GPP_USSD (ctx->self),
                                              (GAsyncReadyCallback)iface_modem_3gpp_ussd_enable_ready,
                                              task);
@@ -10970,7 +11015,7 @@
 
     case ENABLING_STEP_IFACE_CDMA:
         if (ctx->self->priv->modem_cdma_dbus_skeleton) {
-            mm_dbg ("Modem has CDMA capabilities, enabling the Modem CDMA interface...");
+            mm_obj_dbg (ctx->self, "modem has CDMA capabilities, enabling the Modem CDMA interface...");
             /* Enabling the Modem CDMA interface */
             mm_iface_modem_cdma_enable (MM_IFACE_MODEM_CDMA (ctx->self),
                                         g_task_get_cancellable (task),
@@ -10983,7 +11028,7 @@
 
     case ENABLING_STEP_IFACE_LOCATION:
         if (ctx->self->priv->modem_location_dbus_skeleton) {
-            mm_dbg ("Modem has location capabilities, enabling the Location interface...");
+            mm_obj_dbg (ctx->self, "modem has location capabilities, enabling the Location interface...");
             /* Enabling the Modem Location interface */
             mm_iface_modem_location_enable (MM_IFACE_MODEM_LOCATION (ctx->self),
                                             g_task_get_cancellable (task),
@@ -10996,7 +11041,7 @@
 
     case ENABLING_STEP_IFACE_MESSAGING:
         if (ctx->self->priv->modem_messaging_dbus_skeleton) {
-            mm_dbg ("Modem has messaging capabilities, enabling the Messaging interface...");
+            mm_obj_dbg (ctx->self, "modem has messaging capabilities, enabling the Messaging interface...");
             /* Enabling the Modem Messaging interface */
             mm_iface_modem_messaging_enable (MM_IFACE_MODEM_MESSAGING (ctx->self),
                                              g_task_get_cancellable (task),
@@ -11009,7 +11054,7 @@
 
     case ENABLING_STEP_IFACE_TIME:
         if (ctx->self->priv->modem_time_dbus_skeleton) {
-            mm_dbg ("Modem has time capabilities, enabling the Time interface...");
+            mm_obj_dbg (ctx->self, "modem has time capabilities, enabling the Time interface...");
             /* Enabling the Modem Time interface */
             mm_iface_modem_time_enable (MM_IFACE_MODEM_TIME (ctx->self),
                                         g_task_get_cancellable (task),
@@ -11022,7 +11067,7 @@
 
     case ENABLING_STEP_IFACE_SIGNAL:
         if (ctx->self->priv->modem_signal_dbus_skeleton) {
-            mm_dbg ("Modem has extended signal reporting capabilities, enabling the Signal interface...");
+            mm_obj_dbg (ctx->self, "modem has extended signal reporting capabilities, enabling the Signal interface...");
             /* Enabling the Modem Signal interface */
             mm_iface_modem_signal_enable (MM_IFACE_MODEM_SIGNAL (ctx->self),
                                           g_task_get_cancellable (task),
@@ -11035,7 +11080,7 @@
 
     case ENABLING_STEP_IFACE_OMA:
         if (ctx->self->priv->modem_oma_dbus_skeleton) {
-            mm_dbg ("Modem has OMA capabilities, enabling the OMA interface...");
+            mm_obj_dbg (ctx->self, "modem has OMA capabilities, enabling the OMA interface...");
             /* Enabling the Modem Oma interface */
             mm_iface_modem_oma_enable (MM_IFACE_MODEM_OMA (ctx->self),
                                        g_task_get_cancellable (task),
@@ -11048,7 +11093,7 @@
 
     case ENABLING_STEP_IFACE_VOICE:
         if (ctx->self->priv->modem_voice_dbus_skeleton) {
-            mm_dbg ("Modem has voice capabilities, enabling the Voice interface...");
+            mm_obj_dbg (ctx->self, "modem has voice capabilities, enabling the Voice interface...");
             /* Enabling the Modem Voice interface */
             mm_iface_modem_voice_enable (MM_IFACE_MODEM_VOICE (ctx->self),
                                          g_task_get_cancellable (task),
@@ -11198,7 +11243,7 @@
     if (ctx->ports_ctx &&
         MM_BROADBAND_MODEM_GET_CLASS (ctx->self)->initialization_stopped &&
         !MM_BROADBAND_MODEM_GET_CLASS (ctx->self)->initialization_stopped (ctx->self, ctx->ports_ctx, &error)) {
-        mm_warn ("Error when stopping the initialization sequence: %s", error->message);
+        mm_obj_warn (ctx->self, "error when stopping the initialization sequence: %s", error->message);
         g_error_free (error);
     }
 
@@ -11228,7 +11273,7 @@
     /* May return NULL without error */
     ports_ctx = MM_BROADBAND_MODEM_GET_CLASS (self)->initialization_started_finish (self, result, &error);
     if (error) {
-        mm_warn ("Couldn't start initialization: %s", error->message);
+        mm_obj_warn (self, "couldn't start initialization: %s", error->message);
         g_error_free (error);
 
         /* There is no Modem interface yet, so just update the variable directly */
@@ -11264,7 +11309,7 @@
         MMModemStateFailedReason failed_reason = MM_MODEM_STATE_FAILED_REASON_UNKNOWN;
 
         /* Report the new FAILED state */
-        mm_warn ("Modem couldn't be initialized: %s", error->message);
+        mm_obj_warn (self, "modem couldn't be initialized: %s", error->message);
 
         if (g_error_matches (error,
                              MM_MOBILE_EQUIPMENT_ERROR,
@@ -11323,8 +11368,8 @@
                                                                         \
         if (!mm_##NAME##_initialize_finish (TYPE (self), result, &error)) { \
             if (FATAL_ERRORS) {                                         \
-                mm_warn ("Couldn't initialize interface: '%s'",         \
-                         error->message);                               \
+                mm_obj_warn (self, "couldn't initialize interface: '%s'", \
+                             error->message);                           \
                 g_error_free (error);                                   \
                                                                         \
                 /* Report the new FAILED state */                       \
@@ -11337,8 +11382,8 @@
                 return;                                                 \
             }                                                           \
                                                                         \
-            mm_dbg ("Couldn't initialize interface: '%s'",              \
-                    error->message);                                    \
+            mm_obj_dbg (self, "couldn't initialize interface: '%s'",    \
+                        error->message);                                \
             /* Just shutdown this interface */                          \
             mm_##NAME##_shutdown (TYPE (self));                         \
             g_error_free (error);                                       \
@@ -11528,15 +11573,16 @@
             if (is_sim_hot_swap_supported) {
 
                 if (!is_sim_hot_swap_configured) {
-                    mm_warn ("SIM hot swap supported but not configured. Skipping opening ports");
+                    mm_obj_warn (ctx->self, "SIM hot swap supported but not configured. Skipping opening ports");
                 } else {
                     PortsContext *ports;
                     GError *error = NULL;
 
-                    mm_dbg ("Creating ports context for SIM hot swap");
+                    mm_obj_dbg (ctx->self, "creating ports context for SIM hot swap");
                     ports = ports_context_new ();
                     if (!ports_context_open (ctx->self, ports, FALSE, FALSE, FALSE, &error)) {
-                        mm_warn ("Couldn't open ports during Modem SIM hot swap enabling: %s", error? error->message : "unknown reason");
+                        mm_obj_warn (ctx->self, "couldn't open ports during Modem SIM hot swap enabling: %s",
+                                     error ? error->message : "unknown reason");
                         g_error_free (error);
                     } else {
                         ctx->self->priv->sim_hot_swap_ports_ctx = ports_context_ref (ports);
@@ -11546,7 +11592,7 @@
                 }
             }
         } else
-            mm_dbg ("Ports context for SIM hot swap already available");
+            mm_obj_dbg (ctx->self, "ports context for SIM hot swap already available");
 
         ctx->step++;
        /* fall through */
@@ -11584,13 +11630,13 @@
 
                 if (reason == MM_MODEM_STATE_FAILED_REASON_SIM_MISSING) {
                     if (!is_sim_hot_swap_supported) {
-                        mm_dbg ("SIM is missing, but this modem does not support SIM hot swap.");
+                        mm_obj_dbg (ctx->self, "SIM is missing, but this modem does not support SIM hot swap.");
                     } else if (!is_sim_hot_swap_configured) {
-                        mm_warn ("SIM is missing, but SIM hot swap could not be configured.");
+                        mm_obj_warn (ctx->self, "SIM is missing, but SIM hot swap could not be configured.");
                     } else if (!ctx->self->priv->sim_hot_swap_ports_ctx) {
-                        mm_err ("SIM is missing and SIM hot swap is configured, but ports are not opened.");
+                        mm_obj_err (ctx->self, "SIM is missing and SIM hot swap is configured, but ports are not opened.");
                     } else {
-                        mm_dbg ("SIM is missing, but SIM hot swap is enabled. Waiting for SIM...");
+                        mm_obj_dbg (ctx->self, "SIM is missing, but SIM hot swap is enabled; waiting for SIM...");
                         error = g_error_new (MM_CORE_ERROR,
                                              MM_CORE_ERROR_WRONG_STATE,
                                              "Modem is unusable due to SIM missing, "
@@ -11760,6 +11806,7 @@
     return (mm_create_device_identifier (
                 mm_base_modem_get_vendor_id (MM_BASE_MODEM (self)),
                 mm_base_modem_get_product_id (MM_BASE_MODEM (self)),
+                self,
                 ati,
                 ati1,
                 mm_gdbus_modem_get_equipment_identifier (
@@ -11780,20 +11827,20 @@
                                    gpointer user_data)
 {
     GError *error = NULL;
+
     mm_base_modem_disable_finish (self, res, &error);
     if (error) {
-        mm_err ("Disable modem error: %s", error->message);
+        mm_obj_err (self, "failed to disable after hotswap event: %s", error->message);
         g_error_free (error);
-    } else {
+    } else
         mm_base_modem_set_valid (self, FALSE);
-    }
 }
 
 void
 mm_broadband_modem_update_sim_hot_swap_detected (MMBroadbandModem *self)
 {
     if (self->priv->sim_hot_swap_ports_ctx) {
-        mm_dbg ("Releasing SIM hot swap ports context");
+        mm_obj_dbg (self, "releasing SIM hot swap ports context");
         ports_context_unref (self->priv->sim_hot_swap_ports_ctx);
         self->priv->sim_hot_swap_ports_ctx = NULL;
     }
@@ -11902,6 +11949,9 @@
     case PROP_MODEM_3GPP_EPS_NETWORK_SUPPORTED:
         self->priv->modem_3gpp_eps_network_supported = g_value_get_boolean (value);
         break;
+    case PROP_MODEM_3GPP_5GS_NETWORK_SUPPORTED:
+        self->priv->modem_3gpp_5gs_network_supported = g_value_get_boolean (value);
+        break;
     case PROP_MODEM_3GPP_IGNORED_FACILITY_LOCKS:
         self->priv->modem_3gpp_ignored_facility_locks = g_value_get_flags (value);
         break;
@@ -12038,6 +12088,9 @@
     case PROP_MODEM_3GPP_EPS_NETWORK_SUPPORTED:
         g_value_set_boolean (value, self->priv->modem_3gpp_eps_network_supported);
         break;
+    case PROP_MODEM_3GPP_5GS_NETWORK_SUPPORTED:
+        g_value_set_boolean (value, self->priv->modem_3gpp_5gs_network_supported);
+        break;
     case PROP_MODEM_3GPP_IGNORED_FACILITY_LOCKS:
         g_value_set_flags (value, self->priv->modem_3gpp_ignored_facility_locks);
         break;
@@ -12118,6 +12171,7 @@
     self->priv->modem_3gpp_cs_network_supported = TRUE;
     self->priv->modem_3gpp_ps_network_supported = TRUE;
     self->priv->modem_3gpp_eps_network_supported = FALSE;
+    self->priv->modem_3gpp_5gs_network_supported = FALSE;
     self->priv->modem_3gpp_ignored_facility_locks = MM_MODEM_3GPP_FACILITY_NONE;
     self->priv->modem_cdma_cdma1x_registration_state = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN;
     self->priv->modem_cdma_evdo_registration_state = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN;
@@ -12606,6 +12660,10 @@
                                       MM_IFACE_MODEM_3GPP_EPS_NETWORK_SUPPORTED);
 
     g_object_class_override_property (object_class,
+                                      PROP_MODEM_3GPP_5GS_NETWORK_SUPPORTED,
+                                      MM_IFACE_MODEM_3GPP_5GS_NETWORK_SUPPORTED);
+
+    g_object_class_override_property (object_class,
                                       PROP_MODEM_3GPP_IGNORED_FACILITY_LOCKS,
                                       MM_IFACE_MODEM_3GPP_IGNORED_FACILITY_LOCKS);
 
diff --git a/src/mm-charsets.c b/src/mm-charsets.c
index a5c7016..bf0de2b 100644
--- a/src/mm-charsets.c
+++ b/src/mm-charsets.c
@@ -112,29 +112,26 @@
 }
 
 gboolean
-mm_modem_charset_byte_array_append (GByteArray *array,
-                                    const char *utf8,
-                                    gboolean quoted,
-                                    MMModemCharset charset)
+mm_modem_charset_byte_array_append (GByteArray      *array,
+                                    const gchar     *utf8,
+                                    gboolean         quoted,
+                                    MMModemCharset   charset,
+                                    GError         **error)
 {
-    const char *iconv_to;
-    char *converted;
-    GError *error = NULL;
-    gsize written = 0;
+    g_autofree gchar *converted = NULL;
+    const gchar      *iconv_to;
+    gsize             written = 0;
 
     g_return_val_if_fail (array != NULL, FALSE);
     g_return_val_if_fail (utf8 != NULL, FALSE);
 
     iconv_to = charset_iconv_to (charset);
-    g_return_val_if_fail (iconv_to != NULL, FALSE);
+    g_assert (iconv_to);
 
-    converted = g_convert (utf8, -1, iconv_to, "UTF-8", NULL, &written, &error);
+    converted = g_convert (utf8, -1, iconv_to, "UTF-8", NULL, &written, error);
     if (!converted) {
-        if (error) {
-            mm_warn ("failed to convert '%s' to %s character set: (%d) %s",
-                     utf8, iconv_to, error->code, error->message);
-            g_error_free (error);
-        }
+        g_prefix_error (error, "Failed to convert '%s' to %s character set",
+                        utf8, iconv_to);
         return FALSE;
     }
 
@@ -144,7 +141,6 @@
     if (quoted)
         g_byte_array_append (array, (const guint8 *) "\"", 1);
 
-    g_free (converted);
     return TRUE;
 }
 
diff --git a/src/mm-charsets.h b/src/mm-charsets.h
index 2e3e6f3..9e9215d 100644
--- a/src/mm-charsets.h
+++ b/src/mm-charsets.h
@@ -38,10 +38,11 @@
  * into the given charset first.  The original string is assumed to be
  * UTF-8 encoded.
  */
-gboolean mm_modem_charset_byte_array_append (GByteArray *array,
-                                             const char *utf8,
-                                             gboolean quoted,
-                                             MMModemCharset charset);
+gboolean mm_modem_charset_byte_array_append (GByteArray      *array,
+                                             const gchar     *utf8,
+                                             gboolean         quoted,
+                                             MMModemCharset   charset,
+                                             GError         **error);
 
 /* Take a string encoded in the given charset in binary form, and
  * convert it to UTF-8. */
diff --git a/src/mm-context.c b/src/mm-context.c
index 8630be0..406c744 100644
--- a/src/mm-context.c
+++ b/src/mm-context.c
@@ -178,7 +178,7 @@
     GOptionGroup *group;
 
     group = g_option_group_new ("log",
-                                "Logging options",
+                                "Logging options:",
                                 "Show logging options",
                                 NULL,
                                 NULL);
@@ -248,7 +248,7 @@
     GOptionGroup *group;
 
     group = g_option_group_new ("test",
-                                "Test options",
+                                "Test options:",
                                 "Show Test options",
                                 NULL,
                                 NULL);
@@ -279,8 +279,7 @@
 static void
 print_version (void)
 {
-    g_print ("\n"
-             "ModemManager " MM_DIST_VERSION "\n"
+    g_print ("ModemManager " MM_DIST_VERSION "\n"
              "Copyright (C) 2008-2020 The ModemManager authors\n"
              "License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl-2.0.html>\n"
              "This is free software: you are free to change and redistribute it.\n"
diff --git a/src/mm-device.c b/src/mm-device.c
index 86baf7c..a128d63 100644
--- a/src/mm-device.c
+++ b/src/mm-device.c
@@ -25,9 +25,12 @@
 
 #include "mm-device.h"
 #include "mm-plugin.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
-G_DEFINE_TYPE (MMDevice, mm_device, G_TYPE_OBJECT)
+static void log_object_iface_init (MMLogObjectInterface *iface);
+
+G_DEFINE_TYPE_EXTENDED (MMDevice, mm_device, G_TYPE_OBJECT, 0,
+                        G_IMPLEMENT_INTERFACE (MM_TYPE_LOG_OBJECT, log_object_iface_init))
 
 enum {
     PROP_0,
@@ -215,10 +218,8 @@
     probe = device_find_probe_with_device (self, kernel_port, FALSE);
     if (probe) {
         /* Found, remove from list and add to the ignored list */
-        mm_dbg ("[device %s] fully ignoring port '%s/%s' from now on",
-                self->priv->uid,
-                mm_kernel_device_get_subsystem (kernel_port),
-                mm_kernel_device_get_name (kernel_port));
+        mm_obj_dbg (self, "fully ignoring port %s from now on",
+                    mm_kernel_device_get_name (kernel_port));
         self->priv->port_probes = g_list_remove (self->priv->port_probes, probe);
         self->priv->ignored_port_probes = g_list_prepend (self->priv->ignored_port_probes, probe);
     }
@@ -240,7 +241,7 @@
         g_object_set (self->priv->modem,
                       MM_BASE_MODEM_CONNECTION, NULL,
                       NULL);
-        mm_dbg ("[device %s] unexported modem from path '%s'", self->priv->uid, path);
+        mm_obj_dbg (self, "unexported modem from path '%s'", path);
         g_free (path);
     }
 }
@@ -251,15 +252,14 @@
 export_modem (MMDevice *self)
 {
     GDBusConnection *connection = NULL;
-    static guint32 id = 0;
-    gchar *path;
+    gchar           *path;
 
     g_assert (MM_IS_BASE_MODEM (self->priv->modem));
     g_assert (G_IS_DBUS_OBJECT_MANAGER (self->priv->object_manager));
 
     /* If modem not yet valid (not fully initialized), don't export it */
     if (!mm_base_modem_get_valid (self->priv->modem)) {
-        mm_dbg ("[device %s] modem not yet fully initialized", self->priv->uid);
+        mm_obj_dbg (self, "modem not yet fully initialized");
         return;
     }
 
@@ -269,13 +269,13 @@
                   NULL);
     if (path) {
         g_free (path);
-        mm_dbg ("[device %s] modem already exported", self->priv->uid);
+        mm_obj_dbg (self, "modem already exported");
         return;
     }
 
     /* No outstanding port tasks, so if the modem is valid we can export it */
 
-    path = g_strdup_printf (MM_DBUS_MODEM_PREFIX "/%d", id++);
+    path = g_strdup_printf (MM_DBUS_MODEM_PREFIX "/%d", mm_base_modem_get_dbus_id (self->priv->modem));
     g_object_get (self->priv->object_manager,
                   "connection", &connection,
                   NULL);
@@ -288,14 +288,13 @@
     g_dbus_object_manager_server_export (self->priv->object_manager,
                                          G_DBUS_OBJECT_SKELETON (self->priv->modem));
 
-    mm_dbg ("[device %s] exported modem at path '%s'", self->priv->uid, path);
-    mm_dbg ("[device %s]    plugin:  %s", self->priv->uid, mm_base_modem_get_plugin (self->priv->modem));
-    mm_dbg ("[device %s]    vid:pid: 0x%04X:0x%04X",
-            self->priv->uid,
-            (mm_base_modem_get_vendor_id (self->priv->modem) & 0xFFFF),
-            (mm_base_modem_get_product_id (self->priv->modem) & 0xFFFF));
+    mm_obj_dbg (self, " exported modem at path '%s'", path);
+    mm_obj_dbg (self, "    plugin:  %s", mm_base_modem_get_plugin (self->priv->modem));
+    mm_obj_dbg (self, "    vid:pid: 0x%04X:0x%04X",
+                (mm_base_modem_get_vendor_id (self->priv->modem) & 0xFFFF),
+                (mm_base_modem_get_product_id (self->priv->modem) & 0xFFFF));
     if (self->priv->virtual)
-        mm_dbg ("[device %s]    virtual", self->priv->uid);
+        mm_obj_dbg (self, "    virtual");
 
     g_free (path);
 }
@@ -338,12 +337,10 @@
     GError *error = NULL;
 
     if (!mm_device_create_modem (self, &error)) {
-        mm_warn ("Could not recreate modem for device '%s': %s",
-                 self->priv->uid,
-                 error ? error->message : "unknown");
+        mm_obj_warn (self, "could not recreate modem: %s", error->message);
         g_error_free (error);
     } else
-        mm_dbg ("Modem recreated for device '%s'", self->priv->uid);
+        mm_obj_dbg (self, "modem recreated");
 
     return G_SOURCE_REMOVE;
 }
@@ -366,7 +363,7 @@
         if (self->priv->modem)
             export_modem (self);
         else
-            mm_dbg ("[device %s] not exporting modem; no longer available", self->priv->uid);
+            mm_obj_dbg (self, "not exporting modem; no longer available");
     }
 }
 
@@ -391,10 +388,9 @@
             return FALSE;
         }
 
-        mm_info ("[device %s] creating modem with plugin '%s' and '%u' ports",
-                 self->priv->uid,
-                 mm_plugin_get_name (self->priv->plugin),
-                 g_list_length (self->priv->port_probes));
+        mm_obj_info (self, "creating modem with plugin '%s' and '%u' ports",
+                     mm_plugin_get_name (self->priv->plugin),
+                     g_list_length (self->priv->port_probes));
     } else {
         if (!self->priv->virtual_ports) {
             g_set_error (error,
@@ -404,10 +400,9 @@
             return FALSE;
         }
 
-        mm_info ("[device %s] creating virtual modem with plugin '%s' and '%u' ports",
-                 self->priv->uid,
-                 mm_plugin_get_name (self->priv->plugin),
-                 g_strv_length (self->priv->virtual_ports));
+        mm_obj_info (self, "creating virtual modem with plugin '%s' and '%u' ports",
+                     mm_plugin_get_name (self->priv->plugin),
+                     g_strv_length (self->priv->virtual_ports));
     }
 
     self->priv->modem = mm_plugin_create_modem (self->priv->plugin, self, error);
@@ -640,6 +635,17 @@
 
 /*****************************************************************************/
 
+static gchar *
+log_object_build_id (MMLogObject *_self)
+{
+    MMDevice *self;
+
+    self = MM_DEVICE (_self);
+    return g_strdup_printf ("device %s", self->priv->uid);
+}
+
+/*****************************************************************************/
+
 MMDevice *
 mm_device_new (const gchar              *uid,
                gboolean                  hotplugged,
@@ -773,6 +779,12 @@
 }
 
 static void
+log_object_iface_init (MMLogObjectInterface *iface)
+{
+    iface->build_id = log_object_build_id;
+}
+
+static void
 mm_device_class_init (MMDeviceClass *klass)
 {
     GObjectClass *object_class = G_OBJECT_CLASS (klass);
diff --git a/src/mm-error-helpers.c b/src/mm-error-helpers.c
index 7ce3211..57486d8 100644
--- a/src/mm-error-helpers.c
+++ b/src/mm-error-helpers.c
@@ -29,7 +29,8 @@
 /* --- Connection errors --- */
 
 GError *
-mm_connection_error_for_code (MMConnectionError code)
+mm_connection_error_for_code (MMConnectionError code,
+                              gpointer          log_object)
 {
     const gchar *msg;
 
@@ -51,7 +52,7 @@
         break;
 
     default:
-        mm_dbg ("Invalid connection error code: %u", code);
+        mm_obj_dbg (log_object, "invalid connection error code: %u", code);
         /* uhm... make something up (yes, ok, lie!). */
         code = MM_CONNECTION_ERROR_NO_CARRIER;
         msg = "No carrier";
@@ -149,7 +150,8 @@
 };
 
 GError *
-mm_mobile_equipment_error_for_code (MMMobileEquipmentError code)
+mm_mobile_equipment_error_for_code (MMMobileEquipmentError code,
+                                    gpointer               log_object)
 {
     guint i;
 
@@ -162,14 +164,15 @@
     }
 
     /* Not found? Then, default */
-    mm_dbg ("Invalid mobile equipment error code: %u", (guint)code);
+    mm_obj_dbg (log_object, "invalid mobile equipment error code: %u", (guint)code);
     return g_error_new (MM_MOBILE_EQUIPMENT_ERROR,
                         MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN,
                         "Unknown error");
 }
 
 GError *
-mm_mobile_equipment_error_for_string (const gchar *str)
+mm_mobile_equipment_error_for_string (const gchar *str,
+                                      gpointer     log_object)
 {
     MMMobileEquipmentError code = MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN;
     const gchar *msg = NULL;
@@ -198,7 +201,7 @@
 
     /* Not found? Then, default */
     if (!msg) {
-        mm_dbg ("Invalid mobile equipment error string: '%s' (%s)", str, buf);
+        mm_obj_dbg (log_object, "invalid mobile equipment error string: '%s' (%s)", str, buf);
         code = MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN;
         msg = "Unknown error";
     }
@@ -236,7 +239,8 @@
 };
 
 GError *
-mm_message_error_for_code (MMMessageError code)
+mm_message_error_for_code (MMMessageError code,
+                           gpointer       log_object)
 {
     guint i;
 
@@ -249,14 +253,15 @@
     }
 
     /* Not found? Then, default */
-    mm_dbg ("Invalid message error code: %u", (guint)code);
+    mm_obj_dbg (log_object, "invalid message error code: %u", (guint)code);
     return g_error_new (MM_MESSAGE_ERROR,
                         MM_MESSAGE_ERROR_UNKNOWN,
                         "Unknown error");
 }
 
 GError *
-mm_message_error_for_string (const gchar *str)
+mm_message_error_for_string (const gchar *str,
+                             gpointer     log_object)
 {
     MMMessageError code = MM_MESSAGE_ERROR_UNKNOWN;
     const gchar *msg = NULL;
@@ -285,7 +290,7 @@
 
     /* Not found? Then, default */
     if (!msg) {
-        mm_dbg ("Invalid message error string: '%s' (%s)", str, buf);
+        mm_obj_dbg (log_object, "invalid message error string: '%s' (%s)", str, buf);
         code = MM_MESSAGE_ERROR_UNKNOWN;
         msg = "Unknown error";
     }
diff --git a/src/mm-error-helpers.h b/src/mm-error-helpers.h
index 379afb2..e99d166 100644
--- a/src/mm-error-helpers.h
+++ b/src/mm-error-helpers.h
@@ -23,10 +23,10 @@
 #include <ModemManager.h>
 #include <libmm-glib.h>
 
-GError *mm_connection_error_for_code         (MMConnectionError code);
-GError *mm_mobile_equipment_error_for_code   (MMMobileEquipmentError code);
-GError *mm_mobile_equipment_error_for_string (const gchar *str);
-GError *mm_message_error_for_code            (MMMessageError code);
-GError *mm_message_error_for_string          (const gchar *str);
+GError *mm_connection_error_for_code         (MMConnectionError       code, gpointer log_object);
+GError *mm_mobile_equipment_error_for_code   (MMMobileEquipmentError  code, gpointer log_object);
+GError *mm_mobile_equipment_error_for_string (const gchar            *str,  gpointer log_object);
+GError *mm_message_error_for_code            (MMMessageError          code, gpointer log_object);
+GError *mm_message_error_for_string          (const gchar            *str,  gpointer log_object);
 
 #endif /* MM_ERROR_HELPERS_H */
diff --git a/src/mm-filter.c b/src/mm-filter.c
index 73c6bde..cfa620b 100644
--- a/src/mm-filter.c
+++ b/src/mm-filter.c
@@ -21,11 +21,14 @@
 
 #include "mm-daemon-enums-types.h"
 #include "mm-filter.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 #define FILTER_PORT_MAYBE_FORBIDDEN "maybe-forbidden"
 
-G_DEFINE_TYPE (MMFilter, mm_filter, G_TYPE_OBJECT)
+static void log_object_iface_init (MMLogObjectInterface *iface);
+
+G_DEFINE_TYPE_EXTENDED (MMFilter, mm_filter, G_TYPE_OBJECT, 0,
+                        G_IMPLEMENT_INTERFACE (MM_TYPE_LOG_OBJECT, log_object_iface_init))
 
 enum {
     PROP_0,
@@ -46,7 +49,7 @@
                                          const gchar *tag)
 {
     if (!g_list_find_custom (self->priv->plugin_whitelist_tags, tag, (GCompareFunc) g_strcmp0)) {
-        mm_dbg ("[filter] registered plugin whitelist tag: %s", tag);
+        mm_obj_dbg (self, "registered plugin whitelist tag: %s", tag);
         self->priv->plugin_whitelist_tags = g_list_prepend (self->priv->plugin_whitelist_tags, g_strdup (tag));
     }
 }
@@ -73,7 +76,7 @@
     new_item.l = vid;
     new_item.r = pid;
     g_array_append_val (self->priv->plugin_whitelist_product_ids, new_item);
-    mm_dbg ("[filter] registered plugin whitelist product id: %04x:%04x", vid, pid);
+    mm_obj_dbg (self, "registered plugin whitelist product id: %04x:%04x", vid, pid);
 }
 
 /*****************************************************************************/
@@ -95,14 +98,14 @@
     if ((self->priv->enabled_rules & MM_FILTER_RULE_EXPLICIT_WHITELIST) &&
         (mm_kernel_device_get_global_property_as_boolean (port, ID_MM_DEVICE_PROCESS) ||
          mm_kernel_device_get_property_as_boolean (port, ID_MM_DEVICE_PROCESS))) {
-        mm_dbg ("[filter] (%s/%s) port allowed: device is whitelisted", subsystem, name);
+        mm_obj_dbg (self, "(%s/%s) port allowed: device is whitelisted", subsystem, name);
         return TRUE;
     }
 
     /* If the device is explicitly blacklisted, we ignore every port. */
     if ((self->priv->enabled_rules & MM_FILTER_RULE_EXPLICIT_BLACKLIST) &&
         (mm_kernel_device_get_global_property_as_boolean (port, ID_MM_DEVICE_IGNORE))) {
-        mm_dbg ("[filter] (%s/%s): port filtered: device is blacklisted", subsystem, name);
+        mm_obj_dbg (self, "(%s/%s): port filtered: device is blacklisted", subsystem, name);
         return FALSE;
     }
 
@@ -115,7 +118,7 @@
         for (l = self->priv->plugin_whitelist_tags; l; l = g_list_next (l)) {
             if (mm_kernel_device_get_global_property_as_boolean (port, (const gchar *)(l->data)) ||
                 mm_kernel_device_get_property_as_boolean (port, (const gchar *)(l->data))) {
-                mm_dbg ("[filter] (%s/%s) port allowed: device is whitelisted by plugin (tag)", subsystem, name);
+                mm_obj_dbg (self, "(%s/%s) port allowed: device is whitelisted by plugin (tag)", subsystem, name);
                 return TRUE;
             }
         }
@@ -132,7 +135,7 @@
 
                 item = &g_array_index (self->priv->plugin_whitelist_product_ids, mm_uint16_pair, i);
                 if (item->l == vid && item->r == pid) {
-                    mm_dbg ("[filter] (%s/%s) port allowed: device is whitelisted by plugin (vid/pid)", subsystem, name);
+                    mm_obj_dbg (self, "(%s/%s) port allowed: device is whitelisted by plugin (vid/pid)", subsystem, name);
                     return TRUE;
                 }
             }
@@ -142,14 +145,14 @@
     /* If this is a virtual device, don't allow it */
     if ((self->priv->enabled_rules & MM_FILTER_RULE_VIRTUAL) &&
         (!mm_kernel_device_get_physdev_sysfs_path (port))) {
-        mm_dbg ("[filter] (%s/%s) port filtered: virtual device", subsystem, name);
+        mm_obj_dbg (self, "(%s/%s) port filtered: virtual device", subsystem, name);
         return FALSE;
     }
 
     /* If this is a net device, we always allow it */
     if ((self->priv->enabled_rules & MM_FILTER_RULE_NET) &&
         (g_strcmp0 (subsystem, "net") == 0)) {
-        mm_dbg ("[filter] (%s/%s) port allowed: net device", subsystem, name);
+        mm_obj_dbg (self, "(%s/%s) port allowed: net device", subsystem, name);
         return TRUE;
     }
 
@@ -157,7 +160,7 @@
     if ((self->priv->enabled_rules & MM_FILTER_RULE_CDC_WDM) &&
         (g_strcmp0 (subsystem, "usb") == 0 || g_strcmp0 (subsystem, "usbmisc") == 0) &&
         (name && g_str_has_prefix (name, "cdc-wdm"))) {
-        mm_dbg ("[filter] (%s/%s) port allowed: cdc-wdm device", subsystem, name);
+        mm_obj_dbg (self, "(%s/%s) port allowed: cdc-wdm device", subsystem, name);
         return TRUE;
     }
 
@@ -172,7 +175,7 @@
         /* Ignore blacklisted tty devices. */
         if ((self->priv->enabled_rules & MM_FILTER_RULE_TTY_BLACKLIST) &&
             (mm_kernel_device_get_global_property_as_boolean (port, ID_MM_TTY_BLACKLIST))) {
-            mm_dbg ("[filter] (%s/%s): port filtered: tty is blacklisted", subsystem, name);
+            mm_obj_dbg (self, "(%s/%s): port filtered: tty is blacklisted", subsystem, name);
             return FALSE;
         }
 
@@ -180,7 +183,7 @@
          * automatic scan. */
         if ((self->priv->enabled_rules & MM_FILTER_RULE_TTY_MANUAL_SCAN_ONLY) &&
             (!manual_scan && mm_kernel_device_get_global_property_as_boolean (port, ID_MM_TTY_MANUAL_SCAN_ONLY))) {
-            mm_dbg ("[filter] (%s/%s): port filtered: tty probed only in manual scan", subsystem, name);
+            mm_obj_dbg (self, "(%s/%s): port filtered: tty probed only in manual scan", subsystem, name);
             return FALSE;
         }
 
@@ -193,13 +196,13 @@
              !g_strcmp0 (physdev_subsystem, "pci") ||
              !g_strcmp0 (physdev_subsystem, "pnp") ||
              !g_strcmp0 (physdev_subsystem, "sdio"))) {
-            mm_dbg ("[filter] (%s/%s): port filtered: tty platform driver", subsystem, name);
+            mm_obj_dbg (self, "(%s/%s): port filtered: tty platform driver", subsystem, name);
             return FALSE;
         }
 
         /* Default allowed? */
         if (self->priv->enabled_rules & MM_FILTER_RULE_TTY_DEFAULT_ALLOWED) {
-            mm_dbg ("[filter] (%s/%s) port allowed", subsystem, name);
+            mm_obj_dbg (self, "(%s/%s) port allowed", subsystem, name);
             return TRUE;
         }
 
@@ -213,7 +216,7 @@
              !g_strcmp0 (driver, "qcaux") ||
              !g_strcmp0 (driver, "nozomi") ||
              !g_strcmp0 (driver, "sierra"))) {
-            mm_dbg ("[filter] (%s/%s): port allowed: modem-specific kernel driver detected", subsystem, name);
+            mm_obj_dbg (self, "(%s/%s): port allowed: modem-specific kernel driver detected", subsystem, name);
             return TRUE;
         }
 
@@ -246,7 +249,7 @@
              (mm_kernel_device_get_interface_subclass (port) != 2) ||
              (mm_kernel_device_get_interface_protocol (port) < 1)  ||
              (mm_kernel_device_get_interface_protocol (port) > 6))) {
-            mm_dbg ("[filter] (%s/%s): port filtered: cdc-acm interface is not AT-capable", subsystem, name);
+            mm_obj_dbg (self, "(%s/%s): port filtered: cdc-acm interface is not AT-capable", subsystem, name);
             return FALSE;
         }
 
@@ -260,7 +263,7 @@
     }
 
     /* Otherwise forbidden */
-    mm_dbg ("[filter] (%s/%s) port filtered: forbidden port type", subsystem, name);
+    mm_obj_dbg (self, "(%s/%s) port filtered: forbidden port type", subsystem, name);
     return FALSE;
 }
 
@@ -303,7 +306,7 @@
     /* Check whether this device holds a NET port in addition to this TTY */
     if ((self->priv->enabled_rules & MM_FILTER_RULE_TTY_WITH_NET) &&
         device_has_net_port (device)) {
-        mm_dbg ("[filter] (%s/%s): port allowed: device also exports a net interface", subsystem, name);
+        mm_obj_dbg (self, "(%s/%s): port allowed: device also exports a net interface", subsystem, name);
         return TRUE;
     }
 
@@ -312,11 +315,11 @@
     if ((self->priv->enabled_rules & MM_FILTER_RULE_TTY_ACM_INTERFACE) &&
         (!g_strcmp0 (driver, "cdc_acm")) &&
         device_has_multiple_ports (device)) {
-        mm_dbg ("[filter] (%s/%s): port allowed: device exports multiple interfaces", subsystem, name);
+        mm_obj_dbg (self, "(%s/%s): port allowed: device exports multiple interfaces", subsystem, name);
         return TRUE;
     }
 
-    mm_dbg ("[filter] (%s/%s) port filtered: forbidden", subsystem, name);
+    mm_obj_dbg (self, "(%s/%s) port filtered: forbidden", subsystem, name);
     return FALSE;
 }
 
@@ -368,6 +371,14 @@
 
 /*****************************************************************************/
 
+static gchar *
+log_object_build_id (MMLogObject *_self)
+{
+    return g_strdup ("filter");
+}
+
+/*****************************************************************************/
+
 /* If TTY rule enabled, either DEFAULT_ALLOWED or DEFAULT_FORBIDDEN must be set. */
 #define VALIDATE_RULE_TTY(rules) (!(rules & MM_FILTER_RULE_TTY) || \
                                   ((rules & (MM_FILTER_RULE_TTY_DEFAULT_ALLOWED | MM_FILTER_RULE_TTY_DEFAULT_FORBIDDEN)) && \
@@ -396,29 +407,29 @@
 
 #define RULE_ENABLED_STR(flag) ((self->priv->enabled_rules & flag) ? "yes" : "no")
 
-    mm_dbg ("[filter] created");
-    mm_dbg ("[filter]   explicit whitelist:         %s", RULE_ENABLED_STR (MM_FILTER_RULE_EXPLICIT_WHITELIST));
-    mm_dbg ("[filter]   explicit blacklist:         %s", RULE_ENABLED_STR (MM_FILTER_RULE_EXPLICIT_BLACKLIST));
-    mm_dbg ("[filter]   plugin whitelist:           %s", RULE_ENABLED_STR (MM_FILTER_RULE_PLUGIN_WHITELIST));
-    mm_dbg ("[filter]   virtual devices forbidden:  %s", RULE_ENABLED_STR (MM_FILTER_RULE_VIRTUAL));
-    mm_dbg ("[filter]   net devices allowed:        %s", RULE_ENABLED_STR (MM_FILTER_RULE_NET));
-    mm_dbg ("[filter]   cdc-wdm devices allowed:    %s", RULE_ENABLED_STR (MM_FILTER_RULE_CDC_WDM));
+    mm_obj_dbg (self, "created");
+    mm_obj_dbg (self, "  explicit whitelist:         %s", RULE_ENABLED_STR (MM_FILTER_RULE_EXPLICIT_WHITELIST));
+    mm_obj_dbg (self, "  explicit blacklist:         %s", RULE_ENABLED_STR (MM_FILTER_RULE_EXPLICIT_BLACKLIST));
+    mm_obj_dbg (self, "  plugin whitelist:           %s", RULE_ENABLED_STR (MM_FILTER_RULE_PLUGIN_WHITELIST));
+    mm_obj_dbg (self, "  virtual devices forbidden:  %s", RULE_ENABLED_STR (MM_FILTER_RULE_VIRTUAL));
+    mm_obj_dbg (self, "  net devices allowed:        %s", RULE_ENABLED_STR (MM_FILTER_RULE_NET));
+    mm_obj_dbg (self, "  cdc-wdm devices allowed:    %s", RULE_ENABLED_STR (MM_FILTER_RULE_CDC_WDM));
     if (self->priv->enabled_rules & MM_FILTER_RULE_TTY) {
-        mm_dbg ("[filter]   tty devices:");
-        mm_dbg ("[filter]       blacklist applied:        %s", RULE_ENABLED_STR (MM_FILTER_RULE_TTY_BLACKLIST));
-        mm_dbg ("[filter]       manual scan only applied: %s", RULE_ENABLED_STR (MM_FILTER_RULE_TTY_MANUAL_SCAN_ONLY));
-        mm_dbg ("[filter]       platform driver check:    %s", RULE_ENABLED_STR (MM_FILTER_RULE_TTY_PLATFORM_DRIVER));
-        mm_dbg ("[filter]       driver check:             %s", RULE_ENABLED_STR (MM_FILTER_RULE_TTY_DRIVER));
-        mm_dbg ("[filter]       cdc-acm interface check:  %s", RULE_ENABLED_STR (MM_FILTER_RULE_TTY_ACM_INTERFACE));
-        mm_dbg ("[filter]       with net check:           %s", RULE_ENABLED_STR (MM_FILTER_RULE_TTY_WITH_NET));
+        mm_obj_dbg (self, "  tty devices:");
+        mm_obj_dbg (self, "      blacklist applied:        %s", RULE_ENABLED_STR (MM_FILTER_RULE_TTY_BLACKLIST));
+        mm_obj_dbg (self, "      manual scan only applied: %s", RULE_ENABLED_STR (MM_FILTER_RULE_TTY_MANUAL_SCAN_ONLY));
+        mm_obj_dbg (self, "      platform driver check:    %s", RULE_ENABLED_STR (MM_FILTER_RULE_TTY_PLATFORM_DRIVER));
+        mm_obj_dbg (self, "      driver check:             %s", RULE_ENABLED_STR (MM_FILTER_RULE_TTY_DRIVER));
+        mm_obj_dbg (self, "      cdc-acm interface check:  %s", RULE_ENABLED_STR (MM_FILTER_RULE_TTY_ACM_INTERFACE));
+        mm_obj_dbg (self, "      with net check:           %s", RULE_ENABLED_STR (MM_FILTER_RULE_TTY_WITH_NET));
         if (self->priv->enabled_rules & MM_FILTER_RULE_TTY_DEFAULT_ALLOWED)
-            mm_dbg ("[filter]       default:                  allowed");
+            mm_obj_dbg (self, "      default:                  allowed");
         else if (self->priv->enabled_rules & MM_FILTER_RULE_TTY_DEFAULT_FORBIDDEN)
-            mm_dbg ("[filter]       default:                  forbidden");
+            mm_obj_dbg (self, "      default:                  forbidden");
         else
             g_assert_not_reached ();
     } else
-        mm_dbg ("[filter]   tty devices:                no");
+        mm_obj_dbg (self, "  tty devices:                no");
 
 #undef RULE_ENABLED_STR
 
@@ -479,6 +490,12 @@
 }
 
 static void
+log_object_iface_init (MMLogObjectInterface *iface)
+{
+    iface->build_id = log_object_build_id;
+}
+
+static void
 mm_filter_class_init (MMFilterClass *klass)
 {
     GObjectClass *object_class = G_OBJECT_CLASS (klass);
diff --git a/src/mm-iface-modem-3gpp-ussd.c b/src/mm-iface-modem-3gpp-ussd.c
index fd02923..e649a40 100644
--- a/src/mm-iface-modem-3gpp-ussd.c
+++ b/src/mm-iface-modem-3gpp-ussd.c
@@ -26,7 +26,7 @@
 #include "mm-iface-modem-3gpp-ussd.h"
 #include "mm-base-modem.h"
 #include "mm-modem-helpers.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 #define SUPPORT_CHECKED_TAG "3gpp-ussd-support-checked-tag"
 #define SUPPORTED_TAG       "3gpp-ussd-supported-tag"
@@ -526,7 +526,7 @@
     MM_IFACE_MODEM_3GPP_USSD_GET_INTERFACE (self)->disable_unsolicited_events_finish (self, res, &error);
     if (error) {
         /* This error shouldn't be treated as critical */
-        mm_dbg ("Couldn't disable unsolicited USSD events: '%s'", error->message);
+        mm_obj_dbg (self, "couldn't disable unsolicited USSD events: %s", error->message);
         g_error_free (error);
     }
 
@@ -547,7 +547,7 @@
     MM_IFACE_MODEM_3GPP_USSD_GET_INTERFACE (self)->cleanup_unsolicited_events_finish (self, res, &error);
     if (error) {
         /* This error shouldn't be treated as critical */
-        mm_dbg ("Couldn't cleanup unsolicited USSD events: '%s'", error->message);
+        mm_obj_dbg (self, "couldn't cleanup unsolicited USSD events: %s", error->message);
         g_error_free (error);
     }
 
@@ -673,7 +673,7 @@
     MM_IFACE_MODEM_3GPP_USSD_GET_INTERFACE (self)->setup_unsolicited_events_finish (self, res, &error);
     if (error) {
         /* This error shouldn't be treated as critical */
-        mm_dbg ("Couldn't setup unsolicited USSD events: '%s'", error->message);
+        mm_obj_dbg (self, "couldn't setup unsolicited USSD events: %s", error->message);
         g_error_free (error);
     }
 
@@ -694,7 +694,7 @@
     MM_IFACE_MODEM_3GPP_USSD_GET_INTERFACE (self)->enable_unsolicited_events_finish (self, res, &error);
     if (error) {
         /* This error shouldn't be treated as critical */
-        mm_dbg ("Couldn't enable unsolicited USSD events: '%s'", error->message);
+        mm_obj_dbg (self, "couldn't enable unsolicited USSD events: %s", error->message);
         g_error_free (error);
     }
 
@@ -813,7 +813,7 @@
                                                                               &error)) {
         if (error) {
             /* This error shouldn't be treated as critical */
-            mm_dbg ("USSD support check failed: '%s'", error->message);
+            mm_obj_dbg (self, "USSD support check failed: %s", error->message);
             g_error_free (error);
         }
     } else {
diff --git a/src/mm-iface-modem-3gpp.c b/src/mm-iface-modem-3gpp.c
index 0d07b89..f9963e4 100644
--- a/src/mm-iface-modem-3gpp.c
+++ b/src/mm-iface-modem-3gpp.c
@@ -38,9 +38,10 @@
 
 typedef struct {
     /* Registration state */
-    MMModem3gppRegistrationState  cs;
-    MMModem3gppRegistrationState  ps;
-    MMModem3gppRegistrationState  eps;
+    MMModem3gppRegistrationState  state_cs;
+    MMModem3gppRegistrationState  state_ps;
+    MMModem3gppRegistrationState  state_eps;
+    MMModem3gppRegistrationState  state_5gs;
     gboolean                      manual_registration;
     gchar                        *manual_registration_operator_id;
     GCancellable                 *pending_registration_cancellable;
@@ -74,9 +75,10 @@
     priv = g_object_get_qdata (G_OBJECT (self), private_quark);
     if (!priv) {
         priv = g_slice_new0 (Private);
-        priv->cs = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
-        priv->ps = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
-        priv->eps = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
+        priv->state_cs = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
+        priv->state_ps = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
+        priv->state_eps = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
+        priv->state_5gs = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
         g_object_set_qdata_full (G_OBJECT (self), private_quark, priv, (GDestroyNotify)private_free);
     }
 
@@ -140,50 +142,59 @@
      * So here we prefer the +CREG response, but if we never got a successful
      * +CREG response, we'll take +CGREG instead.
      */
-    if (priv->cs == MM_MODEM_3GPP_REGISTRATION_STATE_HOME ||
-        priv->cs == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING) {
-        consolidated = priv->cs;
+    if (priv->state_cs == MM_MODEM_3GPP_REGISTRATION_STATE_HOME ||
+        priv->state_cs == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING) {
+        consolidated = priv->state_cs;
         goto out;
     }
-    if (priv->ps == MM_MODEM_3GPP_REGISTRATION_STATE_HOME ||
-        priv->ps == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING) {
-        consolidated = priv->ps;
+    if (priv->state_ps == MM_MODEM_3GPP_REGISTRATION_STATE_HOME ||
+        priv->state_ps == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING) {
+        consolidated = priv->state_ps;
         goto out;
     }
-    if (priv->eps == MM_MODEM_3GPP_REGISTRATION_STATE_HOME ||
-        priv->eps == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING) {
-        consolidated = priv->eps;
+    if (priv->state_eps == MM_MODEM_3GPP_REGISTRATION_STATE_HOME ||
+        priv->state_eps == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING) {
+        consolidated = priv->state_eps;
+        goto out;
+    }
+    if (priv->state_5gs == MM_MODEM_3GPP_REGISTRATION_STATE_HOME ||
+        priv->state_5gs == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING) {
+        consolidated = priv->state_5gs;
         goto out;
     }
 
     /* Searching? */
-    if (priv->cs  == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING ||
-        priv->ps  == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING ||
-        priv->eps == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING) {
+    if (priv->state_cs  == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING ||
+        priv->state_ps  == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING ||
+        priv->state_eps == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING ||
+        priv->state_5gs == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING) {
          consolidated = MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING;
          goto out;
     }
 
     /* If at least one state is DENIED and the others are UNKNOWN or IDLE, use DENIED */
-    if ((priv->cs == MM_MODEM_3GPP_REGISTRATION_STATE_DENIED ||
-         priv->ps == MM_MODEM_3GPP_REGISTRATION_STATE_DENIED ||
-         priv->eps == MM_MODEM_3GPP_REGISTRATION_STATE_DENIED) &&
-        REG_STATE_IS_UNKNOWN_IDLE_DENIED (priv->cs) &&
-        REG_STATE_IS_UNKNOWN_IDLE_DENIED (priv->ps) &&
-        REG_STATE_IS_UNKNOWN_IDLE_DENIED (priv->eps)) {
+    if ((priv->state_cs == MM_MODEM_3GPP_REGISTRATION_STATE_DENIED ||
+         priv->state_ps == MM_MODEM_3GPP_REGISTRATION_STATE_DENIED ||
+         priv->state_eps == MM_MODEM_3GPP_REGISTRATION_STATE_DENIED ||
+         priv->state_5gs == MM_MODEM_3GPP_REGISTRATION_STATE_DENIED) &&
+        REG_STATE_IS_UNKNOWN_IDLE_DENIED (priv->state_cs) &&
+        REG_STATE_IS_UNKNOWN_IDLE_DENIED (priv->state_ps) &&
+        REG_STATE_IS_UNKNOWN_IDLE_DENIED (priv->state_eps) &&
+        REG_STATE_IS_UNKNOWN_IDLE_DENIED (priv->state_5gs)) {
         consolidated = MM_MODEM_3GPP_REGISTRATION_STATE_DENIED;
         goto out;
     }
 
     /* Emergency services? */
-    if (priv->cs  == MM_MODEM_3GPP_REGISTRATION_STATE_EMERGENCY_ONLY ||
-        priv->ps  == MM_MODEM_3GPP_REGISTRATION_STATE_EMERGENCY_ONLY ||
-        priv->eps == MM_MODEM_3GPP_REGISTRATION_STATE_EMERGENCY_ONLY) {
+    if (priv->state_cs  == MM_MODEM_3GPP_REGISTRATION_STATE_EMERGENCY_ONLY ||
+        priv->state_ps  == MM_MODEM_3GPP_REGISTRATION_STATE_EMERGENCY_ONLY ||
+        priv->state_eps == MM_MODEM_3GPP_REGISTRATION_STATE_EMERGENCY_ONLY ||
+        priv->state_5gs == MM_MODEM_3GPP_REGISTRATION_STATE_EMERGENCY_ONLY) {
          consolidated = MM_MODEM_3GPP_REGISTRATION_STATE_EMERGENCY_ONLY;
          goto out;
     }
 
-    /* Support for additional registration states reported when on LTE.
+    /* Support for additional registration states reported when on LTE/5GNR.
      *
      * For example, we may see the modem registered in LTE (EPS==HOME), and we
      * may get "SMS only" reported for CS.
@@ -195,30 +206,32 @@
      * We also warn in that case, because ideally we should always report the
      * LTE registration state first, not this one.
      */
-    if (priv->cs == MM_MODEM_3GPP_REGISTRATION_STATE_HOME_SMS_ONLY ||
-        priv->cs == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING_SMS_ONLY ||
-        priv->cs == MM_MODEM_3GPP_REGISTRATION_STATE_HOME_CSFB_NOT_PREFERRED ||
-        priv->cs == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING_CSFB_NOT_PREFERRED) {
-        mm_warn ("3GPP CSFB registration state is consolidated: %s",
-                 mm_modem_3gpp_registration_state_get_string (priv->cs));
-        consolidated = priv->cs;
+    if (priv->state_cs == MM_MODEM_3GPP_REGISTRATION_STATE_HOME_SMS_ONLY ||
+        priv->state_cs == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING_SMS_ONLY ||
+        priv->state_cs == MM_MODEM_3GPP_REGISTRATION_STATE_HOME_CSFB_NOT_PREFERRED ||
+        priv->state_cs == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING_CSFB_NOT_PREFERRED) {
+        mm_obj_warn (self, "3GPP CSFB registration state is consolidated: %s",
+                     mm_modem_3gpp_registration_state_get_string (priv->state_cs));
+        consolidated = priv->state_cs;
         goto out;
     }
 
     /* Idle? */
-    if (priv->cs  == MM_MODEM_3GPP_REGISTRATION_STATE_IDLE ||
-        priv->ps  == MM_MODEM_3GPP_REGISTRATION_STATE_IDLE ||
-        priv->eps == MM_MODEM_3GPP_REGISTRATION_STATE_IDLE) {
+    if (priv->state_cs  == MM_MODEM_3GPP_REGISTRATION_STATE_IDLE ||
+        priv->state_ps  == MM_MODEM_3GPP_REGISTRATION_STATE_IDLE ||
+        priv->state_eps == MM_MODEM_3GPP_REGISTRATION_STATE_IDLE ||
+        priv->state_5gs == MM_MODEM_3GPP_REGISTRATION_STATE_IDLE) {
          consolidated = MM_MODEM_3GPP_REGISTRATION_STATE_IDLE;
          goto out;
     }
 
  out:
-    mm_dbg ("building consolidated registration state: cs '%s', ps '%s', eps '%s' --> '%s'",
-            mm_modem_3gpp_registration_state_get_string (priv->cs),
-            mm_modem_3gpp_registration_state_get_string (priv->ps),
-            mm_modem_3gpp_registration_state_get_string (priv->eps),
-            mm_modem_3gpp_registration_state_get_string (consolidated));
+    mm_obj_dbg (self, "building consolidated registration state: cs '%s', ps '%s', eps '%s', 5gs '%s' --> '%s'",
+                mm_modem_3gpp_registration_state_get_string (priv->state_cs),
+                mm_modem_3gpp_registration_state_get_string (priv->state_ps),
+                mm_modem_3gpp_registration_state_get_string (priv->state_eps),
+                mm_modem_3gpp_registration_state_get_string (priv->state_5gs),
+                mm_modem_3gpp_registration_state_get_string (consolidated));
 
     return consolidated;
 }
@@ -298,7 +311,7 @@
 
     mm_iface_modem_3gpp_run_registration_checks_finish (MM_IFACE_MODEM_3GPP (self), res, &error);
     if (error) {
-        mm_dbg ("3GPP registration check failed: '%s'", error->message);
+        mm_obj_dbg (self, "3GPP registration check failed: %s", error->message);
         register_in_network_context_complete_failed (task, error);
         return;
     }
@@ -308,10 +321,10 @@
     /* If we got a final state and it's denied, we can assume the registration is
      * finished */
     if (current_registration_state == MM_MODEM_3GPP_REGISTRATION_STATE_DENIED) {
-        mm_dbg ("Registration denied");
+        mm_obj_dbg (self, "registration denied");
         register_in_network_context_complete_failed (
             task,
-            mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_NETWORK_NOT_ALLOWED));
+            mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_NETWORK_NOT_ALLOWED, self));
         return;
     }
 
@@ -322,7 +335,7 @@
          * wouldn't be an explicit refresh triggered from the modem interface as
          * the modem never got un-registered during the sequence. */
         mm_iface_modem_refresh_signal (MM_IFACE_MODEM (ctx->self));
-        mm_dbg ("Modem is currently registered in a 3GPP network");
+        mm_obj_dbg (self, "currently registered in a 3GPP network");
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
         return;
@@ -330,10 +343,10 @@
 
     /* Don't spend too much time waiting to get registered */
     if (g_timer_elapsed (ctx->timer, NULL) > ctx->max_registration_time) {
-        mm_dbg ("3GPP registration check timed out");
+        mm_obj_dbg (self, "3GPP registration check timed out");
         register_in_network_context_complete_failed (
             task,
-            mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_NETWORK_TIMEOUT));
+            mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_NETWORK_TIMEOUT, self));
         return;
     }
 
@@ -343,7 +356,7 @@
      * This 3s timeout will catch results from automatic registrations as
      * well.
      */
-    mm_dbg ("Modem not yet registered in a 3GPP network... will recheck soon");
+    mm_obj_dbg (self, "not yet registered in a 3GPP network... will recheck soon");
     g_timeout_add_seconds (3, (GSourceFunc)run_registration_checks, task);
 }
 
@@ -441,16 +454,15 @@
             (g_strcmp0 (current_operator_code, ctx->operator_id) == 0) &&
             REG_STATE_IS_REGISTERED (reg_state) &&
             priv->manual_registration) {
-            mm_dbg ("Already registered manually in selected network '%s',"
-                    " manual registration not launched...",
-                    current_operator_code);
+            mm_obj_dbg (self, "already registered manually in selected network '%s', manual registration not launched...",
+                        current_operator_code);
             g_task_return_boolean (task, TRUE);
             g_object_unref (task);
             return;
         }
 
         /* Manual registration to a new operator required */
-        mm_dbg ("Launching manual network registration (%s)...", ctx->operator_id);
+        mm_obj_dbg (self, "launching manual network registration (%s)...", ctx->operator_id);
         g_free (priv->manual_registration_operator_id);
         priv->manual_registration_operator_id = g_strdup (ctx->operator_id);
         priv->manual_registration = TRUE;
@@ -462,16 +474,16 @@
         if (!force_registration &&
             (current_operator_code || REG_STATE_IS_REGISTERED (reg_state)) &&
             !priv->manual_registration) {
-            mm_dbg ("Already registered automatically in network '%s',"
-                    " automatic registration not launched...",
-                    current_operator_code);
+            mm_obj_dbg (self, "already registered automatically in network '%s',"
+                        " automatic registration not launched...",
+                        current_operator_code);
             g_task_return_boolean (task, TRUE);
             g_object_unref (task);
             return;
         }
 
         /* Automatic registration to a new operator requested */
-        mm_dbg ("Launching automatic network registration...");
+        mm_obj_dbg (self, "launching automatic network registration...");
         g_clear_pointer (&priv->manual_registration_operator_id, g_free);
         priv->manual_registration = FALSE;
     }
@@ -1142,27 +1154,31 @@
                                              GAsyncReadyCallback callback,
                                              gpointer user_data)
 {
-    gboolean cs_supported = FALSE;
-    gboolean ps_supported = FALSE;
-    gboolean eps_supported = FALSE;
+    gboolean is_cs_supported = FALSE;
+    gboolean is_ps_supported = FALSE;
+    gboolean is_eps_supported = FALSE;
+    gboolean is_5gs_supported = FALSE;
 
     g_assert (MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->run_registration_checks != NULL);
 
     g_object_get (self,
-                  MM_IFACE_MODEM_3GPP_CS_NETWORK_SUPPORTED, &cs_supported,
-                  MM_IFACE_MODEM_3GPP_PS_NETWORK_SUPPORTED, &ps_supported,
-                  MM_IFACE_MODEM_3GPP_EPS_NETWORK_SUPPORTED, &eps_supported,
+                  MM_IFACE_MODEM_3GPP_CS_NETWORK_SUPPORTED,  &is_cs_supported,
+                  MM_IFACE_MODEM_3GPP_PS_NETWORK_SUPPORTED,  &is_ps_supported,
+                  MM_IFACE_MODEM_3GPP_EPS_NETWORK_SUPPORTED, &is_eps_supported,
+                  MM_IFACE_MODEM_3GPP_5GS_NETWORK_SUPPORTED, &is_5gs_supported,
                   NULL);
 
-    mm_dbg ("Running registration checks (CS: '%s', PS: '%s', EPS: '%s')",
-            cs_supported ? "yes" : "no",
-            ps_supported ? "yes" : "no",
-            eps_supported ? "yes" : "no");
+    mm_obj_dbg (self, "running registration checks (CS: '%s', PS: '%s', EPS: '%s', 5GS: '%s')",
+                is_cs_supported ? "yes" : "no",
+                is_ps_supported ? "yes" : "no",
+                is_eps_supported ? "yes" : "no",
+                is_5gs_supported ? "yes" : "no");
 
     MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->run_registration_checks (self,
-                                                                       cs_supported,
-                                                                       ps_supported,
-                                                                       eps_supported,
+                                                                       is_cs_supported,
+                                                                       is_ps_supported,
+                                                                       is_eps_supported,
+                                                                       is_5gs_supported,
                                                                        callback,
                                                                        user_data);
 }
@@ -1206,7 +1222,7 @@
 
     str = MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_operator_name_finish (self, res, &error);
     if (error) {
-        mm_warn ("Couldn't load Operator Name: '%s'", error->message);
+        mm_obj_warn (self, "couldn't load operator name: %s", error->message);
         g_error_free (error);
     }
 
@@ -1233,9 +1249,9 @@
 
     str = MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_operator_code_finish (self, res, &error);
     if (error) {
-        mm_warn ("Couldn't load Operator Code: '%s'", error->message);
+        mm_obj_warn (self, "couldn't load operator code: %s", error->message);
     } else if (!mm_3gpp_parse_operator_id (str, &mcc, &mnc, &error)) {
-        mm_dbg ("Unexpected MCC/MNC string '%s': '%s'", str, error->message);
+        mm_obj_dbg (self, "unexpected operator code string '%s': %s", str, error->message);
         g_clear_pointer (&str, g_free);
     }
     g_clear_error (&error);
@@ -1417,9 +1433,8 @@
 
     new_state = GPOINTER_TO_UINT (user_data);
 
-    mm_info ("Modem %s: 3GPP Registration state changed (registering -> %s)",
-             g_dbus_object_get_object_path (G_DBUS_OBJECT (self)),
-             mm_modem_3gpp_registration_state_get_string (new_state));
+    mm_obj_info (self, "3GPP Registration state changed (registering -> %s)",
+                 mm_modem_3gpp_registration_state_get_string (new_state));
 
     /* The property in the interface is bound to the property
      * in the skeleton, so just updating here is enough */
@@ -1494,14 +1509,12 @@
                       MM_IFACE_MODEM_STATE, &modem_state,
                       NULL);
         if (modem_state < MM_MODEM_STATE_ENABLED) {
-            mm_dbg ("Modem %s: 3GPP Registration state change ignored as modem isn't enabled",
-                    g_dbus_object_get_object_path (G_DBUS_OBJECT (self)));
+            mm_obj_dbg (self, "3GPP registration state change ignored as modem isn't enabled");
             return;
         }
 
-        mm_info ("Modem %s: 3GPP Registration state changed (%s -> registering)",
-                 g_dbus_object_get_object_path (G_DBUS_OBJECT (self)),
-                 mm_modem_3gpp_registration_state_get_string (old_state));
+        mm_obj_info (self, "3GPP Registration state changed (%s -> registering)",
+                     mm_modem_3gpp_registration_state_get_string (old_state));
 
         /* Reload current registration info. ONLY update the state to REGISTERED
          * after having loaded operator code/name/subscription state */
@@ -1513,10 +1526,9 @@
         return;
     }
 
-    mm_info ("Modem %s: 3GPP Registration state changed (%s -> %s)",
-             g_dbus_object_get_object_path (G_DBUS_OBJECT (self)),
-             mm_modem_3gpp_registration_state_get_string (old_state),
-             mm_modem_3gpp_registration_state_get_string (new_state));
+    mm_obj_info (self, "3GPP Registration state changed (%s -> %s)",
+                 mm_modem_3gpp_registration_state_get_string (old_state),
+                 mm_modem_3gpp_registration_state_get_string (new_state));
 
     update_non_registered_state (self, old_state, new_state);
 }
@@ -1536,7 +1548,7 @@
         return;
 
     priv = get_private (self);
-    priv->cs = state;
+    priv->state_cs = state;
     update_registration_state (self, get_consolidated_reg_state (self), TRUE);
 }
 
@@ -1555,7 +1567,7 @@
         return;
 
     priv = get_private (self);
-    priv->ps = state;
+    priv->state_ps = state;
     update_registration_state (self, get_consolidated_reg_state (self), TRUE);
 }
 
@@ -1574,7 +1586,26 @@
         return;
 
     priv = get_private (self);
-    priv->eps = state;
+    priv->state_eps = state;
+    update_registration_state (self, get_consolidated_reg_state (self), TRUE);
+}
+
+void
+mm_iface_modem_3gpp_update_5gs_registration_state (MMIfaceModem3gpp             *self,
+                                                   MMModem3gppRegistrationState  state)
+{
+    Private  *priv;
+    gboolean supported = FALSE;
+
+    g_object_get (self,
+                  MM_IFACE_MODEM_3GPP_5GS_NETWORK_SUPPORTED, &supported,
+                  NULL);
+
+    if (!supported)
+        return;
+
+    priv = get_private (self);
+    priv->state_5gs = state;
     update_registration_state (self, get_consolidated_reg_state (self), TRUE);
 }
 
@@ -1594,7 +1625,7 @@
 
     mm_iface_modem_3gpp_run_registration_checks_finish (self, res, &error);
     if (error) {
-        mm_dbg ("Couldn't refresh 3GPP registration status: '%s'", error->message);
+        mm_obj_dbg (self, "couldn't refresh 3GPP registration status: %s", error->message);
         g_error_free (error);
     }
 
@@ -1633,7 +1664,7 @@
     g_source_remove (priv->check_timeout_source);
     priv->check_timeout_source = 0;
 
-    mm_dbg ("Periodic 3GPP registration checks disabled");
+    mm_obj_dbg (self, "periodic 3GPP registration checks disabled");
 }
 
 static void
@@ -1648,7 +1679,7 @@
         return;
 
     /* Create context and keep it as object data */
-    mm_dbg ("Periodic 3GPP registration checks enabled");
+    mm_obj_dbg (self, "periodic 3GPP registration checks enabled");
     priv->check_timeout_source = g_timeout_add_seconds (REGISTRATION_CHECK_TIMEOUT_SEC,
                                                         (GSourceFunc)periodic_registration_check,
                                                         self);
@@ -1705,7 +1736,7 @@
     if (properties) {
         MMBaseBearer *new_bearer;
 
-        mm_dbg ("updating initial EPS bearer...");
+        mm_obj_dbg (self, "updating initial EPS bearer...");
         g_assert (MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->create_initial_eps_bearer);
         new_bearer = MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->create_initial_eps_bearer (self, properties);
         g_object_set (self,
@@ -1714,7 +1745,7 @@
         mm_gdbus_modem3gpp_set_initial_eps_bearer (skeleton, mm_base_bearer_get_path (new_bearer));
         g_object_unref (new_bearer);
     } else {
-        mm_dbg ("clearing initial EPS bearer...");
+        mm_obj_dbg (self, "clearing initial EPS bearer...");
         g_object_set (self,
                       MM_IFACE_MODEM_3GPP_INITIAL_EPS_BEARER, NULL,
                       NULL);
@@ -1832,7 +1863,7 @@
                                                                         \
         MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->NAME##_finish (self, res, &error); \
         if (error) {                                                    \
-            mm_dbg ("Couldn't %s: '%s'", DISPLAY, error->message);      \
+            mm_obj_dbg (self, "couldn't %s: %s", DISPLAY, error->message);      \
             g_error_free (error);                                       \
         }                                                               \
                                                                         \
@@ -2036,7 +2067,7 @@
     MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->setup_unsolicited_events_finish (self, res, &error);
     if (error) {
         /* This error shouldn't be treated as critical */
-        mm_dbg ("Setting up unsolicited events failed: '%s'", error->message);
+        mm_obj_dbg (self, "setting up unsolicited events failed: %s", error->message);
         g_error_free (error);
 
         /* If we get an error setting up unsolicited events, don't even bother trying to
@@ -2062,7 +2093,7 @@
     MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->enable_unsolicited_events_finish (self, res, &error);
     if (error) {
         /* This error shouldn't be treated as critical */
-        mm_dbg ("Enabling unsolicited events failed: '%s'", error->message);
+        mm_obj_dbg (self, "enabling unsolicited events failed: %s", error->message);
         g_error_free (error);
     }
 
@@ -2085,7 +2116,7 @@
     MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->setup_unsolicited_registration_events_finish (self, res, &error);
     if (error) {
         /* This error shouldn't be treated as critical */
-        mm_dbg ("Setting up unsolicited registration events failed: '%s'", error->message);
+        mm_obj_dbg (self, "setting up unsolicited registration events failed: %s", error->message);
         g_error_free (error);
 
         /* If we get an error setting up unsolicited events, don't even bother trying to
@@ -2113,7 +2144,7 @@
     MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->enable_unsolicited_registration_events_finish (self, res, &error);
     if (error) {
         /* This error shouldn't be treated as critical */
-        mm_dbg ("Enabling unsolicited registration events failed: '%s'", error->message);
+        mm_obj_dbg (self, "enabling unsolicited registration events failed: %s", error->message);
         g_error_free (error);
         /* If error, setup periodic registration checks */
         periodic_registration_check_enable (self);
@@ -2138,7 +2169,7 @@
 
     properties = MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_initial_eps_bearer_finish (self, res, &error);
     if (!properties) {
-        mm_dbg ("couldn't load initial default bearer properties: '%s'", error->message);
+        mm_obj_dbg (self, "couldn't load initial default bearer properties: %s", error->message);
         g_error_free (error);
         goto out;
     }
@@ -2157,15 +2188,16 @@
                      GAsyncResult     *res,
                      GTask            *task)
 {
-    GList           *profiles;
+    gboolean         success;
+    GList           *profiles = NULL;
     EnablingContext *ctx;
     GError          *error = NULL;
 
     ctx = g_task_get_task_data (task);
 
-    profiles = MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_profiles_finish (self, res, &error);
-    if (error) {
-        mm_dbg ("couldn't load initial profiles: '%s'", error->message);
+    success = MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_profiles_finish (self, res, &profiles, &error);
+    if (!success) {
+        mm_obj_dbg (self, "couldn't load initial profiles: '%s'", error->message);
         g_error_free (error);
         goto out;
     }
@@ -2389,7 +2421,7 @@
 
     config = MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_initial_eps_bearer_settings_finish (self, res, &error);
     if (!config) {
-        mm_warn ("couldn't load initial EPS bearer settings: '%s'", error->message);
+        mm_obj_warn (self, "couldn't load initial EPS bearer settings: %s", error->message);
         g_error_free (error);
     } else {
         GVariant *dictionary;
@@ -2421,7 +2453,7 @@
     mm_gdbus_modem3gpp_set_eps_ue_mode_operation (ctx->skeleton, uemode);
 
     if (error) {
-        mm_warn ("couldn't load UE mode of operation for EPS: '%s'", error->message);
+        mm_obj_warn (self, "couldn't load UE mode of operation for EPS: %s", error->message);
         g_error_free (error);
     }
 
@@ -2445,7 +2477,7 @@
     mm_gdbus_modem3gpp_set_enabled_facility_locks (ctx->skeleton, facilities);
 
     if (error) {
-        mm_warn ("couldn't load facility locks: '%s'", error->message);
+        mm_obj_warn (self, "couldn't load facility locks: %s", error->message);
         g_error_free (error);
     } else {
         MMBaseSim *sim = NULL;
@@ -2485,7 +2517,7 @@
     g_free (imei);
 
     if (error) {
-        mm_warn ("couldn't load IMEI: '%s'", error->message);
+        mm_obj_warn (self, "couldn't load IMEI: %s", error->message);
         g_error_free (error);
     }
 
@@ -2645,15 +2677,6 @@
         g_object_set (self,
                       MM_IFACE_MODEM_3GPP_DBUS_SKELETON, skeleton,
                       NULL);
-
-        /* If the modem is *only* LTE, we assume that CS network is not
-         * supported */
-        if (mm_iface_modem_is_3gpp_lte_only (MM_IFACE_MODEM (self))) {
-            mm_dbg ("Modem is LTE-only, assuming CS network is not supported");
-            g_object_set (self,
-                          MM_IFACE_MODEM_3GPP_CS_NETWORK_SUPPORTED, FALSE,
-                          NULL);
-        }
     }
 
     ctx = g_new0 (InitializationContext, 1);
@@ -2731,6 +2754,14 @@
 
     g_object_interface_install_property
         (g_iface,
+         g_param_spec_boolean (MM_IFACE_MODEM_3GPP_5GS_NETWORK_SUPPORTED,
+                               "5GS network supported",
+                               "Whether the modem works in the 5GS network",
+                               FALSE,
+                               G_PARAM_READWRITE));
+
+    g_object_interface_install_property
+        (g_iface,
          g_param_spec_flags (MM_IFACE_MODEM_3GPP_IGNORED_FACILITY_LOCKS,
                              "Ignored locks",
                              "Ignored facility locks",
diff --git a/src/mm-iface-modem-3gpp.h b/src/mm-iface-modem-3gpp.h
index 9cb1f4d..b91498e 100644
--- a/src/mm-iface-modem-3gpp.h
+++ b/src/mm-iface-modem-3gpp.h
@@ -34,6 +34,7 @@
 #define MM_IFACE_MODEM_3GPP_CS_NETWORK_SUPPORTED    "iface-modem-3gpp-cs-network-supported"
 #define MM_IFACE_MODEM_3GPP_PS_NETWORK_SUPPORTED    "iface-modem-3gpp-ps-network-supported"
 #define MM_IFACE_MODEM_3GPP_EPS_NETWORK_SUPPORTED   "iface-modem-3gpp-eps-network-supported"
+#define MM_IFACE_MODEM_3GPP_5GS_NETWORK_SUPPORTED   "iface-modem-3gpp-5gs-network-supported"
 #define MM_IFACE_MODEM_3GPP_IGNORED_FACILITY_LOCKS  "iface-modem-3gpp-ignored-facility-locks"
 #define MM_IFACE_MODEM_3GPP_INITIAL_EPS_BEARER      "iface-modem-3gpp-initial-eps-bearer"
 
@@ -47,7 +48,8 @@
      MM_MODEM_ACCESS_TECHNOLOGY_HSUPA |                     \
      MM_MODEM_ACCESS_TECHNOLOGY_HSPA |                      \
      MM_MODEM_ACCESS_TECHNOLOGY_HSPA_PLUS |                 \
-     MM_MODEM_ACCESS_TECHNOLOGY_LTE)
+     MM_MODEM_ACCESS_TECHNOLOGY_LTE |                       \
+     MM_MODEM_ACCESS_TECHNOLOGY_5GNR)
 
 typedef struct _MMIfaceModem3gpp MMIfaceModem3gpp;
 
@@ -167,13 +169,14 @@
     MMBaseBearer * (*create_initial_eps_bearer) (MMIfaceModem3gpp   *self,
                                                  MMBearerProperties *properties);
 
-    /* Run CS/PS/EPS registration state checks..
+    /* Run CS/PS/EPS/5GS registration state checks..
      * Note that no registration state is returned, implementations should call
      * mm_iface_modem_3gpp_update_registration_state(). */
     void (* run_registration_checks) (MMIfaceModem3gpp *self,
-                                      gboolean cs_supported,
-                                      gboolean ps_supported,
-                                      gboolean eps_supported,
+                                      gboolean is_cs_supported,
+                                      gboolean is_ps_supported,
+                                      gboolean is_eps_supported,
+                                      gboolean is_5gs_supported,
                                       GAsyncReadyCallback callback,
                                       gpointer user_data);
     gboolean (*run_registration_checks_finish) (MMIfaceModem3gpp *self,
@@ -233,12 +236,13 @@
                                                          GError              **error);
 
     /* Get profiles or provisioned contexts from the modem as a list of MM3gppProfile */
-    void      (* load_profiles) (MMIfaceModem3gpp         *self,
-                                 GAsyncReadyCallback       callback,
-                                 gpointer                  user_data);
-    GList *   (* load_profiles_finish) (MMIfaceModem3gpp  *self,
-                                        GAsyncResult      *res,
-                                        GError           **error);
+    void     (* load_profiles) (MMIfaceModem3gpp         *self,
+                                GAsyncReadyCallback       callback,
+                                gpointer                  user_data);
+    gboolean (* load_profiles_finish) (MMIfaceModem3gpp  *self,
+                                       GAsyncResult      *res,
+                                       GList            **out_list,
+                                       GError           **error);
 };
 
 GType mm_iface_modem_3gpp_get_type (void);
@@ -282,6 +286,8 @@
                                                        MMModem3gppRegistrationState state);
 void mm_iface_modem_3gpp_update_eps_registration_state (MMIfaceModem3gpp *self,
                                                         MMModem3gppRegistrationState state);
+void mm_iface_modem_3gpp_update_5gs_registration_state (MMIfaceModem3gpp *self,
+                                                        MMModem3gppRegistrationState state);
 void mm_iface_modem_3gpp_update_subscription_state (MMIfaceModem3gpp *self,
                                                     MMModem3gppSubscriptionState state);
 void mm_iface_modem_3gpp_update_access_technologies (MMIfaceModem3gpp *self,
diff --git a/src/mm-iface-modem-cdma.c b/src/mm-iface-modem-cdma.c
index c012fe0..877afe4 100644
--- a/src/mm-iface-modem-cdma.c
+++ b/src/mm-iface-modem-cdma.c
@@ -23,7 +23,7 @@
 #include "mm-iface-modem-cdma.h"
 #include "mm-base-modem.h"
 #include "mm-modem-helpers.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 #define SUBSYSTEM_CDMA1X "cdma1x"
 #define SUBSYSTEM_EVDO "evdo"
@@ -161,7 +161,7 @@
 
     /* If we're already activated, nothing to do */
     if (mm_gdbus_modem_cdma_get_activation_state (ctx->skeleton) == MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATED) {
-        mm_dbg ("Modem is already activated");
+        mm_obj_dbg (self, "already activated");
         mm_gdbus_modem_cdma_complete_activate (ctx->skeleton, ctx->invocation);
         handle_activate_context_free (ctx);
         return;
@@ -348,7 +348,7 @@
 
     /* If we're already activated, nothing to do */
     if (mm_gdbus_modem_cdma_get_activation_state (ctx->skeleton) == MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATED) {
-        mm_dbg ("Modem is already activated");
+        mm_obj_dbg (self, "already activated");
         mm_gdbus_modem_cdma_complete_activate_manual (ctx->skeleton, ctx->invocation);
         handle_activate_manual_context_free (ctx);
         return;
@@ -617,7 +617,7 @@
             &ctx->call_manager_system_mode,
             &ctx->call_manager_operating_mode,
             &error)) {
-        mm_dbg ("Could not get call manager state: %s", error->message);
+        mm_obj_dbg (self, "could not get call manager state: %s", error->message);
         g_error_free (error);
         /* Fallback to AT-based check */
         ctx->step = REGISTRATION_CHECK_STEP_AT_CDMA_SERVICE_STATUS;
@@ -654,7 +654,7 @@
             &ctx->hdr_session_state,
             &ctx->hdr_almp_state,
             &error)) {
-        mm_dbg ("Could not get HDR state: %s", error->message);
+        mm_obj_dbg (self, "could not get HDR state: %s", error->message);
         g_error_free (error);
         /* Fallback to AT-based check */
         ctx->step = REGISTRATION_CHECK_STEP_AT_CDMA_SERVICE_STATUS;
@@ -670,14 +670,16 @@
 static void
 parse_qcdm_results (GTask *task)
 {
+    MMIfaceModemCdma             *self;
     RunRegistrationChecksContext *ctx;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
-    mm_dbg ("QCDM CM System Mode: %d", ctx->call_manager_system_mode);
-    mm_dbg ("QCDM HDR Hybrid Mode: %d", ctx->hdr_hybrid_mode);
-    mm_dbg ("QCDM HDR Session State: %d", ctx->hdr_session_state);
-    mm_dbg ("QCDM HDR ALMP State: %d", ctx->hdr_almp_state);
+    mm_obj_dbg (self, "QCDM CM System Mode: %d", ctx->call_manager_system_mode);
+    mm_obj_dbg (self, "QCDM HDR Hybrid Mode: %d", ctx->hdr_hybrid_mode);
+    mm_obj_dbg (self, "QCDM HDR Session State: %d", ctx->hdr_session_state);
+    mm_obj_dbg (self, "QCDM HDR ALMP State: %d", ctx->hdr_almp_state);
 
     /* Set QCDM-obtained registration info */
     switch (ctx->call_manager_system_mode) {
@@ -725,7 +727,7 @@
                                                                               res,
                                                                               &has_service,
                                                                               &error)) {
-        mm_warn ("Could not get service status: %s", error->message);
+        mm_obj_warn (self, "could not get service status: %s", error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -733,7 +735,7 @@
 
     if (!has_service) {
         /* There is no CDMA service at all, end registration checks */
-        mm_dbg ("No CDMA service found");
+        mm_obj_dbg (self, "no CDMA service found");
         ctx->step = REGISTRATION_CHECK_STEP_LAST;
     } else
         /* If we do have service, go on to next step */
@@ -766,7 +768,7 @@
         if (!g_error_matches (error,
                               MM_MOBILE_EQUIPMENT_ERROR,
                               MM_MOBILE_EQUIPMENT_ERROR_NO_NETWORK)) {
-            mm_warn ("Could not get serving system: %s", error->message);
+            mm_obj_warn (self, "could not get serving system: %s", error->message);
             g_task_return_error (task, error);
             g_object_unref (task);
             return;
@@ -786,15 +788,17 @@
 static void
 parse_at_results (GTask *task)
 {
+    MMIfaceModemCdma             *self;
     RunRegistrationChecksContext *ctx;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     /* 99999 means unknown/no service */
     if (ctx->cdma1x_sid == MM_MODEM_CDMA_SID_UNKNOWN &&
         ctx->cdma1x_nid == MM_MODEM_CDMA_NID_UNKNOWN) {
         /* Not registered in CDMA network, end registration checks */
-        mm_dbg ("Not registered in any CDMA network");
+        mm_obj_dbg (self, "no registered in any CDMA network");
         ctx->step = REGISTRATION_CHECK_STEP_LAST;
     } else {
         /* We're registered on the CDMA 1x network (at least) */
@@ -826,7 +830,7 @@
             &error)) {
         /* This error is NOT fatal. If we get an error here, we'll just fallback
          * to the non-detailed values we already got. */
-        mm_dbg ("Could not get more detailed registration state: %s", error->message);
+        mm_obj_dbg (self, "could not get more detailed registration state: %s", error->message);
     } else {
         ctx->cdma1x_state = detailed_cdma1x_state;
         ctx->evdo_state = detailed_evdo_state;
@@ -868,7 +872,7 @@
         /* fall through */
 
     case REGISTRATION_CHECK_STEP_QCDM_CALL_MANAGER_STATE:
-        mm_dbg ("Starting QCDM-based registration checks");
+        mm_obj_dbg (self, "starting QCDM-based registration checks...");
         if (!ctx->skip_qcdm_call_manager_step &&
             MM_IFACE_MODEM_CDMA_GET_INTERFACE (self)->get_call_manager_state &&
             MM_IFACE_MODEM_CDMA_GET_INTERFACE (self)->get_call_manager_state_finish) {
@@ -880,7 +884,7 @@
             return;
         }
         /* Fallback to AT-based check */
-        mm_dbg ("  Skipping all QCDM-based checks and falling back to AT-based checks");
+        mm_obj_dbg (self, "  skipping all QCDM-based checks and falling back to AT-based checks");
         ctx->step = REGISTRATION_CHECK_STEP_AT_CDMA_SERVICE_STATUS;
         registration_check_step (task);
         return;
@@ -897,7 +901,7 @@
                 task);
             return;
         }
-        mm_dbg ("  Skipping HDR check");
+        mm_obj_dbg (self, "  skipping HDR check");
         ctx->step++;
         /* fall through */
 
@@ -913,7 +917,7 @@
                 task);
             return;
         }
-        mm_dbg ("  Skipping CDMA1x Serving System check");
+        mm_obj_dbg (self, "  skipping CDMA1x serving system check");
         ctx->step++;
         /* fall through */
 
@@ -923,8 +927,7 @@
         return;
 
     case REGISTRATION_CHECK_STEP_AT_CDMA_SERVICE_STATUS:
-        mm_dbg ("Starting AT-based registration checks");
-
+        mm_obj_dbg (self, "starting AT-based registration checks");
         /* If we don't have means to get service status, just assume we do have
          * CDMA service and keep on */
         if (!ctx->skip_at_cdma_service_status_step &&
@@ -936,7 +939,7 @@
                 task);
             return;
         }
-        mm_dbg ("  Skipping CDMA service status check, assuming with service");
+        mm_obj_dbg (self, "  skipping CDMA service status check, assuming with service");
         ctx->step++;
         /* fall through */
 
@@ -960,7 +963,7 @@
                 task);
             return;
         }
-        mm_dbg ("  Skipping CDMA1x Serving System check");
+        mm_obj_dbg (self, "  skipping CDMA1x Serving System check");
         ctx->step++;
         /* fall through */
 
@@ -970,7 +973,7 @@
         return;
 
     case REGISTRATION_CHECK_STEP_DETAILED_REGISTRATION_STATE:
-        mm_dbg ("Starting detailed registration state check");
+        mm_obj_dbg (self, "starting detailed registration state check");
         /* We let classes implementing this interface to look for more detailed
          * registration info. */
         if (!ctx->skip_detailed_registration_state &&
@@ -988,13 +991,13 @@
                 task);
             return;
         }
-        mm_dbg ("  Skipping detailed registration state check");
+        mm_obj_dbg (self, "  skipping detailed registration state check");
         ctx->step++;
         /* fall through */
 
     case REGISTRATION_CHECK_STEP_LAST:
         /* We are done without errors! */
-        mm_dbg ("All CDMA registration state checks done");
+        mm_obj_dbg (self, "all CDMA registration state checks done");
         mm_iface_modem_cdma_update_cdma1x_registration_state (self,
                                                               ctx->cdma1x_state,
                                                               ctx->cdma1x_sid,
@@ -1043,9 +1046,9 @@
                   MM_IFACE_MODEM_CDMA_CDMA1X_NETWORK_SUPPORTED, &cdma1x_supported,
                   NULL);
 
-    mm_dbg ("Running registration checks (CDMA1x: '%s', EV-DO: '%s')",
-            cdma1x_supported ? "yes" : "no",
-            evdo_supported ? "yes" : "no");
+    mm_obj_dbg (self, "running registration checks (CDMA1x: '%s', EV-DO: '%s')",
+                cdma1x_supported ? "yes" : "no",
+                evdo_supported ? "yes" : "no");
 
     if (MM_IFACE_MODEM_CDMA_GET_INTERFACE (self)->run_registration_checks &&
         MM_IFACE_MODEM_CDMA_GET_INTERFACE (self)->run_registration_checks_finish) {
@@ -1244,7 +1247,7 @@
 
     mm_iface_modem_cdma_run_registration_checks_finish (self, res, &error);
     if (error) {
-        mm_dbg ("Couldn't refresh CDMA registration status: '%s'", error->message);
+        mm_obj_dbg (self, "couldn't refresh CDMA registration status: %s", error->message);
         g_error_free (error);
     }
 
@@ -1283,7 +1286,7 @@
                         registration_check_context_quark,
                         NULL);
 
-    mm_dbg ("Periodic CDMA registration checks disabled");
+    mm_obj_dbg (self, "periodic CDMA registration checks disabled");
 }
 
 static void
@@ -1302,7 +1305,7 @@
         return;
 
     /* Create context and keep it as object data */
-    mm_dbg ("Periodic CDMA registration checks enabled");
+    mm_obj_dbg (self, "periodic CDMA registration checks enabled");
     ctx = g_new0 (RegistrationCheckContext, 1);
     ctx->timeout_source = g_timeout_add_seconds (REGISTRATION_CHECK_TIMEOUT_SEC,
                                                  (GSourceFunc)periodic_registration_check,
@@ -1339,11 +1342,11 @@
         return;
 
     if (activation_error) {
-        mm_dbg ("Activation failed: %s", activation_error->message);
+        mm_obj_dbg (self, "activation failed: %s", activation_error->message);
         if (activation_error->domain == MM_CDMA_ACTIVATION_ERROR)
             error = activation_error->code;
         else {
-            mm_warn ("Error given is not an activation error");
+            mm_obj_warn (self, "error given is not an activation error");
             error = MM_CDMA_ACTIVATION_ERROR_UNKNOWN;
         }
     }
@@ -1406,7 +1409,7 @@
 
     MM_IFACE_MODEM_CDMA_GET_INTERFACE (self)->disable_unsolicited_events_finish (self, res, &error);
     if (error) {
-        mm_dbg ("Couldn't disable unsolicited events: '%s'", error->message);
+        mm_obj_dbg (self, "couldn't disable unsolicited events: %s", error->message);
         g_error_free (error);
     }
 
@@ -1426,7 +1429,7 @@
 
     MM_IFACE_MODEM_CDMA_GET_INTERFACE (self)->cleanup_unsolicited_events_finish (self, res, &error);
     if (error) {
-        mm_dbg ("Couldn't cleanup unsolicited events: '%s'", error->message);
+        mm_obj_dbg (self, "couldn't cleanup unsolicited events: %s", error->message);
         g_error_free (error);
     }
 
@@ -1567,7 +1570,7 @@
     MM_IFACE_MODEM_CDMA_GET_INTERFACE (self)->setup_unsolicited_events_finish (self, res, &error);
     if (error) {
         /* This error shouldn't be treated as critical */
-        mm_dbg ("Setting up unsolicited events failed: '%s'", error->message);
+        mm_obj_dbg (self, "setting up unsolicited events failed: %s", error->message);
         g_error_free (error);
     }
 
@@ -1588,7 +1591,7 @@
     MM_IFACE_MODEM_CDMA_GET_INTERFACE (self)->enable_unsolicited_events_finish (self, res, &error);
     if (error) {
         /* This error shouldn't be treated as critical */
-        mm_dbg ("Enabling unsolicited events failed: '%s'", error->message);
+        mm_obj_dbg (self, "enabling unsolicited events failed: %s", error->message);
         g_error_free (error);
     }
 
@@ -1733,7 +1736,7 @@
         g_free (val);                                                   \
                                                                         \
         if (error) {                                                    \
-            mm_warn ("couldn't load %s: '%s'", DISPLAY, error->message); \
+            mm_obj_warn (self, "couldn't load %s: %s", DISPLAY, error->message); \
             g_error_free (error);                                       \
         }                                                               \
                                                                         \
@@ -1760,7 +1763,7 @@
     mm_gdbus_modem_cdma_set_activation_state (ctx->skeleton, state);
 
     if (error) {
-        mm_warn ("couldn't load activation state: '%s'", error->message);
+        mm_obj_warn (self, "couldn't load activation state: %s", error->message);
         g_error_free (error);
     }
 
diff --git a/src/mm-iface-modem-firmware.c b/src/mm-iface-modem-firmware.c
index 8344778..9268c4b 100644
--- a/src/mm-iface-modem-firmware.c
+++ b/src/mm-iface-modem-firmware.c
@@ -19,7 +19,7 @@
 
 #include "mm-iface-modem.h"
 #include "mm-iface-modem-firmware.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 /*****************************************************************************/
 
@@ -70,7 +70,7 @@
             handle_list_context_free (ctx);
             return;
         }
-        mm_dbg ("Couldn't load current firmware image: %s", error->message);
+        mm_obj_dbg (self, "couldn't load current firmware image: %s", error->message);
         g_clear_error (&error);
     }
 
@@ -104,7 +104,7 @@
             handle_list_context_free (ctx);
             return;
         }
-        mm_dbg ("Couldn't load firmware image list: %s", error->message);
+        mm_obj_dbg (self, "couldn't load firmware image list: %s", error->message);
         g_clear_error (&error);
     }
 
@@ -380,7 +380,7 @@
 
     update_settings = MM_IFACE_MODEM_FIRMWARE_GET_INTERFACE (self)->load_update_settings_finish (self, res, &error);
     if (!update_settings) {
-        mm_dbg ("Couldn't load update settings: '%s'", error->message);
+        mm_obj_dbg (self, "couldn't load update settings: %s", error->message);
         g_error_free (error);
         goto out;
     }
@@ -388,7 +388,7 @@
     /* If the plugin didn't specify custom device ids, add the default ones ourselves */
     if (!mm_firmware_update_settings_get_device_ids (update_settings) &&
         !add_generic_device_ids (MM_BASE_MODEM (self), update_settings, &error)) {
-        mm_warn ("Couldn't build device ids: '%s'", error->message);
+        mm_obj_warn (self, "couldn't build device ids: %s", error->message);
         g_error_free (error);
         g_clear_object (&update_settings);
         goto out;
@@ -397,7 +397,7 @@
     /* If the plugin didn't specify custom version, add the default one ourselves */
     if (!mm_firmware_update_settings_get_version (update_settings) &&
         !add_generic_version (MM_BASE_MODEM (self), update_settings, &error)) {
-        mm_warn ("Couldn't set version: '%s'", error->message);
+        mm_obj_warn (self, "couldn't set version: %s", error->message);
         g_error_free (error);
         g_clear_object (&update_settings);
         goto out;
diff --git a/src/mm-iface-modem-location.c b/src/mm-iface-modem-location.c
index 9a85c9e..f40f48a 100644
--- a/src/mm-iface-modem-location.c
+++ b/src/mm-iface-modem-location.c
@@ -21,7 +21,7 @@
 
 #include "mm-iface-modem.h"
 #include "mm-iface-modem-location.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-modem-helpers.h"
 
 #define MM_LOCATION_GPS_REFRESH_TIME_SECS 30
@@ -235,11 +235,7 @@
                             MMLocationGpsNmea *location_gps_nmea,
                             MMLocationGpsRaw *location_gps_raw)
 {
-    const gchar *dbus_path;
-
-    dbus_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (self));
-    mm_dbg ("Modem %s: GPS location updated",
-            dbus_path);
+    mm_obj_dbg (self, "GPS location updated");
 
     /* We only update the property if we are supposed to signal
      * location */
@@ -322,7 +318,7 @@
             g_autoptr(GString)   str = NULL;
             g_autoptr(GDateTime) now = NULL;
 
-            mm_dbg ("GGA trace detected: '%s'", nmea_trace);
+            mm_obj_dbg (self, "GGA trace detected: %s", nmea_trace);
 
             now = g_date_time_new_now_utc ();
             str = g_string_new ("");
@@ -349,17 +345,13 @@
                              MmGdbusModemLocation *skeleton,
                              MMLocation3gpp *location_3gpp)
 {
-    const gchar *dbus_path;
-
-    dbus_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (self));
-    mm_dbg ("Modem %s: 3GPP location updated "
-            "(MCC: '%u', MNC: '%u', Location area code: '%lX', Tracking area code: '%lX', Cell ID: '%lX')",
-            dbus_path,
-            mm_location_3gpp_get_mobile_country_code (location_3gpp),
-            mm_location_3gpp_get_mobile_network_code (location_3gpp),
-            mm_location_3gpp_get_location_area_code (location_3gpp),
-            mm_location_3gpp_get_tracking_area_code (location_3gpp),
-            mm_location_3gpp_get_cell_id (location_3gpp));
+    mm_obj_dbg (self, "3GPP location updated "
+                "(MCC: '%u', MNC: '%u', location area code: '%lX', tracking area code: '%lX', cell ID: '%lX')",
+                mm_location_3gpp_get_mobile_country_code (location_3gpp),
+                mm_location_3gpp_get_mobile_network_code (location_3gpp),
+                mm_location_3gpp_get_location_area_code (location_3gpp),
+                mm_location_3gpp_get_tracking_area_code (location_3gpp),
+                mm_location_3gpp_get_cell_id (location_3gpp));
 
     /* We only update the property if we are supposed to signal
      * location */
@@ -461,14 +453,9 @@
                                 MmGdbusModemLocation *skeleton,
                                 MMLocationCdmaBs *location_cdma_bs)
 {
-    const gchar *dbus_path;
-
-    dbus_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (self));
-    mm_dbg ("Modem %s: CDMA BS location updated "
-            "(Longitude: '%lf', Latitude: '%lf')",
-            dbus_path,
-            mm_location_cdma_bs_get_longitude (location_cdma_bs),
-            mm_location_cdma_bs_get_latitude (location_cdma_bs));
+    mm_obj_dbg (self, "CDMA base station location updated (longitude: '%lf', latitude: '%lf')",
+                mm_location_cdma_bs_get_longitude (location_cdma_bs),
+                mm_location_cdma_bs_get_latitude (location_cdma_bs));
 
     /* We only update the property if we are supposed to signal
      * location */
@@ -712,7 +699,7 @@
             }
 
             source_str = mm_modem_location_source_build_string_from_mask (ctx->current);
-            mm_dbg ("Enabled location '%s' gathering...", source_str);
+            mm_obj_dbg (self, "enabled location '%s' gathering...", source_str);
             g_free (source_str);
         } else if (ctx->to_disable & ctx->current) {
             /* Remove from mask */
@@ -732,7 +719,7 @@
             }
 
             source_str = mm_modem_location_source_build_string_from_mask (ctx->current);
-            mm_dbg ("Disabled location '%s' gathering...", source_str);
+            mm_obj_dbg (self, "disabled location '%s' gathering...", source_str);
             g_free (source_str);
         }
 
@@ -797,7 +784,7 @@
         if (mask & source) {
             /* Source set in mask, need to enable if disabled */
             if (currently_enabled & source)
-                mm_dbg ("Location '%s' gathering is already enabled...", str);
+                mm_obj_dbg (self, "location '%s' gathering is already enabled...", str);
             else
                 ctx->to_enable |= source;
         } else {
@@ -805,7 +792,7 @@
             if (currently_enabled & source)
                 ctx->to_disable |= source;
             else
-                mm_dbg ("Location '%s' gathering is already disabled...", str);
+                mm_obj_dbg (self, "location '%s' gathering is already disabled...", str);
         }
 
         g_free (str);
@@ -847,13 +834,13 @@
 
     if (ctx->to_enable != MM_MODEM_LOCATION_SOURCE_NONE) {
         str = mm_modem_location_source_build_string_from_mask (ctx->to_enable);
-        mm_dbg ("Need to enable the following location sources: '%s'", str);
+        mm_obj_dbg (self, "need to enable the following location sources: '%s'", str);
         g_free (str);
     }
 
     if (ctx->to_disable != MM_MODEM_LOCATION_SOURCE_NONE) {
         str = mm_modem_location_source_build_string_from_mask (ctx->to_disable);
-        mm_dbg ("Need to disable the following location sources: '%s'", str);
+        mm_obj_dbg (self, "need to disable the following location sources: '%s'", str);
         g_free (str);
     }
 
@@ -944,8 +931,8 @@
     /* Enable/disable location signaling */
     location_ctx = get_location_context (ctx->self);
     if (mm_gdbus_modem_location_get_signals_location (ctx->skeleton) != ctx->signal_location) {
-        mm_dbg ("%s location signaling",
-                ctx->signal_location ? "Enabling" : "Disabling");
+        mm_obj_dbg (self, "%s location signaling",
+                    ctx->signal_location ? "enabling" : "disabling");
         mm_gdbus_modem_location_set_signals_location (ctx->skeleton,
                                                       ctx->signal_location);
         if (ctx->signal_location)
@@ -963,7 +950,7 @@
     }
 
     str = mm_modem_location_source_build_string_from_mask (ctx->sources);
-    mm_dbg ("Setting up location sources: '%s'", str);
+    mm_obj_dbg (self, "setting up location sources: '%s'", str);
     g_free (str);
 
     /* Go on to enable or disable the requested sources */
@@ -1674,7 +1661,7 @@
 
     servers = MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->load_assistance_data_servers_finish (self, res, &error);
     if (error) {
-        mm_warn ("couldn't load assistance data servers: '%s'", error->message);
+        mm_obj_warn (self, "couldn't load assistance data servers: %s", error->message);
         g_error_free (error);
     }
 
@@ -1699,7 +1686,7 @@
 
     mask = MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->load_supported_assistance_data_finish (self, res, &error);
     if (error) {
-        mm_warn ("couldn't load supported assistance data types: '%s'", error->message);
+        mm_obj_warn (self, "couldn't load supported assistance data types: %s", error->message);
         g_error_free (error);
     }
 
@@ -1723,7 +1710,7 @@
 
     supl = MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->load_supl_server_finish (self, res, &error);
     if (error) {
-        mm_warn ("couldn't load SUPL server: '%s'", error->message);
+        mm_obj_warn (self, "couldn't load SUPL server: %s", error->message);
         g_error_free (error);
     }
 
@@ -1747,7 +1734,7 @@
 
     ctx->capabilities = MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->load_capabilities_finish (self, res, &error);
     if (error) {
-        mm_warn ("couldn't load location capabilities: '%s'", error->message);
+        mm_obj_warn (self, "couldn't load location capabilities: %s", error->message);
         g_error_free (error);
     }
 
diff --git a/src/mm-iface-modem-messaging.c b/src/mm-iface-modem-messaging.c
index 02e6a76..b5be318 100644
--- a/src/mm-iface-modem-messaging.c
+++ b/src/mm-iface-modem-messaging.c
@@ -20,7 +20,7 @@
 #include "mm-iface-modem.h"
 #include "mm-iface-modem-messaging.h"
 #include "mm-sms-list.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 #define SUPPORT_CHECKED_TAG "messaging-support-checked-tag"
 #define SUPPORTED_TAG       "messaging-supported-tag"
@@ -426,7 +426,7 @@
 
     added = mm_sms_list_take_part (list, sms_part, state, storage, &error);
     if (!added) {
-        mm_dbg ("Couldn't take part in SMS list: '%s'", error->message);
+        mm_obj_dbg (self, "couldn't take part in SMS list: %s", error->message);
         g_error_free (error);
 
         /* If part wasn't taken, we need to free the part ourselves */
@@ -503,24 +503,20 @@
 }
 
 static void
-sms_added (MMSmsList *list,
-           const gchar *sms_path,
-           gboolean received,
+sms_added (MMSmsList             *list,
+           const gchar           *sms_path,
+           gboolean               received,
            MmGdbusModemMessaging *skeleton)
 {
-    mm_dbg ("Added %s SMS at '%s'",
-            received ? "received" : "local",
-            sms_path);
     update_message_list (skeleton, list);
     mm_gdbus_modem_messaging_emit_added (skeleton, sms_path, received);
 }
 
 static void
-sms_deleted (MMSmsList *list,
-             const gchar *sms_path,
+sms_deleted (MMSmsList             *list,
+             const gchar           *sms_path,
              MmGdbusModemMessaging *skeleton)
 {
-    mm_dbg ("Deleted SMS at '%s'", sms_path);
     update_message_list (skeleton, list);
     mm_gdbus_modem_messaging_emit_deleted (skeleton, sms_path);
 }
@@ -762,11 +758,11 @@
         StorageContext *storage_ctx;
 
         storage_ctx = get_storage_context (self);
-        mm_dbg ("Couldn't load SMS parts from storage '%s': '%s'",
-                mm_sms_storage_get_string (g_array_index (storage_ctx->supported_mem1,
-                                                          MMSmsStorage,
-                                                          ctx->mem1_storage_index)),
-                error->message);
+        mm_obj_dbg (self, "couldn't load SMS parts from storage '%s': %s",
+                    mm_sms_storage_get_string (g_array_index (storage_ctx->supported_mem1,
+                                                              MMSmsStorage,
+                                                              ctx->mem1_storage_index)),
+                    error->message);
         g_error_free (error);
     }
 
@@ -784,7 +780,7 @@
     GError *error = NULL;
 
     if (!MM_IFACE_MODEM_MESSAGING_GET_INTERFACE (self)->set_default_storage_finish (self, res, &error)) {
-        mm_warn ("Could not set default storage: '%s'", error->message);
+        mm_obj_warn (self, "could not set default storage: %s", error->message);
         g_error_free (error);
     }
 
@@ -866,7 +862,7 @@
 
     /* Not critical! */
     if (!MM_IFACE_MODEM_MESSAGING_GET_INTERFACE (self)->enable_unsolicited_events_finish (self, res, &error)) {
-        mm_dbg ("Couldn't enable unsolicited events: '%s'", error->message);
+        mm_obj_dbg (self, "couldn't enable unsolicited events: %s", error->message);
         g_error_free (error);
     }
 
@@ -989,7 +985,7 @@
                       NULL);
 
         if (default_storage == MM_SMS_STORAGE_UNKNOWN)
-            mm_info ("Cannot set default storage, none of the suggested ones supported");
+            mm_obj_warn (self, "cannot set default storage, none of the suggested ones supported");
         else if (MM_IFACE_MODEM_MESSAGING_GET_INTERFACE (self)->set_default_storage &&
                  MM_IFACE_MODEM_MESSAGING_GET_INTERFACE (self)->set_default_storage_finish) {
             MM_IFACE_MODEM_MESSAGING_GET_INTERFACE (self)->set_default_storage (
@@ -1141,7 +1137,7 @@
             &storage_ctx->supported_mem2,
             &storage_ctx->supported_mem3,
             &error)) {
-        mm_dbg ("Couldn't load supported storages: '%s'", error->message);
+        mm_obj_dbg (self, "couldn't load supported storages: %s", error->message);
         g_error_free (error);
     } else {
         gchar *mem1;
@@ -1162,10 +1158,10 @@
         mem3 = mm_common_build_sms_storages_string ((MMSmsStorage *)storage_ctx->supported_mem3->data,
                                                     storage_ctx->supported_mem3->len);
 
-        mm_dbg ("Supported storages loaded:");
-        mm_dbg ("  mem1 (list/read/delete) storages: '%s'", mem1);
-        mm_dbg ("  mem2 (write/send) storages:       '%s'", mem2);
-        mm_dbg ("  mem3 (reception) storages:        '%s'", mem3);
+        mm_obj_dbg (self, "supported storages loaded:");
+        mm_obj_dbg (self, "  mem1 (list/read/delete) storages: '%s'", mem1);
+        mm_obj_dbg (self, "  mem2 (write/send) storages:       '%s'", mem2);
+        mm_obj_dbg (self, "  mem3 (reception) storages:        '%s'", mem3);
         g_free (mem1);
         g_free (mem2);
         g_free (mem3);
@@ -1215,7 +1211,7 @@
                                                                               &error)) {
         if (error) {
             /* This error shouldn't be treated as critical */
-            mm_dbg ("Messaging support check failed: '%s'", error->message);
+            mm_obj_dbg (self, "messaging support check failed: %s", error->message);
             g_error_free (error);
         }
     } else {
@@ -1243,11 +1239,10 @@
             self,
             res,
             &error)) {
-        mm_dbg ("Couldn't initialize current storages: '%s'", error->message);
+        mm_obj_dbg (self, "couldn't initialize current storages: %s", error->message);
         g_error_free (error);
-    } else {
-        mm_dbg ("Current storages initialized");
-    }
+    } else
+        mm_obj_dbg (self, "current storages initialized");
 
     /* Go on to next step */
     ctx = g_task_get_task_data (task);
diff --git a/src/mm-iface-modem-oma.c b/src/mm-iface-modem-oma.c
index cf3a7a3..cc796b8 100644
--- a/src/mm-iface-modem-oma.c
+++ b/src/mm-iface-modem-oma.c
@@ -19,7 +19,7 @@
 
 #include "mm-iface-modem.h"
 #include "mm-iface-modem-oma.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 #define SUPPORT_CHECKED_TAG "oma-support-checked-tag"
 #define SUPPORTED_TAG       "oma-supported-tag"
@@ -124,10 +124,9 @@
 
     old_session_state = mm_gdbus_modem_oma_get_session_state (skeleton);
     if (old_session_state != new_session_state) {
-        mm_info ("Modem %s: OMA session state changed (%s -> %s)",
-                 g_dbus_object_get_object_path (G_DBUS_OBJECT (self)),
-                 mm_oma_session_state_get_string (old_session_state),
-                 mm_oma_session_state_get_string (new_session_state));
+        mm_obj_info (self, "OMA session state changed (%s -> %s)",
+                     mm_oma_session_state_get_string (old_session_state),
+                     mm_oma_session_state_get_string (new_session_state));
 
         /* Flush current change before signaling the state change,
          * so that clients get the proper state already in the
@@ -220,7 +219,7 @@
     }
 
     str = mm_oma_feature_build_string_from_mask (ctx->features);
-    mm_dbg ("Setting up OMA features: '%s'", str);
+    mm_obj_dbg (self, "setting up OMA features: '%s'", str);
     g_free (str);
 
     MM_IFACE_MODEM_OMA_GET_INTERFACE (ctx->self)->setup (
@@ -342,8 +341,8 @@
         return;
     }
 
-    mm_dbg ("Starting client-initiated OMA session (%s)",
-            mm_oma_session_type_get_string (ctx->session_type));
+    mm_obj_dbg (self, "starting client-initiated OMA session (%s)",
+                mm_oma_session_type_get_string (ctx->session_type));
     MM_IFACE_MODEM_OMA_GET_INTERFACE (ctx->self)->start_client_initiated_session (
         ctx->self,
         ctx->session_type,
@@ -501,10 +500,10 @@
         return;
     }
 
-    mm_dbg ("%s network-initiated OMA session (%s, %u)",
-            ctx->accept ? "Accepting" : "Rejecting",
-            mm_oma_session_type_get_string (ctx->session_type),
-            ctx->session_id);
+    mm_obj_dbg (self, "%s network-initiated OMA session (%s, %u)",
+                ctx->accept ? "accepting" : "rejecting",
+                mm_oma_session_type_get_string (ctx->session_type),
+                ctx->session_id);
     MM_IFACE_MODEM_OMA_GET_INTERFACE (ctx->self)->accept_network_initiated_session (
         ctx->self,
         ctx->session_id,
@@ -615,7 +614,7 @@
         return;
     }
 
-    mm_dbg ("Cancelling OMA session");
+    mm_obj_dbg (self, "cancelling OMA session");
     MM_IFACE_MODEM_OMA_GET_INTERFACE (ctx->self)->cancel_session (
         ctx->self,
         (GAsyncReadyCallback)cancel_session_ready,
@@ -890,7 +889,7 @@
 
     /* Not critical! */
     if (!MM_IFACE_MODEM_OMA_GET_INTERFACE (self)->enable_unsolicited_events_finish (self, res, &error)) {
-        mm_dbg ("Couldn't enable unsolicited events: '%s'", error->message);
+        mm_obj_dbg (self, "couldn't enable unsolicited events: %s", error->message);
         g_error_free (error);
     }
 
@@ -1036,7 +1035,7 @@
     if (!MM_IFACE_MODEM_OMA_GET_INTERFACE (self)->check_support_finish (self, res, &error)) {
         if (error) {
             /* This error shouldn't be treated as critical */
-            mm_dbg ("OMA support check failed: '%s'", error->message);
+            mm_obj_dbg (self, "OMA support check failed: %s", error->message);
             g_error_free (error);
         }
     } else {
diff --git a/src/mm-iface-modem-signal.c b/src/mm-iface-modem-signal.c
index 396ce68..03e4ce1 100644
--- a/src/mm-iface-modem-signal.c
+++ b/src/mm-iface-modem-signal.c
@@ -19,7 +19,7 @@
 
 #include "mm-iface-modem.h"
 #include "mm-iface-modem-signal.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 #define SUPPORT_CHECKED_TAG "signal-support-checked-tag"
 #define SUPPORTED_TAG       "signal-supported-tag"
@@ -93,7 +93,7 @@
             &umts,
             &lte,
             &error)) {
-        mm_warn ("Couldn't load extended signal information: %s", error->message);
+        mm_obj_warn (self, "couldn't load extended signal information: %s", error->message);
         g_error_free (error);
         clear_values (self);
         return;
@@ -103,8 +103,7 @@
                   MM_IFACE_MODEM_SIGNAL_DBUS_SKELETON, &skeleton,
                   NULL);
     if (!skeleton) {
-        mm_warn ("Cannot update extended signal information: "
-                 "Couldn't get interface skeleton");
+        mm_obj_warn (self, "cannot update extended signal information: couldn't get interface skeleton");
         return;
     }
 
@@ -172,7 +171,7 @@
     if (G_UNLIKELY (!refresh_context_quark))
         refresh_context_quark  = g_quark_from_static_string (REFRESH_CONTEXT_TAG);
     if (g_object_get_qdata (G_OBJECT (self), refresh_context_quark)) {
-        mm_dbg ("Extended signal information reporting disabled");
+        mm_obj_dbg (self, "extended signal information reporting disabled");
         g_object_set_qdata (G_OBJECT (self), refresh_context_quark, NULL);
     }
 }
@@ -210,14 +209,14 @@
 
     /* User disabling? */
     if (new_rate == 0) {
-        mm_dbg ("Extended signal information reporting disabled (rate: 0 seconds)");
+        mm_obj_dbg (self, "extended signal information reporting disabled (rate: 0 seconds)");
         clear_values (self);
         g_object_set_qdata (G_OBJECT (self), refresh_context_quark, NULL);
         return TRUE;
     }
 
     if (modem_state < MM_MODEM_STATE_ENABLING) {
-        mm_dbg ("Extended signal information reporting disabled (modem not yet enabled)");
+        mm_obj_dbg (self, "extended signal information reporting disabled (modem not yet enabled)");
         return TRUE;
     }
 
@@ -238,7 +237,7 @@
     }
 
     /* Update refresh context */
-    mm_dbg ("Extended signal information reporting enabled (rate: %u seconds)", new_rate);
+    mm_obj_dbg (self, "extended signal information reporting enabled (rate: %u seconds)", new_rate);
     ctx->rate = new_rate;
     if (ctx->timeout_source)
         g_source_remove (ctx->timeout_source);
@@ -402,7 +401,7 @@
     if (!MM_IFACE_MODEM_SIGNAL_GET_INTERFACE (self)->check_support_finish (self, res, &error)) {
         if (error) {
             /* This error shouldn't be treated as critical */
-            mm_dbg ("Extended signal support check failed: '%s'", error->message);
+            mm_obj_dbg (self, "extended signal support check failed: %s", error->message);
             g_error_free (error);
         }
     } else {
diff --git a/src/mm-iface-modem-simple.c b/src/mm-iface-modem-simple.c
index ccf4ecc..b0cf5e2 100644
--- a/src/mm-iface-modem-simple.c
+++ b/src/mm-iface-modem-simple.c
@@ -26,7 +26,7 @@
 #include "mm-iface-modem-3gpp.h"
 #include "mm-iface-modem-cdma.h"
 #include "mm-iface-modem-simple.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 /*****************************************************************************/
 /* Private data context */
@@ -164,7 +164,7 @@
     /* No more tries of anything */
     g_task_return_error (
         task,
-        mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_NETWORK_TIMEOUT));
+        mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_NETWORK_TIMEOUT, self));
     g_object_unref (task);
 }
 
@@ -280,7 +280,7 @@
     GError *error = NULL;
 
     if (!mm_base_bearer_connect_finish (bearer, res, &error)) {
-        mm_dbg ("Couldn't connect bearer: '%s'", error->message);
+        mm_obj_dbg (ctx->self, "couldn't connect bearer: %s", error->message);
         g_dbus_method_invocation_take_error (ctx->invocation, error);
         connection_context_free (ctx);
         return;
@@ -541,8 +541,8 @@
         /* fall through */
 
     case CONNECTION_STEP_UNLOCK_CHECK:
-        mm_info ("Simple connect state (%d/%d): Unlock check",
-                 ctx->step, CONNECTION_STEP_LAST);
+        mm_obj_info (ctx->self, "simple connect state (%d/%d): unlock check",
+                     ctx->step, CONNECTION_STEP_LAST);
         mm_iface_modem_update_lock_info (MM_IFACE_MODEM (ctx->self),
                                          MM_MODEM_LOCK_UNKNOWN, /* ask */
                                          (GAsyncReadyCallback)update_lock_info_ready,
@@ -550,8 +550,8 @@
         return;
 
     case CONNECTION_STEP_WAIT_FOR_INITIALIZED:
-        mm_info ("Simple connect state (%d/%d): Wait to get fully initialized",
-                 ctx->step, CONNECTION_STEP_LAST);
+        mm_obj_info (ctx->self, "simple connect state (%d/%d): wait to get fully initialized",
+                     ctx->step, CONNECTION_STEP_LAST);
         mm_iface_modem_wait_for_final_state (MM_IFACE_MODEM (ctx->self),
                                              MM_MODEM_STATE_DISABLED, /* disabled == initialized */
                                              (GAsyncReadyCallback)wait_for_initialized_ready,
@@ -559,16 +559,16 @@
         return;
 
     case CONNECTION_STEP_ENABLE:
-        mm_info ("Simple connect state (%d/%d): Enable",
-                 ctx->step, CONNECTION_STEP_LAST);
+        mm_obj_info (ctx->self, "simple connect state (%d/%d): enable",
+                     ctx->step, CONNECTION_STEP_LAST);
         mm_base_modem_enable (MM_BASE_MODEM (ctx->self),
                               (GAsyncReadyCallback)enable_ready,
                               ctx);
         return;
 
     case CONNECTION_STEP_WAIT_FOR_ENABLED:
-        mm_info ("Simple connect state (%d/%d): Wait to get fully enabled",
-                 ctx->step, CONNECTION_STEP_LAST);
+        mm_obj_info (ctx->self, "simple connect state (%d/%d): wait to get fully enabled",
+                     ctx->step, CONNECTION_STEP_LAST);
         mm_iface_modem_wait_for_final_state (MM_IFACE_MODEM (ctx->self),
                                              MM_MODEM_STATE_UNKNOWN, /* just a final state */
                                              (GAsyncReadyCallback)wait_for_enabled_ready,
@@ -576,9 +576,8 @@
         return;
 
     case CONNECTION_STEP_REGISTER:
-        mm_info ("Simple connect state (%d/%d): Register",
-                 ctx->step, CONNECTION_STEP_LAST);
-
+        mm_obj_info (ctx->self, "simple connect state (%d/%d): register",
+                     ctx->step, CONNECTION_STEP_LAST);
         if (mm_iface_modem_is_3gpp (MM_IFACE_MODEM (ctx->self)) ||
             mm_iface_modem_is_cdma (MM_IFACE_MODEM (ctx->self))) {
             /* 3GPP or CDMA registration */
@@ -599,9 +598,8 @@
         MMBearerList *list = NULL;
         MMBearerProperties *bearer_properties;
 
-        mm_info ("Simple connect state (%d/%d): Bearer",
-                 ctx->step, CONNECTION_STEP_LAST);
-
+        mm_obj_info (ctx->self, "simple connect state (%d/%d): bearer",
+                     ctx->step, CONNECTION_STEP_LAST);
         g_object_get (ctx->self,
                       MM_IFACE_MODEM_BEARER_LIST, &list,
                       NULL);
@@ -620,7 +618,7 @@
         /* Check if the bearer we want to create is already in the list */
         ctx->bearer = mm_bearer_list_find_by_properties (list, bearer_properties);
         if (!ctx->bearer) {
-            mm_dbg ("Creating new bearer...");
+            mm_obj_dbg (ctx->self, "creating new bearer...");
             /* If we don't have enough space to create the bearer, try to remove
              * a disconnected bearer first. */
             if (mm_bearer_list_get_max (list) == mm_bearer_list_get_count (list)) {
@@ -638,13 +636,13 @@
                     if (!mm_bearer_list_delete_bearer (list,
                                                        mm_base_bearer_get_path (foreach_ctx.found),
                                                        &error)) {
-                        mm_dbg ("Couldn't delete disconnected bearer at '%s': '%s'",
-                                mm_base_bearer_get_path (foreach_ctx.found),
-                                error->message);
+                        mm_obj_dbg (ctx->self, "couldn't delete disconnected bearer at '%s': %s",
+                                    mm_base_bearer_get_path (foreach_ctx.found),
+                                    error->message);
                         g_error_free (error);
                     } else
-                        mm_dbg ("Deleted disconnected bearer at '%s'",
-                                mm_base_bearer_get_path (foreach_ctx.found));
+                        mm_obj_dbg (ctx->self, "deleted disconnected bearer at '%s'",
+                                    mm_base_bearer_get_path (foreach_ctx.found));
                     g_object_unref (foreach_ctx.found);
                 }
 
@@ -672,16 +670,16 @@
             return;
         }
 
-        mm_dbg ("Using already existing bearer at '%s'...",
-                mm_base_bearer_get_path (ctx->bearer));
+        mm_obj_dbg (ctx->self, "Using already existing bearer at '%s'...",
+                    mm_base_bearer_get_path (ctx->bearer));
         g_object_unref (list);
         g_object_unref (bearer_properties);
         ctx->step++;
     } /* fall through */
 
     case CONNECTION_STEP_CONNECT:
-        mm_info ("Simple connect state (%d/%d): Connect",
-                 ctx->step, CONNECTION_STEP_LAST);
+        mm_obj_info (ctx->self, "simple connect state (%d/%d): connect",
+                     ctx->step, CONNECTION_STEP_LAST);
 
         /* At this point, we can cleanup the cancellation point in the Simple interface,
          * because the bearer connection has its own cancellation setup. */
@@ -696,15 +694,15 @@
             return;
         }
 
-        mm_dbg ("Bearer at '%s' is already connected...",
-                mm_base_bearer_get_path (ctx->bearer));
+        mm_obj_dbg (ctx->self, "bearer at '%s' is already connected...",
+                    mm_base_bearer_get_path (ctx->bearer));
 
         ctx->step++;
         /* fall through */
 
     case CONNECTION_STEP_LAST:
-        mm_info ("Simple connect state (%d/%d): All done",
-                 ctx->step, CONNECTION_STEP_LAST);
+        mm_obj_info (ctx->self, "simple connect state (%d/%d): all done",
+                     ctx->step, CONNECTION_STEP_LAST);
         /* All done, yey! */
         mm_gdbus_modem_simple_complete_connect (
             ctx->skeleton,
@@ -752,7 +750,7 @@
                   MM_IFACE_MODEM_STATE, &current,
                   NULL);
 
-    mm_info ("Simple connect started...");
+    mm_obj_info (self, "simple connect started...");
 
     /* Log about all the parameters being used for the simple connect */
     {
@@ -762,33 +760,29 @@
 
 #define VALIDATE_UNSPECIFIED(str) (str ? str : "unspecified")
 
-        mm_dbg ("   PIN: %s", VALIDATE_UNSPECIFIED (mm_simple_connect_properties_get_pin (ctx->properties)));
-
-        mm_dbg ("   Operator ID: %s", VALIDATE_UNSPECIFIED (mm_simple_connect_properties_get_operator_id (ctx->properties)));
-
-        mm_dbg ("   Allowed roaming: %s", mm_simple_connect_properties_get_allow_roaming (ctx->properties) ? "yes" : "no");
-
-        mm_dbg ("   APN: %s", VALIDATE_UNSPECIFIED (mm_simple_connect_properties_get_apn (ctx->properties)));
+        mm_obj_dbg (self, "   PIN: %s", VALIDATE_UNSPECIFIED (mm_simple_connect_properties_get_pin (ctx->properties)));
+        mm_obj_dbg (self, "   operator ID: %s", VALIDATE_UNSPECIFIED (mm_simple_connect_properties_get_operator_id (ctx->properties)));
+        mm_obj_dbg (self, "   allowed roaming: %s", mm_simple_connect_properties_get_allow_roaming (ctx->properties) ? "yes" : "no");
+        mm_obj_dbg (self, "   APN: %s", VALIDATE_UNSPECIFIED (mm_simple_connect_properties_get_apn (ctx->properties)));
 
         ip_family = mm_simple_connect_properties_get_ip_type (ctx->properties);
         if (ip_family != MM_BEARER_IP_FAMILY_NONE) {
             str = mm_bearer_ip_family_build_string_from_mask (ip_family);
-            mm_dbg ("   IP family: %s", str);
+            mm_obj_dbg (self, "   IP family: %s", str);
             g_free (str);
         } else
-            mm_dbg ("   IP family: %s", VALIDATE_UNSPECIFIED (NULL));
+            mm_obj_dbg (self, "   IP family: %s", VALIDATE_UNSPECIFIED (NULL));
 
         allowed_auth = mm_simple_connect_properties_get_allowed_auth (ctx->properties);
         if (allowed_auth != MM_BEARER_ALLOWED_AUTH_UNKNOWN) {
             str = mm_bearer_allowed_auth_build_string_from_mask (allowed_auth);
-            mm_dbg ("   Allowed authentication: %s", str);
+            mm_obj_dbg (self, "   allowed authentication: %s", str);
             g_free (str);
         } else
-            mm_dbg ("   Allowed authentication: %s", VALIDATE_UNSPECIFIED (NULL));
+            mm_obj_dbg (self, "   allowed authentication: %s", VALIDATE_UNSPECIFIED (NULL));
 
-        mm_dbg ("   User: %s", VALIDATE_UNSPECIFIED (mm_simple_connect_properties_get_user (ctx->properties)));
-
-        mm_dbg ("   Password: %s", VALIDATE_UNSPECIFIED (mm_simple_connect_properties_get_password (ctx->properties)));
+        mm_obj_dbg (self, "   User: %s", VALIDATE_UNSPECIFIED (mm_simple_connect_properties_get_user (ctx->properties)));
+        mm_obj_dbg (self, "   Password: %s", VALIDATE_UNSPECIFIED (mm_simple_connect_properties_get_password (ctx->properties)));
 
 #undef VALIDATE_UNSPECIFIED
     }
@@ -848,7 +842,7 @@
     ctx->self = g_object_ref (self);
     ctx->dictionary = g_variant_ref (dictionary);
 
-    mm_dbg ("User request to connect modem");
+    mm_obj_dbg (self, "user request to connect modem");
 
     mm_base_modem_authorize (MM_BASE_MODEM (self),
                              invocation,
@@ -1009,10 +1003,10 @@
      * We will detect the '/' string and set the bearer path as NULL in the
      * context if so, and otherwise use the given input string as path */
     if (g_strcmp0 (bearer_path, "/") != 0) {
-        mm_dbg ("User request to disconnect modem (bearer '%s')", bearer_path);
+        mm_obj_dbg (self, "user request to disconnect modem (bearer '%s')", bearer_path);
         ctx->bearer_path = g_strdup (bearer_path);
     } else
-        mm_dbg ("User request to disconnect modem (all bearers)");
+        mm_obj_dbg (self, "user request to disconnect modem (all bearers)");
 
     mm_base_modem_authorize (MM_BASE_MODEM (self),
                              invocation,
diff --git a/src/mm-iface-modem-time.c b/src/mm-iface-modem-time.c
index 3aa2082..f02bc34 100644
--- a/src/mm-iface-modem-time.c
+++ b/src/mm-iface-modem-time.c
@@ -19,7 +19,7 @@
 
 #include "mm-iface-modem.h"
 #include "mm-iface-modem-time.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 #define SUPPORT_CHECKED_TAG          "time-support-checked-tag"
 #define SUPPORTED_TAG                "time-supported-tag"
@@ -202,7 +202,7 @@
     if (!tz) {
         NetworkTimezoneContext *ctx;
 
-        mm_dbg ("Couldn't load network timezone: %s", error->message);
+        mm_obj_dbg (self, "couldn't load network timezone: %s", error->message);
         g_error_free (error);
 
         /* Note: may be NULL if the polling has been removed while processing the async operation */
@@ -216,7 +216,7 @@
         /* If no more retries, we don't do anything else */
         if (ctx->network_timezone_poll_retries == 0 ||
             !g_error_matches (error, MM_CORE_ERROR, MM_CORE_ERROR_RETRY)) {
-            mm_warn ("Couldn't load network timezone from the current network");
+            mm_obj_warn (self, "couldn't load network timezone from the current network");
             return;
         }
 
@@ -255,7 +255,7 @@
 
     ctx = (NetworkTimezoneContext *) g_object_get_qdata (G_OBJECT (self), network_timezone_context_quark);
 
-    mm_dbg ("Network timezone polling started");
+    mm_obj_dbg (self, "network timezone polling started");
     ctx->network_timezone_poll_retries = NETWORK_TIMEZONE_POLL_RETRIES;
     ctx->network_timezone_poll_id = g_timeout_add_seconds (NETWORK_TIMEZONE_POLL_INTERVAL_SEC, (GSourceFunc)network_timezone_poll_cb, self);
 }
@@ -268,7 +268,7 @@
     ctx = (NetworkTimezoneContext *) g_object_get_qdata (G_OBJECT (self), network_timezone_context_quark);
 
     if (ctx->network_timezone_poll_id) {
-        mm_dbg ("Network timezone polling stopped");
+        mm_obj_dbg (self, "network timezone polling stopped");
         g_source_remove (ctx->network_timezone_poll_id);
         ctx->network_timezone_poll_id = 0;
     }
@@ -322,7 +322,7 @@
     /* If loading network timezone not supported, just finish here */
     if (!MM_IFACE_MODEM_TIME_GET_INTERFACE (self)->load_network_timezone ||
         !MM_IFACE_MODEM_TIME_GET_INTERFACE (self)->load_network_timezone_finish) {
-        mm_dbg ("Loading network timezone is not supported");
+        mm_obj_dbg (self, "loading network timezone is not supported");
         return;
     }
 
@@ -622,7 +622,7 @@
 
     /* Not critical! */
     if (!MM_IFACE_MODEM_TIME_GET_INTERFACE (self)->enable_unsolicited_events_finish (self, res, &error)) {
-        mm_dbg ("Couldn't enable unsolicited events: '%s'", error->message);
+        mm_obj_dbg (self, "couldn't enable unsolicited events: %s", error->message);
         g_error_free (error);
     }
 
@@ -764,7 +764,7 @@
                                                                          &error)) {
         if (error) {
             /* This error shouldn't be treated as critical */
-            mm_dbg ("Time support check failed: '%s'", error->message);
+            mm_obj_dbg (self, "time support check failed: %s", error->message);
             g_error_free (error);
         }
     } else {
diff --git a/src/mm-iface-modem-voice.c b/src/mm-iface-modem-voice.c
index 9a57aa0..ba6b52c 100644
--- a/src/mm-iface-modem-voice.c
+++ b/src/mm-iface-modem-voice.c
@@ -21,7 +21,7 @@
 #include "mm-iface-modem.h"
 #include "mm-iface-modem-voice.h"
 #include "mm-call-list.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 #define CALL_LIST_POLLING_CONTEXT_TAG "voice-call-list-polling-context-tag"
 #define IN_CALL_EVENT_CONTEXT_TAG     "voice-in-call-event-context-tag"
@@ -89,14 +89,14 @@
 
     /* If we're not in emergency mode, the call (emergency or normal) is always allowed */
     if (!emergency_only) {
-        mm_dbg ("voice call to %s allowed", number);
+        mm_obj_dbg (self, "voice call to %s allowed", number);
         call_allowed = TRUE;
         goto out;
     }
 
     for (i = 0; i < G_N_ELEMENTS (always_valid_emergency_numbers); i++) {
         if (g_strcmp0 (number, always_valid_emergency_numbers[i]) == 0) {
-            mm_dbg ("voice call to %s allowed: emergency call number always valid", number);
+            mm_obj_dbg (self, "voice call to %s allowed: emergency call number always valid", number);
             call_allowed = TRUE;
             goto out;
         }
@@ -110,22 +110,22 @@
         /* If no SIM available, some additional numbers may be valid emergency numbers */
         for (i = 0; i < G_N_ELEMENTS (no_sim_valid_emergency_numbers); i++) {
             if (g_strcmp0 (number, no_sim_valid_emergency_numbers[i]) == 0) {
-                mm_dbg ("voice call to %s allowed: emergency call number valid when no SIM", number);
+                mm_obj_dbg (self, "voice call to %s allowed: emergency call number valid when no SIM", number);
                 call_allowed = TRUE;
                 goto out;
             }
         }
 
-        mm_dbg ("voice call to %s NOT allowed: not a valid emergency call number when no SIM", number);
+        mm_obj_dbg (self, "voice call to %s NOT allowed: not a valid emergency call number when no SIM", number);
         goto out;
     }
 
     /* Check if the number is programmed in EF_ECC */
     if (mm_base_sim_is_emergency_number (sim, number)) {
-        mm_dbg ("voice call to %s allowed: emergency call number programmed in the SIM", number);
+        mm_obj_dbg (self, "voice call to %s allowed: emergency call number programmed in the SIM", number);
         call_allowed = TRUE;
     } else
-        mm_dbg ("voice call to %s NOT allowed: not a valid emergency call number programmed in the SIM", number);
+        mm_obj_dbg (self, "voice call to %s NOT allowed: not a valid emergency call number programmed in the SIM", number);
 
  out:
 
@@ -188,8 +188,9 @@
 /* Common helper to match call info against a known call object */
 
 static gboolean
-match_single_call_info (const MMCallInfo *call_info,
-                        MMBaseCall       *call)
+match_single_call_info (MMIfaceModemVoice *self,
+                        const MMCallInfo  *call_info,
+                        MMBaseCall        *call)
 {
     MMCallState      state;
     MMCallDirection  direction;
@@ -242,20 +243,20 @@
         !match_terminated)
         return FALSE;
 
-    mm_dbg ("call info matched (matched direction/state %s, matched number %s"
-            ", matched index %s, matched terminated %s) with call at '%s'",
-            match_direction_and_state ? "yes" : "no",
-            match_number ? "yes" : "no",
-            match_index ? "yes" : "no",
-            match_terminated ? "yes" : "no",
-            mm_base_call_get_path (call));
+    mm_obj_dbg (self, "call info matched (matched direction/state %s, matched number %s"
+                ", matched index %s, matched terminated %s) with call at '%s'",
+                match_direction_and_state ? "yes" : "no",
+                match_number ? "yes" : "no",
+                match_index ? "yes" : "no",
+                match_terminated ? "yes" : "no",
+                mm_base_call_get_path (call));
 
     /* Early detect if a known incoming call that was created
      * from a plain CRING URC (i.e. without caller number)
      * needs to have the number provided.
      */
     if (call_info->number && !number) {
-        mm_dbg ("  number set: %s", call_info->number);
+        mm_obj_dbg (self, "  number set: %s", call_info->number);
         mm_base_call_set_number (call, call_info->number);
     }
 
@@ -263,20 +264,20 @@
      * not have a known call index yet.
      */
     if (call_info->index && !idx) {
-        mm_dbg ("  index set: %u", call_info->index);
+        mm_obj_dbg (self, "  index set: %u", call_info->index);
         mm_base_call_set_index (call, call_info->index);
     }
 
     /* Update state if it changed */
     if (call_info->state != state) {
-        mm_dbg ("  state updated: %s", mm_call_state_get_string (call_info->state));
+        mm_obj_dbg (self, "  state updated: %s", mm_call_state_get_string (call_info->state));
         mm_base_call_change_state (call, call_info->state, MM_CALL_STATE_REASON_UNKNOWN);
     }
 
     /* refresh if incoming and new state is not terminated */
     if ((call_info->state != MM_CALL_STATE_TERMINATED) &&
         (direction == MM_CALL_DIRECTION_INCOMING)) {
-        mm_dbg ("  incoming refreshed");
+        mm_obj_dbg (self, "  incoming refreshed");
         mm_base_call_incoming_refresh (call);
     }
 
@@ -286,7 +287,8 @@
 /*****************************************************************************/
 
 typedef struct {
-    const MMCallInfo *call_info;
+    MMIfaceModemVoice *self;
+    const MMCallInfo  *call_info;
 } ReportCallForeachContext;
 
 static void
@@ -302,7 +304,7 @@
         return;
 
     /* Reset call info in context if the call info matches an existing call */
-    if (match_single_call_info (ctx->call_info, call))
+    if (match_single_call_info (ctx->self, ctx->call_info, call))
         ctx->call_info = NULL;
 }
 
@@ -322,22 +324,23 @@
     g_assert (call_info->state != MM_CALL_STATE_UNKNOWN);
 
     /* Early debugging of the call state update */
-    mm_dbg ("call at index %u: direction %s, state %s, number %s",
-            call_info->index,
-            mm_call_direction_get_string (call_info->direction),
-            mm_call_state_get_string (call_info->state),
-            call_info->number ? call_info->number : "n/a");
+    mm_obj_dbg (self, "call at index %u: direction %s, state %s, number %s",
+                call_info->index,
+                mm_call_direction_get_string (call_info->direction),
+                mm_call_state_get_string (call_info->state),
+                call_info->number ? call_info->number : "n/a");
 
     g_object_get (MM_BASE_MODEM (self),
                   MM_IFACE_MODEM_VOICE_CALL_LIST, &list,
                   NULL);
 
     if (!list) {
-        mm_warn ("Cannot process call state update: missing call list");
+        mm_obj_warn (self, "cannot process call state update: missing call list");
         return;
     }
 
     /* Iterate over all known calls and try to match a known one */
+    ctx.self = self;
     ctx.call_info = call_info;
     mm_call_list_foreach (list, (MMCallListForeachFunc)report_call_foreach, &ctx);
 
@@ -349,13 +352,13 @@
      * reported a NEW incoming call. If that's not the case, we'll ignore the report. */
     if ((call_info->direction != MM_CALL_DIRECTION_INCOMING) ||
         ((call_info->state != MM_CALL_STATE_WAITING) && (call_info->state != MM_CALL_STATE_RINGING_IN))) {
-        mm_dbg ("unhandled call state update reported: direction: %s, state %s",
-                mm_call_direction_get_string (call_info->direction),
-                mm_call_state_get_string (call_info->state));
+        mm_obj_dbg (self, "unhandled call state update reported: direction: %s, state %s",
+                    mm_call_direction_get_string (call_info->direction),
+                    mm_call_state_get_string (call_info->state));
         goto out;
     }
 
-    mm_dbg ("Creating new incoming call...");
+    mm_obj_dbg (self, "creating new incoming call...");
     call = create_incoming_call (self, call_info->number);
 
     /* Set the state */
@@ -393,7 +396,8 @@
  */
 
 typedef struct {
-    GList *call_info_list;
+    MMIfaceModemVoice *self;
+    GList             *call_info_list;
 } ReportAllCallsForeachContext;
 
 static void
@@ -413,20 +417,20 @@
         MMCallInfo *call_info = (MMCallInfo *)(l->data);
 
         /* if match found, delete item from list and halt iteration right away */
-        if (match_single_call_info (call_info, call)) {
+        if (match_single_call_info (ctx->self, call_info, call)) {
             ctx->call_info_list = g_list_delete_link (ctx->call_info_list, l);
             return;
         }
     }
 
     /* not found in list! this call is now terminated */
-    mm_dbg ("Call '%s' with direction %s, state %s, number '%s', index %u"
-            " not found in list, terminating",
-            mm_base_call_get_path (call),
-            mm_call_direction_get_string (mm_base_call_get_direction (call)),
-            mm_call_state_get_string (state),
-            mm_base_call_get_number (call),
-            mm_base_call_get_index (call));
+    mm_obj_dbg (ctx->self, "call '%s' with direction %s, state %s, number '%s', index %u"
+                " not found in list, terminating",
+                mm_base_call_get_path (call),
+                mm_call_direction_get_string (mm_base_call_get_direction (call)),
+                mm_call_state_get_string (state),
+                mm_base_call_get_number (call),
+                mm_base_call_get_index (call));
     mm_base_call_change_state (call, MM_CALL_STATE_TERMINATED, MM_CALL_STATE_REASON_UNKNOWN);
 }
 
@@ -439,7 +443,7 @@
     GList                        *l;
 
     /* Early debugging of the full list of calls */
-    mm_dbg ("Reported %u ongoing calls", g_list_length (call_info_list));
+    mm_obj_dbg (self, "reported %u ongoing calls", g_list_length (call_info_list));
     for (l = call_info_list; l; l = g_list_next (l)) {
         MMCallInfo *call_info = (MMCallInfo *)(l->data);
 
@@ -447,11 +451,11 @@
         g_assert (call_info->index != 0);
         g_assert (call_info->state != MM_CALL_STATE_UNKNOWN);
 
-        mm_dbg ("call at index %u: direction %s, state %s, number %s",
-                call_info->index,
-                mm_call_direction_get_string (call_info->direction),
-                mm_call_state_get_string (call_info->state),
-                call_info->number ? call_info->number : "n/a");
+        mm_obj_dbg (self, "call at index %u: direction %s, state %s, number %s",
+                    call_info->index,
+                    mm_call_direction_get_string (call_info->direction),
+                    mm_call_state_get_string (call_info->state),
+                    call_info->number ? call_info->number : "n/a");
     }
 
     /* Retrieve list of known calls */
@@ -459,12 +463,13 @@
                   MM_IFACE_MODEM_VOICE_CALL_LIST, &list,
                   NULL);
     if (!list) {
-        mm_warn ("Cannot report all calls: missing call list");
+        mm_obj_warn (self, "cannot report all calls: missing call list");
         return;
     }
 
     /* Iterate over all the calls already known to us.
      * Whenever a known call is updated, it will be removed from the call info list */
+    ctx.self = self;
     ctx.call_info_list = g_list_copy (call_info_list);
     mm_call_list_foreach (list, (MMCallListForeachFunc)report_all_calls_foreach, &ctx);
 
@@ -480,9 +485,9 @@
             continue;
 
         if (call_info->direction == MM_CALL_DIRECTION_OUTGOING) {
-            mm_warn ("unexpected outgoing call to number '%s' reported in call list: state %s",
-                     call_info->number ? call_info->number : "n/a",
-                     mm_call_state_get_string (call_info->state));
+            mm_obj_warn (self, "unexpected outgoing call to number '%s' reported in call list: state %s",
+                         call_info->number ? call_info->number : "n/a",
+                         mm_call_state_get_string (call_info->state));
             continue;
         }
 
@@ -492,13 +497,13 @@
             /* We only expect either RINGING-IN or WAITING states */
             if ((call_info->state != MM_CALL_STATE_RINGING_IN) &&
                 (call_info->state != MM_CALL_STATE_WAITING)) {
-                    mm_warn ("unexpected incoming call to number '%s' reported in call list: state %s",
-                             call_info->number ? call_info->number : "n/a",
-                             mm_call_state_get_string (call_info->state));
+                    mm_obj_warn (self, "unexpected incoming call to number '%s' reported in call list: state %s",
+                                 call_info->number ? call_info->number : "n/a",
+                                 mm_call_state_get_string (call_info->state));
                     continue;
             }
 
-            mm_dbg ("Creating new incoming call...");
+            mm_obj_dbg (self, "creating new incoming call...");
             call = create_incoming_call (self, call_info->number);
 
             /* Set the state and the index */
@@ -515,9 +520,9 @@
             continue;
         }
 
-        mm_warn ("unexpected call to number '%s' reported in call list: state %s, direction unknown",
-                 call_info->number ? call_info->number : "n/a",
-                 mm_call_state_get_string (call_info->state));
+        mm_obj_warn (self, "unexpected call to number '%s' reported in call list: state %s, direction unknown",
+                     call_info->number ? call_info->number : "n/a",
+                     mm_call_state_get_string (call_info->state));
     }
     g_list_free (ctx.call_info_list);
     g_object_unref (list);
@@ -556,7 +561,7 @@
                   MM_IFACE_MODEM_VOICE_CALL_LIST, &list,
                   NULL);
     if (!list) {
-        mm_warn ("Cannot report received DTMF: missing call list");
+        mm_obj_warn (self, "cannot report received DTMF: missing call list");
         return;
     }
 
@@ -1839,7 +1844,7 @@
                                                                                         &ctx->audio_port,
                                                                                         &ctx->audio_format,
                                                                                         &error)) {
-        mm_warn ("Couldn't setup in-call audio channel: %s", error->message);
+        mm_obj_warn (self, "couldn't setup in-call audio channel: %s", error->message);
         g_clear_error (&error);
     }
 
@@ -1858,7 +1863,7 @@
     ctx = g_task_get_task_data (task);
 
     if (!MM_IFACE_MODEM_VOICE_GET_INTERFACE (self)->setup_in_call_unsolicited_events_finish (self, res, &error)) {
-        mm_warn ("Couldn't setup in-call unsolicited events: %s", error->message);
+        mm_obj_warn (self, "couldn't setup in-call unsolicited events: %s", error->message);
         g_clear_error (&error);
     }
 
@@ -1974,7 +1979,7 @@
     ctx = g_task_get_task_data (task);
 
     if (!MM_IFACE_MODEM_VOICE_GET_INTERFACE (self)->cleanup_in_call_unsolicited_events_finish (self, res, &error)) {
-        mm_warn ("Couldn't cleanup in-call unsolicited events: %s", error->message);
+        mm_obj_warn (self, "couldn't cleanup in-call unsolicited events: %s", error->message);
         g_clear_error (&error);
     }
 
@@ -1993,7 +1998,7 @@
     ctx = g_task_get_task_data (task);
 
     if (!MM_IFACE_MODEM_VOICE_GET_INTERFACE (self)->cleanup_in_call_audio_channel_finish (self, res, &error)) {
-        mm_warn ("Couldn't cleanup in-call audio channel: %s", error->message);
+        mm_obj_warn (self, "couldn't cleanup in-call audio channel: %s", error->message);
         g_clear_error (&error);
     }
 
@@ -2154,7 +2159,7 @@
                   MM_IFACE_MODEM_VOICE_CALL_LIST, &list,
                   NULL);
     if (!list) {
-        mm_warn ("Cannot update audio settings in active calls: missing internal call list");
+        mm_obj_warn (self, "cannot update audio settings in active calls: missing internal call list");
         return;
     }
 
@@ -2209,10 +2214,10 @@
     if (!in_call_cleanup_finish (self, res, &error)) {
         /* ignore cancelled operations */
         if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-            mm_warn ("Cannot cleanup in-call modem state: %s", error->message);
+            mm_obj_warn (self, "cannot cleanup in-call modem state: %s", error->message);
         g_clear_error (&error);
     } else {
-        mm_dbg ("modem is no longer in-call state");
+        mm_obj_dbg (self, "modem is no longer in-call state");
         ctx->in_call_state = FALSE;
         g_clear_object (&ctx->audio_port);
         g_clear_object (&ctx->audio_format);
@@ -2233,10 +2238,10 @@
     if (!in_call_setup_finish (self, res, &ctx->audio_port, &ctx->audio_format, &error)) {
         /* ignore cancelled operations */
         if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-            mm_warn ("Cannot setup in-call modem state: %s", error->message);
+            mm_obj_warn (self, "cannot setup in-call modem state: %s", error->message);
         g_clear_error (&error);
     } else {
-        mm_dbg ("modem is now in-call state");
+        mm_obj_dbg (self, "modem is now in-call state");
         ctx->in_call_state = TRUE;
         update_audio_settings_in_ongoing_calls (self);
     }
@@ -2258,7 +2263,7 @@
                   MM_IFACE_MODEM_VOICE_CALL_LIST, &list,
                   NULL);
     if (!list) {
-        mm_warn ("Cannot update in-call state: missing internal call list");
+        mm_obj_warn (self, "cannot update in-call state: missing internal call list");
         goto out;
     }
 
@@ -2277,7 +2282,7 @@
         }
 
         /* run setup */
-        mm_dbg ("Setting up in-call state...");
+        mm_obj_dbg (self, "setting up in-call state...");
         ctx->setup_cancellable = g_cancellable_new ();
         in_call_setup (self, ctx->setup_cancellable, (GAsyncReadyCallback) in_call_setup_ready, NULL);
         goto out;
@@ -2296,7 +2301,7 @@
         }
 
         /* run cleanup */
-        mm_dbg ("Cleaning up in-call state...");
+        mm_obj_dbg (self, "cleaning up in-call state...");
         ctx->cleanup_cancellable = g_cancellable_new ();
         in_call_cleanup (self, ctx->cleanup_cancellable, (GAsyncReadyCallback) in_call_cleanup_ready, NULL);
         goto out;
@@ -2406,7 +2411,7 @@
 
     g_assert (MM_IFACE_MODEM_VOICE_GET_INTERFACE (self)->load_call_list_finish);
     if (!MM_IFACE_MODEM_VOICE_GET_INTERFACE (self)->load_call_list_finish (self, res, &call_info_list, &error)) {
-        mm_warn ("couldn't load call list: %s", error->message);
+        mm_obj_warn (self, "couldn't load call list: %s", error->message);
         g_error_free (error);
     } else {
         /* Always report the list even if NULL (it would mean no ongoing calls) */
@@ -2458,7 +2463,7 @@
                   NULL);
 
     if (!list) {
-        mm_warn ("Cannot poll call list: missing internal call list");
+        mm_obj_warn (self, "Cannot poll call list: missing internal call list");
         goto out;
     }
 
@@ -2466,14 +2471,14 @@
 
     /* If there is at least ONE call being established, we need the call list */
     if (n_calls_establishing > 0) {
-        mm_dbg ("%u calls being established: call list polling required", n_calls_establishing);
+        mm_obj_dbg (self, "%u calls being established: call list polling required", n_calls_establishing);
         ctx->polling_ongoing = TRUE;
         g_assert (MM_IFACE_MODEM_VOICE_GET_INTERFACE (self)->load_call_list);
         MM_IFACE_MODEM_VOICE_GET_INTERFACE (self)->load_call_list (self,
                                                                    (GAsyncReadyCallback)load_call_list_ready,
                                                                    NULL);
     } else
-        mm_dbg ("no calls being established: call list polling stopped");
+        mm_obj_dbg (self, "no calls being established: call list polling stopped");
 
 out:
     g_clear_object (&list);
@@ -2515,7 +2520,6 @@
             const gchar       *call_path,
             MmGdbusModemVoice *skeleton)
 {
-    mm_dbg ("Added call at '%s'", call_path);
     update_call_list (skeleton, list);
     mm_gdbus_modem_voice_emit_call_added (skeleton, call_path);
 }
@@ -2525,7 +2529,6 @@
               const gchar       *call_path,
               MmGdbusModemVoice *skeleton)
 {
-    mm_dbg ("Deleted call at '%s'", call_path);
     update_call_list (skeleton, list);
     mm_gdbus_modem_voice_emit_call_deleted (skeleton, call_path);
 }
@@ -2752,7 +2755,7 @@
 
     /* Not critical! */
     if (!MM_IFACE_MODEM_VOICE_GET_INTERFACE (self)->enable_unsolicited_events_finish (self, res, &error)) {
-        mm_dbg ("Couldn't enable unsolicited events: '%s'", error->message);
+        mm_obj_dbg (self, "couldn't enable unsolicited events: %s", error->message);
         g_error_free (error);
     }
 
@@ -2885,7 +2888,7 @@
 
     if (!MM_IFACE_MODEM_VOICE_GET_INTERFACE (self)->check_support_finish (self, res, &error)) {
         if (error) {
-            mm_dbg ("Voice support check failed: '%s'", error->message);
+            mm_obj_dbg (self, "voice support check failed: %s", error->message);
             g_error_free (error);
         }
         g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, "Voice not supported");
@@ -2981,7 +2984,7 @@
                           MM_IFACE_MODEM_VOICE_PERIODIC_CALL_LIST_CHECK_DISABLED, &periodic_call_list_check_disabled,
                           NULL);
             if (!periodic_call_list_check_disabled) {
-                mm_dbg ("periodic call list polling will be used if supported");
+                mm_obj_dbg (self, "periodic call list polling will be used if supported");
                 g_signal_connect (list,
                                   MM_CALL_ADDED,
                                   G_CALLBACK (setup_call_list_polling),
diff --git a/src/mm-iface-modem.c b/src/mm-iface-modem.c
index b2272cb..14e64ec 100644
--- a/src/mm-iface-modem.c
+++ b/src/mm-iface-modem.c
@@ -26,7 +26,7 @@
 #include "mm-base-modem-at.h"
 #include "mm-base-sim.h"
 #include "mm-bearer-list.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-context.h"
 
 #define SIGNAL_QUALITY_RECENT_TIMEOUT_SEC 60
@@ -310,7 +310,7 @@
 
     lock = MM_IFACE_MODEM_GET_INTERFACE (self)->load_unlock_required_finish (self, res, &error);
     if (error) {
-        mm_dbg ("Couldn't check if unlock required: '%s'", error->message);
+        mm_obj_dbg (self, "couldn't check if unlock required: %s", error->message);
 
         /* For several kinds of errors, just return them directly */
         if (error->domain == MM_SERIAL_ERROR ||
@@ -334,7 +334,7 @@
         /* For the remaining ones, retry if possible */
         if (ctx->retries < MAX_RETRIES) {
             ctx->retries++;
-            mm_dbg ("Retrying (%u) unlock required check", ctx->retries);
+            mm_obj_dbg (self, "retrying (%u) unlock required check", ctx->retries);
 
             g_assert (ctx->pin_check_timeout_id == 0);
             ctx->pin_check_timeout_id = g_timeout_add_seconds (2,
@@ -990,10 +990,9 @@
         /* Log */
         old_access_tech_string = mm_modem_access_technology_build_string_from_mask (old_access_tech);
         new_access_tech_string = mm_modem_access_technology_build_string_from_mask (built_access_tech);
-        mm_dbg ("Modem %s: access technology changed (%s -> %s)",
-                g_dbus_object_get_object_path (G_DBUS_OBJECT (self)),
-                old_access_tech_string,
-                new_access_tech_string);
+        mm_obj_dbg (self, "access technology changed (%s -> %s)",
+                    old_access_tech_string,
+                    new_access_tech_string);
         g_free (old_access_tech_string);
         g_free (new_access_tech_string);
     }
@@ -1038,9 +1037,8 @@
 
         /* If value is already not recent, we're done */
         if (recent) {
-            mm_dbg ("Signal quality value not updated in %us, "
-                    "marking as not being recent",
-                    SIGNAL_QUALITY_RECENT_TIMEOUT_SEC);
+            mm_obj_dbg (self, "signal quality value not updated in %us, marking as not being recent",
+                        SIGNAL_QUALITY_RECENT_TIMEOUT_SEC);
             mm_gdbus_modem_set_signal_quality (skeleton,
                                                g_variant_new ("(ub)",
                                                               signal_quality,
@@ -1063,7 +1061,6 @@
 {
     SignalQualityUpdateContext *ctx;
     MmGdbusModem *skeleton = NULL;
-    const gchar *dbus_path;
 
     g_object_get (self,
                   MM_IFACE_MODEM_DBUS_SKELETON, &skeleton,
@@ -1098,10 +1095,7 @@
                                                       signal_quality,
                                                       expire));
 
-    dbus_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (self));
-    mm_dbg ("Modem %s: signal quality updated (%u)",
-            dbus_path,
-            signal_quality);
+    mm_obj_dbg (self, "signal quality updated (%u)", signal_quality);
 
     /* Remove any previous expiration refresh timeout */
     if (ctx->recent_timeout_source) {
@@ -1233,12 +1227,12 @@
             &error)) {
         /* Did the plugin report that polling access technology is unsupported? */
         if (g_error_matches (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED)) {
-            mm_dbg ("Polling to refresh access technologies is unsupported");
+            mm_obj_dbg (self, "polling to refresh access technologies is unsupported");
             ctx->access_technology_polling_supported = FALSE;
         }
         /* Ignore logging any message if the error is in 'in-progress' */
         else if (!g_error_matches (error, MM_CORE_ERROR, MM_CORE_ERROR_IN_PROGRESS))
-            mm_dbg ("Couldn't refresh access technologies: '%s'", error->message);
+            mm_obj_dbg (self, "couldn't refresh access technologies: %s", error->message);
         g_error_free (error);
     }
     /* We may have been disabled while this command was running. */
@@ -1263,12 +1257,12 @@
     if (error) {
         /* Did the plugin report that polling signal quality is unsupported? */
         if (g_error_matches (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED)) {
-            mm_dbg ("Polling to refresh signal quality is unsupported");
+            mm_obj_dbg (self, "polling to refresh signal quality is unsupported");
             ctx->signal_quality_polling_supported = FALSE;
         }
         /* Ignore logging any message if the error is in 'in-progress' */
         else if (!g_error_matches (error, MM_CORE_ERROR, MM_CORE_ERROR_IN_PROGRESS))
-            mm_dbg ("Couldn't refresh signal quality: '%s'", error->message);
+            mm_obj_dbg (self, "couldn't refresh signal quality: %s", error->message);
         g_error_free (error);
     }
     /* We may have been disabled while this command was running. */
@@ -1322,7 +1316,7 @@
         /* If we have been disabled while we were running the steps, we don't
          * do anything else. */
         if (!ctx->enabled) {
-            mm_dbg ("Periodic signal quality and access technology checks not rescheduled: disabled");
+            mm_obj_dbg (self, "periodic signal quality and access technology checks not rescheduled: disabled");
             return;
         }
 
@@ -1353,12 +1347,12 @@
         if (ctx->initial_check_done &&
             (!ctx->signal_quality_polling_supported    || ctx->signal_quality_polling_disabled) &&
             (!ctx->access_technology_polling_supported || ctx->access_technology_polling_disabled)) {
-            mm_dbg ("Periodic signal quality and access technology checks not rescheduled: unneeded or unsupported");
+            mm_obj_dbg (self, "periodic signal quality and access technology checks not rescheduled: unneeded or unsupported");
             periodic_signal_check_disable (self, FALSE);
             return;
         }
 
-        mm_dbg ("Periodic signal quality and access technology checks scheduled");
+        mm_obj_dbg (self, "periodic signal quality and access technology checks scheduled");
         g_assert (!ctx->timeout_source);
         ctx->timeout_source = g_timeout_add_seconds (ctx->initial_check_done ? SIGNAL_CHECK_TIMEOUT_SEC : SIGNAL_CHECK_INITIAL_TIMEOUT_SEC,
                                                      (GSourceFunc) periodic_signal_check_cb,
@@ -1399,17 +1393,17 @@
     /* Don't refresh polling if we're not enabled */
     ctx = get_signal_check_context (self);
     if (!ctx->enabled) {
-        mm_dbg ("Periodic signal check refresh ignored: checks not enabled");
+        mm_obj_dbg (self, "periodic signal check refresh ignored: checks not enabled");
         return;
     }
 
     /* Don't refresh if we're already doing it */
     if (ctx->running_step != SIGNAL_CHECK_STEP_NONE) {
-        mm_dbg ("Periodic signal check refresh ignored: check already running");
+        mm_obj_dbg (self, "periodic signal check refresh ignored: check already running");
         return;
     }
 
-    mm_dbg ("Periodic signal check refresh requested");
+    mm_obj_dbg (self, "periodic signal check refresh requested");
 
     /* Remove the scheduled timeout as we're going to refresh
      * right away */
@@ -1452,7 +1446,7 @@
     }
 
     ctx->enabled = FALSE;
-    mm_dbg ("Periodic signal checks disabled");
+    mm_obj_dbg (self, "periodic signal checks disabled");
 }
 
 static void
@@ -1465,13 +1459,13 @@
     /* If polling access technology and signal quality not supported, don't even
      * bother trying. */
     if (!ctx->signal_quality_polling_supported && !ctx->access_technology_polling_supported) {
-        mm_dbg ("Not enabling periodic signal checks: unsupported");
+        mm_obj_dbg (self, "not enabling periodic signal checks: unsupported");
         return;
     }
 
     /* Log and flag as enabled */
     if (!ctx->enabled) {
-        mm_dbg ("Periodic signal checks enabled");
+        mm_obj_dbg (self, "periodic signal checks enabled");
         ctx->enabled = TRUE;
     }
 
@@ -1535,14 +1529,9 @@
 
     /* Update state only if different */
     if (new_state != old_state) {
-        const gchar *dbus_path;
-
-        dbus_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (self));
-        mm_info ("Modem%s%s: state changed (%s -> %s)",
-                 dbus_path ? " " : "",
-                 dbus_path ? dbus_path : "",
-                 mm_modem_state_get_string (old_state),
-                 mm_modem_state_get_string (new_state));
+        mm_obj_info (self, "state changed (%s -> %s)",
+                     mm_modem_state_get_string (old_state),
+                     mm_modem_state_get_string (new_state));
 
         /* The property in the interface is bound to the property
          * in the skeleton, so just updating here is enough */
@@ -1707,8 +1696,7 @@
     if (i == subsystem_states->len) {
         SubsystemState s;
 
-        mm_dbg ("Will start keeping track of state for subsystem '%s'",
-                subsystem);
+        mm_obj_dbg (self, "will start keeping track of state for subsystem '%s'", subsystem);
         s.subsystem = g_strdup (subsystem);
         s.state = subsystem_state;
         g_array_append_val (subsystem_states, s);
@@ -2233,7 +2221,7 @@
     }
 
     capabilities_string = mm_modem_capability_build_string_from_mask (ctx->capabilities);
-    mm_dbg ("Setting new list of capabilities: '%s'", capabilities_string);
+    mm_obj_dbg (self, "setting new list of capabilities: %s", capabilities_string);
     g_free (capabilities_string);
 
     MM_IFACE_MODEM_GET_INTERFACE (self)->set_current_capabilities (
@@ -2337,14 +2325,14 @@
     if (!current_bands) {
         /* If we can retry, do it */
         if (ctx->retries > 0) {
-            mm_dbg ("couldn't load current bands: '%s' (will retry)", error->message);
+            mm_obj_dbg (self, "couldn't load current bands: %s (will retry)", error->message);
             g_clear_error (&error);
             set_current_bands_reload_schedule (task);
             goto out;
         }
 
         /* Errors when reloading bands won't be critical */
-        mm_warn ("couldn't load current bands: '%s'", error->message);
+        mm_obj_warn (self, "couldn't load current bands: %s", error->message);
         g_clear_error (&error);
         set_current_bands_complete_with_defaults (task);
         goto out;
@@ -2362,7 +2350,7 @@
 
         /* If we can retry, do it */
         if (ctx->retries > 0) {
-            mm_dbg ("reloaded current bands different to the requested ones (will retry)");
+            mm_obj_dbg (self, "reloaded current bands different to the requested ones (will retry)");
             set_current_bands_reload_schedule (task);
             goto out;
         }
@@ -2580,8 +2568,7 @@
     current_bands_array = (mm_common_bands_variant_to_garray (
                               mm_gdbus_modem_get_current_bands (ctx->skeleton)));
     if (mm_common_bands_garray_cmp (ctx->bands_array, current_bands_array)) {
-        mm_dbg ("Requested list of bands (%s) is equal to the current ones, skipping re-set",
-                bands_string);
+        mm_obj_dbg (self, "requested list of bands (%s) is equal to the current ones, skipping re-set", bands_string);
         g_free (bands_string);
         g_array_unref (current_bands_array);
         g_task_return_boolean (task, TRUE);
@@ -2600,8 +2587,7 @@
     if (!validate_bands (ctx->supported_bands_array,
                          ctx->bands_array,
                          &error)) {
-        mm_dbg ("Requested list of bands (%s) cannot be handled",
-                bands_string);
+        mm_obj_dbg (self, "requested list of bands (%s) cannot be handled", bands_string);
         g_free (bands_string);
         g_array_unref (current_bands_array);
         g_task_return_error (task, error);
@@ -2609,7 +2595,7 @@
         return;
     }
 
-    mm_dbg ("Setting new list of bands: '%s'", bands_string);
+    mm_obj_dbg (self, "setting new list of bands: %s", bands_string);
     MM_IFACE_MODEM_GET_INTERFACE (self)->set_current_bands (
         self,
         ctx->bands_array,
@@ -2754,14 +2740,14 @@
                                                                          &error)) {
         /* If we can retry, do it */
         if (ctx->retries > 0) {
-            mm_dbg ("couldn't load current allowed/preferred modes: '%s'", error->message);
+            mm_obj_dbg (self, "couldn't load current allowed/preferred modes: %s", error->message);
             g_error_free (error);
             set_current_modes_reload_schedule (task);
             return;
         }
 
         /* Errors when getting allowed/preferred won't be critical */
-        mm_warn ("couldn't load current allowed/preferred modes: '%s'", error->message);
+        mm_obj_warn (self, "couldn't load current allowed/preferred modes: %s", error->message);
         g_clear_error (&error);
 
         /* If errors getting allowed modes, default to the ones we asked for */
@@ -2782,7 +2768,7 @@
 
         /* If we can retry, do it */
         if (ctx->retries > 0) {
-            mm_dbg ("reloaded current modes different to the requested ones (will retry)");
+            mm_obj_dbg (self, "reloaded current modes different to the requested ones (will retry)");
             set_current_modes_reload_schedule (task);
             return;
         }
@@ -3103,7 +3089,7 @@
 
     mm_base_modem_initialize_finish (self, res, &error);
     if (error) {
-        mm_warn ("Modem reinitialization failed: '%s'", error->message);
+        mm_obj_warn (self, "reinitialization failed: %s", error->message);
         g_error_free (error);
     }
 }
@@ -3294,7 +3280,7 @@
 
     unlock_retries = MM_IFACE_MODEM_GET_INTERFACE (self)->load_unlock_retries_finish (self, res, &error);
     if (!unlock_retries) {
-        mm_warn ("Couldn't load unlock retries: '%s'", error->message);
+        mm_obj_warn (self, "couldn't load unlock retries: %s", error->message);
         g_error_free (error);
     } else {
         /* Update the dictionary in the DBus interface */
@@ -3317,7 +3303,7 @@
     GError *error = NULL;
 
     if (!MM_IFACE_MODEM_GET_INTERFACE (self)->modem_after_sim_unlock_finish (self, res, &error)) {
-        mm_warn ("After SIM unlock failed setup: '%s'", error->message);
+        mm_obj_warn (self, "after SIM unlock failed: %s", error->message);
         g_error_free (error);
     }
 
@@ -3370,11 +3356,11 @@
             }
 
             /* For mixed 3GPP+3GPP2 devices, skip SIM errors */
-            mm_dbg ("Skipping SIM error in 3GPP2-capable device, assuming no lock is needed");
+            mm_obj_dbg (self, "skipping SIM error in 3GPP2-capable device, assuming no lock is needed");
             g_error_free (error);
             ctx->lock = MM_MODEM_LOCK_NONE;
         } else {
-            mm_dbg ("Couldn't check if unlock required: '%s'", error->message);
+            mm_obj_dbg (self, "couldn't check if unlock required: %s", error->message);
             g_error_free (error);
             ctx->lock = MM_MODEM_LOCK_UNKNOWN;
         }
@@ -3431,7 +3417,7 @@
              ctx->lock == MM_MODEM_LOCK_SIM_PUK2)) {
             if (MM_IFACE_MODEM_GET_INTERFACE (self)->modem_after_sim_unlock != NULL &&
                 MM_IFACE_MODEM_GET_INTERFACE (self)->modem_after_sim_unlock_finish != NULL) {
-                mm_dbg ("SIM is ready, running after SIM unlock step...");
+                mm_obj_dbg (self, "SIM is ready, running after SIM unlock step...");
                 MM_IFACE_MODEM_GET_INTERFACE (self)->modem_after_sim_unlock (
                     self,
                     (GAsyncReadyCallback)modem_after_sim_unlock_ready,
@@ -3440,7 +3426,7 @@
             }
 
             /* If no way to run after SIM unlock step, we're done */
-            mm_dbg ("SIM is ready, and no need for the after SIM unlock step...");
+            mm_obj_dbg (self, "SIM is ready, and no need for the after SIM unlock step...");
         }
         ctx->step++;
         /* fall-through */
@@ -3561,7 +3547,7 @@
         return;
     }
 
-    mm_dbg ("Modem set in full-power mode...");
+    mm_obj_dbg (self, "set in full-power mode...");
     mm_gdbus_modem_set_power_state (ctx->skeleton, ctx->power_state);
 
     /* If we have something to do just after power-up, do it */
@@ -3596,7 +3582,7 @@
             mm_gdbus_modem_set_power_state (ctx->skeleton, ctx->previous_real_power_state);
         g_task_return_error (task, error);
     } else {
-        mm_dbg ("Modem set in low-power mode...");
+        mm_obj_dbg (self, "set in low-power mode...");
         mm_gdbus_modem_set_power_state (ctx->skeleton, ctx->power_state);
         g_task_return_boolean (task, TRUE);
     }
@@ -3621,7 +3607,7 @@
             mm_gdbus_modem_set_power_state (ctx->skeleton, ctx->previous_real_power_state);
         g_task_return_error (task, error);
     } else {
-        mm_info ("Modem powered off... may no longer be accessible");
+        mm_obj_info (self, "powered off... may no longer be accessible");
         mm_gdbus_modem_set_power_state (ctx->skeleton, ctx->power_state);
         g_task_return_boolean (task, TRUE);
     }
@@ -3640,8 +3626,8 @@
 
     /* Already done if we're in the desired power state */
     if (ctx->previous_real_power_state == ctx->power_state) {
-        mm_dbg ("No need to change power state: already in '%s' power state",
-                mm_modem_power_state_get_string (ctx->power_state));
+        mm_obj_dbg (self, "no need to change power state: already in '%s' power state",
+                    mm_modem_power_state_get_string (ctx->power_state));
         /* If the real and cached ones are different, set the real one */
         if (ctx->previous_cached_power_state != ctx->previous_real_power_state)
             mm_gdbus_modem_set_power_state (ctx->skeleton, ctx->previous_real_power_state);
@@ -3725,7 +3711,7 @@
 
     ctx->previous_real_power_state = MM_IFACE_MODEM_GET_INTERFACE (self)->load_power_state_finish (self, res, &error);
     if (error) {
-        mm_dbg ("Couldn't reload current power state: %s", error->message);
+        mm_obj_dbg (self, "couldn't reload current power state: %s", error->message);
         g_error_free (error);
         /* Default to the cached one */
         ctx->previous_real_power_state = ctx->previous_cached_power_state;
@@ -3875,7 +3861,7 @@
     GError *error = NULL;
 
     if (!MM_IFACE_MODEM_GET_INTERFACE (self)->check_for_sim_swap_finish (self, res, &error)) {
-        mm_warn ("Error checking if SIM was swapped: '%s'", error->message);
+        mm_obj_warn (self, "failed to check if SIM was swapped: %s", error->message);
         g_error_free (error);
     }
 
@@ -3919,7 +3905,7 @@
     ctx->supported_charsets =
         MM_IFACE_MODEM_GET_INTERFACE (self)->load_supported_charsets_finish (self, res, &error);
     if (error) {
-        mm_warn ("couldn't load Supported Charsets: '%s'", error->message);
+        mm_obj_warn (self, "couldn't load supported charsets: %s", error->message);
         g_error_free (error);
     }
 
@@ -3939,9 +3925,9 @@
     ctx = g_task_get_task_data (task);
 
     if (!MM_IFACE_MODEM_GET_INTERFACE (self)->setup_charset_finish (self, res, &error)) {
-        mm_dbg ("couldn't set charset '%s': '%s'",
-                mm_modem_charset_to_string (*ctx->current_charset),
-                error->message);
+        mm_obj_dbg (self, "couldn't set charset '%s': %s",
+                    mm_modem_charset_to_string (*ctx->current_charset),
+                    error->message);
         g_error_free (error);
 
         /* Will retry step with some other charset type */
@@ -4172,7 +4158,7 @@
         g_free (val);                                                   \
                                                                         \
         if (error) {                                                    \
-            mm_warn ("couldn't load %s: '%s'", DISPLAY, error->message); \
+            mm_obj_warn (self, "couldn't load %s: %s", DISPLAY, error->message); \
             g_error_free (error);                                       \
         }                                                               \
                                                                         \
@@ -4198,7 +4184,7 @@
             MM_IFACE_MODEM_GET_INTERFACE (self)->load_##NAME##_finish (self, res, &error)); \
                                                                         \
         if (error) {                                                    \
-            mm_warn ("couldn't load %s: '%s'", DISPLAY, error->message); \
+            mm_obj_warn (self, "couldn't load %s: %s", DISPLAY, error->message); \
             g_error_free (error);                                       \
         }                                                               \
                                                                         \
@@ -4232,10 +4218,9 @@
                              MM_MOBILE_EQUIPMENT_ERROR_SIM_WRONG)) {
             MMModemCapability caps;
 
-            mm_dbg ("Multimode device without SIM, no 3GPP capabilities");
+            mm_obj_dbg (self, "multimode device without SIM, no 3GPP capabilities");
             caps = mm_gdbus_modem_get_current_capabilities (ctx->skeleton);
-            caps &= ~MM_MODEM_CAPABILITY_GSM_UMTS;
-            caps &= ~MM_MODEM_CAPABILITY_LTE;
+            caps &= ~MM_MODEM_CAPABILITY_3GPP;
 
             /* CDMA-EVDO must still be around */
             g_assert (caps & MM_MODEM_CAPABILITY_CDMA_EVDO);
@@ -4271,24 +4256,35 @@
         return;
     }
 
-    /* If LTE capability is reported, enable EPS network registration checks */
+    /* By default CS/PS/CDMA1X/EVDO network registration checks are the only
+     * ones enabled, so fix them up based on capabilities, enabling EPS or 5GS
+     * checks if required, and disabling CS/PS/CDMA1X/EVDO if required. */
     if (caps & MM_MODEM_CAPABILITY_LTE) {
-        mm_dbg ("Setting EPS network as supported");
+        mm_obj_dbg (self, "setting EPS network as supported");
         g_object_set (G_OBJECT (self),
                       MM_IFACE_MODEM_3GPP_EPS_NETWORK_SUPPORTED, TRUE,
                       NULL);
     }
-
-    /* If LTE capability is the only one reported, disable all other network registration checks */
-    if (caps == MM_MODEM_CAPABILITY_LTE) {
-        mm_dbg ("Setting CS/PS/CDMA1x/EVDO networks as unsupported");
+    if (caps & MM_MODEM_CAPABILITY_5GNR) {
+        mm_obj_dbg (self, "setting 5GS network as supported");
         g_object_set (G_OBJECT (self),
-                      MM_IFACE_MODEM_3GPP_CS_NETWORK_SUPPORTED,     FALSE,
-                      MM_IFACE_MODEM_3GPP_PS_NETWORK_SUPPORTED,     FALSE,
+                      MM_IFACE_MODEM_3GPP_5GS_NETWORK_SUPPORTED, TRUE,
+                      NULL);
+    }
+    if (!(caps & MM_MODEM_CAPABILITY_CDMA_EVDO)) {
+        mm_obj_dbg (self, "setting CDMA1x/EVDO networks as unsupported");
+        g_object_set (G_OBJECT (self),
                       MM_IFACE_MODEM_CDMA_CDMA1X_NETWORK_SUPPORTED, FALSE,
                       MM_IFACE_MODEM_CDMA_EVDO_NETWORK_SUPPORTED,   FALSE,
                       NULL);
     }
+    if (!(caps & MM_MODEM_CAPABILITY_GSM_UMTS)) {
+        mm_obj_dbg (self, "setting CS/PS networks as unsupported");
+        g_object_set (G_OBJECT (self),
+                      MM_IFACE_MODEM_3GPP_CS_NETWORK_SUPPORTED, FALSE,
+                      MM_IFACE_MODEM_3GPP_PS_NETWORK_SUPPORTED, FALSE,
+                      NULL);
+    }
 
     /* Update current caps right away, even if we may fix them during the
      * multimode device check. No big deal in updating them twice, as we're not
@@ -4297,9 +4293,8 @@
 
     /* If the device is a multimode device (3GPP+3GPP2) check whether we have a
      * SIM or not. */
-    if (caps & MM_MODEM_CAPABILITY_CDMA_EVDO &&
-        (caps & MM_MODEM_CAPABILITY_GSM_UMTS || caps & MM_MODEM_CAPABILITY_LTE)) {
-        mm_dbg ("Checking if multimode device has a SIM...");
+    if ((caps & MM_MODEM_CAPABILITY_CDMA_EVDO) && (caps & MM_MODEM_CAPABILITY_3GPP)) {
+        mm_obj_dbg (self, "checking if multimode device has a SIM...");
         internal_load_unlock_required (
             self,
             (GAsyncReadyCallback)current_capabilities_internal_load_unlock_required_ready,
@@ -4341,12 +4336,12 @@
     interface_initialization_step (task);
 }
 
-STR_REPLY_READY_FN (manufacturer, "Manufacturer")
-STR_REPLY_READY_FN (model, "Model")
-STR_REPLY_READY_FN (revision, "Revision")
-STR_REPLY_READY_FN (hardware_revision, "HardwareRevision")
-STR_REPLY_READY_FN (equipment_identifier, "Equipment Identifier")
-STR_REPLY_READY_FN (device_identifier, "Device Identifier")
+STR_REPLY_READY_FN (manufacturer, "manufacturer")
+STR_REPLY_READY_FN (model, "model")
+STR_REPLY_READY_FN (revision, "revision")
+STR_REPLY_READY_FN (hardware_revision, "hardware revision")
+STR_REPLY_READY_FN (equipment_identifier, "equipment identifier")
+STR_REPLY_READY_FN (device_identifier, "device identifier")
 
 static void
 load_supported_modes_ready (MMIfaceModem *self,
@@ -4367,7 +4362,7 @@
     }
 
     if (error) {
-        mm_warn ("couldn't load Supported Modes: '%s'", error->message);
+        mm_obj_warn (self, "couldn't load supported modes: %s", error->message);
         g_error_free (error);
     }
 
@@ -4396,7 +4391,7 @@
     }
 
     if (error) {
-        mm_warn ("couldn't load Supported Bands: '%s'", error->message);
+        mm_obj_warn (self, "couldn't load supported bands: %s", error->message);
         g_error_free (error);
     }
 
@@ -4422,7 +4417,7 @@
         mm_gdbus_modem_set_supported_ip_families (ctx->skeleton, ip_families);
 
     if (error) {
-        mm_warn ("couldn't load Supported IP families: '%s'", error->message);
+        mm_obj_warn (self, "couldn't load supported IP families: %s", error->message);
         g_error_free (error);
     }
 
@@ -4431,7 +4426,7 @@
     interface_initialization_step (task);
 }
 
-UINT_REPLY_READY_FN (power_state, "Power State")
+UINT_REPLY_READY_FN (power_state, "power state")
 
 static void
 modem_update_lock_info_ready (MMIfaceModem *self,
@@ -4471,7 +4466,7 @@
 
     sim = MM_IFACE_MODEM_GET_INTERFACE (self)->create_sim_finish (self, res, &error);
     if (error) {
-        mm_warn ("couldn't create SIM: '%s'", error->message);
+        mm_obj_warn (self, "couldn't create SIM: %s", error->message);
         g_task_return_error (task, error);
         g_object_unref (task);
         return;
@@ -4500,14 +4495,16 @@
                   GAsyncResult *res,
                   GTask *task)
 {
+    MMIfaceModem          *self;
     InitializationContext *ctx;
-    GError *error = NULL;
+    GError                *error = NULL;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     if (!mm_base_sim_initialize_finish (sim, res, &error)) {
-        mm_warn ("SIM re-initialization failed: '%s'",
-                 error ? error->message : "Unknown error");
+        mm_obj_warn (self, "SIM re-initialization failed: %s",
+                     error ? error->message : "Unknown error");
         g_clear_error (&error);
     }
 
@@ -4527,7 +4524,7 @@
     ctx = g_task_get_task_data (task);
 
     if (!MM_IFACE_MODEM_GET_INTERFACE (self)->setup_carrier_config_finish (self, res, &error)) {
-        mm_warn ("couldn't setup carrier config: '%s'", error->message);
+        mm_obj_warn (self, "couldn't setup carrier config: %s", error->message);
         g_error_free (error);
     }
 
@@ -4549,7 +4546,7 @@
     ctx = g_task_get_task_data (task);
 
     if (!MM_IFACE_MODEM_GET_INTERFACE (self)->load_carrier_config_finish (self, res, &name, &revision, &error)) {
-        mm_warn ("couldn't load carrier config: '%s'", error->message);
+        mm_obj_warn (self, "couldn't load carrier config: %s", error->message);
         g_error_free (error);
     } else {
         mm_gdbus_modem_set_carrier_configuration          (ctx->skeleton, name);
@@ -4591,7 +4588,7 @@
 
     str_list = MM_IFACE_MODEM_GET_INTERFACE (self)->load_own_numbers_finish (self, res, &error);
     if (error) {
-        mm_warn ("couldn't load list of Own Numbers: '%s'", error->message);
+        mm_obj_warn (self, "couldn't load list of own numbers: %s", error->message);
         g_error_free (error);
     }
 
@@ -4623,7 +4620,7 @@
                                                                          &preferred,
                                                                          &error)) {
         /* Errors when getting allowed/preferred won't be critical */
-        mm_warn ("couldn't load current allowed/preferred modes: '%s'", error->message);
+        mm_obj_warn (self, "couldn't load current allowed/preferred modes: %s", error->message);
         g_error_free (error);
     } else
         mm_gdbus_modem_set_current_modes (ctx->skeleton, g_variant_new ("(uu)", allowed, preferred));
@@ -4647,7 +4644,7 @@
     current_bands = MM_IFACE_MODEM_GET_INTERFACE (self)->load_current_bands_finish (self, res, &error);
     if (!current_bands) {
         /* Errors when getting current bands won't be critical */
-        mm_warn ("couldn't load current Bands: '%s'", error->message);
+        mm_obj_warn (self, "couldn't load current bands: %s", error->message);
         g_error_free (error);
     } else {
         GArray *filtered_bands;
@@ -4688,10 +4685,10 @@
 
     MM_IFACE_MODEM_GET_INTERFACE (self)->setup_sim_hot_swap_finish (self, res, &error);
     if (error) {
-        mm_warn ("Iface modem: SIM hot swap setup failed: '%s'", error->message);
+        mm_obj_warn (self, "SIM hot swap setup failed: %s", error->message);
         g_error_free (error);
     } else {
-        mm_dbg ("Iface modem: SIM hot swap setup succeeded");
+        mm_obj_dbg (self, "SIM hot swap setup succeeded");
         g_object_set (self,
                       MM_IFACE_MODEM_SIM_HOT_SWAP_CONFIGURED, TRUE,
                       NULL);
@@ -4853,7 +4850,7 @@
             /* The maximum number of available/connected modems is guessed from
              * the size of the data ports list. */
             n = g_list_length (mm_base_modem_peek_data_ports (MM_BASE_MODEM (self)));
-            mm_dbg ("Modem allows up to %u bearers", n);
+            mm_obj_dbg (self, "allowed up to %u bearers", n);
 
             /* Create new default list */
             list = mm_bearer_list_new (n, n);
@@ -5158,9 +5155,9 @@
             /* If we have a SIM object, and carrier config switching is supported,
              * validate whether we're already using the best config or not. */
             if (!sim)
-                mm_dbg ("not setting up carrier config: SIM not found");
+                mm_obj_dbg (self, "not setting up carrier config: SIM not found");
             else if (!carrier_config_mapping)
-                mm_dbg ("not setting up carrier config: mapping file not configured");
+                mm_obj_dbg (self, "not setting up carrier config: mapping file not configured");
             else {
                 const gchar *imsi;
 
@@ -5175,7 +5172,7 @@
                     g_free (carrier_config_mapping);
                     return;
                 }
-                mm_warn ("couldn't setup carrier config: unknown IMSI");
+                mm_obj_warn (self, "couldn't setup carrier config: unknown IMSI");
             }
             g_clear_object (&sim);
             g_free (carrier_config_mapping);
@@ -5529,6 +5526,22 @@
             FALSE);
 }
 
+gboolean
+mm_iface_modem_is_5g (MMIfaceModem *self)
+{
+    return find_supported_mode (self, MM_MODEM_MODE_5G, NULL);
+}
+
+gboolean
+mm_iface_modem_is_5g_only (MMIfaceModem *self)
+{
+    gboolean only;
+
+    return (find_supported_mode (self, MM_MODEM_MODE_5G, &only) ?
+            only :
+            FALSE);
+}
+
 /*****************************************************************************/
 
 MMModemCapability
@@ -5558,7 +5571,7 @@
 gboolean
 mm_iface_modem_is_3gpp_lte (MMIfaceModem *self)
 {
-    return (mm_iface_modem_get_current_capabilities (self) & MM_MODEM_CAPABILITY_3GPP_LTE);
+    return (mm_iface_modem_get_current_capabilities (self) & MM_MODEM_CAPABILITY_LTE);
 }
 
 gboolean
@@ -5577,21 +5590,9 @@
 }
 
 gboolean
-mm_iface_modem_is_3gpp_lte_only (MMIfaceModem *self)
-{
-    MMModemCapability capabilities;
-
-    capabilities = mm_iface_modem_get_current_capabilities (self);
-    return (capabilities & MM_MODEM_CAPABILITY_3GPP_LTE) && !((MM_MODEM_CAPABILITY_3GPP_LTE ^ capabilities) & capabilities);
-}
-
-gboolean
 mm_iface_modem_is_cdma_only (MMIfaceModem *self)
 {
-    MMModemCapability capabilities;
-
-    capabilities = mm_iface_modem_get_current_capabilities (self);
-    return (capabilities & MM_MODEM_CAPABILITY_CDMA_EVDO) && !((MM_MODEM_CAPABILITY_CDMA_EVDO ^ capabilities) & capabilities);
+    return (mm_iface_modem_get_current_capabilities (self) == MM_MODEM_CAPABILITY_CDMA_EVDO);
 }
 
 /*****************************************************************************/
diff --git a/src/mm-iface-modem.h b/src/mm-iface-modem.h
index 4cb6860..541d6f6 100644
--- a/src/mm-iface-modem.h
+++ b/src/mm-iface-modem.h
@@ -391,7 +391,6 @@
 gboolean          mm_iface_modem_is_3gpp                  (MMIfaceModem *self);
 gboolean          mm_iface_modem_is_3gpp_only             (MMIfaceModem *self);
 gboolean          mm_iface_modem_is_3gpp_lte              (MMIfaceModem *self);
-gboolean          mm_iface_modem_is_3gpp_lte_only         (MMIfaceModem *self);
 gboolean          mm_iface_modem_is_cdma                  (MMIfaceModem *self);
 gboolean          mm_iface_modem_is_cdma_only             (MMIfaceModem *self);
 
@@ -402,6 +401,8 @@
 gboolean mm_iface_modem_is_3g_only (MMIfaceModem *self);
 gboolean mm_iface_modem_is_4g      (MMIfaceModem *self);
 gboolean mm_iface_modem_is_4g_only (MMIfaceModem *self);
+gboolean mm_iface_modem_is_5g      (MMIfaceModem *self);
+gboolean mm_iface_modem_is_5g_only (MMIfaceModem *self);
 
 /* Helpers to query properties */
 const gchar *mm_iface_modem_get_model          (MMIfaceModem  *self);
diff --git a/src/mm-log-object.c b/src/mm-log-object.c
new file mode 100644
index 0000000..ed41355
--- /dev/null
+++ b/src/mm-log-object.c
@@ -0,0 +1,89 @@
+/* -*- 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) 2020 Aleksander Morgado <aleksander@aleksander.es>
+ */
+
+#include "mm-log-object.h"
+
+G_DEFINE_INTERFACE (MMLogObject, mm_log_object, G_TYPE_OBJECT)
+
+/*****************************************************************************/
+/* Private data context */
+
+#define PRIVATE_TAG "log-object"
+static GQuark private_quark;
+
+typedef struct {
+  gchar *owner_id;
+  gchar *id;
+} Private;
+
+static void
+private_free (Private *priv)
+{
+    g_free (priv->owner_id);
+    g_free (priv->id);
+    g_slice_free (Private, priv);
+}
+
+static Private *
+get_private (MMLogObject *self)
+{
+    Private *priv;
+
+    if (G_UNLIKELY (!private_quark))
+        private_quark = g_quark_from_static_string (PRIVATE_TAG);
+
+    priv = g_object_get_qdata (G_OBJECT (self), private_quark);
+    if (!priv) {
+        priv = g_slice_new0 (Private);
+        g_object_set_qdata_full (G_OBJECT (self), private_quark, priv, (GDestroyNotify)private_free);
+    }
+
+    return priv;
+}
+
+const gchar *
+mm_log_object_get_id (MMLogObject *self)
+{
+    Private *priv;
+
+    priv = get_private (self);
+    if (!priv->id) {
+        gchar *self_id;
+
+        self_id = MM_LOG_OBJECT_GET_IFACE (self)->build_id (self);
+        if (priv->owner_id) {
+            priv->id = g_strdup_printf ("%s/%s", priv->owner_id, self_id);
+            g_free (self_id);
+        } else
+            priv->id = self_id;
+    }
+    return priv->id;
+}
+
+void
+mm_log_object_set_owner_id (MMLogObject *self,
+                            const gchar *owner_id)
+{
+    Private *priv;
+
+    priv = get_private (self);
+    g_free (priv->owner_id);
+    priv->owner_id = g_strdup (owner_id);
+}
+
+static void
+mm_log_object_default_init (MMLogObjectInterface *iface)
+{
+}
diff --git a/src/mm-log-object.h b/src/mm-log-object.h
new file mode 100644
index 0000000..21ffc05
--- /dev/null
+++ b/src/mm-log-object.h
@@ -0,0 +1,38 @@
+/* -*- 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) 2020 Aleksander Morgado <aleksander@aleksander.es>
+ */
+
+#ifndef MM_LOG_OBJECT_H
+#define MM_LOG_OBJECT_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include "mm-log.h"
+
+#define MM_TYPE_LOG_OBJECT mm_log_object_get_type ()
+G_DECLARE_INTERFACE (MMLogObject, mm_log_object, MM, LOG_OBJECT, GObject)
+
+struct _MMLogObjectInterface
+{
+  GTypeInterface g_iface;
+
+  gchar * (* build_id) (MMLogObject *self);
+};
+
+const gchar *mm_log_object_get_id       (MMLogObject *self);
+void         mm_log_object_set_owner_id (MMLogObject *self,
+                                         const gchar *owner_id);
+
+#endif /* MM_LOG_OBJECT_H */
diff --git a/src/mm-log-test.h b/src/mm-log-test.h
new file mode 100644
index 0000000..22493d6
--- /dev/null
+++ b/src/mm-log-test.h
@@ -0,0 +1,46 @@
+/* -*- 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) 2020 Aleksander Morgado <aleksander@aleksander.es>
+ */
+
+#ifndef MM_LOG_TEST_H
+#define MM_LOG_TEST_H
+
+#include <glib.h>
+#include "mm-log.h"
+
+/* This is a common logging method to be used by all test applications */
+
+void
+_mm_log (gpointer     obj,
+         const gchar *module,
+         const gchar *loc,
+         const gchar *func,
+         guint32      level,
+         const gchar *fmt,
+         ...)
+{
+    va_list  args;
+    gchar   *msg;
+
+    if (!g_test_verbose ())
+        return;
+
+    va_start (args, fmt);
+    msg = g_strdup_vprintf (fmt, args);
+    va_end (args);
+    g_print ("%s\n", msg);
+    g_free (msg);
+}
+
+#endif /* MM_LOG_TEST_H */
diff --git a/src/mm-log.c b/src/mm-log.c
index 470f188..658e0c1 100644
--- a/src/mm-log.c
+++ b/src/mm-log.c
@@ -10,7 +10,8 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details:
  *
- * Copyright (C) 2011 Red Hat, Inc.
+ * Copyright (C) 2011-2020 Red Hat, Inc.
+ * Copyright (C) 2020 Aleksander Morgado <aleksander@aleksander.es>
  */
 
 #define _GNU_SOURCE
@@ -41,6 +42,7 @@
 #endif
 
 #include "mm-log.h"
+#include "mm-log-object.h"
 
 enum {
     TS_FLAG_NONE = 0,
@@ -200,10 +202,12 @@
 #endif
 
 void
-_mm_log (const char *loc,
-         const char *func,
-         MMLogLevel level,
-         const char *fmt,
+_mm_log (gpointer     obj,
+         const gchar *module,
+         const gchar *loc,
+         const gchar *func,
+         MMLogLevel   level,
+         const gchar *fmt,
          ...)
 {
     va_list args;
@@ -243,6 +247,11 @@
     g_string_append_printf (msgbuf, "[%s] %s(): ", loc, func);
 #endif
 
+    if (obj)
+        g_string_append_printf (msgbuf, "[%s] ", mm_log_object_get_id (MM_LOG_OBJECT (obj)));
+    if (module)
+        g_string_append_printf (msgbuf, "(%s) ", module);
+
     va_start (args, fmt);
     g_string_append_vprintf (msgbuf, fmt, args);
     va_end (args);
diff --git a/src/mm-log.h b/src/mm-log.h
index d9f11f2..d0b5c60 100644
--- a/src/mm-log.h
+++ b/src/mm-log.h
@@ -10,7 +10,8 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details:
  *
- * Copyright (C) 2011 Red Hat, Inc.
+ * Copyright (C) 2011-2020 Red Hat, Inc.
+ * Copyright (C) 2020 Aleksander Morgado <aleksander@aleksander.es>
  */
 
 #ifndef MM_LOG_H
@@ -26,26 +27,31 @@
     MM_LOG_LEVEL_DEBUG = 0x00000008
 } MMLogLevel;
 
-#define mm_err(...) \
-    _mm_log (G_STRLOC, G_STRFUNC, MM_LOG_LEVEL_ERR, ## __VA_ARGS__ )
+#if !defined MM_MODULE_NAME
+# define MM_MODULE_NAME (const gchar *)NULL
+#endif
 
-#define mm_warn(...) \
-    _mm_log (G_STRLOC, G_STRFUNC, MM_LOG_LEVEL_WARN, ## __VA_ARGS__ )
+#define mm_obj_err(obj, ...)  _mm_log (obj, MM_MODULE_NAME, G_STRLOC, G_STRFUNC, MM_LOG_LEVEL_ERR,   ## __VA_ARGS__ )
+#define mm_obj_warn(obj, ...) _mm_log (obj, MM_MODULE_NAME, G_STRLOC, G_STRFUNC, MM_LOG_LEVEL_WARN,  ## __VA_ARGS__ )
+#define mm_obj_info(obj, ...) _mm_log (obj, MM_MODULE_NAME, G_STRLOC, G_STRFUNC, MM_LOG_LEVEL_INFO,  ## __VA_ARGS__ )
+#define mm_obj_dbg(obj, ...)  _mm_log (obj, MM_MODULE_NAME, G_STRLOC, G_STRFUNC, MM_LOG_LEVEL_DEBUG, ## __VA_ARGS__ )
 
-#define mm_info(...) \
-    _mm_log (G_STRLOC, G_STRFUNC, MM_LOG_LEVEL_INFO, ## __VA_ARGS__ )
+/* only allow using non-object logging API if explicitly requested
+ * (e.g. in the main daemon source) */
+#if defined MM_LOG_NO_OBJECT
+# define mm_err(...)  mm_obj_err  (NULL, ## __VA_ARGS__ )
+# define mm_warn(...) mm_obj_warn (NULL, ## __VA_ARGS__ )
+# define mm_info(...) mm_obj_info (NULL, ## __VA_ARGS__ )
+# define mm_dbg(...)  mm_obj_dbg  (NULL, ## __VA_ARGS__ )
+#endif
 
-#define mm_dbg(...) \
-    _mm_log (G_STRLOC, G_STRFUNC, MM_LOG_LEVEL_DEBUG, ## __VA_ARGS__ )
-
-#define mm_log(level, ...) \
-    _mm_log (G_STRLOC, G_STRFUNC, level, ## __VA_ARGS__ )
-
-void _mm_log (const char *loc,
-              const char *func,
-              MMLogLevel level,
-              const char *fmt,
-              ...)  __attribute__((__format__ (__printf__, 4, 5)));
+void _mm_log (gpointer     obj,
+              const gchar *module,
+              const gchar *loc,
+              const gchar *func,
+              MMLogLevel   level,
+              const gchar *fmt,
+              ...)  __attribute__((__format__ (__printf__, 6, 7)));
 
 gboolean mm_log_set_level (const char *level, GError **error);
 
diff --git a/src/mm-modem-helpers-mbim.c b/src/mm-modem-helpers-mbim.c
index e1adcca..6e4013c 100644
--- a/src/mm-modem-helpers-mbim.c
+++ b/src/mm-modem-helpers-mbim.c
@@ -17,7 +17,7 @@
 #include "mm-modem-helpers.h"
 #include "mm-enums-types.h"
 #include "mm-errors-types.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 /*****************************************************************************/
 
@@ -394,6 +394,7 @@
 
 MbimAuthProtocol
 mm_bearer_allowed_auth_to_mbim_auth_protocol (MMBearerAllowedAuth   bearer_auth,
+                                              gpointer              log_object,
                                               GError              **error)
 {
     gchar *str;
@@ -401,7 +402,7 @@
     /* NOTE: the input is a BITMASK, so we try to find a "best match" */
 
     if (bearer_auth == MM_BEARER_ALLOWED_AUTH_UNKNOWN) {
-        mm_dbg ("Using default (PAP) authentication method");
+        mm_obj_dbg (log_object, "using default (PAP) authentication method");
         return MBIM_AUTH_PROTOCOL_PAP;
     }
     if (bearer_auth & MM_BEARER_ALLOWED_AUTH_PAP)
diff --git a/src/mm-modem-helpers-mbim.h b/src/mm-modem-helpers-mbim.h
index 090b764..c70b9a4 100644
--- a/src/mm-modem-helpers-mbim.h
+++ b/src/mm-modem-helpers-mbim.h
@@ -44,6 +44,7 @@
 
 MMBearerAllowedAuth mm_bearer_allowed_auth_from_mbim_auth_protocol (MbimAuthProtocol      auth_protocol);
 MbimAuthProtocol    mm_bearer_allowed_auth_to_mbim_auth_protocol   (MMBearerAllowedAuth   bearer_auth,
+                                                                    gpointer              log_object,
                                                                     GError              **error);
 MMBearerIpFamily    mm_bearer_ip_family_from_mbim_context_ip_type  (MbimContextIpType     ip_type);
 MbimContextIpType   mm_bearer_ip_family_to_mbim_context_ip_type    (MMBearerIpFamily      ip_family,
diff --git a/src/mm-modem-helpers-qmi.c b/src/mm-modem-helpers-qmi.c
index e4a3c58..9abd296 100644
--- a/src/mm-modem-helpers-qmi.c
+++ b/src/mm-modem-helpers-qmi.c
@@ -22,12 +22,13 @@
 #include "mm-modem-helpers-qmi.h"
 #include "mm-modem-helpers.h"
 #include "mm-enums-types.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 /*****************************************************************************/
 
 MMModemCapability
-mm_modem_capability_from_qmi_radio_interface (QmiDmsRadioInterface network)
+mm_modem_capability_from_qmi_radio_interface (QmiDmsRadioInterface network,
+                                              gpointer             log_object)
 {
     switch (network) {
     case QMI_DMS_RADIO_INTERFACE_CDMA20001X:
@@ -41,9 +42,9 @@
     case QMI_DMS_RADIO_INTERFACE_LTE:
         return MM_MODEM_CAPABILITY_LTE;
     case QMI_DMS_RADIO_INTERFACE_5GNR:
+        return MM_MODEM_CAPABILITY_5GNR;
     default:
-        mm_warn ("Unhandled QMI radio interface (%u)",
-                 (guint)network);
+        mm_obj_warn (log_object, "unhandled QMI radio interface '%u'", (guint)network);
         return MM_MODEM_CAPABILITY_NONE;
     }
 }
@@ -51,7 +52,8 @@
 /*****************************************************************************/
 
 MMModemMode
-mm_modem_mode_from_qmi_radio_interface (QmiDmsRadioInterface network)
+mm_modem_mode_from_qmi_radio_interface (QmiDmsRadioInterface network,
+                                        gpointer             log_object)
 {
     switch (network) {
     case QMI_DMS_RADIO_INTERFACE_CDMA20001X:
@@ -65,9 +67,9 @@
     case QMI_DMS_RADIO_INTERFACE_LTE:
         return MM_MODEM_MODE_4G;
     case QMI_DMS_RADIO_INTERFACE_5GNR:
+        return MM_MODEM_MODE_5G;
     default:
-        mm_warn ("Unhandled QMI radio interface (%u)",
-                 (guint)network);
+        mm_obj_warn (log_object, "unhandled QMI radio interface '%u'", (guint)network);
         return MM_MODEM_MODE_NONE;
     }
 }
@@ -217,8 +219,9 @@
 };
 
 static void
-dms_add_qmi_bands (GArray *mm_bands,
-                   QmiDmsBandCapability qmi_bands)
+dms_add_qmi_bands (GArray               *mm_bands,
+                   QmiDmsBandCapability  qmi_bands,
+                   gpointer              log_object)
 {
     static QmiDmsBandCapability qmi_bands_expected = 0;
     QmiDmsBandCapability not_expected;
@@ -236,11 +239,10 @@
     /* Log about the bands that cannot be represented in ModemManager */
     not_expected = ((qmi_bands_expected ^ qmi_bands) & qmi_bands);
     if (not_expected) {
-        gchar *aux;
+        g_autofree gchar *aux = NULL;
 
         aux = qmi_dms_band_capability_build_string_from_mask (not_expected);
-        mm_dbg ("Cannot add the following bands: '%s'", aux);
-        g_free (aux);
+        mm_obj_dbg (log_object, "cannot add the following bands: '%s'", aux);
     }
 
     /* And add the expected ones */
@@ -314,8 +316,9 @@
 }
 
 static void
-dms_add_extended_qmi_lte_bands (GArray *mm_bands,
-                                GArray *extended_qmi_bands)
+dms_add_extended_qmi_lte_bands (GArray   *mm_bands,
+                                GArray   *extended_qmi_bands,
+                                gpointer  log_object)
 {
     guint i;
 
@@ -334,7 +337,7 @@
          * MM_MODEM_BAND_EUTRAN_71 = 101
          */
         if (val < 1 || val > 71)
-            mm_dbg ("Unexpected LTE band supported by module: EUTRAN %u", val);
+            mm_obj_dbg (log_object, "unexpected LTE band supported by module: EUTRAN %u", val);
         else {
             MMModemBand band;
 
@@ -345,17 +348,18 @@
 }
 
 GArray *
-mm_modem_bands_from_qmi_band_capabilities (QmiDmsBandCapability qmi_bands,
-                                           QmiDmsLteBandCapability qmi_lte_bands,
-                                           GArray *extended_qmi_lte_bands)
+mm_modem_bands_from_qmi_band_capabilities (QmiDmsBandCapability     qmi_bands,
+                                           QmiDmsLteBandCapability  qmi_lte_bands,
+                                           GArray                  *extended_qmi_lte_bands,
+                                           gpointer                 log_object)
 {
     GArray *mm_bands;
 
     mm_bands = g_array_new (FALSE, FALSE, sizeof (MMModemBand));
-    dms_add_qmi_bands (mm_bands, qmi_bands);
+    dms_add_qmi_bands (mm_bands, qmi_bands, log_object);
 
     if (extended_qmi_lte_bands)
-        dms_add_extended_qmi_lte_bands (mm_bands, extended_qmi_lte_bands);
+        dms_add_extended_qmi_lte_bands (mm_bands, extended_qmi_lte_bands, log_object);
     else
         dms_add_qmi_lte_bands (mm_bands, qmi_lte_bands);
 
@@ -421,8 +425,9 @@
 };
 
 static void
-nas_add_qmi_bands (GArray *mm_bands,
-                   QmiNasBandPreference qmi_bands)
+nas_add_qmi_bands (GArray               *mm_bands,
+                   QmiNasBandPreference  qmi_bands,
+                   gpointer              log_object)
 {
     static QmiNasBandPreference qmi_bands_expected = 0;
     QmiNasBandPreference not_expected;
@@ -440,11 +445,10 @@
     /* Log about the bands that cannot be represented in ModemManager */
     not_expected = ((qmi_bands_expected ^ qmi_bands) & qmi_bands);
     if (not_expected) {
-        gchar *aux;
+        g_autofree gchar *aux = NULL;
 
         aux = qmi_nas_band_preference_build_string_from_mask (not_expected);
-        mm_dbg ("Cannot add the following bands: '%s'", aux);
-        g_free (aux);
+        mm_obj_dbg (log_object, "cannot add the following bands: '%s'", aux);
     }
 
     /* And add the expected ones */
@@ -518,9 +522,10 @@
 }
 
 static void
-nas_add_extended_qmi_lte_bands (GArray *mm_bands,
+nas_add_extended_qmi_lte_bands (GArray        *mm_bands,
                                 const guint64 *extended_qmi_lte_bands,
-                                guint extended_qmi_lte_bands_size)
+                                guint          extended_qmi_lte_bands_size,
+                                gpointer       log_object)
 {
     guint i;
 
@@ -542,7 +547,7 @@
              * MM_MODEM_BAND_EUTRAN_71 = 101
              */
             if (val < 1 || val > 71)
-                mm_dbg ("Unexpected LTE band supported by module: EUTRAN %u", val);
+                mm_obj_dbg (log_object, "unexpected LTE band supported by module: EUTRAN %u", val);
             else {
                 MMModemBand band;
 
@@ -554,18 +559,19 @@
 }
 
 GArray *
-mm_modem_bands_from_qmi_band_preference (QmiNasBandPreference qmi_bands,
-                                         QmiNasLteBandPreference qmi_lte_bands,
-                                         const guint64 *extended_qmi_lte_bands,
-                                         guint extended_qmi_lte_bands_size)
+mm_modem_bands_from_qmi_band_preference (QmiNasBandPreference     qmi_bands,
+                                         QmiNasLteBandPreference  qmi_lte_bands,
+                                         const guint64           *extended_qmi_lte_bands,
+                                         guint                    extended_qmi_lte_bands_size,
+                                         gpointer                 log_object)
 {
     GArray *mm_bands;
 
     mm_bands = g_array_new (FALSE, FALSE, sizeof (MMModemBand));
-    nas_add_qmi_bands (mm_bands, qmi_bands);
+    nas_add_qmi_bands (mm_bands, qmi_bands, log_object);
 
     if (extended_qmi_lte_bands && extended_qmi_lte_bands_size)
-        nas_add_extended_qmi_lte_bands (mm_bands, extended_qmi_lte_bands, extended_qmi_lte_bands_size);
+        nas_add_extended_qmi_lte_bands (mm_bands, extended_qmi_lte_bands, extended_qmi_lte_bands_size, log_object);
     else
         nas_add_qmi_lte_bands (mm_bands, qmi_lte_bands);
 
@@ -573,11 +579,12 @@
 }
 
 void
-mm_modem_bands_to_qmi_band_preference (GArray *mm_bands,
-                                       QmiNasBandPreference *qmi_bands,
+mm_modem_bands_to_qmi_band_preference (GArray                  *mm_bands,
+                                       QmiNasBandPreference    *qmi_bands,
                                        QmiNasLteBandPreference *qmi_lte_bands,
-                                       guint64 *extended_qmi_lte_bands,
-                                       guint extended_qmi_lte_bands_size)
+                                       guint64                 *extended_qmi_lte_bands,
+                                       guint                    extended_qmi_lte_bands_size,
+                                       gpointer                 log_object)
 {
     guint i;
 
@@ -618,8 +625,8 @@
                 }
 
                 if (j == G_N_ELEMENTS (nas_lte_bands_map))
-                    mm_dbg ("Cannot add the following LTE band: '%s'",
-                            mm_modem_band_get_string (band));
+                    mm_obj_dbg (log_object, "cannot add the following LTE band: '%s'",
+                                mm_modem_band_get_string (band));
             }
         } else {
             /* Add non-LTE band preference */
@@ -633,8 +640,8 @@
             }
 
             if (j == G_N_ELEMENTS (nas_bands_map))
-                mm_dbg ("Cannot add the following band: '%s'",
-                        mm_modem_band_get_string (band));
+                mm_obj_dbg (log_object, "cannot add the following band: '%s'",
+                            mm_modem_band_get_string (band));
         }
     }
 }
@@ -788,6 +795,7 @@
     case QMI_NAS_RADIO_INTERFACE_LTE:
         return MM_MODEM_ACCESS_TECHNOLOGY_LTE;
     case QMI_NAS_RADIO_INTERFACE_5GNR:
+        return MM_MODEM_ACCESS_TECHNOLOGY_5GNR;
     case QMI_NAS_RADIO_INTERFACE_UNKNOWN:
     case QMI_NAS_RADIO_INTERFACE_TD_SCDMA:
     case QMI_NAS_RADIO_INTERFACE_AMPS:
@@ -885,6 +893,7 @@
         case QMI_NAS_RADIO_INTERFACE_LTE:
             return MM_MODEM_MODE_4G;
         case QMI_NAS_RADIO_INTERFACE_5GNR:
+            return MM_MODEM_MODE_5G;
         case QMI_NAS_RADIO_INTERFACE_NONE:
         case QMI_NAS_RADIO_INTERFACE_AMPS:
         case QMI_NAS_RADIO_INTERFACE_TD_SCDMA:
@@ -970,6 +979,9 @@
     if (qmi & QMI_NAS_RAT_MODE_PREFERENCE_LTE)
         mode |= MM_MODEM_MODE_4G;
 
+    if (qmi & QMI_NAS_RAT_MODE_PREFERENCE_5GNR)
+        mode |= MM_MODEM_MODE_5G;
+
     return mode;
 }
 
@@ -997,6 +1009,9 @@
 
         if (mode & MM_MODEM_MODE_4G)
             pref |= QMI_NAS_RAT_MODE_PREFERENCE_LTE;
+
+        if (mode & MM_MODEM_MODE_5G)
+            pref |= QMI_NAS_RAT_MODE_PREFERENCE_5GNR;
     }
 
     return pref;
@@ -1024,7 +1039,8 @@
     if (qmi & QMI_NAS_RAT_MODE_PREFERENCE_LTE)
         caps |= MM_MODEM_CAPABILITY_LTE;
 
-    /* FIXME: LTE Advanced? */
+    if (qmi & QMI_NAS_RAT_MODE_PREFERENCE_5GNR)
+        caps |= MM_MODEM_CAPABILITY_5GNR;
 
     return caps;
 }
@@ -1047,6 +1063,9 @@
     if (caps & MM_MODEM_CAPABILITY_LTE)
         qmi |= QMI_NAS_RAT_MODE_PREFERENCE_LTE;
 
+    if (caps & MM_MODEM_CAPABILITY_5GNR)
+        qmi |= QMI_NAS_RAT_MODE_PREFERENCE_5GNR;
+
     return qmi;
 }
 
@@ -1060,6 +1079,11 @@
 
     array = g_array_new (FALSE, FALSE, sizeof (QmiNasRadioInterface));
 
+    if (caps & MM_MODEM_CAPABILITY_5GNR) {
+        value = QMI_NAS_RADIO_INTERFACE_5GNR;
+        g_array_append_val (array, value);
+    }
+
     if (caps & MM_MODEM_CAPABILITY_LTE) {
         value = QMI_NAS_RADIO_INTERFACE_LTE;
         g_array_append_val (array, value);
@@ -1093,6 +1117,14 @@
 
     array = g_array_new (FALSE, FALSE, sizeof (QmiNasRadioInterface));
 
+    if (allowed & MM_MODEM_MODE_5G) {
+        value = QMI_NAS_RADIO_INTERFACE_5GNR;
+        if (preferred == MM_MODEM_MODE_5G)
+            g_array_prepend_val (array, value);
+        else
+            g_array_append_val (array, value);
+    }
+
     if (allowed & MM_MODEM_MODE_4G) {
         value = QMI_NAS_RADIO_INTERFACE_LTE;
         if (preferred == MM_MODEM_MODE_4G)
@@ -1163,7 +1195,7 @@
     if (qmi & QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_LTE)
         caps |= MM_MODEM_CAPABILITY_LTE;
 
-    /* FIXME: LTE Advanced? */
+    /* NOTE: no 5GNR defined in Technology Preference */
 
     return caps;
 }
@@ -1252,7 +1284,8 @@
 /*****************************************************************************/
 
 MMModemMode
-mm_modem_mode_from_qmi_gsm_wcdma_acquisition_order_preference (QmiNasGsmWcdmaAcquisitionOrderPreference qmi)
+mm_modem_mode_from_qmi_gsm_wcdma_acquisition_order_preference (QmiNasGsmWcdmaAcquisitionOrderPreference qmi,
+                                                               gpointer                                 log_object)
 {
     switch (qmi) {
     case QMI_NAS_GSM_WCDMA_ACQUISITION_ORDER_PREFERENCE_AUTOMATIC:
@@ -1262,16 +1295,17 @@
     case QMI_NAS_GSM_WCDMA_ACQUISITION_ORDER_PREFERENCE_WCDMA:
         return MM_MODEM_MODE_3G;
     default:
-        mm_dbg ("Unknown acquisition order preference: '%s'",
-                qmi_nas_gsm_wcdma_acquisition_order_preference_get_string (qmi));
+        mm_obj_dbg (log_object, "unknown acquisition order preference: '%s'",
+                    qmi_nas_gsm_wcdma_acquisition_order_preference_get_string (qmi));
         return MM_MODEM_MODE_NONE;
     }
 }
 
 QmiNasGsmWcdmaAcquisitionOrderPreference
-mm_modem_mode_to_qmi_gsm_wcdma_acquisition_order_preference (MMModemMode mode)
+mm_modem_mode_to_qmi_gsm_wcdma_acquisition_order_preference (MMModemMode mode,
+                                                             gpointer    log_object)
 {
-    gchar *str;
+    g_autofree gchar *str = NULL;
 
     /* mode is not a mask in this case, only a value */
 
@@ -1284,14 +1318,14 @@
         return QMI_NAS_GSM_WCDMA_ACQUISITION_ORDER_PREFERENCE_AUTOMATIC;
     case MM_MODEM_MODE_CS:
     case MM_MODEM_MODE_4G:
+    case MM_MODEM_MODE_5G:
     case MM_MODEM_MODE_ANY:
     default:
         break;
     }
 
     str = mm_modem_mode_build_string_from_mask (mode);
-    mm_dbg ("Unhandled modem mode: '%s'", str);
-    g_free (str);
+    mm_obj_dbg (log_object, "unhandled modem mode: '%s'", str);
 
     return QMI_NAS_GSM_WCDMA_ACQUISITION_ORDER_PREFERENCE_AUTOMATIC;
 }
@@ -1498,56 +1532,55 @@
  * as there would be no capability switching support.
  */
 MMModemCapability
-mm_modem_capability_from_qmi_capabilities_context (MMQmiCapabilitiesContext *ctx)
+mm_modem_capability_from_qmi_capabilities_context (MMQmiCapabilitiesContext *ctx,
+                                                   gpointer                  log_object)
 {
     MMModemCapability tmp = MM_MODEM_CAPABILITY_NONE;
-    gchar *nas_ssp_mode_preference_str;
-    gchar *nas_tp_str;
-    gchar *dms_capabilities_str;
-    gchar *tmp_str;
+    g_autofree gchar *nas_ssp_mode_preference_str = NULL;
+    g_autofree gchar *nas_tp_str = NULL;
+    g_autofree gchar *dms_capabilities_str = NULL;
+    g_autofree gchar *tmp_str = NULL;
 
     /* If not a multimode device, we're done */
 #define MULTIMODE (MM_MODEM_CAPABILITY_GSM_UMTS | MM_MODEM_CAPABILITY_CDMA_EVDO)
     if ((ctx->dms_capabilities & MULTIMODE) != MULTIMODE)
-        return ctx->dms_capabilities;
-
-    /* We have a multimode CDMA/EVDO+GSM/UMTS device, check SSP and TP */
-
-    /* SSP logic to gather capabilities uses the Mode Preference TLV if available */
-    if (ctx->nas_ssp_mode_preference_mask)
-        tmp = mm_modem_capability_from_qmi_rat_mode_preference (ctx->nas_ssp_mode_preference_mask);
-    /* If no value retrieved from SSP, check TP. We only process TP
-     * values if not 'auto' (0). */
-    else if (ctx->nas_tp_mask != QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_AUTO)
-        tmp = mm_modem_capability_from_qmi_radio_technology_preference (ctx->nas_tp_mask);
-
-    /* Final capabilities are the intersection between the Technology
-     * Preference or SSP and the device's capabilities.
-     * If the Technology Preference was "auto" or unknown we just fall back
-     * to the Get Capabilities response.
-     */
-    if (tmp == MM_MODEM_CAPABILITY_NONE)
         tmp = ctx->dms_capabilities;
-    else
-        tmp &= ctx->dms_capabilities;
+    else {
+        /* We have a multimode CDMA/EVDO+GSM/UMTS device, check SSP and TP */
+
+        /* SSP logic to gather capabilities uses the Mode Preference TLV if available */
+        if (ctx->nas_ssp_mode_preference_mask)
+            tmp = mm_modem_capability_from_qmi_rat_mode_preference (ctx->nas_ssp_mode_preference_mask);
+        /* If no value retrieved from SSP, check TP. We only process TP
+         * values if not 'auto' (0). */
+        else if (ctx->nas_tp_mask != QMI_NAS_RADIO_TECHNOLOGY_PREFERENCE_AUTO)
+            tmp = mm_modem_capability_from_qmi_radio_technology_preference (ctx->nas_tp_mask);
+
+        /* Final capabilities are the intersection between the Technology
+         * Preference or SSP and the device's capabilities.
+         * If the Technology Preference was "auto" or unknown we just fall back
+         * to the Get Capabilities response.
+         */
+        if (tmp == MM_MODEM_CAPABILITY_NONE)
+            tmp = ctx->dms_capabilities;
+        else
+            tmp &= ctx->dms_capabilities;
+    }
 
     /* Log about the logic applied */
     nas_ssp_mode_preference_str = qmi_nas_rat_mode_preference_build_string_from_mask (ctx->nas_ssp_mode_preference_mask);
     nas_tp_str = qmi_nas_radio_technology_preference_build_string_from_mask (ctx->nas_tp_mask);
     dms_capabilities_str = mm_modem_capability_build_string_from_mask (ctx->dms_capabilities);
     tmp_str = mm_modem_capability_build_string_from_mask (tmp);
-    mm_dbg ("Current capabilities built: '%s'\n"
-            "  SSP mode preference: '%s'\n"
-            "  TP: '%s'\n"
-            "  DMS Capabilities: '%s'",
-            tmp_str,
-            nas_ssp_mode_preference_str ? nas_ssp_mode_preference_str : "unknown",
-            nas_tp_str ? nas_tp_str : "unknown",
-            dms_capabilities_str);
-    g_free (nas_ssp_mode_preference_str);
-    g_free (nas_tp_str);
-    g_free (dms_capabilities_str);
-    g_free (tmp_str);
+    mm_obj_dbg (log_object,
+                "Current capabilities built: '%s'\n"
+                "  SSP mode preference: '%s'\n"
+                "  TP: '%s'\n"
+                "  DMS Capabilities: '%s'",
+                tmp_str,
+                nas_ssp_mode_preference_str ? nas_ssp_mode_preference_str : "unknown",
+                nas_tp_str ? nas_tp_str : "unknown",
+                dms_capabilities_str);
 
     return tmp;
 }
diff --git a/src/mm-modem-helpers-qmi.h b/src/mm-modem-helpers-qmi.h
index 29b61af..a5ef00d 100644
--- a/src/mm-modem-helpers-qmi.h
+++ b/src/mm-modem-helpers-qmi.h
@@ -24,9 +24,11 @@
 /*****************************************************************************/
 /* QMI/DMS to MM translations */
 
-MMModemCapability mm_modem_capability_from_qmi_radio_interface (QmiDmsRadioInterface network);
+MMModemCapability mm_modem_capability_from_qmi_radio_interface (QmiDmsRadioInterface network,
+                                                                gpointer             log_object);
 
-MMModemMode mm_modem_mode_from_qmi_radio_interface (QmiDmsRadioInterface network);
+MMModemMode mm_modem_mode_from_qmi_radio_interface (QmiDmsRadioInterface network,
+                                                    gpointer             log_object);
 
 MMModemLock mm_modem_lock_from_qmi_uim_pin_status (QmiDmsUimPinStatus status,
                                                        gboolean pin1);
@@ -34,9 +36,10 @@
 gboolean mm_pin_enabled_from_qmi_uim_pin_status (QmiDmsUimPinStatus status);
 QmiDmsUimFacility mm_3gpp_facility_to_qmi_uim_facility (MMModem3gppFacility mm);
 
-GArray *mm_modem_bands_from_qmi_band_capabilities (QmiDmsBandCapability qmi_bands,
-                                                   QmiDmsLteBandCapability qmi_lte_bands,
-                                                   GArray *extended_qmi_lte_bands);
+GArray *mm_modem_bands_from_qmi_band_capabilities (QmiDmsBandCapability     qmi_bands,
+                                                   QmiDmsLteBandCapability  qmi_lte_bands,
+                                                   GArray                  *extended_qmi_lte_bands,
+                                                   gpointer                 log_object);
 
 /*****************************************************************************/
 /* QMI/NAS to MM translations */
@@ -72,20 +75,24 @@
 
 MMModemCapability mm_modem_capability_from_qmi_band_preference (QmiNasBandPreference qmi);
 
-MMModemMode mm_modem_mode_from_qmi_gsm_wcdma_acquisition_order_preference (QmiNasGsmWcdmaAcquisitionOrderPreference qmi);
-QmiNasGsmWcdmaAcquisitionOrderPreference mm_modem_mode_to_qmi_gsm_wcdma_acquisition_order_preference (MMModemMode mode);
+MMModemMode mm_modem_mode_from_qmi_gsm_wcdma_acquisition_order_preference (QmiNasGsmWcdmaAcquisitionOrderPreference qmi,
+                                                                           gpointer                                 log_object);
+QmiNasGsmWcdmaAcquisitionOrderPreference mm_modem_mode_to_qmi_gsm_wcdma_acquisition_order_preference (MMModemMode mode,
+                                                                                                      gpointer    log_object);
 
 GArray *mm_modem_bands_from_qmi_rf_band_information_array (GArray *info_array);
 
-GArray *mm_modem_bands_from_qmi_band_preference (QmiNasBandPreference qmi_bands,
-                                                 QmiNasLteBandPreference qmi_lte_bands,
-                                                 const guint64 *extended_qmi_lte_bands,
-                                                 guint extended_qmi_lte_bands_size);
-void mm_modem_bands_to_qmi_band_preference (GArray *mm_bands,
-                                            QmiNasBandPreference *qmi_bands,
+GArray *mm_modem_bands_from_qmi_band_preference (QmiNasBandPreference     qmi_bands,
+                                                 QmiNasLteBandPreference  qmi_lte_bands,
+                                                 const guint64           *extended_qmi_lte_bands,
+                                                 guint                    extended_qmi_lte_bands_size,
+                                                 gpointer                 log_object);
+void mm_modem_bands_to_qmi_band_preference (GArray                  *mm_bands,
+                                            QmiNasBandPreference    *qmi_bands,
                                             QmiNasLteBandPreference *qmi_lte_bands,
-                                            guint64 *extended_qmi_lte_bands,
-                                            guint extended_qmi_lte_bands_size);
+                                            guint64                 *extended_qmi_lte_bands,
+                                            guint                    extended_qmi_lte_bands_size,
+                                            gpointer                 log_object);
 
 MMModem3gppRegistrationState mm_modem_3gpp_registration_state_from_qmi_registration_state (QmiNasAttachState attach_state,
                                                                                            QmiNasRegistrationState registration_state,
@@ -140,7 +147,8 @@
     MMModemCapability dms_capabilities;
 } MMQmiCapabilitiesContext;
 
-MMModemCapability mm_modem_capability_from_qmi_capabilities_context (MMQmiCapabilitiesContext *ctx);
+MMModemCapability mm_modem_capability_from_qmi_capabilities_context (MMQmiCapabilitiesContext *ctx,
+                                                                     gpointer                  log_object);
 
 /*****************************************************************************/
 /* QMI unique id manipulation */
diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c
index 7761d01..0099ebe 100644
--- a/src/mm-modem-helpers.c
+++ b/src/mm-modem-helpers.c
@@ -31,7 +31,7 @@
 #include "mm-sms-part.h"
 #include "mm-modem-helpers.h"
 #include "mm-helper-enums-types.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 /*****************************************************************************/
 
@@ -254,8 +254,9 @@
 /*****************************************************************************/
 
 gchar *
-mm_create_device_identifier (guint vid,
-                             guint pid,
+mm_create_device_identifier (guint        vid,
+                             guint        pid,
+                             gpointer     log_object,
                              const gchar *ati,
                              const gchar *ati1,
                              const gchar *gsn,
@@ -263,9 +264,11 @@
                              const gchar *model,
                              const gchar *manf)
 {
-    GString *devid, *msg = NULL;
-    GChecksum *sum;
-    gchar *p, *ret = NULL;
+    g_autoptr(GString) devid = NULL;
+    g_autoptr(GString) msg = NULL;
+    g_autoptr(GChecksum) sum = NULL;
+    const gchar *ret;
+    gchar *p = NULL;
     gchar str_vid[10], str_pid[10];
 
     /* Build up the device identifier */
@@ -286,14 +289,11 @@
     if (manf)
         g_string_append (devid, manf);
 
-    if (!strlen (devid->str)) {
-        g_string_free (devid, TRUE);
+    if (!strlen (devid->str))
         return NULL;
-    }
 
     p = devid->str;
     msg = g_string_sized_new (strlen (devid->str) + 17);
-
     sum = g_checksum_new (G_CHECKSUM_SHA1);
 
     if (vid) {
@@ -315,15 +315,10 @@
         }
         p++;
     }
-    ret = g_strdup (g_checksum_get_string (sum));
-    g_checksum_free (sum);
 
-    mm_dbg ("Device ID source '%s'", msg->str);
-    mm_dbg ("Device ID '%s'", ret);
-    g_string_free (msg, TRUE);
-    g_string_free (devid, TRUE);
-
-    return ret;
+    ret = g_checksum_get_string (sum);
+    mm_obj_dbg (log_object, "device identifier built: %s -> %s", msg->str, ret);
+    return g_strdup (ret);
 }
 
 /*****************************************************************************/
@@ -423,7 +418,8 @@
 
 GArray *
 mm_filter_supported_modes (const GArray *all,
-                           const GArray *supported_combinations)
+                           const GArray *supported_combinations,
+                           gpointer      log_object)
 {
     MMModemModeCombination all_item;
     guint i;
@@ -434,6 +430,9 @@
     g_return_val_if_fail (all->len == 1, NULL);
     g_return_val_if_fail (supported_combinations != NULL, NULL);
 
+    mm_obj_dbg (log_object, "filtering %u supported mode combinations with %u modes",
+                supported_combinations->len, all->len);
+
     all_item = g_array_index (all, MMModemModeCombination, 0);
     g_return_val_if_fail (all_item.allowed != MM_MODEM_MODE_NONE, NULL);
 
@@ -455,41 +454,16 @@
     }
 
     if (filtered_combinations->len == 0)
-        mm_warn ("All supported mode combinations were filtered out.");
+        mm_obj_warn (log_object, "all supported mode combinations were filtered out");
 
     /* Add default entry with the generic mask including all items */
     if (!all_item_added) {
-        mm_dbg ("Adding an explicit item with all supported modes allowed");
+        mm_obj_dbg (log_object, "adding an explicit item with all supported modes allowed");
         g_array_append_val (filtered_combinations, all_item);
     }
 
-    return filtered_combinations;
-}
-
-/*****************************************************************************/
-
-GArray *
-mm_filter_supported_capabilities (MMModemCapability all,
-                                  const GArray *supported_combinations)
-{
-    guint i;
-    GArray *filtered_combinations;
-
-    g_return_val_if_fail (all != MM_MODEM_CAPABILITY_NONE, NULL);
-    g_return_val_if_fail (supported_combinations != NULL, NULL);
-
-    /* We will filter out all combinations which have modes not listed in 'all' */
-    filtered_combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemCapability), supported_combinations->len);
-    for (i = 0; i < supported_combinations->len; i++) {
-        MMModemCapability capability;
-
-        capability = g_array_index (supported_combinations, MMModemCapability, i);
-        if (!(capability & ~all))
-            g_array_append_val (filtered_combinations, capability);
-    }
-
-    if (filtered_combinations->len == 0)
-        mm_warn ("All supported capability combinations were filtered out.");
+    mm_obj_dbg (log_object, "device supports %u different mode combinations",
+                filtered_combinations->len);
 
     return filtered_combinations;
 }
@@ -586,6 +560,7 @@
 
 gboolean
 mm_3gpp_parse_clcc_response (const gchar  *str,
+                             gpointer      log_object,
                              GList       **out_list,
                              GError      **error)
 {
@@ -649,20 +624,20 @@
         call_info = g_slice_new0 (MMCallInfo);
 
         if (!mm_get_uint_from_match_info (match_info, 1, &call_info->index)) {
-            mm_warn ("couldn't parse call index from +CLCC line");
+            mm_obj_warn (log_object, "couldn't parse call index from +CLCC line");
             goto next;
         }
 
         if (!mm_get_uint_from_match_info (match_info, 2, &aux) ||
             (aux >= G_N_ELEMENTS (call_direction))) {
-            mm_warn ("couldn't parse call direction from +CLCC line");
+            mm_obj_warn (log_object, "couldn't parse call direction from +CLCC line");
             goto next;
         }
         call_info->direction = call_direction[aux];
 
         if (!mm_get_uint_from_match_info (match_info, 3, &aux) ||
             (aux >= G_N_ELEMENTS (call_state))) {
-            mm_warn ("couldn't parse call state from +CLCC line");
+            mm_obj_warn (log_object, "couldn't parse call state from +CLCC line");
             goto next;
         }
         call_info->state = call_state[aux];
@@ -703,7 +678,8 @@
 
 static MMFlowControl
 flow_control_array_to_mask (GArray      *array,
-                            const gchar *item)
+                            const gchar *item,
+                            gpointer     log_object)
 {
     MMFlowControl mask = MM_FLOW_CONTROL_UNKNOWN;
     guint         i;
@@ -714,15 +690,15 @@
         mode = g_array_index (array, guint, i);
         switch (mode) {
             case 0:
-                mm_dbg ("%s supports no flow control", item);
+                mm_obj_dbg (log_object, "%s supports no flow control", item);
                 mask |= MM_FLOW_CONTROL_NONE;
                 break;
             case 1:
-                mm_dbg ("%s supports XON/XOFF flow control", item);
+                mm_obj_dbg (log_object, "%s supports XON/XOFF flow control", item);
                 mask |= MM_FLOW_CONTROL_XON_XOFF;
                 break;
             case 2:
-                mm_dbg ("%s supports RTS/CTS flow control", item);
+                mm_obj_dbg (log_object, "%s supports RTS/CTS flow control", item);
                 mask |= MM_FLOW_CONTROL_RTS_CTS;
                 break;
             default:
@@ -737,6 +713,7 @@
 flow_control_match_info_to_mask (GMatchInfo   *match_info,
                                  guint         index,
                                  const gchar  *item,
+                                 gpointer      log_object,
                                  GError      **error)
 {
     MMFlowControl  mask  = MM_FLOW_CONTROL_UNKNOWN;
@@ -754,7 +731,7 @@
         goto out;
     }
 
-    if ((mask = flow_control_array_to_mask (array, item)) == MM_FLOW_CONTROL_UNKNOWN) {
+    if ((mask = flow_control_array_to_mask (array, item, log_object)) == MM_FLOW_CONTROL_UNKNOWN) {
         g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
                      "No known %s flow control method given", item);
         goto out;
@@ -769,6 +746,7 @@
 
 MMFlowControl
 mm_parse_ifc_test_response (const gchar  *response,
+                            gpointer      log_object,
                             GError      **error)
 {
     GRegex        *r;
@@ -791,11 +769,11 @@
     }
 
     /* Parse TE flow control methods */
-    if ((te_mask = flow_control_match_info_to_mask (match_info, 1, "TE", &inner_error)) == MM_FLOW_CONTROL_UNKNOWN)
+    if ((te_mask = flow_control_match_info_to_mask (match_info, 1, "TE", log_object, &inner_error)) == MM_FLOW_CONTROL_UNKNOWN)
         goto out;
 
     /* Parse TA flow control methods */
-    if ((ta_mask = flow_control_match_info_to_mask (match_info, 2, "TA", &inner_error)) == MM_FLOW_CONTROL_UNKNOWN)
+    if ((ta_mask = flow_control_match_info_to_mask (match_info, 2, "TA", log_object, &inner_error)) == MM_FLOW_CONTROL_UNKNOWN)
         goto out;
 
     /* Only those methods in both TA and TE will be the ones we report */
@@ -842,150 +820,57 @@
 
 /*************************************************************************/
 
-/* +CREG: <stat>                      (GSM 07.07 CREG=1 unsolicited) */
-#define CREG1 "\\+(CREG|CGREG|CEREG):\\s*0*([0-9])"
-
-/* +CREG: <n>,<stat>                  (GSM 07.07 CREG=1 solicited) */
-#define CREG2 "\\+(CREG|CGREG|CEREG):\\s*0*([0-9]),\\s*0*([0-9])"
-
-/* +CREG: <stat>,<lac>,<ci>           (GSM 07.07 CREG=2 unsolicited) */
-#define CREG3 "\\+(CREG|CGREG|CEREG):\\s*0*([0-9]),\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)"
-#define CREG11 "\\+(CREG|CGREG|CEREG):\\s*0*([0-9]),\\s*(\"[^\"\\s]*\")\\s*,\\s*(\"[^\"\\s]*\")"
-
-/* +CREG: <n>,<stat>,<lac>,<ci>       (GSM 07.07 solicited and some CREG=2 unsolicited) */
-#define CREG4 "\\+(CREG|CGREG|CEREG):\\s*([0-9]),\\s*([0-9])\\s*,\\s*([^,]*)\\s*,\\s*([^,\\s]*)"
-#define CREG5 "\\+(CREG|CGREG|CEREG):\\s*0*([0-9]),\\s*0*([0-9])\\s*,\\s*(\"[^,]*\")\\s*,\\s*(\"[^,\\s]*\")"
-
-/* +CREG: <stat>,<lac>,<ci>,<AcT>     (ETSI 27.007 CREG=2 unsolicited) */
-#define CREG6 "\\+(CREG|CGREG|CEREG):\\s*([0-9])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*([0-9])"
-#define CREG7 "\\+(CREG|CGREG|CEREG):\\s*0*([0-9])\\s*,\\s*(\"[^,\\s]*\")\\s*,\\s*(\"[^,\\s]*\")\\s*,\\s*0*([0-9])"
-
-/* +CREG: <n>,<stat>,<lac>,<ci>,<AcT> (ETSI 27.007 solicited and some CREG=2 unsolicited) */
-#define CREG8 "\\+(CREG|CGREG|CEREG):\\s*0*([0-9]),\\s*0*([0-9])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*0*([0-9])"
-
-/* +CREG: <n>,<stat>,<lac>,<ci>,<AcT?>,<something> (Samsung Wave S8500) */
-/* '<CR><LF>+CREG: 2,1,000B,2816, B, C2816<CR><LF><CR><LF>OK<CR><LF>' */
-#define CREG9 "\\+(CREG|CGREG):\\s*0*([0-9]),\\s*0*([0-9])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*[^,\\s]*"
-
-/* +CREG: <stat>,<lac>,<ci>,<AcT>,<RAC> (ETSI 27.007 v9.20 CREG=2 unsolicited with RAC) */
-#define CREG10 "\\+(CREG|CGREG):\\s*0*([0-9])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*0*([0-9])\\s*,\\s*([^,\\s]*)"
-
-/* +CEREG: <stat>,<lac>,<rac>,<ci>,<AcT>     (ETSI 27.007 v8.6 CREG=2 unsolicited with RAC) */
-#define CEREG1 "\\+(CEREG):\\s*0*([0-9])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*0*([0-9])"
-
-/* +CEREG: <n>,<stat>,<lac>,<rac>,<ci>,<AcT> (ETSI 27.007 v8.6 CREG=2 solicited with RAC) */
-#define CEREG2 "\\+(CEREG):\\s*0*([0-9]),\\s*0*([0-9])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*0*([0-9])"
+static const gchar *creg_regex[] = {
+    /* +CREG: <stat>                      (GSM 07.07 CREG=1 unsolicited) */
+    [0] = "\\+(CREG|CGREG|CEREG|C5GREG):\\s*0*([0-9])",
+    /* +CREG: <n>,<stat>                  (GSM 07.07 CREG=1 solicited) */
+    [1] = "\\+(CREG|CGREG|CEREG|C5GREG):\\s*0*([0-9]),\\s*0*([0-9])",
+    /* +CREG: <stat>,<lac>,<ci>           (GSM 07.07 CREG=2 unsolicited) */
+    [2] = "\\+(CREG|CGREG|CEREG):\\s*0*([0-9]),\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)",
+    /* +CREG: <n>,<stat>,<lac>,<ci>       (GSM 07.07 solicited and some CREG=2 unsolicited) */
+    [3] = "\\+(CREG|CGREG|CEREG):\\s*([0-9]),\\s*([0-9])\\s*,\\s*([^,]*)\\s*,\\s*([^,\\s]*)",
+    [4] = "\\+(CREG|CGREG|CEREG):\\s*0*([0-9]),\\s*0*([0-9])\\s*,\\s*(\"[^,]*\")\\s*,\\s*(\"[^,\\s]*\")",
+    /* +CREG: <stat>,<lac>,<ci>,<AcT>     (ETSI 27.007 CREG=2 unsolicited) */
+    [5] = "\\+(CREG|CGREG|CEREG):\\s*([0-9])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*([0-9])",
+    [6] = "\\+(CREG|CGREG|CEREG):\\s*0*([0-9])\\s*,\\s*(\"[^,\\s]*\")\\s*,\\s*(\"[^,\\s]*\")\\s*,\\s*0*([0-9])",
+    /* +CREG: <n>,<stat>,<lac>,<ci>,<AcT> (ETSI 27.007 solicited and some CREG=2 unsolicited) */
+    [7] = "\\+(CREG|CGREG|CEREG):\\s*0*([0-9]),\\s*0*([0-9])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*0*([0-9])",
+    /* +CREG: <n>,<stat>,<lac>,<ci>,<AcT?>,<something> (Samsung Wave S8500) */
+    /* '<CR><LF>+CREG: 2,1,000B,2816, B, C2816<CR><LF><CR><LF>OK<CR><LF>' */
+    [8] = "\\+(CREG|CGREG):\\s*0*([0-9]),\\s*0*([0-9])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*[^,\\s]*",
+    /* +CREG: <stat>,<lac>,<ci>,<AcT>,<RAC> (ETSI 27.007 v9.20 CREG=2 unsolicited with RAC) */
+    [9] = "\\+(CREG|CGREG):\\s*0*([0-9])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*0*([0-9])\\s*,\\s*([^,\\s]*)",
+    /* +CEREG: <stat>,<lac>,<rac>,<ci>,<AcT>     (ETSI 27.007 v8.6 CREG=2 unsolicited with RAC) */
+    [10] = "\\+(CEREG):\\s*0*([0-9])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*0*([0-9])",
+    /* +CEREG: <n>,<stat>,<lac>,<rac>,<ci>,<AcT> (ETSI 27.007 v8.6 CREG=2 solicited with RAC) */
+    [11] = "\\+(CEREG):\\s*0*([0-9]),\\s*0*([0-9])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*0*([0-9])",
+    /* +C5GREG: <stat>,<lac>,<ci>,<AcT>,<Allowed_NSSAI_length>,<Allowed_NSSAI>   (ETSI 27.007 CREG=2 unsolicited) */
+    [12] = "\\+(C5GREG):\\s*([0-9]+)\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*([0-9]+)\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)",
+    /* +C5GREG: <n>,<stat>,<lac>,<ci>,<AcT>,<Allowed_NSSAI_length>,<Allowed_NSSAI> (ETSI 27.007 solicited) */
+    [13] = "\\+(C5GREG):\\s*([0-9]+)\\s*,\\s*([0-9+])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*([0-9]+)\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)",
+};
 
 GPtrArray *
 mm_3gpp_creg_regex_get (gboolean solicited)
 {
-    GPtrArray *array = g_ptr_array_sized_new (13);
-    GRegex *regex;
+    GPtrArray *array;
+    guint      i;
 
-    /* #1 */
-    if (solicited)
-        regex = g_regex_new (CREG1 "$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-    else
-        regex = g_regex_new ("\\r\\n" CREG1 "\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-    g_assert (regex);
-    g_ptr_array_add (array, regex);
+    array = g_ptr_array_sized_new (G_N_ELEMENTS (creg_regex));
+    for (i = 0; i < G_N_ELEMENTS (creg_regex); i++) {
+        GRegex           *regex;
+        g_autofree gchar *pattern = NULL;
 
-    /* #2 */
-    if (solicited)
-        regex = g_regex_new (CREG2 "$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-    else
-        regex = g_regex_new ("\\r\\n" CREG2 "\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-    g_assert (regex);
-    g_ptr_array_add (array, regex);
-
-    /* #3 */
-    if (solicited)
-        regex = g_regex_new (CREG3 "$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-    else
-        regex = g_regex_new ("\\r\\n" CREG3 "\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-    g_assert (regex);
-    g_ptr_array_add (array, regex);
-
-    /* #4 */
-    if (solicited)
-        regex = g_regex_new (CREG4 "$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-    else
-        regex = g_regex_new ("\\r\\n" CREG4 "\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-    g_assert (regex);
-    g_ptr_array_add (array, regex);
-
-    /* #5 */
-    if (solicited)
-        regex = g_regex_new (CREG5 "$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-    else
-        regex = g_regex_new ("\\r\\n" CREG5 "\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-    g_assert (regex);
-    g_ptr_array_add (array, regex);
-
-    /* #6 */
-    if (solicited)
-        regex = g_regex_new (CREG6 "$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-    else
-        regex = g_regex_new ("\\r\\n" CREG6 "\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-    g_assert (regex);
-    g_ptr_array_add (array, regex);
-
-    /* #7 */
-    if (solicited)
-        regex = g_regex_new (CREG7 "$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-    else
-        regex = g_regex_new ("\\r\\n" CREG7 "\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-    g_assert (regex);
-    g_ptr_array_add (array, regex);
-
-    /* #8 */
-    if (solicited)
-        regex = g_regex_new (CREG8 "$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-    else
-        regex = g_regex_new ("\\r\\n" CREG8 "\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-    g_assert (regex);
-    g_ptr_array_add (array, regex);
-
-    /* #9 */
-    if (solicited)
-        regex = g_regex_new (CREG9 "$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-    else
-        regex = g_regex_new ("\\r\\n" CREG9 "\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-    g_assert (regex);
-    g_ptr_array_add (array, regex);
-
-    /* #10 */
-    if (solicited)
-        regex = g_regex_new (CREG10 "$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-    else
-        regex = g_regex_new ("\\r\\n" CREG10 "\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-    g_assert (regex);
-    g_ptr_array_add (array, regex);
-
-    /* #11 */
-    if (solicited)
-        regex = g_regex_new (CREG11 "$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-    else
-        regex = g_regex_new ("\\r\\n" CREG11 "\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-    g_assert (regex);
-    g_ptr_array_add (array, regex);
-
-    /* CEREG #1 */
-    if (solicited)
-        regex = g_regex_new (CEREG1 "$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-    else
-        regex = g_regex_new ("\\r\\n" CEREG1 "\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-    g_assert (regex);
-    g_ptr_array_add (array, regex);
-
-    /* CEREG #2 */
-    if (solicited)
-        regex = g_regex_new (CEREG2 "$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-    else
-        regex = g_regex_new ("\\r\\n" CEREG2 "\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-    g_assert (regex);
-    g_ptr_array_add (array, regex);
-
+        if (solicited) {
+            pattern = g_strdup_printf ("%s$", creg_regex[i]);
+            regex = g_regex_new (pattern, G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
+        } else {
+            pattern = g_strdup_printf ("\\r\\n%s\\r\\n", creg_regex[i]);
+            regex = g_regex_new (pattern, G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
+        }
+        g_assert (regex);
+        g_ptr_array_add (array, regex);
+    }
     return array;
 }
 
@@ -1061,7 +946,9 @@
  * NOTE: ignore WS46 prefix or it will break Cinterion handling.
  *
  * For the specific case of '25', we will check if any other mode supports
- * 4G, and if there is none, we'll remove 4G caps from it.
+ * 4G, and if there is none, we'll remove 4G caps from it. This is needed
+ * because pre-LTE modems used '25' to report GERAN+URAN instead of the
+ * new '29' value since LTE modems are around.
  */
 
 typedef struct {
@@ -1069,7 +956,7 @@
     MMModemMode mode;
 } Ws46Mode;
 
-/* 3GPP TS 27.007 r14, section 5.9: select wireless network +WS46 */
+/* 3GPP TS 27.007 v16.3.0, section 5.9: select wireless network +WS46 */
 static const Ws46Mode ws46_modes[] = {
     /* GSM Digital Cellular Systems (GERAN only) */
     { 12, MM_MODEM_MODE_2G },
@@ -1083,8 +970,24 @@
     { 29, MM_MODEM_MODE_2G | MM_MODEM_MODE_3G },
     /* GERAN and E-UTRAN */
     { 30, MM_MODEM_MODE_2G | MM_MODEM_MODE_4G },
-    /* UERAN and E-UTRAN */
+    /* UTRAN and E-UTRAN */
     { 31, MM_MODEM_MODE_3G | MM_MODEM_MODE_4G },
+    /* GERAN, UTRAN, E-UTRAN and NG-RAN */
+    { 35, MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G | MM_MODEM_MODE_5G },
+    /* NG-RAN only */
+    { 36, MM_MODEM_MODE_5G },
+    /* E-UTRAN and NG-RAN */
+    { 37, MM_MODEM_MODE_4G | MM_MODEM_MODE_5G },
+    /* UTRAN, E-UTRAN and NG-RAN */
+    { 38, MM_MODEM_MODE_3G | MM_MODEM_MODE_4G | MM_MODEM_MODE_5G },
+    /* GERAN, E-UTRAN and NG-RAN */
+    { 39, MM_MODEM_MODE_2G | MM_MODEM_MODE_4G | MM_MODEM_MODE_5G },
+    /* UTRAN and NG-RAN */
+    { 40, MM_MODEM_MODE_3G | MM_MODEM_MODE_5G },
+    /* GERAN, UTRAN and NG-RAN */
+    { 41, MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_5G },
+    /* GERAN and NG-RAN */
+    { 42, MM_MODEM_MODE_2G | MM_MODEM_MODE_5G },
 };
 
 GArray *
@@ -1100,9 +1003,12 @@
     guint       val;
     guint       i;
     guint       j;
+    gboolean    supported_5g = FALSE;
     gboolean    supported_4g = FALSE;
     gboolean    supported_3g = FALSE;
     gboolean    supported_2g = FALSE;
+    gboolean    supported_mode_25 = FALSE;
+    gboolean    supported_mode_29 = FALSE;
 
     r = g_regex_new ("(?:\\+WS46:)?\\s*\\((.*)\\)(?:\\r\\n)?", 0, 0, NULL);
     g_assert (r != NULL);
@@ -1131,15 +1037,21 @@
 
         for (j = 0; j < G_N_ELEMENTS (ws46_modes); j++) {
             if (ws46_modes[j].ws46 == val) {
-                if (val != 25) {
+                if (val == 25)
+                    supported_mode_25 = TRUE;
+                else {
+                    if (val == 29)
+                        supported_mode_29 = TRUE;
+                    if (ws46_modes[j].mode & MM_MODEM_MODE_5G)
+                        supported_5g = TRUE;
                     if (ws46_modes[j].mode & MM_MODEM_MODE_4G)
                         supported_4g = TRUE;
                     if (ws46_modes[j].mode & MM_MODEM_MODE_3G)
                         supported_3g = TRUE;
                     if (ws46_modes[j].mode & MM_MODEM_MODE_2G)
                         supported_2g = TRUE;
+                    g_array_append_val (modes, ws46_modes[j].mode);
                 }
-                g_array_append_val (modes, ws46_modes[j].mode);
                 break;
             }
         }
@@ -1148,6 +1060,17 @@
             g_warning ("Unknown +WS46 mode reported: %u", val);
     }
 
+    if (supported_mode_25) {
+        MMModemMode mode_25;
+
+        mode_25 = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G;
+        if (supported_4g) {
+            mode_25 |= MM_MODEM_MODE_4G;
+            g_array_append_val (modes, mode_25);
+        } else if (!supported_mode_29)
+            g_array_append_val (modes, mode_25);
+    }
+
     if (modes->len == 0) {
         inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "No valid modes reported");
         g_clear_pointer (&modes, g_array_unref);
@@ -1167,6 +1090,8 @@
                 *mode |= MM_MODEM_MODE_3G;
             if (supported_4g)
                 *mode |= MM_MODEM_MODE_4G;
+            if (supported_5g)
+                *mode |= MM_MODEM_MODE_5G;
 
             if (*mode == 0) {
                 inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "No way to fixup the ANY value");
@@ -1216,7 +1141,8 @@
 {
     /* See ETSI TS 27.007 */
     switch (act) {
-    case 0:
+    case 0: /* GSM */
+    case 8: /* EC-GSM-IoT (A/Gb mode) */
         return MM_MODEM_ACCESS_TECHNOLOGY_GSM;
     case 1:
         return MM_MODEM_ACCESS_TECHNOLOGY_GSM_COMPACT;
@@ -1230,22 +1156,30 @@
         return MM_MODEM_ACCESS_TECHNOLOGY_HSUPA;
     case 6:
         return MM_MODEM_ACCESS_TECHNOLOGY_HSPA;
-    case 7:
+    case 7:  /* E-UTRAN */
+    case 9:  /* E-UTRAN (NB-S1) */
+    case 10: /* E-UTRA connected to a 5GCN */
         return MM_MODEM_ACCESS_TECHNOLOGY_LTE;
+    case 11: /* NR connected to a 5G CN */
+    case 12: /* NG-RAN */
+        return MM_MODEM_ACCESS_TECHNOLOGY_5GNR;
+    case 13: /* E-UTRA-NR dual connectivity */
+        return (MM_MODEM_ACCESS_TECHNOLOGY_5GNR | MM_MODEM_ACCESS_TECHNOLOGY_LTE);
     default:
         return MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
     }
 }
 
 static MMModem3gppNetworkAvailability
-parse_network_status (const gchar *str)
+parse_network_status (const gchar *str,
+                      gpointer     log_object)
 {
     /* Expecting a value between '0' and '3' inclusive */
     if (!str ||
         strlen (str) != 1 ||
         str[0] < '0' ||
         str[0] > '3') {
-        mm_warn ("Cannot parse network status: '%s'", str);
+        mm_obj_warn (log_object, "cannot parse network status value '%s'", str);
         return MM_MODEM_3GPP_NETWORK_AVAILABILITY_UNKNOWN;
     }
 
@@ -1253,14 +1187,15 @@
 }
 
 static MMModemAccessTechnology
-parse_access_tech (const gchar *str)
+parse_access_tech (const gchar *str,
+                   gpointer     log_object)
 {
     /* Recognized access technologies are between '0' and '7' inclusive... */
     if (!str ||
         strlen (str) != 1 ||
         str[0] < '0' ||
         str[0] > '7') {
-        mm_warn ("Cannot parse access tech: '%s'", str);
+        mm_obj_warn (log_object, "cannot parse access technology value '%s'", str);
         return MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
     }
 
@@ -1270,13 +1205,13 @@
 GList *
 mm_3gpp_parse_cops_test_response (const gchar     *reply,
                                   MMModemCharset   cur_charset,
+                                  gpointer         log_object,
                                   GError         **error)
 {
     GRegex *r;
     GList *info_list = NULL;
     GMatchInfo *match_info;
     gboolean umts_format = TRUE;
-    GError *inner_error = NULL;
 
     g_return_val_if_fail (reply != NULL, NULL);
     if (error)
@@ -1305,15 +1240,8 @@
      *       +COPS: (2,"","T-Mobile","31026",0),(1,"AT&T","AT&T","310410"),0)
      */
 
-    r = g_regex_new ("\\((\\d),\"([^\"\\)]*)\",([^,\\)]*),([^,\\)]*)[\\)]?,(\\d)\\)", G_REGEX_UNGREEDY, 0, &inner_error);
-    if (inner_error) {
-        mm_err ("Invalid regular expression: %s", inner_error->message);
-        g_error_free (inner_error);
-        g_set_error_literal (error,
-                             MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
-                             "Could not parse scan results");
-        return NULL;
-    }
+    r = g_regex_new ("\\((\\d),\"([^\"\\)]*)\",([^,\\)]*),([^,\\)]*)[\\)]?,(\\d)\\)", G_REGEX_UNGREEDY, 0, NULL);
+    g_assert (r);
 
     /* If we didn't get any hits, try the pre-UMTS format match */
     if (!g_regex_match (r, reply, 0, &match_info)) {
@@ -1334,15 +1262,8 @@
          *       +COPS: (2,"T - Mobile",,"31026"),(1,"Einstein PCS",,"31064"),(1,"Cingular",,"31041"),,(0,1,3),(0,2)
          */
 
-        r = g_regex_new ("\\((\\d),([^,\\)]*),([^,\\)]*),([^\\)]*)\\)", G_REGEX_UNGREEDY, 0, &inner_error);
-        if (inner_error) {
-            mm_err ("Invalid regular expression: %s", inner_error->message);
-            g_error_free (inner_error);
-            g_set_error_literal (error,
-                                 MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
-                                 "Could not parse scan results");
-            return NULL;
-        }
+        r = g_regex_new ("\\((\\d),([^,\\)]*),([^,\\)]*),([^\\)]*)\\)", G_REGEX_UNGREEDY, 0, NULL);
+        g_assert (r);
 
         g_regex_match (r, reply, 0, &match_info);
         umts_format = FALSE;
@@ -1357,7 +1278,7 @@
         info = g_new0 (MM3gppNetworkInfo, 1);
 
         tmp = mm_get_string_unquoted_from_match_info (match_info, 1);
-        info->status = parse_network_status (tmp);
+        info->status = parse_network_status (tmp, log_object);
         g_free (tmp);
 
         info->operator_long = mm_get_string_unquoted_from_match_info (match_info, 2);
@@ -1375,7 +1296,7 @@
                mm_get_string_unquoted_from_match_info (match_info, 5) :
                NULL);
         info->access_tech = (tmp ?
-                             parse_access_tech (tmp) :
+                             parse_access_tech (tmp, log_object) :
                              MM_MODEM_ACCESS_TECHNOLOGY_GSM);
         g_free (tmp);
 
@@ -1397,17 +1318,15 @@
         }
 
         if (valid) {
-            gchar *access_tech_str;
+            g_autofree gchar *access_tech_str = NULL;
 
             access_tech_str = mm_modem_access_technology_build_string_from_mask (info->access_tech);
-            mm_dbg ("Found network '%s' ('%s','%s'); availability: %s, access tech: %s",
-                    info->operator_code,
-                    info->operator_short ? info->operator_short : "no short name",
-                    info->operator_long ? info->operator_long : "no long name",
-                    mm_modem_3gpp_network_availability_get_string (info->status),
-                    access_tech_str);
-            g_free (access_tech_str);
-
+            mm_obj_dbg (log_object, "found network '%s' ('%s','%s'); availability: %s, access tech: %s",
+                        info->operator_code,
+                        info->operator_short ? info->operator_short : "no short name",
+                        info->operator_long ? info->operator_long : "no long name",
+                        mm_modem_3gpp_network_availability_get_string (info->status),
+                        access_tech_str);
             info_list = g_list_prepend (info_list, info);
         }
         else
@@ -1576,8 +1495,9 @@
                          MMBearerIpFamily  ip_family,
                          GList            *context_list,
                          GList            *context_format_list,
-                         gboolean         *cid_reused,
-                         gboolean         *cid_overwritten)
+                         gpointer          log_object,
+                         gboolean         *out_cid_reused,
+                         gboolean         *out_cid_overwritten)
 {
     GList *l;
     guint  prev_cid = 0;
@@ -1588,9 +1508,12 @@
     guint  blank_cid = 0;
     gchar *ip_family_str;
 
+    g_assert (out_cid_reused);
+    g_assert (out_cid_overwritten);
+
     ip_family_str = mm_bearer_ip_family_build_string_from_mask (ip_family);
-    mm_dbg ("Looking for best CID matching APN '%s' and PDP type '%s'...",
-            apn, ip_family_str);
+    mm_obj_dbg (log_object, "looking for best CID matching APN '%s' and PDP type '%s'...",
+                apn, ip_family_str);
     g_free (ip_family_str);
 
     /* Look for the exact PDP context we want */
@@ -1631,17 +1554,17 @@
 
     /* Always prefer an exact match */
     if (exact_cid) {
-        mm_dbg ("Found exact context at CID %u", exact_cid);
-        *cid_reused = TRUE;
-        *cid_overwritten = FALSE;
+        mm_obj_dbg (log_object, "found exact context at CID %u", exact_cid);
+        *out_cid_reused = TRUE;
+        *out_cid_overwritten = FALSE;
         return exact_cid;
     }
 
     /* Try to use an unused CID detected in between the already defined contexts */
     if (unused_cid) {
-        mm_dbg ("Found unused context at CID %u", unused_cid);
-        *cid_reused = FALSE;
-        *cid_overwritten = FALSE;
+        mm_obj_dbg (log_object, "found unused context at CID %u", unused_cid);
+        *out_cid_reused = FALSE;
+        *out_cid_overwritten = FALSE;
         return unused_cid;
     }
 
@@ -1649,32 +1572,32 @@
      * CID, then we can use the next available CID because it's an unused one. */
     max_allowed_cid = find_max_allowed_cid (context_format_list, ip_family);
     if (max_cid && (max_cid < max_allowed_cid)) {
-        mm_dbg ("Found unused context at CID %u (<%u)", max_cid + 1, max_allowed_cid);
-        *cid_reused = FALSE;
-        *cid_overwritten = FALSE;
+        mm_obj_dbg (log_object, "found unused context at CID %u (<%u)", max_cid + 1, max_allowed_cid);
+        *out_cid_reused = FALSE;
+        *out_cid_overwritten = FALSE;
         return (max_cid + 1);
     }
 
     /* Rewrite a context defined with no APN, if any */
     if (blank_cid) {
-        mm_dbg ("Rewriting context with empty APN at CID %u", blank_cid);
-        *cid_reused = FALSE;
-        *cid_overwritten = TRUE;
+        mm_obj_dbg (log_object, "rewriting context with empty APN at CID %u", blank_cid);
+        *out_cid_reused = FALSE;
+        *out_cid_overwritten = TRUE;
         return blank_cid;
     }
 
     /* Rewrite the last existing one found */
     if (max_cid) {
-        mm_dbg ("Rewriting last context detected at CID %u", max_cid);
-        *cid_reused = FALSE;
-        *cid_overwritten = TRUE;
+        mm_obj_dbg (log_object, "rewriting last context detected at CID %u", max_cid);
+        *out_cid_reused = FALSE;
+        *out_cid_overwritten = TRUE;
         return max_cid;
     }
 
     /* Otherwise, just fallback to CID=1 */
-    mm_dbg ("Falling back to CID 1");
-    *cid_reused = FALSE;
-    *cid_overwritten = TRUE;
+    mm_obj_dbg (log_object, "falling back to CID 1");
+    *out_cid_reused = FALSE;
+    *out_cid_overwritten = TRUE;
     return 1;
 }
 
@@ -1693,8 +1616,9 @@
 }
 
 GList *
-mm_3gpp_parse_cgdcont_test_response (const gchar *response,
-                                     GError **error)
+mm_3gpp_parse_cgdcont_test_response (const gchar  *response,
+                                     gpointer      log_object,
+                                     GError      **error)
 {
     GRegex *r;
     GMatchInfo *match_info;
@@ -1722,11 +1646,11 @@
         pdp_type_str = mm_get_string_unquoted_from_match_info (match_info, 3);
         pdp_type = mm_3gpp_get_ip_family_from_pdp_type (pdp_type_str);
         if (pdp_type == MM_BEARER_IP_FAMILY_NONE)
-            mm_dbg ("Unhandled PDP type in CGDCONT=? reply: '%s'", pdp_type_str);
+            mm_obj_dbg (log_object, "unhandled PDP type in CGDCONT=? reply: '%s'", pdp_type_str);
         else {
             /* Read min CID */
             if (!mm_get_uint_from_match_info (match_info, 1, &min_cid))
-                mm_warn ("Invalid min CID in CGDCONT=? reply for PDP type '%s'", pdp_type_str);
+                mm_obj_warn (log_object, "invalid min CID in CGDCONT=? reply for PDP type '%s'", pdp_type_str);
             else {
                 MM3gppPdpContextFormat *format;
 
@@ -1751,7 +1675,7 @@
     g_regex_unref (r);
 
     if (inner_error) {
-        mm_warn ("Unexpected error matching +CGDCONT response: '%s'", inner_error->message);
+        mm_obj_warn (log_object, "unexpected error matching +CGDCONT response: '%s'", inner_error->message);
         g_error_free (inner_error);
     }
 
@@ -1807,9 +1731,7 @@
 
             str = mm_get_string_unquoted_from_match_info (match_info, 2);
             ip_family = mm_3gpp_get_ip_family_from_pdp_type (str);
-            if (ip_family == MM_BEARER_IP_FAMILY_NONE)
-                mm_dbg ("Ignoring PDP context type: '%s'", str);
-            else {
+            if (ip_family != MM_BEARER_IP_FAMILY_NONE) {
                 MM3gppPdpContext *pdp;
 
                 pdp = g_slice_new0 (MM3gppPdpContext);
@@ -1861,6 +1783,26 @@
     g_list_free_full (list, (GDestroyNotify) mm_3gpp_profile_free);
 }
 
+static MM3gppProfile *
+mm_3gpp_profile_copy (MM3gppProfile *profile)
+{
+    MM3gppProfile *copy;
+
+    copy = g_slice_new0 (MM3gppProfile);
+    copy->profile_id = profile->profile_id;
+    copy->apn = g_strdup (profile->apn);
+    copy->username = g_strdup (profile->username);
+    copy->password = g_strdup (profile->password);
+    copy->auth_type = profile->auth_type;
+    return copy;
+}
+
+GList *
+mm_3gpp_profile_list_copy (GList *list)
+{
+    return g_list_copy_deep (list, (GCopyFunc)mm_3gpp_profile_copy, NULL);
+}
+
 /*************************************************************************/
 
 static void
@@ -1946,35 +1888,6 @@
 
 /*************************************************************************/
 
-static gulong
-parse_uint (gchar    *str,
-            gint      base,
-            gulong    nmin,
-            gulong    nmax,
-            gboolean *valid)
-{
-    gulong ret = 0;
-    gchar *endquote;
-
-    *valid = FALSE;
-    if (!str)
-        return 0;
-
-    /* Strip quotes */
-    if (str[0] == '"')
-        str++;
-    endquote = strchr (str, '"');
-    if (endquote)
-        *endquote = '\0';
-
-    if (strlen (str)) {
-        ret = strtol (str, NULL, base);
-        if ((nmin == nmax) || (ret >= nmin && ret <= nmax))
-            *valid = TRUE;
-    }
-    return *valid ? (guint) ret : 0;
-}
-
 static gboolean
 item_is_lac_not_stat (GMatchInfo *info, guint32 item)
 {
@@ -1990,32 +1903,36 @@
 }
 
 gboolean
-mm_3gpp_parse_creg_response (GMatchInfo *info,
-                             MMModem3gppRegistrationState *out_reg_state,
-                             gulong *out_lac,
-                             gulong *out_ci,
-                             MMModemAccessTechnology *out_act,
-                             gboolean *out_cgreg,
-                             gboolean *out_cereg,
-                             GError **error)
+mm_3gpp_parse_creg_response (GMatchInfo                    *info,
+                             gpointer                       log_object,
+                             MMModem3gppRegistrationState  *out_reg_state,
+                             gulong                        *out_lac,
+                             gulong                        *out_ci,
+                             MMModemAccessTechnology       *out_act,
+                             gboolean                      *out_cgreg,
+                             gboolean                      *out_cereg,
+                             gboolean                      *out_c5greg,
+                             GError                       **error)
 {
-    gboolean success = FALSE, foo;
     gint n_matches, act = -1;
-    gulong stat = 0, lac = 0, ci = 0;
+    guint stat = 0;
+    guint64 lac = 0, ci = 0;
     guint istat = 0, ilac = 0, ici = 0, iact = 0;
     gchar *str;
 
-    g_return_val_if_fail (info != NULL, FALSE);
-    g_return_val_if_fail (out_reg_state != NULL, FALSE);
-    g_return_val_if_fail (out_lac != NULL, FALSE);
-    g_return_val_if_fail (out_ci != NULL, FALSE);
-    g_return_val_if_fail (out_act != NULL, FALSE);
-    g_return_val_if_fail (out_cgreg != NULL, FALSE);
-    g_return_val_if_fail (out_cereg != NULL, FALSE);
+    g_assert (info != NULL);
+    g_assert (out_reg_state != NULL);
+    g_assert (out_lac != NULL);
+    g_assert (out_ci != NULL);
+    g_assert (out_act != NULL);
+    g_assert (out_cgreg != NULL);
+    g_assert (out_cereg != NULL);
+    g_assert (out_c5greg != NULL);
 
     str = g_match_info_fetch (info, 1);
     *out_cgreg = (str && strstr (str, "CGREG")) ? TRUE : FALSE;
     *out_cereg = (str && strstr (str, "CEREG")) ? TRUE : FALSE;
+    *out_c5greg = (str && strstr (str, "C5GREG")) ? TRUE : FALSE;
     g_free (str);
 
     /* Normally the number of matches could be used to determine what each
@@ -2060,88 +1977,85 @@
             /* Check if the third item is the LAC to distinguish the two cases */
             if (item_is_lac_not_stat (info, 3)) {
                 istat = 2;
-                ilac = 3;
+                ilac  = 3;
             } else {
                 istat = 3;
-                ilac = 4;
+                ilac  = 4;
             }
-            ici = 5;
+            ici  = 5;
             iact = 6;
         } else {
             /* Check if the third item is the LAC to distinguish the two cases */
             if (item_is_lac_not_stat (info, 3)) {
                 istat = 2;
-                ilac = 3;
-                ici = 4;
-                iact = 5;
+                ilac  = 3;
+                ici   = 4;
+                iact  = 5;
             } else {
                 istat = 3;
-                ilac = 4;
-                ici = 5;
-                iact = 6;
+                ilac  = 4;
+                ici   = 5;
+                iact  = 6;
             }
         }
     } else if (n_matches == 8) {
         /* CEREG=2 (solicited with RAC):  +CEREG: <n>,<stat>,<lac>,<rac>,<ci>,<AcT>
+         * C5GREG=2 (unsolicited):        +C5GREG: <stat>,<tac>,<ci>,<AcT>,<Allowed_NSSAI_length>,<Allowed_NSSAI>
          */
         if (*out_cereg) {
             istat = 3;
-            ilac = 4;
-            ici = 6;
-            iact = 7;
+            ilac  = 4;
+            ici   = 6;
+            iact  = 7;
+        } else if (*out_c5greg) {
+            istat = 2;
+            ilac  = 3;
+            ici   = 4;
+            iact  = 5;
         }
-     }
+    } else if (n_matches == 9) {
+        /* C5GREG=2 (solicited): +C5GREG: <n>,<stat>,<tac>,<ci>,<AcT>,<Allowed_NSSAI_length>,<Allowed_NSSAI> */
+        istat = 3;
+        ilac  = 4;
+        ici   = 5;
+        iact  = 6;
+    }
 
     /* Status */
-    str = g_match_info_fetch (info, istat);
-    stat = parse_uint (str, 10, 0, G_MAXUINT, &success);
-    g_free (str);
-    if (!success) {
+    if (!mm_get_uint_from_match_info (info, istat, &stat)) {
         g_set_error_literal (error,
                              MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
                              "Could not parse the registration status response");
         return FALSE;
     }
 
-    /* 'roaming (csfb not preferred)' is the last valid state */
-    if (stat > MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING_CSFB_NOT_PREFERRED) {
-        mm_warn ("Registration State '%lu' is unknown", stat);
+    /* 'attached RLOS' is the last valid state */
+    if (stat > MM_MODEM_3GPP_REGISTRATION_STATE_ATTACHED_RLOS) {
+        mm_obj_warn (log_object, "unknown registration state value '%u'", stat);
         stat = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
     }
 
-    /* Location Area Code */
-    if (ilac) {
-        /* FIXME: some phones apparently swap the LAC bytes (LG, SonyEricsson,
-         * Sagem).  Need to handle that.
-         */
-        str = g_match_info_fetch (info, ilac);
-        lac = parse_uint (str, 16, 1, 0xFFFF, &foo);
-        g_free (str);
-    }
+    /* Location Area Code/Tracking Area Code
+     * FIXME: some phones apparently swap the LAC bytes (LG, SonyEricsson,
+     * Sagem).  Need to handle that.
+     */
+    if (ilac)
+        mm_get_u64_from_hex_match_info (info, ilac, &lac);
 
     /* Cell ID */
-    if (ici) {
-        str = g_match_info_fetch (info, ici);
-        ci = parse_uint (str, 16, 1, 0x0FFFFFFE, &foo);
-        g_free (str);
-    }
+    if (ici)
+        mm_get_u64_from_hex_match_info (info, ici, &ci);
 
     /* Access Technology */
-    if (iact) {
-        str = g_match_info_fetch (info, iact);
-        act = (gint) parse_uint (str, 10, 0, 7, &foo);
-        g_free (str);
-        if (!foo)
-            act = -1;
-    }
+    if (iact)
+        mm_get_int_from_match_info (info, iact, &act);
 
     *out_reg_state = (MMModem3gppRegistrationState) stat;
     if (stat != MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN) {
         /* Don't fill in lac/ci/act if the device's state is unknown */
-        *out_lac = lac;
-        *out_ci = ci;
-
-        *out_act = get_mm_access_tech_from_etsi_access_tech (act);
+        *out_lac = (gulong)lac;
+        *out_ci  = (gulong)ci;
+        *out_act = (act >= 0 ? get_mm_access_tech_from_etsi_access_tech (act) : MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
     }
     return TRUE;
 }
@@ -2662,8 +2576,9 @@
 }
 
 gboolean
-mm_3gpp_rxlev_to_rssi (guint    rxlev,
-                       gdouble *out_rssi)
+mm_3gpp_rxlev_to_rssi (guint     rxlev,
+                       gpointer  log_object,
+                       gdouble  *out_rssi)
 {
     if (rxlev <= 63) {
         *out_rssi = -111.0 + rxlev;
@@ -2671,13 +2586,14 @@
     }
 
     if (rxlev != 99)
-        mm_warn ("unexpected rxlev: %u", rxlev);
+        mm_obj_warn (log_object, "unexpected rxlev: %u", rxlev);
     return FALSE;
 }
 
 gboolean
-mm_3gpp_rscp_level_to_rscp (guint    rscp_level,
-                            gdouble *out_rscp)
+mm_3gpp_rscp_level_to_rscp (guint     rscp_level,
+                            gpointer  log_object,
+                            gdouble  *out_rscp)
 {
     if (rscp_level <= 96) {
         *out_rscp = -121.0 + rscp_level;
@@ -2685,13 +2601,14 @@
     }
 
     if (rscp_level != 255)
-        mm_warn ("unexpected rscp level: %u", rscp_level);
+        mm_obj_warn (log_object, "unexpected rscp level: %u", rscp_level);
     return FALSE;
 }
 
 gboolean
-mm_3gpp_ecn0_level_to_ecio (guint    ecn0_level,
-                            gdouble *out_ecio)
+mm_3gpp_ecn0_level_to_ecio (guint     ecn0_level,
+                            gpointer  log_object,
+                            gdouble  *out_ecio)
 {
     if (ecn0_level <= 49) {
         *out_ecio = -24.5 + (((gdouble) ecn0_level) * 0.5);
@@ -2699,13 +2616,14 @@
     }
 
     if (ecn0_level != 255)
-        mm_warn ("unexpected Ec/N0 level: %u", ecn0_level);
+        mm_obj_warn (log_object, "unexpected Ec/N0 level: %u", ecn0_level);
     return FALSE;
 }
 
 gboolean
-mm_3gpp_rsrq_level_to_rsrq (guint    rsrq_level,
-                            gdouble *out_rsrq)
+mm_3gpp_rsrq_level_to_rsrq (guint     rsrq_level,
+                            gpointer  log_object,
+                            gdouble  *out_rsrq)
 {
     if (rsrq_level <= 34) {
         *out_rsrq = -20.0 + (((gdouble) rsrq_level) * 0.5);
@@ -2713,13 +2631,14 @@
     }
 
     if (rsrq_level != 255)
-        mm_warn ("unexpected RSRQ level: %u", rsrq_level);
+        mm_obj_warn (log_object, "unexpected RSRQ level: %u", rsrq_level);
     return FALSE;
 }
 
 gboolean
-mm_3gpp_rsrp_level_to_rsrp (guint    rsrp_level,
-                            gdouble *out_rsrp)
+mm_3gpp_rsrp_level_to_rsrp (guint     rsrp_level,
+                            gpointer  log_object,
+                            gdouble  *out_rsrp)
 {
     if (rsrp_level <= 97) {
         *out_rsrp = -141.0 + rsrp_level;
@@ -2727,12 +2646,13 @@
     }
 
     if (rsrp_level != 255)
-        mm_warn ("unexpected RSRP level: %u", rsrp_level);
+        mm_obj_warn (log_object, "unexpected RSRP level: %u", rsrp_level);
     return FALSE;
 }
 
 gboolean
 mm_3gpp_cesq_response_to_signal_info (const gchar  *response,
+                                      gpointer      log_object,
                                       MMSignal    **out_gsm,
                                       MMSignal    **out_umts,
                                       MMSignal    **out_lte,
@@ -2761,7 +2681,7 @@
         return FALSE;
 
     /* GERAN RSSI */
-    if (mm_3gpp_rxlev_to_rssi (rxlev, &rssi)) {
+    if (mm_3gpp_rxlev_to_rssi (rxlev, log_object, &rssi)) {
         gsm = mm_signal_new ();
         mm_signal_set_rssi (gsm, rssi);
     }
@@ -2769,26 +2689,26 @@
     /* ignore BER */
 
     /* UMTS RSCP */
-    if (mm_3gpp_rscp_level_to_rscp (rscp_level, &rscp)) {
+    if (mm_3gpp_rscp_level_to_rscp (rscp_level, log_object, &rscp)) {
         umts = mm_signal_new ();
         mm_signal_set_rscp (umts, rscp);
     }
 
     /* UMTS EcIo (assumed EcN0) */
-    if (mm_3gpp_ecn0_level_to_ecio (ecn0_level, &ecio)) {
+    if (mm_3gpp_ecn0_level_to_ecio (ecn0_level, log_object, &ecio)) {
         if (!umts)
             umts = mm_signal_new ();
         mm_signal_set_ecio (umts, ecio);
     }
 
     /* LTE RSRQ */
-    if (mm_3gpp_rsrq_level_to_rsrq (rsrq_level, &rsrq)) {
+    if (mm_3gpp_rsrq_level_to_rsrq (rsrq_level, log_object, &rsrq)) {
         lte = mm_signal_new ();
         mm_signal_set_rsrq (lte, rsrq);
     }
 
     /* LTE RSRP */
-    if (mm_3gpp_rsrp_level_to_rsrp (rsrp_level, &rsrp)) {
+    if (mm_3gpp_rsrp_level_to_rsrp (rsrp_level, log_object, &rsrp)) {
         if (!lte)
             lte = mm_signal_new ();
         mm_signal_set_rsrp (lte, rsrp);
@@ -2887,6 +2807,7 @@
 
 gboolean
 mm_3gpp_parse_ccwa_service_query_response (const gchar  *response,
+                                           gpointer      log_object,
                                            gboolean     *status,
                                            GError      **error)
 {
@@ -2922,10 +2843,10 @@
         guint class;
 
         if (!mm_get_uint_from_match_info (match_info, 2, &class))
-            mm_warn ("couldn't parse class from +CCWA line");
+            mm_obj_warn (log_object, "couldn't parse class from +CCWA line");
         else if (class == 1 || class == 255) {
             if (!mm_get_uint_from_match_info (match_info, 1, &st))
-                mm_warn ("couldn't parse status from +CCWA line");
+                mm_obj_warn (log_object, "couldn't parse status from +CCWA line");
             else {
                 class_1_status = st;
                 break;
@@ -2982,17 +2903,18 @@
 }
 
 gboolean
-mm_3gpp_parse_cpms_test_response (const gchar *reply,
-                                  GArray **mem1,
-                                  GArray **mem2,
-                                  GArray **mem3)
+mm_3gpp_parse_cpms_test_response (const gchar  *reply,
+                                  GArray      **mem1,
+                                  GArray      **mem2,
+                                  GArray      **mem3,
+                                  GError      **error)
 {
-    GRegex *r;
-    gchar **split;
     guint i;
-    GArray *tmp1 = NULL;
-    GArray *tmp2 = NULL;
-    GArray *tmp3 = NULL;
+    g_autoptr(GRegex) r = NULL;
+    g_autoptr(GArray) tmp1 = NULL;
+    g_autoptr(GArray) tmp2 = NULL;
+    g_autoptr(GArray) tmp3 = NULL;
+    g_auto(GStrv)     split = NULL;
 
     g_assert (mem1 != NULL);
     g_assert (mem2 != NULL);
@@ -3005,9 +2927,9 @@
         return FALSE;
 
     if (g_strv_length (split) != N_EXPECTED_GROUPS) {
-        mm_warn ("Cannot parse +CPMS test response: invalid number of groups (%u != %u)",
-                 g_strv_length (split), N_EXPECTED_GROUPS);
-        g_strfreev (split);
+        g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+                     "Cannot parse +CPMS test response: invalid number of groups (%u != %u)",
+                     g_strv_length (split), N_EXPECTED_GROUPS);
         return FALSE;
     }
 
@@ -3050,29 +2972,20 @@
             g_assert_not_reached ();
     }
 
-    g_strfreev (split);
-    g_regex_unref (r);
-
-    g_warn_if_fail (tmp1 != NULL);
-    g_warn_if_fail (tmp2 != NULL);
-    g_warn_if_fail (tmp3 != NULL);
-
     /* Only return TRUE if all sets have been parsed correctly
      * (even if the arrays may be empty) */
     if (tmp1 && tmp2 && tmp3) {
-        *mem1 = tmp1;
-        *mem2 = tmp2;
-        *mem3 = tmp3;
+        *mem1 = g_steal_pointer (&tmp1);
+        *mem2 = g_steal_pointer (&tmp2);
+        *mem3 = g_steal_pointer (&tmp3);
         return TRUE;
     }
 
-    /* Otherwise, cleanup and return FALSE */
-    if (tmp1)
-        g_array_unref (tmp1);
-    if (tmp2)
-        g_array_unref (tmp2);
-    if (tmp3)
-        g_array_unref (tmp3);
+    g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+                 "Cannot parse +CPMS test response: mem1 %s, mem2 %s, mem3 %s",
+                 tmp1 ? "yes" : "no",
+                 tmp2 ? "yes" : "no",
+                 tmp3 ? "yes" : "no");
     return FALSE;
 }
 
@@ -3352,6 +3265,7 @@
 
 gboolean
 mm_3gpp_parse_cmer_test_response (const gchar     *response,
+                                  gpointer         log_object,
                                   MM3gppCmerMode  *out_supported_modes,
                                   MM3gppCmerInd   *out_supported_inds,
                                   GError         **error)
@@ -3406,7 +3320,7 @@
         if (mode_val <= 3)
             supported_modes |= (MM3gppCmerMode) (1 << mode_val);
         else
-            mm_dbg ("Unknown +CMER mode reported: %u", mode_val);
+            mm_obj_dbg (log_object, "unknown +CMER mode reported: %u", mode_val);
     }
 
     for (i = 0; i < array_supported_inds->len; i++) {
@@ -3416,7 +3330,7 @@
         if (ind_val <= 2)
             supported_inds |= (MM3gppCmerInd) (1 << ind_val);
         else
-            mm_dbg ("Unknown +CMER ind reported: %u", ind_val);
+            mm_obj_dbg (log_object, "unknown +CMER ind reported: %u", ind_val);
     }
 
     if (out_supported_modes)
diff --git a/src/mm-modem-helpers.h b/src/mm-modem-helpers.h
index 2ad24fa..819c90a 100644
--- a/src/mm-modem-helpers.h
+++ b/src/mm-modem-helpers.h
@@ -39,13 +39,10 @@
 /* Common utilities */
 /*****************************************************************************/
 
-#define MM_MODEM_CAPABILITY_3GPP_LTE    \
-    (MM_MODEM_CAPABILITY_LTE |          \
-     MM_MODEM_CAPABILITY_LTE_ADVANCED)
-
 #define MM_MODEM_CAPABILITY_3GPP        \
     (MM_MODEM_CAPABILITY_GSM_UMTS |     \
-     MM_MODEM_CAPABILITY_3GPP_LTE)
+     MM_MODEM_CAPABILITY_LTE |          \
+     MM_MODEM_CAPABILITY_5GNR)
 
 gchar       *mm_strip_quotes (gchar *str);
 const gchar *mm_strip_tag    (const gchar *str,
@@ -59,8 +56,9 @@
 guint mm_count_bits_set (gulong number);
 guint mm_find_bit_set   (gulong number);
 
-gchar *mm_create_device_identifier (guint vid,
-                                    guint pid,
+gchar *mm_create_device_identifier (guint        vid,
+                                    guint        pid,
+                                    gpointer     log_object,
                                     const gchar *ati,
                                     const gchar *ati1,
                                     const gchar *gsn,
@@ -83,10 +81,8 @@
                             gint offset_minutes);
 
 GArray *mm_filter_supported_modes (const GArray *all,
-                                   const GArray *supported_combinations);
-
-GArray *mm_filter_supported_capabilities (MMModemCapability all,
-                                          const GArray *supported_combinations);
+                                   const GArray *supported_combinations,
+                                   gpointer      log_object);
 
 gchar *mm_bcd_to_string (const guint8 *bcd, gsize bcd_len);
 
@@ -107,6 +103,7 @@
     gchar           *number; /* optional */
 } MMCallInfo;
 gboolean mm_3gpp_parse_clcc_response (const gchar  *str,
+                                      gpointer      log_object,
                                       GList       **out_list,
                                       GError      **error);
 void     mm_3gpp_call_info_list_free (GList        *call_info_list);
@@ -126,6 +123,7 @@
 } MMFlowControl;
 
 MMFlowControl mm_parse_ifc_test_response (const gchar  *response,
+                                          gpointer      log_object,
                                           GError      **error);
 
 MMFlowControl mm_flow_control_from_string (const gchar  *str,
@@ -159,6 +157,7 @@
 void mm_3gpp_network_info_list_free (GList *info_list);
 GList *mm_3gpp_parse_cops_test_response (const gchar     *reply,
                                          MMModemCharset   cur_charset,
+                                         gpointer         log_object,
                                          GError         **error);
 
 /* AT+COPS? (current operator) response parser */
@@ -180,8 +179,9 @@
     MMBearerIpFamily pdp_type;
 } MM3gppPdpContextFormat;
 void mm_3gpp_pdp_context_format_list_free (GList *pdp_format_list);
-GList *mm_3gpp_parse_cgdcont_test_response (const gchar *reply,
-                                            GError **error);
+GList *mm_3gpp_parse_cgdcont_test_response (const gchar  *reply,
+                                            gpointer      log_object,
+                                            GError      **error);
 
 /* AT+CGDCONT? (PDP context query) response parser */
 typedef struct {
@@ -198,8 +198,9 @@
                                MMBearerIpFamily  ip_family,
                                GList            *context_list,
                                GList            *context_format_list,
-                               gboolean         *cid_reused,
-                               gboolean         *cid_overwritten);
+                               gpointer          log_object,
+                               gboolean         *out_cid_reused,
+                               gboolean         *out_cid_overwritten);
 
 typedef struct {
     guint profile_id;
@@ -209,6 +210,7 @@
     MMBearerAllowedAuth auth_type;
 } MM3gppProfile;
 void mm_3gpp_profile_list_free (GList *profiles);
+GList *mm_3gpp_profile_list_copy (GList *profiles);
 
 /* AT+CGACT? (active PDP context query) response parser */
 typedef struct {
@@ -222,14 +224,16 @@
                                           GError **error);
 
 /* CREG/CGREG response/unsolicited message parser */
-gboolean mm_3gpp_parse_creg_response (GMatchInfo *info,
-                                      MMModem3gppRegistrationState *out_reg_state,
-                                      gulong *out_lac,
-                                      gulong *out_ci,
-                                      MMModemAccessTechnology *out_act,
-                                      gboolean *out_cgreg,
-                                      gboolean *out_cereg,
-                                      GError **error);
+gboolean mm_3gpp_parse_creg_response (GMatchInfo                    *info,
+                                      gpointer                       log_object,
+                                      MMModem3gppRegistrationState  *out_reg_state,
+                                      gulong                        *out_lac,
+                                      gulong                        *out_ci,
+                                      MMModemAccessTechnology       *out_act,
+                                      gboolean                      *out_cgreg,
+                                      gboolean                      *out_cereg,
+                                      gboolean                      *out_c5greg,
+                                      GError                       **error);
 
 /* AT+CMGF=? (SMS message format) response parser */
 gboolean mm_3gpp_parse_cmgf_test_response (const gchar *reply,
@@ -238,10 +242,11 @@
                                            GError **error);
 
 /* AT+CPMS=? (Preferred SMS storage) response parser */
-gboolean mm_3gpp_parse_cpms_test_response (const gchar *reply,
-                                           GArray **mem1,
-                                           GArray **mem2,
-                                           GArray **mem3);
+gboolean mm_3gpp_parse_cpms_test_response (const gchar  *reply,
+                                           GArray      **mem1,
+                                           GArray      **mem2,
+                                           GArray      **mem3,
+                                           GError      **error);
 
 /* AT+CPMS? (Current SMS storage) response parser */
 gboolean mm_3gpp_parse_cpms_query_response (const gchar *reply,
@@ -288,6 +293,7 @@
 gchar    *mm_3gpp_build_cmer_set_request   (MM3gppCmerMode   mode,
                                             MM3gppCmerInd    ind);
 gboolean  mm_3gpp_parse_cmer_test_response (const gchar     *reply,
+                                            gpointer         log_object,
                                             MM3gppCmerMode  *supported_modes,
                                             MM3gppCmerInd   *supported_inds,
                                             GError         **error);
@@ -404,6 +410,7 @@
                                       GError      **error);
 
 gboolean mm_3gpp_cesq_response_to_signal_info (const gchar  *response,
+                                               gpointer      log_object,
                                                MMSignal    **out_gsm,
                                                MMSignal    **out_umts,
                                                MMSignal    **out_lte,
@@ -417,6 +424,7 @@
 
 /* CCWA service query response parser */
 gboolean mm_3gpp_parse_ccwa_service_query_response (const gchar  *response,
+                                                    gpointer      log_object,
                                                     gboolean     *status,
                                                     GError      **error);
 
@@ -442,18 +450,24 @@
 char *mm_3gpp_parse_iccid (const char *raw_iccid, GError **error);
 
 
-gboolean mm_3gpp_rscp_level_to_rscp   (guint    rscp_level,
-                                       gdouble *out_rscp);
-gboolean mm_3gpp_rxlev_to_rssi        (guint    rxlev,
-                                       gdouble *out_rssi);
-gboolean mm_3gpp_ecn0_level_to_ecio   (guint    ecn0_level,
-                                       gdouble *out_ecio);
-gboolean mm_3gpp_rsrq_level_to_rsrq   (guint    rsrq_level,
-                                       gdouble *out_rsrq);
-gboolean mm_3gpp_rsrp_level_to_rsrp   (guint    rsrp_level,
-                                       gdouble *out_rsrp);
-gboolean mm_3gpp_rssnr_level_to_rssnr (gint     rssnr_level,
-                                       gdouble *out_rssnr);
+gboolean mm_3gpp_rscp_level_to_rscp   (guint     rscp_level,
+                                       gpointer  log_object,
+                                       gdouble  *out_rscp);
+gboolean mm_3gpp_rxlev_to_rssi        (guint     rxlev,
+                                       gpointer  log_object,
+                                       gdouble  *out_rssi);
+gboolean mm_3gpp_ecn0_level_to_ecio   (guint     ecn0_level,
+                                       gpointer  log_object,
+                                       gdouble  *out_ecio);
+gboolean mm_3gpp_rsrq_level_to_rsrq   (guint     rsrq_level,
+                                       gpointer  log_object,
+                                       gdouble  *out_rsrq);
+gboolean mm_3gpp_rsrp_level_to_rsrp   (guint     rsrp_level,
+                                       gpointer  log_object,
+                                       gdouble  *out_rsrp);
+gboolean mm_3gpp_rssnr_level_to_rssnr (gint      rssnr_level,
+                                       gpointer  log_object,
+                                       gdouble  *out_rssnr);
 
 GStrv mm_3gpp_parse_emergency_numbers (const char *raw, GError **error);
 
diff --git a/src/mm-plugin-manager.c b/src/mm-plugin-manager.c
index 950af44..9ee4eda 100644
--- a/src/mm-plugin-manager.c
+++ b/src/mm-plugin-manager.c
@@ -28,16 +28,17 @@
 #include "mm-plugin-manager.h"
 #include "mm-plugin.h"
 #include "mm-shared.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 #define SHARED_PREFIX "libmm-shared"
 #define PLUGIN_PREFIX "libmm-plugin"
 
-static void initable_iface_init (GInitableIface *iface);
+static void initable_iface_init   (GInitableIface *iface);
+static void log_object_iface_init (MMLogObjectInterface *iface);
 
 G_DEFINE_TYPE_EXTENDED (MMPluginManager, mm_plugin_manager, G_TYPE_OBJECT, 0,
-                        G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
-                                               initable_iface_init))
+                        G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init)
+                        G_IMPLEMENT_INTERFACE (MM_TYPE_LOG_OBJECT, log_object_iface_init))
 
 enum {
     PROP_0,
@@ -260,7 +261,8 @@
 static void
 port_context_complete (PortContext *port_context)
 {
-    GTask *task;
+    MMPluginManager *self;
+    GTask           *task;
 
     /* If already completed, do nothing */
     if (!port_context->task)
@@ -271,8 +273,9 @@
     port_context->task = NULL;
 
     /* Log about the time required to complete the checks */
-    mm_dbg ("[plugin manager] task %s: finished in '%lf' seconds",
-            port_context->name, g_timer_elapsed (port_context->timer, NULL));
+    self = g_task_get_source_object (task);
+    mm_obj_dbg (self, "task %s: finished in '%lf' seconds",
+                port_context->name, g_timer_elapsed (port_context->timer, NULL));
 
     if (!port_context->best_plugin)
         g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, "Unsupported");
@@ -287,10 +290,13 @@
 port_context_supported (PortContext *port_context,
                         MMPlugin    *plugin)
 {
-    g_assert (plugin);
+    MMPluginManager *self;
 
-    mm_dbg ("[plugin manager] task %s: found best plugin for port (%s)",
-            port_context->name, mm_plugin_get_name (plugin));
+    g_assert (plugin);
+    self = g_task_get_source_object (port_context->task);
+
+    mm_obj_dbg (self, "task %s: found best plugin for port (%s)",
+                port_context->name, mm_plugin_get_name (plugin));
 
     /* Found a best plugin, store it to return it */
     port_context->best_plugin = g_object_ref (plugin);
@@ -309,7 +315,8 @@
 port_context_set_suggestion (PortContext *port_context,
                              MMPlugin    *suggested_plugin)
 {
-    gboolean forbidden_icera;
+    MMPluginManager *self;
+    gboolean         forbidden_icera;
 
     /* Plugin suggestions serve two different purposes here:
      *  1) Finish all the probes which were deferred until suggested.
@@ -325,6 +332,9 @@
     if (port_context->best_plugin || port_context->suggested_plugin)
         return;
 
+    /* There may not be a task at this point, so be gentle */
+    self = port_context->task ? g_task_get_source_object (port_context->task) : NULL;
+
     /* Complete tasks which were deferred until suggested */
     if (port_context->defer_until_suggested) {
         /* Reset the defer until suggested flag; we consider this
@@ -332,8 +342,8 @@
         port_context->defer_until_suggested = FALSE;
 
         if (suggested_plugin) {
-            mm_dbg ("[plugin manager] task %s: deferred task completed, got suggested plugin (%s)",
-                    port_context->name, mm_plugin_get_name (suggested_plugin));
+            mm_obj_dbg (self, "task %s: deferred task completed, got suggested plugin (%s)",
+                        port_context->name, mm_plugin_get_name (suggested_plugin));
             /* Advance to the suggested plugin and re-check support there */
             port_context->suggested_plugin = g_object_ref (suggested_plugin);
             port_context->current = g_list_find (port_context->current, port_context->suggested_plugin);
@@ -343,8 +353,7 @@
             return;
         }
 
-        mm_dbg ("[plugin manager] task %s: deferred task completed, no suggested plugin",
-                port_context->name);
+        mm_obj_dbg (self, "task %s: deferred task completed, no suggested plugin", port_context->name);
         port_context_complete (port_context);
         return;
     }
@@ -354,7 +363,7 @@
         return;
 
     /* The GENERIC plugin is NEVER suggested to others */
-    if (g_str_equal (mm_plugin_get_name (suggested_plugin), MM_PLUGIN_GENERIC_NAME))
+    if (mm_plugin_is_generic (suggested_plugin))
         return;
 
     /* If the plugin has MM_PLUGIN_FORBIDDEN_ICERA set, we do *not* suggest
@@ -372,8 +381,8 @@
      * should run its probing independently, and we'll later decide
      * which result applies to the whole device.
      */
-    mm_dbg ("[plugin manager] task %s: got suggested plugin (%s)",
-            port_context->name, mm_plugin_get_name (suggested_plugin));
+    mm_obj_dbg (self, "task %s: got suggested plugin (%s)",
+                port_context->name, mm_plugin_get_name (suggested_plugin));
     port_context->suggested_plugin = g_object_ref (suggested_plugin);
 }
 
@@ -381,7 +390,10 @@
 port_context_unsupported (PortContext *port_context,
                           MMPlugin    *plugin)
 {
+    MMPluginManager *self;
+
     g_assert (plugin);
+    self = g_task_get_source_object (port_context->task);
 
     /* If there is no suggested plugin, go on to the next one */
     if (!port_context->suggested_plugin) {
@@ -396,8 +408,8 @@
      * just cancel the port probing and avoid more tests.
      */
     if (port_context->suggested_plugin == plugin) {
-        mm_dbg ("[plugin manager] task %s: ignoring port unsupported by physical modem's plugin",
-                port_context->name);
+        mm_obj_dbg (self, "task %s: ignoring port unsupported by physical modem's plugin",
+                    port_context->name);
         port_context_complete (port_context);
         return;
     }
@@ -412,14 +424,17 @@
 static void
 port_context_defer (PortContext *port_context)
 {
+    MMPluginManager *self;
+
+    self = g_task_get_source_object (port_context->task);
+
     /* Try with the suggested one after being deferred */
     if (port_context->suggested_plugin) {
-        mm_dbg ("[plugin manager] task %s: deferring support check (%s suggested)",
-                port_context->name, mm_plugin_get_name (MM_PLUGIN (port_context->suggested_plugin)));
+        mm_obj_dbg (self, "task %s: deferring support check (%s suggested)",
+                    port_context->name, mm_plugin_get_name (MM_PLUGIN (port_context->suggested_plugin)));
         port_context->current = g_list_find (port_context->current, port_context->suggested_plugin);
     } else
-        mm_dbg ("[plugin manager] task %s: deferring support check",
-                port_context->name);
+        mm_obj_dbg (self, "task %s: deferring support check", port_context->name);
 
     /* Schedule checking support.
      *
@@ -434,14 +449,17 @@
 port_context_defer_until_suggested (PortContext *port_context,
                                     MMPlugin    *plugin)
 {
+    MMPluginManager *self;
+
     g_assert (plugin);
+    self = g_task_get_source_object (port_context->task);
 
     /* If we arrived here and we already have a plugin suggested, use it */
     if (port_context->suggested_plugin) {
         /* We can finish this context */
         if (port_context->suggested_plugin == plugin) {
-            mm_dbg ("[plugin manager] task %s: completed, got suggested plugin (%s)",
-                    port_context->name, mm_plugin_get_name (port_context->suggested_plugin));
+            mm_obj_dbg (self, "task %s: completed, got suggested plugin (%s)",
+                        port_context->name, mm_plugin_get_name (port_context->suggested_plugin));
             /* Store best plugin and end operation */
             port_context->best_plugin = g_object_ref (port_context->suggested_plugin);
             port_context_complete (port_context);
@@ -449,8 +467,8 @@
         }
 
         /* Recheck support in deferred task */
-        mm_dbg ("[plugin manager] task %s: re-checking support on deferred task, got suggested plugin (%s)",
-                port_context->name, mm_plugin_get_name (port_context->suggested_plugin));
+        mm_obj_dbg (self, "task %s: re-checking support on deferred task, got suggested plugin (%s)",
+                    port_context->name, mm_plugin_get_name (port_context->suggested_plugin));
         port_context->current = g_list_find (port_context->current, port_context->suggested_plugin);
         port_context_next (port_context);
         return;
@@ -459,8 +477,7 @@
     /* We are deferred until a suggested plugin is given. If last supports task
      * of a given device is finished without finding a best plugin, this task
      * will get finished reporting unsupported. */
-    mm_dbg ("[plugin manager] task %s: deferring support check until result suggested",
-            port_context->name);
+    mm_obj_dbg (self, "task %s: deferring support check until result suggested", port_context->name);
     port_context->defer_until_suggested = TRUE;
 }
 
@@ -469,15 +486,18 @@
                             GAsyncResult *res,
                             PortContext  *port_context)
 {
+    MMPluginManager        *self;
     MMPluginSupportsResult  support_result;
     GError                 *error = NULL;
 
+    self = g_task_get_source_object (port_context->task);
+
     /* Get supports check results */
     support_result = mm_plugin_supports_port_finish (plugin, res, &error);
     if (error) {
         g_assert_cmpuint (support_result, ==, MM_PLUGIN_SUPPORTS_PORT_UNKNOWN);
-        mm_warn ("[plugin manager] task %s: error when checking support with plugin '%s': '%s'",
-                 port_context->name, mm_plugin_get_name (plugin), error->message);
+        mm_obj_warn (self, "task %s: error when checking support with plugin '%s': %s",
+                     port_context->name, mm_plugin_get_name (plugin), error->message);
         g_error_free (error);
     }
 
@@ -507,7 +527,10 @@
 static void
 port_context_next (PortContext *port_context)
 {
-    MMPlugin *plugin;
+    MMPluginManager *self;
+    MMPlugin        *plugin;
+
+    self = g_task_get_source_object (port_context->task);
 
     /* If we're cancelled, done */
     if (g_cancellable_is_cancelled (port_context->cancellable)) {
@@ -527,8 +550,8 @@
      * async method because we want to make sure the context is still valid
      * once the method finishes. */
     plugin = MM_PLUGIN (port_context->current->data);
-    mm_dbg ("[plugin manager] task %s: checking with plugin '%s'",
-            port_context->name, mm_plugin_get_name (plugin));
+    mm_obj_dbg (self, "task %s: checking with plugin '%s'",
+                port_context->name, mm_plugin_get_name (plugin));
     mm_plugin_supports_port (plugin,
                              port_context->device,
                              port_context->port,
@@ -540,6 +563,8 @@
 static gboolean
 port_context_cancel (PortContext *port_context)
 {
+    MMPluginManager *self;
+
     /* Port context cancellation, which only makes sense if the context is
      * actually being run, so just exit if it isn't. */
     if (!port_context->task)
@@ -549,8 +574,8 @@
     if (g_cancellable_is_cancelled (port_context->cancellable))
         return FALSE;
 
-    mm_dbg ("[plugin manager) task %s: cancellation requested",
-            port_context->name);
+    self = g_task_get_source_object (port_context->task);
+    mm_obj_dbg (self, "task %s: cancellation requested", port_context->name);
 
     /* Make sure we hold a port context reference while cancelling, as the
      * cancellable signal handlers may end up unref-ing our last reference
@@ -600,8 +625,8 @@
         port_context->suggested_plugin = g_object_ref (suggested);
         port_context->current = g_list_find (port_context->current, port_context->suggested_plugin);
         if (!port_context->current)
-            mm_warn ("[plugin manager] task %s: suggested plugin (%s) not among the ones to test",
-                     port_context->name, mm_plugin_get_name (suggested));
+            mm_obj_warn (self, "task %s: suggested plugin (%s) not among the ones to test",
+                         port_context->name, mm_plugin_get_name (suggested));
     }
 
     /* Log the list of plugins found and specify which are the ones that are going
@@ -610,31 +635,31 @@
         gboolean  suggested_found = FALSE;
         GList    *l;
 
-        mm_dbg ("[plugin manager] task %s: found '%u' plugins to try",
-                port_context->name, g_list_length (port_context->plugins));
+        mm_obj_dbg (self, "task %s: found '%u' plugins to try",
+                    port_context->name, g_list_length (port_context->plugins));
 
         for (l = port_context->plugins; l; l = g_list_next (l)) {
             MMPlugin *plugin;
 
             plugin = MM_PLUGIN (l->data);
             if (suggested_found) {
-                mm_dbg ("[plugin manager] task %s: may try with plugin '%s'",
-                        port_context->name, mm_plugin_get_name (plugin));
+                mm_obj_dbg (self, "task %s: may try with plugin '%s'",
+                            port_context->name, mm_plugin_get_name (plugin));
                 continue;
             }
             if (suggested && l == port_context->current) {
                 suggested_found = TRUE;
-                mm_dbg ("[plugin manager] task %s: will try with plugin '%s' (suggested)",
-                        port_context->name, mm_plugin_get_name (plugin));
+                mm_obj_dbg (self, "task %s: will try with plugin '%s' (suggested)",
+                            port_context->name, mm_plugin_get_name (plugin));
                 continue;
             }
             if (suggested && !suggested_found) {
-                mm_dbg ("[plugin manager] task %s: won't try with plugin '%s' (skipped)",
-                        port_context->name, mm_plugin_get_name (plugin));
+                mm_obj_dbg (self, "task %s: won't try with plugin '%s' (skipped)",
+                            port_context->name, mm_plugin_get_name (plugin));
                 continue;
             }
-            mm_dbg ("[plugin manager] task %s: will try with plugin '%s'",
-                    port_context->name, mm_plugin_get_name (plugin));
+            mm_obj_dbg (self, "task %s: will try with plugin '%s'",
+                        port_context->name, mm_plugin_get_name (plugin));
         }
     }
 
@@ -647,7 +672,7 @@
      * best plugin found for the port. */
     port_context->task = g_task_new (self, port_context->cancellable, callback, user_data);
 
-    mm_dbg ("[plugin manager) task %s: started", port_context->name);
+    mm_obj_dbg (self, "task %s: started", port_context->name);
 
     /* Go probe with the first plugin */
     port_context_next (port_context);
@@ -828,22 +853,25 @@
 static void
 device_context_complete (DeviceContext *device_context)
 {
-    GTask *task;
+    MMPluginManager *self;
+    GTask           *task;
+
+    self = g_task_get_source_object (device_context->task);
 
     /* If the context is completed before the 2500ms minimum probing time, we need to wait
      * until that happens, so that we give enough time to udev/hotplug to report the
      * new port additions. */
     if (device_context->min_probing_time_id) {
-        mm_dbg ("[plugin manager] task %s: all port probings completed, but not reached min probing time yet",
-                device_context->name);
+        mm_obj_dbg (self, "task %s: all port probings completed, but not reached min probing time yet",
+                    device_context->name);
         return;
     }
 
     /* If the context is completed less than 1500ms before the last port was exposed,
      * wait some more. */
     if (device_context->extra_probing_time_id) {
-        mm_dbg ("[plugin manager] task %s: all port probings completed, but not reached extra probing time yet",
-                device_context->name);
+        mm_obj_dbg (self, "task %s: all port probings completed, but not reached extra probing time yet",
+                    device_context->name);
         return;
     }
 
@@ -853,8 +881,8 @@
     device_context->task = NULL;
 
     /* Log about the time required to complete the checks */
-    mm_dbg ("[plugin manager] task %s: finished in '%lf' seconds",
-            device_context->name, g_timer_elapsed (device_context->timer, NULL));
+    mm_obj_dbg (self, "task %s: finished in '%lf' seconds",
+                device_context->name, g_timer_elapsed (device_context->timer, NULL));
 
     /* Remove signal handlers */
     if (device_context->grabbed_id) {
@@ -913,20 +941,24 @@
                                 PortContext   *port_context,
                                 MMPlugin      *best_plugin)
 {
+    MMPluginManager *self;
+
+    self = g_task_get_source_object (device_context->task);
+
     if (!best_plugin) {
         /* If the port appeared after an already probed port, which decided that
          * the Generic plugin was the best one (which is by default not initially
          * suggested), we'll end up arriving here. Don't ignore it, it may well
          * be a wwan port that we do need to grab. */
         if (device_context->best_plugin) {
-            mm_dbg ("[plugin manager] task %s: assuming port can be handled by the '%s' plugin",
-                    port_context->name, mm_plugin_get_name (device_context->best_plugin));
+            mm_obj_dbg (self, "task %s: assuming port can be handled by the '%s' plugin",
+                        port_context->name, mm_plugin_get_name (device_context->best_plugin));
             return;
         }
 
         /* Unsupported error, this is generic when we cannot find a plugin */
-        mm_dbg ("[plugin manager] task %s: not supported by any plugin" ,
-                port_context->name);
+        mm_obj_dbg (self, "task %s: not supported by any plugin" ,
+                    port_context->name);
 
         /* Tell the device to ignore this port */
         mm_device_ignore_port (device_context->device, port_context->port);
@@ -942,12 +974,12 @@
      * one and now we're reporting a more specific one, use the new one.
      */
     if (!device_context->best_plugin ||
-        (g_str_equal (mm_plugin_get_name (device_context->best_plugin), MM_PLUGIN_GENERIC_NAME) &&
+        (mm_plugin_is_generic (device_context->best_plugin) &&
          device_context->best_plugin != best_plugin)) {
         /* Only log best plugin if it's not the generic one */
-        if (!g_str_equal (mm_plugin_get_name (best_plugin), MM_PLUGIN_GENERIC_NAME))
-            mm_dbg ("[plugin manager] task %s: found best plugin: %s",
-                    port_context->name, mm_plugin_get_name (best_plugin));
+        if (!mm_plugin_is_generic (best_plugin))
+            mm_obj_dbg (self, "task %s: found best plugin: %s",
+                        port_context->name, mm_plugin_get_name (best_plugin));
         /* Store and suggest this plugin also to other port probes */
         device_context->best_plugin = g_object_ref (best_plugin);
         device_context_suggest_plugin (device_context, port_context, best_plugin);
@@ -979,19 +1011,19 @@
         g_assert (new_allowed_icera == FALSE || new_forbidden_icera == FALSE);
 
         if (previous_allowed_icera && new_forbidden_icera)
-            mm_warn ("[plugin manager] task %s: will use plugin '%s' instead of '%s', modem is icera-capable",
+            mm_obj_warn (self, "task %s: will use plugin '%s' instead of '%s', modem is icera-capable",
                      port_context->name,
                      mm_plugin_get_name (device_context->best_plugin),
                      mm_plugin_get_name (best_plugin));
         else if (new_allowed_icera && previous_forbidden_icera) {
-            mm_warn ("[plugin manager] task %s: overriding previously selected device plugin '%s' with '%s', modem is icera-capable",
+            mm_obj_warn (self, "task %s: overriding previously selected device plugin '%s' with '%s', modem is icera-capable",
                      port_context->name,
                      mm_plugin_get_name (device_context->best_plugin),
                      mm_plugin_get_name (best_plugin));
             g_object_unref (device_context->best_plugin);
             device_context->best_plugin = g_object_ref (best_plugin);
         } else
-            mm_warn ("[plugin manager] task %s: plugin mismatch error (device reports '%s', port reports '%s')",
+            mm_obj_warn (self, "task %s: plugin mismatch error (device reports '%s', port reports '%s')",
                      port_context->name,
                      mm_plugin_get_name (device_context->best_plugin),
                      mm_plugin_get_name (best_plugin));
@@ -999,21 +1031,24 @@
     }
 
     /* Device plugin equal to best plugin */
-    mm_dbg ("[plugin manager] task %s: best plugin matches device reported one: %s",
-            port_context->name, mm_plugin_get_name (best_plugin));
+    mm_obj_dbg (self, "task %s: best plugin matches device reported one: %s",
+                port_context->name, mm_plugin_get_name (best_plugin));
 }
 
 static void
 device_context_continue (DeviceContext *device_context)
 {
-    GList   *l;
-    GString *s = NULL;
-    guint    n = 0;
-    guint    n_active = 0;
+    MMPluginManager *self;
+    GList           *l;
+    GString         *s = NULL;
+    guint            n = 0;
+    guint            n_active = 0;
+
+    self = g_task_get_source_object (device_context->task);
 
     /* If there are no running port contexts around, we're free to finish */
     if (!device_context->port_contexts) {
-        mm_dbg ("[plugin manager] task %s: no more ports to probe", device_context->name);
+        mm_obj_dbg (self, "task %s: no more ports to probe", device_context->name);
         device_context_complete (device_context);
         return;
     }
@@ -1038,12 +1073,12 @@
     }
 
     g_assert (n > 0 && s);
-    mm_dbg ("[plugin Manager] task %s: still %u running probes (%u active): %s",
-            device_context->name, n, n_active, s->str);
+    mm_obj_dbg (self, "task %s: still %u running probes (%u active): %s",
+                device_context->name, n, n_active, s->str);
     g_string_free (s, TRUE);
 
     if (n_active == 0) {
-        mm_dbg ("[plugin manager] task %s: no active tasks to probe", device_context->name);
+        mm_obj_dbg (self, "task %s: no active tasks to probe", device_context->name);
         device_context_suggest_plugin (device_context, NULL, NULL);
     }
 }
@@ -1064,7 +1099,7 @@
             /* This error is not critical */
             device_context_set_best_plugin (common->device_context, common->port_context, NULL);
         } else
-            mm_warn ("[plugin manager] task %s: failed: %s", common->port_context->name, error->message);
+            mm_obj_warn (self, "task %s: failed: %s", common->port_context->name, error->message);
         g_error_free (error);
     } else {
         /* Set the plugin as the best one in the device context */
@@ -1090,9 +1125,12 @@
 static gboolean
 device_context_min_probing_time_elapsed (DeviceContext *device_context)
 {
+    MMPluginManager *self;
+
     device_context->min_probing_time_id = 0;
 
-    mm_dbg ("[plugin manager] task %s: min probing time elapsed", device_context->name);
+    self = g_task_get_source_object (device_context->task);
+    mm_obj_dbg (self, "task %s: min probing time elapsed", device_context->name);
 
     /* Wakeup the device context logic */
     device_context_continue (device_context);
@@ -1102,9 +1140,12 @@
 static gboolean
 device_context_extra_probing_time_elapsed (DeviceContext *device_context)
 {
+    MMPluginManager *self;
+
     device_context->extra_probing_time_id = 0;
 
-    mm_dbg ("[plugin manager] task %s: extra probing time elapsed", device_context->name);
+    self = g_task_get_source_object (device_context->task);
+    mm_obj_dbg (self, "task %s: extra probing time elapsed", device_context->name);
 
     /* Wakeup the device context logic */
     device_context_continue (device_context);
@@ -1129,10 +1170,8 @@
 
     /* If we got one already set in the device context, it will be the first one,
      * unless it is the generic plugin */
-    if (device_context->best_plugin &&
-        !g_str_equal (mm_plugin_get_name (device_context->best_plugin), MM_PLUGIN_GENERIC_NAME)) {
+    if (device_context->best_plugin && !mm_plugin_is_generic (device_context->best_plugin))
         suggested = device_context->best_plugin;
-    }
 
     port_context_run (self,
                       port_context,
@@ -1156,7 +1195,7 @@
     self = device_context->self;
 
     device_context->min_wait_time_id = 0;
-    mm_dbg ("[plugin manager] task %s: min wait time elapsed", device_context->name);
+    mm_obj_dbg (self, "task %s: min wait time elapsed", device_context->name);
 
     /* Move list of port contexts out of the wait list */
     g_assert (!device_context->port_contexts);
@@ -1185,10 +1224,12 @@
 device_context_port_released (DeviceContext  *device_context,
                               MMKernelDevice *port)
 {
-    PortContext *port_context;
+    MMPluginManager *self;
+    PortContext     *port_context;
 
-    mm_dbg ("[plugin manager] task %s: port released: %s",
-            device_context->name, mm_kernel_device_get_name (port));
+    self = g_task_get_source_object (device_context->task);
+    mm_obj_dbg (self, "task %s: port released: %s",
+                device_context->name, mm_kernel_device_get_name (port));
 
     /* Check if there's a waiting port context */
     port_context = device_context_peek_waiting_port_context (device_context, port);
@@ -1209,8 +1250,8 @@
 
     /* This is not something worth warning. If the probing task has already
      * been finished, it will already be removed from the list */
-    mm_dbg ("[plugin manager] task %s: port wasn't found: %s",
-            device_context->name, mm_kernel_device_get_name (port));
+    mm_obj_dbg (self, "task %s: port wasn't found: %s",
+                device_context->name, mm_kernel_device_get_name (port));
 }
 
 static void
@@ -1223,13 +1264,13 @@
     /* Recover plugin manager */
     self = MM_PLUGIN_MANAGER (device_context->self);
 
-    mm_dbg ("[plugin manager] task %s: port grabbed: %s",
-            device_context->name, mm_kernel_device_get_name (port));
+    mm_obj_dbg (self, "task %s: port grabbed: %s",
+                device_context->name, mm_kernel_device_get_name (port));
 
     /* Ignore if for any reason we still have it in the running list */
     port_context = device_context_peek_running_port_context (device_context, port);
     if (port_context) {
-        mm_warn ("[plugin manager] task %s: port context already being processed",
+        mm_obj_warn (self, "task %s: port context already being processed",
                  device_context->name);
         return;
     }
@@ -1237,7 +1278,7 @@
     /* Ignore if for any reason we still have it in the waiting list */
     port_context = device_context_peek_waiting_port_context (device_context, port);
     if (port_context) {
-        mm_warn ("[plugin manager] task %s: port context already scheduled",
+        mm_obj_warn (self, "task %s: port context already scheduled",
                  device_context->name);
         return;
     }
@@ -1255,13 +1296,13 @@
                                      device_context->device,
                                      port);
 
-    mm_dbg ("[plugin manager] task %s: new support task for port",
-            port_context->name);
+    mm_obj_dbg (self, "task %s: new support task for port",
+                port_context->name);
 
     /* Îf still waiting the min wait time, store it in the waiting list */
     if (device_context->min_wait_time_id) {
-        mm_dbg ("[plugin manager) task %s: deferred until min wait time elapsed",
-                port_context->name);
+        mm_obj_dbg (self, "task %s: deferred until min wait time elapsed",
+                    port_context->name);
         /* Store the port reference in the list within the device */
         device_context->wait_port_contexts = g_list_prepend (device_context->wait_port_contexts, port_context);
         return;
@@ -1278,12 +1319,14 @@
 static gboolean
 device_context_cancel (DeviceContext *device_context)
 {
+    MMPluginManager *self;
+
     /* If cancelled already, do nothing */
     if (g_cancellable_is_cancelled (device_context->cancellable))
         return FALSE;
 
-    mm_dbg ("[plugin manager) task %s: cancellation requested",
-            device_context->name);
+    self = g_task_get_source_object (device_context->task);
+    mm_obj_dbg (self, "task %s: cancellation requested", device_context->name);
 
     /* The device context is cancelled now */
     g_cancellable_cancel (device_context->cancellable);
@@ -1502,7 +1545,7 @@
      * Note that we handle cancellations ourselves, as we don't want the caller
      * to be required to keep track of a GCancellable for each of these tasks.
      */
-    task = g_task_new (G_OBJECT (self), NULL, callback, user_data);
+    task = g_task_new (self, NULL, callback, user_data);
 
     /* Fail if there is already a task for the same device */
     device_context = plugin_manager_peek_device_context (self, device);
@@ -1520,8 +1563,8 @@
     /* Track the device context in the list within the plugin manager. */
     self->priv->device_contexts = g_list_prepend (self->priv->device_contexts, device_context);
 
-    mm_dbg ("[plugin manager] task %s: new support task for device: %s",
-            device_context->name, mm_device_get_uid (device_context->device));
+    mm_obj_dbg (self, "task %s: new support task for device: %s",
+                device_context->name, mm_device_get_uid (device_context->device));
 
     /* Run device context */
     device_context_run (self,
@@ -1589,57 +1632,58 @@
 }
 
 static MMPlugin *
-load_plugin (const gchar *path)
+load_plugin (MMPluginManager *self,
+             const gchar     *path)
 {
-    MMPlugin *plugin = NULL;
-    GModule *module;
-    MMPluginCreateFunc plugin_create_func;
-    gint *major_plugin_version;
-    gint *minor_plugin_version;
-    gchar *path_display;
+    MMPlugin           *plugin = NULL;
+    GModule            *module;
+    MMPluginCreateFunc  plugin_create_func;
+    gint               *major_plugin_version;
+    gint               *minor_plugin_version;
+    gchar              *path_display;
 
     /* Get printable UTF-8 string of the path */
     path_display = g_filename_display_name (path);
 
     module = g_module_open (path, 0);
     if (!module) {
-        mm_warn ("[plugin manager] could not load plugin '%s': %s", path_display, g_module_error ());
+        mm_obj_warn (self, "could not load plugin '%s': %s", path_display, g_module_error ());
         goto out;
     }
 
     if (!g_module_symbol (module, "mm_plugin_major_version", (gpointer *) &major_plugin_version)) {
-        mm_warn ("[plugin manager] could not load plugin '%s': Missing major version info", path_display);
+        mm_obj_warn (self, "could not load plugin '%s': Missing major version info", path_display);
         goto out;
     }
 
     if (*major_plugin_version != MM_PLUGIN_MAJOR_VERSION) {
-        mm_warn ("[plugin manager] could not load plugin '%s': Plugin major version %d, %d is required",
+        mm_obj_warn (self, "could not load plugin '%s': Plugin major version %d, %d is required",
                  path_display, *major_plugin_version, MM_PLUGIN_MAJOR_VERSION);
         goto out;
     }
 
     if (!g_module_symbol (module, "mm_plugin_minor_version", (gpointer *) &minor_plugin_version)) {
-        mm_warn ("[plugin manager] could not load plugin '%s': Missing minor version info", path_display);
+        mm_obj_warn (self, "could not load plugin '%s': Missing minor version info", path_display);
         goto out;
     }
 
     if (*minor_plugin_version != MM_PLUGIN_MINOR_VERSION) {
-        mm_warn ("[plugin manager] could not load plugin '%s': Plugin minor version %d, %d is required",
+        mm_obj_warn (self, "could not load plugin '%s': Plugin minor version %d, %d is required",
                    path_display, *minor_plugin_version, MM_PLUGIN_MINOR_VERSION);
         goto out;
     }
 
     if (!g_module_symbol (module, "mm_plugin_create", (gpointer *) &plugin_create_func)) {
-        mm_warn ("[plugin manager] could not load plugin '%s': %s", path_display, g_module_error ());
+        mm_obj_warn (self, "could not load plugin '%s': %s", path_display, g_module_error ());
         goto out;
     }
 
     plugin = (*plugin_create_func) ();
     if (plugin) {
-        mm_dbg ("[plugin manager] loaded plugin '%s' from '%s'", mm_plugin_get_name (plugin), path_display);
+        mm_obj_dbg (self, "loaded plugin '%s' from '%s'", mm_plugin_get_name (plugin), path_display);
         g_object_weak_ref (G_OBJECT (plugin), (GWeakNotify) g_module_close, module);
     } else
-        mm_warn ("[plugin manager] could not load plugin '%s': initialization failed", path_display);
+        mm_obj_warn (self, "could not load plugin '%s': initialization failed", path_display);
 
 out:
     if (module && !plugin)
@@ -1651,7 +1695,8 @@
 }
 
 static void
-load_shared (const gchar *path)
+load_shared (MMPluginManager *self,
+             const gchar     *path)
 {
     GModule      *module;
     gchar        *path_display;
@@ -1664,38 +1709,38 @@
 
     module = g_module_open (path, 0);
     if (!module) {
-        mm_warn ("[plugin manager] could not load shared '%s': %s", path_display, g_module_error ());
+        mm_obj_warn (self, "could not load shared '%s': %s", path_display, g_module_error ());
         goto out;
     }
 
     if (!g_module_symbol (module, "mm_shared_major_version", (gpointer *) &major_shared_version)) {
-        mm_warn ("[plugin manager] could not load shared '%s': Missing major version info", path_display);
+        mm_obj_warn (self, "could not load shared '%s': Missing major version info", path_display);
         goto out;
     }
 
     if (*major_shared_version != MM_SHARED_MAJOR_VERSION) {
-        mm_warn ("[plugin manager] could not load shared '%s': Shared major version %d, %d is required",
-                 path_display, *major_shared_version, MM_SHARED_MAJOR_VERSION);
+        mm_obj_warn (self, "could not load shared '%s': Shared major version %d, %d is required",
+                     path_display, *major_shared_version, MM_SHARED_MAJOR_VERSION);
         goto out;
     }
 
     if (!g_module_symbol (module, "mm_shared_minor_version", (gpointer *) &minor_shared_version)) {
-        mm_warn ("[plugin manager] could not load shared '%s': Missing minor version info", path_display);
+        mm_obj_warn (self, "could not load shared '%s': Missing minor version info", path_display);
         goto out;
     }
 
     if (*minor_shared_version != MM_SHARED_MINOR_VERSION) {
-        mm_warn ("[plugin manager] could not load shared '%s': Shared minor version %d, %d is required",
-                   path_display, *minor_shared_version, MM_SHARED_MINOR_VERSION);
+        mm_obj_warn (self, "could not load shared '%s': Shared minor version %d, %d is required",
+                     path_display, *minor_shared_version, MM_SHARED_MINOR_VERSION);
         goto out;
     }
 
     if (!g_module_symbol (module, "mm_shared_name", (gpointer *) &shared_name)) {
-        mm_warn ("[plugin manager] could not load shared '%s': Missing name", path_display);
+        mm_obj_warn (self, "could not load shared '%s': Missing name", path_display);
         goto out;
     }
 
-    mm_dbg ("[plugin manager] loaded shared '%s' utils from '%s'", *shared_name, path_display);
+    mm_obj_dbg (self, "loaded shared '%s' utils from '%s'", *shared_name, path_display);
 
 out:
     if (module && !(*shared_name))
@@ -1726,7 +1771,7 @@
     /* Get printable UTF-8 string of the path */
     plugindir_display = g_filename_display_name (self->priv->plugin_dir);
 
-    mm_dbg ("[plugin manager] looking for plugins in '%s'", plugindir_display);
+    mm_obj_dbg (self, "looking for plugins in '%s'", plugindir_display);
     dir = g_dir_open (self->priv->plugin_dir, 0, NULL);
     if (!dir) {
         g_set_error (error,
@@ -1748,21 +1793,22 @@
 
     /* Load all shared utils */
     for (l = shared_paths; l; l = g_list_next (l))
-        load_shared ((const gchar *)(l->data));
+        load_shared (self, (const gchar *)(l->data));
 
     /* Load all plugins */
     for (l = plugin_paths; l; l = g_list_next (l)) {
         MMPlugin *plugin;
 
-        plugin = load_plugin ((const gchar *)(l->data));
+        plugin = load_plugin (self, (const gchar *)(l->data));
         if (!plugin)
             continue;
 
-        if (g_str_equal (mm_plugin_get_name (plugin), MM_PLUGIN_GENERIC_NAME))
-            /* Generic plugin */
-            self->priv->generic = plugin;
-        else
-            /* Vendor specific plugin */
+        if (mm_plugin_is_generic (plugin)) {
+            if (self->priv->generic)
+                mm_obj_warn (self, "cannot register more than one generic plugin");
+            else
+                self->priv->generic = plugin;
+        } else
             self->priv->plugins = g_list_append (self->priv->plugins, plugin);
 
         /* Register plugin whitelist rules in filter, if any */
@@ -1772,7 +1818,7 @@
 
     /* Check the generic plugin once all looped */
     if (!self->priv->generic)
-        mm_warn ("[plugin manager] generic plugin not loaded");
+        mm_obj_dbg (self, "generic plugin not loaded");
 
     /* Treat as error if we don't find any plugin */
     if (!self->priv->plugins && !self->priv->generic) {
@@ -1784,8 +1830,8 @@
         goto out;
     }
 
-    mm_dbg ("[plugin manager] successfully loaded %u plugins",
-            g_list_length (self->priv->plugins) + !!self->priv->generic);
+    mm_obj_dbg (self, "successfully loaded %u plugins",
+                g_list_length (self->priv->plugins) + !!self->priv->generic);
 
 out:
     g_list_free_full (shared_paths, g_free);
@@ -1798,6 +1844,16 @@
     return (self->priv->plugins || self->priv->generic);
 }
 
+/*****************************************************************************/
+
+static gchar *
+log_object_build_id (MMLogObject *_self)
+{
+    return g_strdup ("plugin-manager");
+}
+
+/*****************************************************************************/
+
 MMPluginManager *
 mm_plugin_manager_new (const gchar  *plugin_dir,
                        MMFilter     *filter,
@@ -1899,6 +1955,12 @@
 }
 
 static void
+log_object_iface_init (MMLogObjectInterface *iface)
+{
+    iface->build_id = log_object_build_id;
+}
+
+static void
 mm_plugin_manager_class_init (MMPluginManagerClass *manager_class)
 {
     GObjectClass *object_class = G_OBJECT_CLASS (manager_class);
diff --git a/src/mm-plugin.c b/src/mm-plugin.c
index 4407ece..4f3ec18 100644
--- a/src/mm-plugin.c
+++ b/src/mm-plugin.c
@@ -34,7 +34,7 @@
 #include "mm-port-serial-qcdm.h"
 #include "mm-serial-parsers.h"
 #include "mm-private-boxed-types.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-daemon-enums-types.h"
 
 #if defined WITH_QMI
@@ -44,7 +44,10 @@
 # include "mm-broadband-modem-mbim.h"
 #endif
 
-G_DEFINE_TYPE (MMPlugin, mm_plugin, G_TYPE_OBJECT)
+static void log_object_iface_init (MMLogObjectInterface *iface);
+
+G_DEFINE_TYPE_EXTENDED (MMPlugin, mm_plugin, G_TYPE_OBJECT, 0,
+                        G_IMPLEMENT_INTERFACE (MM_TYPE_LOG_OBJECT, log_object_iface_init))
 
 /* Virtual port corresponding to the embedded modem */
 static const gchar *virtual_port[] = {"smd0", NULL};
@@ -61,8 +64,9 @@
 
 
 struct _MMPluginPrivate {
-    gchar *name;
+    gchar      *name;
     GHashTable *tasks;
+    gboolean    is_generic;
 
     /* Pre-probing filters */
     gchar **subsystems;
@@ -104,6 +108,7 @@
 enum {
     PROP_0,
     PROP_NAME,
+    PROP_IS_GENERIC,
     PROP_ALLOWED_SUBSYSTEMS,
     PROP_ALLOWED_DRIVERS,
     PROP_FORBIDDEN_DRIVERS,
@@ -153,6 +158,12 @@
     return self->priv->product_ids;
 }
 
+gboolean
+mm_plugin_is_generic (MMPlugin *self)
+{
+    return self->priv->is_generic;
+}
+
 /*****************************************************************************/
 
 static gboolean
@@ -234,9 +245,7 @@
     /* The plugin may specify that only some subsystems are supported. If that
      * is the case, filter by subsystem */
     if (apply_subsystem_filter (self, port)) {
-        mm_dbg ("(%s) [%s] filtered by subsystem",
-                self->priv->name,
-                mm_kernel_device_get_name (port));
+        mm_obj_dbg (self, "port %s filtered by subsystem", mm_kernel_device_get_name (port));
         return TRUE;
     }
 
@@ -265,9 +274,7 @@
 
         /* If error retrieving driver: unsupported */
         if (!drivers) {
-            mm_dbg ("(%s) [%s] filtered as couldn't retrieve drivers",
-                    self->priv->name,
-                    mm_kernel_device_get_name (port));
+            mm_obj_dbg (self, "port %s filtered as couldn't retrieve drivers", mm_kernel_device_get_name (port));
             return TRUE;
         }
 
@@ -286,9 +293,7 @@
 
             /* If we didn't match any driver: unsupported */
             if (!found) {
-                mm_dbg ("(%s) [%s] filtered by drivers",
-                        self->priv->name,
-                        mm_kernel_device_get_name (port));
+                mm_obj_dbg (self, "port %s filtered by drivers", mm_kernel_device_get_name (port));
                 return TRUE;
             }
         }
@@ -301,9 +306,7 @@
                 for (j = 0; drivers[j]; j++) {
                     /* If we match a forbidden driver: unsupported */
                     if (g_str_equal (drivers[j], self->priv->forbidden_drivers[i])) {
-                        mm_dbg ("(%s) [%s] filtered by forbidden drivers",
-                                self->priv->name,
-                                mm_kernel_device_get_name (port));
+                        mm_obj_dbg (self, "port %s filtered by forbidden drivers", mm_kernel_device_get_name (port));
                         return TRUE;
                     }
                 }
@@ -317,9 +320,7 @@
             for (j = 0; drivers[j]; j++) {
                 /* If we match the QMI driver: unsupported */
                 if (g_str_equal (drivers[j], "qmi_wwan")) {
-                    mm_dbg ("(%s) [%s] filtered by implicit QMI driver",
-                            self->priv->name,
-                            mm_kernel_device_get_name (port));
+                    mm_obj_dbg (self, "port %s filtered by implicit QMI driver", mm_kernel_device_get_name (port));
                     return TRUE;
                 }
             }
@@ -332,9 +333,7 @@
             for (j = 0; drivers[j]; j++) {
                 /* If we match the MBIM driver: unsupported */
                 if (g_str_equal (drivers[j], "cdc_mbim")) {
-                    mm_dbg ("(%s) [%s] filtered by implicit MBIM driver",
-                            self->priv->name,
-                            mm_kernel_device_get_name (port));
+                    mm_obj_dbg (self, "port %s filtered by implicit MBIM driver", mm_kernel_device_get_name (port));
                     return TRUE;
                 }
             }
@@ -398,9 +397,7 @@
           !self->priv->forbidden_product_strings) ||
          g_str_equal (mm_kernel_device_get_subsystem (port), "net") ||
          g_str_has_prefix (mm_kernel_device_get_name (port), "cdc-wdm"))) {
-        mm_dbg ("(%s) [%s] filtered by vendor/product IDs",
-                self->priv->name,
-                mm_kernel_device_get_name (port));
+        mm_obj_dbg (self, "port %s filtered by vendor/product IDs", mm_kernel_device_get_name (port));
         return TRUE;
     }
 
@@ -410,9 +407,7 @@
         for (i = 0; self->priv->forbidden_product_ids[i].l; i++) {
             if (vendor == self->priv->forbidden_product_ids[i].l &&
                 product == self->priv->forbidden_product_ids[i].r) {
-                mm_dbg ("(%s) [%s] filtered by forbidden vendor/product IDs",
-                        self->priv->name,
-                        mm_kernel_device_get_name (port));
+                mm_obj_dbg (self, "port %s filtered by forbidden vendor/product IDs", mm_kernel_device_get_name (port));
                 return TRUE;
             }
         }
@@ -451,9 +446,7 @@
 
         /* If we didn't match any udev tag: unsupported */
         if (!self->priv->udev_tags[i]) {
-            mm_dbg ("(%s) [%s] filtered by udev tags",
-                    self->priv->name,
-                    mm_kernel_device_get_name (port));
+            mm_obj_dbg (self, "port %s filtered by udev tags", mm_kernel_device_get_name (port));
             return TRUE;
         }
     }
@@ -500,9 +493,7 @@
 
         if (vendor_filtered) {
             if (!self->priv->product_strings) {
-                mm_dbg ("(%s) [%s] filtered by vendor strings",
-                        self->priv->name,
-                        mm_port_probe_get_port_name (probe));
+                mm_obj_dbg (self, "port %s filtered by vendor strings", mm_port_probe_get_port_name (probe));
                 return TRUE;
             }
         } else
@@ -525,9 +516,7 @@
         if (self->priv->product_strings) {
             /* If we didn't get any vendor or product: filtered */
             if (!vendor || !product) {
-                mm_dbg ("(%s) [%s] filtered as no vendor/product strings given",
-                        self->priv->name,
-                        mm_port_probe_get_port_name (probe));
+                mm_obj_dbg (self, "port %s filtered as no vendor/product strings given", mm_port_probe_get_port_name (probe));
                 return TRUE;
             }
             else {
@@ -548,9 +537,7 @@
 
                 /* If we didn't match any product: unsupported */
                 if (!self->priv->product_strings[i].l) {
-                    mm_dbg ("(%s) [%s] filtered by vendor/product strings",
-                            self->priv->name,
-                            mm_port_probe_get_port_name (probe));
+                    mm_obj_dbg (self, "port %s filtered by vendor/product strings", mm_port_probe_get_port_name (probe));
                     return TRUE;
                 }
             }
@@ -570,9 +557,7 @@
                 g_free (casefolded_product);
                 if (found) {
                     /* If we match a forbidden product: unsupported */
-                    mm_dbg ("(%s) [%s] filtered by forbidden vendor/product strings",
-                            self->priv->name,
-                            mm_port_probe_get_port_name (probe));
+                    mm_obj_dbg (self, "port %s filtered by forbidden vendor/product strings", mm_port_probe_get_port_name (probe));
                     return TRUE;
                 }
             }
@@ -586,9 +571,7 @@
     if (self->priv->allowed_icera &&
         !mm_port_probe_is_icera (probe)) {
         /* Unsupported! */
-        mm_dbg ("(%s) [%s] filtered as modem is not icera",
-                self->priv->name,
-                mm_port_probe_get_port_name (probe));
+        mm_obj_dbg (self, "port %s filtered as modem is not icera", mm_port_probe_get_port_name (probe));
         return TRUE;
     }
 
@@ -597,9 +580,7 @@
     if (self->priv->forbidden_icera &&
         mm_port_probe_is_icera (probe)) {
         /* Unsupported! */
-        mm_dbg ("(%s) [%s] filtered as modem is icera",
-                self->priv->name,
-                mm_port_probe_get_port_name (probe));
+        mm_obj_dbg (self, "port %s filtered as modem is icera", mm_port_probe_get_port_name (probe));
         return TRUE;
     }
 
@@ -608,9 +589,7 @@
     if (self->priv->allowed_xmm &&
         !mm_port_probe_is_xmm (probe)) {
         /* Unsupported! */
-        mm_dbg ("(%s) [%s] filtered as modem is not XMM",
-                self->priv->name,
-                mm_port_probe_get_port_name (probe));
+        mm_obj_dbg (self, "port %s filtered as modem is not XMM", mm_port_probe_get_port_name (probe));
         return TRUE;
     }
 
@@ -619,9 +598,7 @@
     if (self->priv->forbidden_xmm &&
         mm_port_probe_is_xmm (probe)) {
         /* Unsupported! */
-        mm_dbg ("(%s) [%s] filtered as modem is XMM",
-                self->priv->name,
-                mm_port_probe_get_port_name (probe));
+        mm_obj_dbg (self, "port %s filtered as modem is XMM", mm_port_probe_get_port_name (probe));
         return TRUE;
     }
 
@@ -782,8 +759,7 @@
 
     /* Before launching any probing, check if the port is a net device. */
     if (g_str_equal (mm_kernel_device_get_subsystem (port), "net")) {
-        mm_dbg ("(%s) [%s] probing deferred until result suggested",
-                self->priv->name, mm_kernel_device_get_name (port));
+        mm_obj_dbg (self, "probing of port %s deferred until result suggested", mm_kernel_device_get_name (port));
         g_task_return_int (task, MM_PLUGIN_SUPPORTS_PORT_DEFER_UNTIL_SUGGESTED);
         g_object_unref (task);
         return;
@@ -835,10 +811,9 @@
     if (self->priv->single_at &&
         mm_port_probe_list_has_at_port (mm_device_peek_port_probe_list (device)) &&
         !mm_port_probe_is_at (probe)) {
-        mm_dbg ("(%s) [%s] not setting up AT probing tasks: "
-                "modem already has the expected single AT port",
-                self->priv->name,
-                mm_kernel_device_get_name (port));
+        mm_obj_dbg (self, "not setting up AT probing tasks in port %s: "
+                    "modem already has the expected single AT port",
+                    mm_kernel_device_get_name (port));
 
         /* Assuming it won't be an AT port. We still run the probe anyway, in
          * case we need to check for other port types (e.g. QCDM) */
@@ -856,10 +831,9 @@
 
     /* Launch the probe */
     probe_list_str = mm_port_probe_flag_build_string_from_mask (ctx->flags);
-    mm_dbg ("(%s) [%s] probe required: '%s'",
-            self->priv->name,
-            mm_kernel_device_get_name (port),
-            probe_list_str);
+    mm_obj_dbg (self, "probes required for port %s: '%s'",
+                mm_kernel_device_get_name (port),
+                probe_list_str);
     g_free (probe_list_str);
 
     mm_port_probe_run (probe,
@@ -972,7 +946,7 @@
 
             /* Ports that are explicitly blacklisted will be grabbed as ignored */
             if (mm_port_probe_is_ignored (probe)) {
-                mm_dbg ("(%s/%s): port is blacklisted", subsys, name);
+                mm_obj_dbg (self, "port %s is blacklisted", name);
                 force_ignored = TRUE;
                 goto grab_port;
             }
@@ -982,7 +956,7 @@
                 port_type == MM_PORT_TYPE_NET &&
                 g_strcmp0 (driver, "qmi_wwan") != 0) {
                 /* Non-QMI net ports are ignored in QMI modems */
-                mm_dbg ("(%s/%s): ignoring non-QMI net port in QMI modem", subsys, name);
+                mm_obj_dbg (self, "ignoring non-QMI net port %s in QMI modem", name);
                 force_ignored = TRUE;
                 goto grab_port;
             }
@@ -991,7 +965,7 @@
                 port_type == MM_PORT_TYPE_NET &&
                 g_strcmp0 (driver, "qmi_wwan") == 0) {
                 /* QMI net ports are ignored in non-QMI modems */
-                mm_dbg ("(%s/%s): ignoring QMI net port in non-QMI modem", subsys, name);
+                mm_obj_dbg (self, "ignoring QMI net port %s in non-QMI modem", name);
                 force_ignored = TRUE;
                 goto grab_port;
             }
@@ -999,7 +973,7 @@
             if (port_type == MM_PORT_TYPE_NET &&
                 g_strcmp0 (driver, "qmi_wwan") == 0) {
                 /* QMI net ports are ignored if QMI support not built */
-                mm_dbg ("(%s/%s): ignoring QMI net port as QMI support isn't available", subsys, name);
+                mm_obj_dbg (self, "ignoring QMI net port %s as QMI support isn't available", name);
                 force_ignored = TRUE;
                 goto grab_port;
             }
@@ -1010,7 +984,7 @@
                 port_type == MM_PORT_TYPE_NET &&
                 g_strcmp0 (driver, "cdc_mbim") != 0) {
                 /* Non-MBIM net ports are ignored in MBIM modems */
-                mm_dbg ("(%s/%s): ignoring non-MBIM net port in MBIM modem", subsys, name);
+                mm_obj_dbg (self, "ignoring non-MBIM net port %s in MBIM modem", name);
                 force_ignored = TRUE;
                 goto grab_port;
             }
@@ -1019,14 +993,14 @@
                 port_type == MM_PORT_TYPE_NET &&
                 g_strcmp0 (driver, "cdc_mbim") == 0) {
                 /* MBIM net ports are ignored in non-MBIM modems */
-                mm_dbg ("(%s/%s): ignoring MBIM net port in non-MBIM modem", subsys, name);
+                mm_obj_dbg (self, "ignoring MBIM net port %s in non-MBIM modem", name);
                 force_ignored = TRUE;
                 goto grab_port;
             }
 #else
             if (port_type == MM_PORT_TYPE_NET &&
                 g_strcmp0 (driver, "cdc_mbim") == 0) {
-                mm_dbg ("(%s/%s): ignoring MBIM net port as MBIM support isn't available", subsys, name);
+                mm_obj_dbg (self, "ignoring MBIM net port %s as MBIM support isn't available", name);
                 force_ignored = TRUE;
                 goto grab_port;
             }
@@ -1053,9 +1027,7 @@
 
         next:
             if (!grabbed) {
-                mm_warn ("Could not grab port (%s/%s): '%s'",
-                         subsys, name,
-                         inner_error ? inner_error->message : "unknown error");
+                mm_obj_warn (self, "could not grab port %s: %s", name, inner_error ? inner_error->message : "unknown error");
                 g_clear_error (&inner_error);
             }
         }
@@ -1077,18 +1049,18 @@
              * installed yet). */
             kernel_device = mm_kernel_device_generic_new_with_rules (properties, NULL, &inner_error);
             if (!kernel_device) {
-                mm_warn ("Could not grab port (virtual/%s): '%s'",
-                         virtual_ports[i],
-                         inner_error ? inner_error->message : "unknown error");
+                mm_obj_warn (self, "could not create generic device for virtual port %s: %s",
+                             virtual_ports[i],
+                             inner_error ? inner_error->message : "unknown error");
                 g_clear_error (&inner_error);
             } else if (!mm_base_modem_grab_port (modem,
                                                  kernel_device,
                                                  MM_PORT_TYPE_AT,
                                                  MM_PORT_SERIAL_AT_FLAG_NONE,
                                                  &inner_error)) {
-                mm_warn ("Could not grab port (virtual/%s): '%s'",
-                         virtual_ports[i],
-                         inner_error ? inner_error->message : "unknown error");
+                mm_obj_warn (self, "could not grab virtual port %s: %s",
+                             virtual_ports[i],
+                             inner_error ? inner_error->message : "unknown error");
                 g_clear_error (&inner_error);
             }
 
@@ -1107,6 +1079,19 @@
 
 /*****************************************************************************/
 
+static gchar *
+log_object_build_id (MMLogObject *_self)
+{
+    MMPlugin         *self;
+    g_autofree gchar *plugin_name_lowercase;
+
+    self = MM_PLUGIN (_self);
+    plugin_name_lowercase = g_ascii_strdown (self->priv->name, -1);
+    return g_strdup_printf ("plugin/%s", plugin_name_lowercase);
+}
+
+/*****************************************************************************/
+
 static void
 mm_plugin_init (MMPlugin *self)
 {
@@ -1133,6 +1118,10 @@
         /* Construct only */
         self->priv->name = g_value_dup_string (value);
         break;
+    case PROP_IS_GENERIC:
+        /* Construct only */
+        self->priv->is_generic = g_value_get_boolean (value);
+        break;
     case PROP_ALLOWED_SUBSYSTEMS:
         /* Construct only */
         self->priv->subsystems = g_value_dup_boxed (value);
@@ -1255,6 +1244,9 @@
     case PROP_NAME:
         g_value_set_string (value, self->priv->name);
         break;
+    case PROP_IS_GENERIC:
+        g_value_set_boolean (value, self->priv->is_generic);
+        break;
     case PROP_ALLOWED_SUBSYSTEMS:
         g_value_set_boxed (value, self->priv->subsystems);
         break;
@@ -1367,6 +1359,12 @@
 }
 
 static void
+log_object_iface_init (MMLogObjectInterface *iface)
+{
+    iface->build_id = log_object_build_id;
+}
+
+static void
 mm_plugin_class_init (MMPluginClass *klass)
 {
     GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -1387,6 +1385,14 @@
                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
     g_object_class_install_property
+        (object_class, PROP_IS_GENERIC,
+         g_param_spec_boolean (MM_PLUGIN_IS_GENERIC,
+                               "Generic",
+                               "Whether the plugin is the generic one",
+                               FALSE,
+                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+    g_object_class_install_property
         (object_class, PROP_ALLOWED_SUBSYSTEMS,
          g_param_spec_boxed (MM_PLUGIN_ALLOWED_SUBSYSTEMS,
                              "Allowed subsystems",
diff --git a/src/mm-plugin.h b/src/mm-plugin.h
index 926840b..fe0469c 100644
--- a/src/mm-plugin.h
+++ b/src/mm-plugin.h
@@ -27,7 +27,6 @@
 #include "mm-device.h"
 #include "mm-kernel-device.h"
 
-#define MM_PLUGIN_GENERIC_NAME "Generic"
 #define MM_PLUGIN_MAJOR_VERSION 4
 #define MM_PLUGIN_MINOR_VERSION 0
 
@@ -48,6 +47,7 @@
 #define MM_PLUGIN_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  MM_TYPE_PLUGIN, MMPluginClass))
 
 #define MM_PLUGIN_NAME                      "name"
+#define MM_PLUGIN_IS_GENERIC                "is-generic"
 #define MM_PLUGIN_ALLOWED_SUBSYSTEMS        "allowed-subsystems"
 #define MM_PLUGIN_ALLOWED_DRIVERS           "allowed-drivers"
 #define MM_PLUGIN_FORBIDDEN_DRIVERS         "forbidden-drivers"
@@ -127,6 +127,7 @@
 const gchar           *mm_plugin_get_name                (MMPlugin *self);
 const gchar          **mm_plugin_get_allowed_udev_tags   (MMPlugin *self);
 const mm_uint16_pair  *mm_plugin_get_allowed_product_ids (MMPlugin *self);
+gboolean               mm_plugin_is_generic              (MMPlugin *self);
 
 /* This method will run all pre-probing filters, to see if we can discard this
  * plugin from the probing logic as soon as possible. */
diff --git a/src/mm-port-mbim.c b/src/mm-port-mbim.c
index 1778e78..8e848e4 100644
--- a/src/mm-port-mbim.c
+++ b/src/mm-port-mbim.c
@@ -26,7 +26,7 @@
 #include <mm-errors-types.h>
 
 #include "mm-port-mbim.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 G_DEFINE_TYPE (MMPortMbim, mm_port_mbim, MM_TYPE_PORT)
 
@@ -176,18 +176,14 @@
     self = g_task_get_source_object (task);
 
     if (!qmi_device_open_finish (dev, res, &error)) {
-        mm_dbg ("[%s] error: couldn't open QmiDevice: %s",
-                mm_port_get_device (MM_PORT (self)),
-                error->message);
+        mm_obj_dbg (self, "error: couldn't open QmiDevice: %s", error->message);
         g_error_free (error);
         g_clear_object (&self->priv->qmi_device);
         /* Ignore error and complete */
-        mm_info ("[%s] MBIM device is not QMI capable",
-                 mm_port_get_device (MM_PORT (self)));
+        mm_obj_info (self, "MBIM device is not QMI capable");
         self->priv->qmi_supported = FALSE;
     } else {
-        mm_info ("[%s] MBIM device is QMI capable",
-                 mm_port_get_device (MM_PORT (self)));
+        mm_obj_info (self, "MBIM device is QMI capable");
     }
 
     self->priv->in_progress = FALSE;
@@ -207,13 +203,10 @@
 
     self->priv->qmi_device = qmi_device_new_finish (res, &error);
     if (!self->priv->qmi_device) {
-        mm_dbg ("[%s] error: couldn't create QmiDevice: %s",
-                mm_port_get_device (MM_PORT (self)),
-                error->message);
+        mm_obj_dbg (self, "error: couldn't create QmiDevice: %s", error->message);
         g_error_free (error);
         /* Ignore error and complete */
-        mm_info ("[%s] MBIM device is not QMI capable",
-                 mm_port_get_device (MM_PORT (self)));
+        mm_obj_info (self, "MBIM device is not QMI capable");
         self->priv->qmi_supported = FALSE;
         self->priv->in_progress = FALSE;
         g_task_return_boolean (task, TRUE);
@@ -222,8 +215,7 @@
     }
 
     /* Try to open using QMI over MBIM */
-    mm_dbg ("[%s] trying to open QMI over MBIM device...",
-            mm_port_get_device (MM_PORT (self)));
+    mm_obj_dbg (self, "trying to open QMI over MBIM device...");
     qmi_device_open (self->priv->qmi_device,
                      (QMI_DEVICE_OPEN_FLAGS_PROXY        |
                       QMI_DEVICE_OPEN_FLAGS_MBIM         |
@@ -272,7 +264,7 @@
         mbim_device_service_element_array_free (device_services);
     } else {
         /* Ignore error */
-        mm_dbg ("Couldn't query device services, will attempt QMI open anyway: %s", error->message);
+        mm_obj_dbg (self, "Couldn't query device services, will attempt QMI open anyway: %s", error->message);
         g_error_free (error);
     }
 
@@ -283,8 +275,7 @@
     file = G_FILE (g_task_get_task_data (task));
 
     if (!file || !self->priv->qmi_supported) {
-        mm_info ("[%s] MBIM device is not QMI capable",
-                 mm_port_get_device (MM_PORT (self)));
+        mm_obj_info (self, "MBIM device is not QMI capable");
         self->priv->in_progress = FALSE;
         g_task_return_boolean (task, TRUE);
         g_object_unref (task);
@@ -292,8 +283,7 @@
     }
 
     /* Attempt to create and open the QMI device */
-    mm_dbg ("[%s] checking if QMI over MBIM is supported",
-            mm_port_get_device (MM_PORT (self)));
+    mm_obj_dbg (self, "checking if QMI over MBIM is supported...");
     qmi_device_new (file,
                     g_task_get_cancellable (task),
                     (GAsyncReadyCallback) qmi_device_new_ready,
@@ -338,8 +328,7 @@
         return;
     }
 
-    mm_dbg ("[%s] MBIM device is now open",
-            mm_port_get_device (MM_PORT (self)));
+    mm_obj_dbg (self, "MBIM device is now open");
 
 #if defined WITH_QMI && QMI_MBIM_QMUX_SUPPORTED
     if (self->priv->qmi_supported) {
@@ -507,10 +496,13 @@
                         GAsyncResult *res,
                         GTask        *task)
 {
-    GError *error = NULL;
+    GError     *error = NULL;
+    MMPortMbim *self;
+
+    self = g_task_get_source_object (task);
 
     if (!qmi_device_close_finish (qmi_device, res, &error)) {
-        mm_warn ("Couldn't properly close QMI device: %s", error->message);
+        mm_obj_warn (self, "Couldn't properly close QMI device: %s", error->message);
         g_error_free (error);
     }
 
@@ -561,7 +553,8 @@
         for (l = self->priv->qmi_clients; l; l = g_list_next (l)) {
             QmiClient *qmi_client = QMI_CLIENT (l->data);
 
-            mm_dbg ("Releasing client for service '%s'...", qmi_service_get_string (qmi_client_get_service (qmi_client)));
+            mm_obj_dbg (self, "Releasing client for service '%s'...",
+                        qmi_service_get_string (qmi_client_get_service (qmi_client)));
             qmi_device_release_client (self->priv->qmi_device,
                                        qmi_client,
                                        QMI_DEVICE_RELEASE_CLIENT_FLAGS_RELEASE_CID,
diff --git a/src/mm-port-probe-at.c b/src/mm-port-probe-at.c
index 10cce9e..37a5ab2 100644
--- a/src/mm-port-probe-at.c
+++ b/src/mm-port-probe-at.c
@@ -40,8 +40,6 @@
                                         GError **result_error)
 {
     if (error) {
-        mm_dbg ("Parsing AT got: '%s'", error->message);
-
         /* Timeout errors are the only ones not fatal;
          * they will just go on to the next command. */
         if (g_error_matches (error,
diff --git a/src/mm-port-probe.c b/src/mm-port-probe.c
index 1700111..0c1edef 100644
--- a/src/mm-port-probe.c
+++ b/src/mm-port-probe.c
@@ -27,7 +27,7 @@
 #include <mm-errors-types.h>
 
 #include "mm-port-probe.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-port-serial-at.h"
 #include "mm-port-serial.h"
 #include "mm-serial-parsers.h"
@@ -63,7 +63,10 @@
  *   |----> MBIM capabilities check
  */
 
-G_DEFINE_TYPE (MMPortProbe, mm_port_probe, G_TYPE_OBJECT)
+static void log_object_iface_init (MMLogObjectInterface *iface);
+
+G_DEFINE_TYPE_EXTENDED (MMPortProbe, mm_port_probe, G_TYPE_OBJECT, 0,
+                        G_IMPLEMENT_INTERFACE (MM_TYPE_LOG_OBJECT, log_object_iface_init))
 
 enum {
     PROP_0,
@@ -159,9 +162,7 @@
     self->priv->flags |= MM_PORT_PROBE_AT;
 
     if (self->priv->is_at) {
-        mm_dbg ("(%s/%s) port is AT-capable",
-                mm_kernel_device_get_subsystem (self->priv->port),
-                mm_kernel_device_get_name (self->priv->port));
+        mm_obj_dbg (self, "port is AT-capable");
 
         /* Also set as not a QCDM/QMI/MBIM port */
         self->priv->is_qcdm = FALSE;
@@ -169,9 +170,7 @@
         self->priv->is_mbim = FALSE;
         self->priv->flags |= (MM_PORT_PROBE_QCDM | MM_PORT_PROBE_QMI | MM_PORT_PROBE_MBIM);
     } else {
-        mm_dbg ("(%s/%s) port is not AT-capable",
-                mm_kernel_device_get_subsystem (self->priv->port),
-                mm_kernel_device_get_name (self->priv->port));
+        mm_obj_dbg (self, "port is not AT-capable");
         self->priv->vendor = NULL;
         self->priv->product = NULL;
         self->priv->is_icera = FALSE;
@@ -188,15 +187,11 @@
                                     const gchar *at_vendor)
 {
     if (at_vendor) {
-        mm_dbg ("(%s/%s) vendor probing finished",
-                mm_kernel_device_get_subsystem (self->priv->port),
-                mm_kernel_device_get_name (self->priv->port));
+        mm_obj_dbg (self, "vendor probing finished");
         self->priv->vendor = g_utf8_casefold (at_vendor, -1);
         self->priv->flags |= MM_PORT_PROBE_AT_VENDOR;
     } else {
-        mm_dbg ("(%s/%s) couldn't probe for vendor string",
-                mm_kernel_device_get_subsystem (self->priv->port),
-                mm_kernel_device_get_name (self->priv->port));
+        mm_obj_dbg (self, "couldn't probe for vendor string");
         self->priv->vendor = NULL;
         self->priv->product = NULL;
         self->priv->flags |= (MM_PORT_PROBE_AT_VENDOR | MM_PORT_PROBE_AT_PRODUCT);
@@ -208,15 +203,11 @@
                                      const gchar *at_product)
 {
     if (at_product) {
-        mm_dbg ("(%s/%s) product probing finished",
-                mm_kernel_device_get_subsystem (self->priv->port),
-                mm_kernel_device_get_name (self->priv->port));
+        mm_obj_dbg (self, "product probing finished");
         self->priv->product = g_utf8_casefold (at_product, -1);
         self->priv->flags |= MM_PORT_PROBE_AT_PRODUCT;
     } else {
-        mm_dbg ("(%s/%s) couldn't probe for product string",
-                mm_kernel_device_get_subsystem (self->priv->port),
-                mm_kernel_device_get_name (self->priv->port));
+        mm_obj_dbg (self, "couldn't probe for product string");
         self->priv->product = NULL;
         self->priv->flags |= MM_PORT_PROBE_AT_PRODUCT;
     }
@@ -227,15 +218,11 @@
                                    gboolean is_icera)
 {
     if (is_icera) {
-        mm_dbg ("(%s/%s) Modem is Icera-based",
-                mm_kernel_device_get_subsystem (self->priv->port),
-                mm_kernel_device_get_name (self->priv->port));
+        mm_obj_dbg (self, "modem is Icera-based");
         self->priv->is_icera = TRUE;
         self->priv->flags |= MM_PORT_PROBE_AT_ICERA;
     } else {
-        mm_dbg ("(%s/%s) Modem is probably not Icera-based",
-                mm_kernel_device_get_subsystem (self->priv->port),
-                mm_kernel_device_get_name (self->priv->port));
+        mm_obj_dbg (self, "modem is probably not Icera-based");
         self->priv->is_icera = FALSE;
         self->priv->flags |= MM_PORT_PROBE_AT_ICERA;
     }
@@ -246,15 +233,11 @@
                                  gboolean is_xmm)
 {
     if (is_xmm) {
-        mm_dbg ("(%s/%s) Modem is XMM-based",
-                mm_kernel_device_get_subsystem (self->priv->port),
-                mm_kernel_device_get_name (self->priv->port));
+        mm_obj_dbg (self, "modem is XMM-based");
         self->priv->is_xmm = TRUE;
         self->priv->flags |= MM_PORT_PROBE_AT_XMM;
     } else {
-        mm_dbg ("(%s/%s) Modem is probably not XMM-based",
-                mm_kernel_device_get_subsystem (self->priv->port),
-                mm_kernel_device_get_name (self->priv->port));
+        mm_obj_dbg (self, "modem is probably not XMM-based");
         self->priv->is_xmm = FALSE;
         self->priv->flags |= MM_PORT_PROBE_AT_XMM;
     }
@@ -268,9 +251,7 @@
     self->priv->flags |= MM_PORT_PROBE_QCDM;
 
     if (self->priv->is_qcdm) {
-        mm_dbg ("(%s/%s) port is QCDM-capable",
-                mm_kernel_device_get_subsystem (self->priv->port),
-                mm_kernel_device_get_name (self->priv->port));
+        mm_obj_dbg (self, "port is QCDM-capable");
 
         /* Also set as not an AT/QMI/MBIM port */
         self->priv->is_at = FALSE;
@@ -288,9 +269,7 @@
                               MM_PORT_PROBE_QMI |
                               MM_PORT_PROBE_MBIM);
     } else
-        mm_dbg ("(%s/%s) port is not QCDM-capable",
-                mm_kernel_device_get_subsystem (self->priv->port),
-                mm_kernel_device_get_name (self->priv->port));
+        mm_obj_dbg (self, "port is not QCDM-capable");
 }
 
 void
@@ -301,9 +280,7 @@
     self->priv->flags |= MM_PORT_PROBE_QMI;
 
     if (self->priv->is_qmi) {
-        mm_dbg ("(%s/%s) port is QMI-capable",
-                mm_kernel_device_get_subsystem (self->priv->port),
-                mm_kernel_device_get_name (self->priv->port));
+        mm_obj_dbg (self, "port is QMI-capable");
 
         /* Also set as not an AT/QCDM/MBIM port */
         self->priv->is_at = FALSE;
@@ -319,9 +296,7 @@
                               MM_PORT_PROBE_QCDM |
                               MM_PORT_PROBE_MBIM);
     } else
-        mm_dbg ("(%s/%s) port is not QMI-capable",
-                mm_kernel_device_get_subsystem (self->priv->port),
-                mm_kernel_device_get_name (self->priv->port));
+        mm_obj_dbg (self, "port is not QMI-capable");
 }
 
 void
@@ -332,9 +307,7 @@
     self->priv->flags |= MM_PORT_PROBE_MBIM;
 
     if (self->priv->is_mbim) {
-        mm_dbg ("(%s/%s) port is MBIM-capable",
-                mm_kernel_device_get_subsystem (self->priv->port),
-                mm_kernel_device_get_name (self->priv->port));
+        mm_obj_dbg (self, "port is MBIM-capable");
 
         /* Also set as not an AT/QCDM/QMI port */
         self->priv->is_at = FALSE;
@@ -350,9 +323,7 @@
                               MM_PORT_PROBE_QCDM |
                               MM_PORT_PROBE_QMI);
     } else
-        mm_dbg ("(%s/%s) port is not MBIM-capable",
-                mm_kernel_device_get_subsystem (self->priv->port),
-                mm_kernel_device_get_name (self->priv->port));
+        mm_obj_dbg (self, "port is not MBIM-capable");
 }
 
 /*****************************************************************************/
@@ -494,10 +465,8 @@
 
     is_qmi = mm_port_qmi_open_finish (port_qmi, res, &error);
     if (!is_qmi) {
-        mm_dbg ("(%s/%s) error checking QMI support: '%s'",
-                mm_kernel_device_get_subsystem (self->priv->port),
-                mm_kernel_device_get_name (self->priv->port),
-                error ? error->message : "unknown error");
+        mm_obj_dbg (self, "error checking QMI support: %s",
+                    error ? error->message : "unknown error");
         g_clear_error (&error);
     }
 
@@ -520,9 +489,7 @@
     ctx = g_task_get_task_data (self->priv->task);
 
 #if defined WITH_QMI
-    mm_dbg ("(%s/%s) probing QMI...",
-            mm_kernel_device_get_subsystem (self->priv->port),
-            mm_kernel_device_get_name (self->priv->port));
+    mm_obj_dbg (self, "probing QMI...");
 
     /* Create a port and try to open it */
     ctx->port_qmi = mm_port_qmi_new (mm_kernel_device_get_name (self->priv->port));
@@ -570,10 +537,8 @@
 
     is_mbim = mm_port_mbim_open_finish (mbim_port, res, &error);
     if (!is_mbim) {
-        mm_dbg ("(%s/%s) error checking MBIM support: '%s'",
-                mm_kernel_device_get_subsystem (self->priv->port),
-                mm_kernel_device_get_name (self->priv->port),
-                error ? error->message : "unknown error");
+        mm_obj_dbg (self, "error checking MBIM support: %s",
+                    error ? error->message : "unknown error");
         g_clear_error (&error);
     }
 
@@ -596,9 +561,7 @@
     ctx = g_task_get_task_data (self->priv->task);
 
 #if defined WITH_MBIM
-    mm_dbg ("(%s/%s) probing MBIM...",
-            mm_kernel_device_get_subsystem (self->priv->port),
-            mm_kernel_device_get_name (self->priv->port));
+    mm_obj_dbg (self, "probing MBIM...");
 
     /* Create a port and try to open it */
     ctx->mbim_port = mm_port_mbim_new (mm_kernel_device_get_name (self->priv->port));
@@ -668,10 +631,7 @@
 
         flow_control = mm_flow_control_from_string (flow_control_tag, &error);
         if (flow_control == MM_FLOW_CONTROL_UNKNOWN) {
-            mm_warn ("(%s/%s) Unsupported flow control settings in port: %s",
-                     mm_kernel_device_get_subsystem (self->priv->port),
-                     mm_kernel_device_get_name (self->priv->port),
-                     error->message);
+            mm_obj_warn (self, "unsupported flow control settings in port: %s", error->message);
             g_error_free (error);
         } else {
             g_object_set (serial,
@@ -708,10 +668,7 @@
         /* Parse the response */
         result = qcdm_cmd_version_info_result ((const gchar *) response->data, response->len, &err);
         if (!result) {
-            mm_warn ("(%s/%s) failed to parse QCDM version info command result: %d",
-                     mm_kernel_device_get_subsystem (self->priv->port),
-                     mm_kernel_device_get_name (self->priv->port),
-                     err);
+            mm_obj_warn (self, "failed to parse QCDM version info command result: %d", err);
             retry = TRUE;
         } else {
             /* yay, probably a QCDM port */
@@ -721,11 +678,11 @@
         g_byte_array_unref (response);
     } else if (g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_PARSE_FAILED)) {
         /* Failed to unescape QCDM packet: don't retry */
-        mm_dbg ("QCDM parsing error: %s", error->message);
+        mm_obj_dbg (self, "QCDM parsing error: %s", error->message);
         g_error_free (error);
     } else {
         if (!g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_RESPONSE_TIMEOUT))
-            mm_dbg ("QCDM probe error: (%d) %s", error->code, error->message);
+            mm_obj_dbg (self, "QCDM probe error: (%d) %s", error->code, error->message);
         g_error_free (error);
         retry = TRUE;
     }
@@ -772,9 +729,7 @@
     if (port_probe_task_return_error_if_cancelled (self))
         return G_SOURCE_REMOVE;
 
-    mm_dbg ("(%s/%s) probing QCDM...",
-            mm_kernel_device_get_subsystem (self->priv->port),
-            mm_kernel_device_get_name (self->priv->port));
+    mm_obj_dbg (self, "probing QCDM...");
 
     /* If open, close the AT port */
     if (ctx->serial) {
@@ -1003,9 +958,7 @@
 
     /* If AT probing cancelled, end this partial probing */
     if (g_cancellable_is_cancelled (ctx->at_probing_cancellable)) {
-        mm_dbg ("(%s/%s) no need to keep on probing the port for AT support",
-                mm_kernel_device_get_subsystem (self->priv->port),
-                mm_kernel_device_get_name (self->priv->port));
+        mm_obj_dbg (self, "no need to keep on probing the port for AT support");
         ctx->at_result_processor (self, NULL);
         serial_probe_schedule (self);
         return;
@@ -1046,10 +999,8 @@
         if (ctx->at_commands_wait_secs == 0)
             ctx->source_id = g_idle_add ((GSourceFunc) serial_probe_at, self);
         else {
-            mm_dbg ("(%s/%s) re-scheduling next command in probing group in %u seconds...",
-                    mm_kernel_device_get_subsystem (self->priv->port),
-                    mm_kernel_device_get_name (self->priv->port),
-                    ctx->at_commands_wait_secs);
+            mm_obj_dbg (self, "re-scheduling next command in probing group in %u seconds...",
+                        ctx->at_commands_wait_secs);
             ctx->source_id = g_timeout_add_seconds (ctx->at_commands_wait_secs, (GSourceFunc) serial_probe_at, self);
         }
         goto out;
@@ -1083,9 +1034,7 @@
 
     /* If AT probing cancelled, end this partial probing */
     if (g_cancellable_is_cancelled (ctx->at_probing_cancellable)) {
-        mm_dbg ("(%s/%s) no need to launch probing for AT support",
-                mm_kernel_device_get_subsystem (self->priv->port),
-                mm_kernel_device_get_name (self->priv->port));
+        mm_obj_dbg (self, "no need to launch probing for AT support");
         ctx->at_result_processor (self, NULL);
         serial_probe_schedule (self);
         return G_SOURCE_REMOVE;
@@ -1275,9 +1224,7 @@
     g_assert (self->priv->task);
     ctx = g_task_get_task_data (self->priv->task);
 
-    mm_dbg ("(%s/%s) serial buffer full",
-            mm_kernel_device_get_subsystem (self->priv->port),
-            mm_kernel_device_get_name (self->priv->port));
+    mm_obj_dbg (self, "serial buffer full");
     /* Don't explicitly close the AT port, just end the AT probing
      * (or custom init probing) */
     mm_port_probe_set_result_at (self, FALSE);
@@ -1420,9 +1367,7 @@
     if (g_cancellable_is_cancelled (ctx->at_probing_cancellable))
         return FALSE;
 
-    mm_dbg ("(%s/%s) requested to cancel all AT probing",
-            mm_kernel_device_get_subsystem (self->priv->port),
-            mm_kernel_device_get_name (self->priv->port));
+    mm_obj_dbg (self, "requested to cancel all AT probing");
     g_cancellable_cancel (ctx->at_probing_cancellable);
     return TRUE;
 }
@@ -1478,44 +1423,34 @@
 
     /* If we're told to completely ignore the port, don't do any probing */
     if (self->priv->is_ignored) {
-        mm_dbg ("(%s/%s) port probing finished: skipping for blacklisted port",
-                mm_kernel_device_get_subsystem (self->priv->port),
-                mm_kernel_device_get_name (self->priv->port));
+        mm_obj_dbg (self, "port probing finished: skipping for blacklisted port");
         port_probe_task_return_boolean (self, TRUE);
         return;
     }
 
     /* If this is a port flagged as a GPS port, don't do any AT or QCDM probing */
     if (self->priv->is_gps) {
-        mm_dbg ("(%s/%s) GPS port detected",
-                mm_kernel_device_get_subsystem (self->priv->port),
-                mm_kernel_device_get_name (self->priv->port));
+        mm_obj_dbg (self, "GPS port detected");
         mm_port_probe_set_result_at (self, FALSE);
         mm_port_probe_set_result_qcdm (self, FALSE);
     }
 
     /* If this is a port flagged as an audio port, don't do any AT or QCDM probing */
     if (self->priv->is_audio) {
-        mm_dbg ("(%s/%s) audio port detected",
-                mm_kernel_device_get_subsystem (self->priv->port),
-                mm_kernel_device_get_name (self->priv->port));
+        mm_obj_dbg (self, "audio port detected");
         mm_port_probe_set_result_at (self, FALSE);
         mm_port_probe_set_result_qcdm (self, FALSE);
     }
 
     /* If this is a port flagged as being an AT port, don't do any QCDM probing */
     if (self->priv->maybe_at_primary || self->priv->maybe_at_secondary || self->priv->maybe_at_ppp) {
-        mm_dbg ("(%s/%s) no QCDM probing in possible AT port",
-                mm_kernel_device_get_subsystem (self->priv->port),
-                mm_kernel_device_get_name (self->priv->port));
+        mm_obj_dbg (self, "no QCDM probing in possible AT port");
         mm_port_probe_set_result_qcdm (self, FALSE);
     }
 
     /* If this is a port flagged as being a QCDM port, don't do any AT probing */
     if (self->priv->maybe_qcdm) {
-        mm_dbg ("(%s/%s) no AT probing in possible QCDM port",
-                mm_kernel_device_get_subsystem (self->priv->port),
-                mm_kernel_device_get_name (self->priv->port));
+        mm_obj_dbg (self, "no AT probing in possible QCDM port");
         mm_port_probe_set_result_at (self, FALSE);
     }
 
@@ -1529,19 +1464,14 @@
 
     /* All requested probings already available? If so, we're done */
     if (!ctx->flags) {
-        mm_dbg ("(%s/%s) port probing finished: no more probings needed",
-                mm_kernel_device_get_subsystem (self->priv->port),
-                mm_kernel_device_get_name (self->priv->port));
+        mm_obj_dbg (self, "port probing finished: no more probings needed");
         port_probe_task_return_boolean (self, TRUE);
         return;
     }
 
     /* Log the probes scheduled to be run */
     probe_list_str = mm_port_probe_flag_build_string_from_mask (ctx->flags);
-    mm_dbg ("(%s/%s) launching port probing: '%s'",
-            mm_kernel_device_get_subsystem (self->priv->port),
-            mm_kernel_device_get_name (self->priv->port),
-            probe_list_str);
+    mm_obj_dbg (self, "launching port probing: '%s'", probe_list_str);
     g_free (probe_list_str);
 
     /* If any AT probing is needed, start by opening as AT port */
@@ -1893,6 +1823,17 @@
 
 /*****************************************************************************/
 
+static gchar *
+log_object_build_id (MMLogObject *_self)
+{
+    MMPortProbe *self;
+
+    self = MM_PORT_PROBE (_self);
+    return g_strdup_printf ("%s/probe", mm_kernel_device_get_name (self->priv->port));
+}
+
+/*****************************************************************************/
+
 MMPortProbe *
 mm_port_probe_new (MMDevice       *device,
                    MMKernelDevice *port)
@@ -1990,6 +1931,12 @@
 }
 
 static void
+log_object_iface_init (MMLogObjectInterface *iface)
+{
+    iface->build_id = log_object_build_id;
+}
+
+static void
 mm_port_probe_class_init (MMPortProbeClass *klass)
 {
     GObjectClass *object_class = G_OBJECT_CLASS (klass);
diff --git a/src/mm-port-qmi.c b/src/mm-port-qmi.c
index 75d3ee4..3f39bfc 100644
--- a/src/mm-port-qmi.c
+++ b/src/mm-port-qmi.c
@@ -22,7 +22,7 @@
 #include <mm-errors-types.h>
 
 #include "mm-port-qmi.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 G_DEFINE_TYPE (MMPortQmi, mm_port_qmi, MM_TYPE_PORT)
 
@@ -41,25 +41,39 @@
 
 /*****************************************************************************/
 
-QmiClient *
-mm_port_qmi_peek_client (MMPortQmi *self,
-                         QmiService service,
-                         MMPortQmiFlag flag)
+static QmiClient *
+lookup_client (MMPortQmi     *self,
+               QmiService     service,
+               MMPortQmiFlag  flag,
+               gboolean       steal)
 {
     GList *l;
 
     for (l = self->priv->services; l; l = g_list_next (l)) {
         ServiceInfo *info = l->data;
 
-        if (info->service == service &&
-            info->flag == flag)
-            return info->client;
+        if (info->service == service && info->flag == flag) {
+            QmiClient *found;
+
+            found = info->client;
+            if (steal)
+                self->priv->services = g_list_delete_link (self->priv->services, l);
+            return found;
+        }
     }
 
     return NULL;
 }
 
 QmiClient *
+mm_port_qmi_peek_client (MMPortQmi *self,
+                         QmiService service,
+                         MMPortQmiFlag flag)
+{
+    return lookup_client (self, service, flag, FALSE);
+}
+
+QmiClient *
 mm_port_qmi_get_client (MMPortQmi *self,
                         QmiService service,
                         MMPortQmiFlag flag)
@@ -82,6 +96,30 @@
 
 /*****************************************************************************/
 
+void
+mm_port_qmi_release_client (MMPortQmi     *self,
+                            QmiService     service,
+                            MMPortQmiFlag  flag)
+{
+    QmiClient *client;
+
+    if (!self->priv->qmi_device)
+        return;
+
+    client = lookup_client (self, service, flag, TRUE);
+    if (!client)
+        return;
+
+    mm_obj_dbg (self, "explicitly releasing client for service '%s'...", qmi_service_get_string (service));
+    qmi_device_release_client (self->priv->qmi_device,
+                               client,
+                               QMI_DEVICE_RELEASE_CLIENT_FLAGS_RELEASE_CID,
+                               3, NULL, NULL, NULL);
+    g_object_unref (client);
+}
+
+/*****************************************************************************/
+
 typedef struct {
     ServiceInfo *info;
 } AllocateClientContext;
@@ -254,10 +292,13 @@
                                  GAsyncResult *res,
                                  GTask        *task)
 {
-    GError *error = NULL;
+    MMPortQmi *self;
+    GError    *error = NULL;
+
+    self = g_task_get_source_object (task);
 
     if (!qmi_device_close_finish (qmi_device, res, &error)) {
-        mm_warn ("Couldn't close QMI device after failed open sequence: %s", error->message);
+        mm_obj_warn (self, "Couldn't close QMI device after failed open sequence: %s", error->message);
         g_error_free (error);
     }
 
@@ -285,12 +326,14 @@
                                   GAsyncResult *res,
                                   GTask        *task)
 {
+    MMPortQmi       *self;
     PortOpenContext *ctx;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     if (!qmi_device_close_finish (qmi_device, res, &ctx->error)) {
-        mm_warn ("Couldn't close QMI device to reopen it");
+        mm_obj_warn (self, "Couldn't close QMI device to reopen it");
         ctx->step = PORT_OPEN_STEP_LAST;
     } else
         ctx->step++;
@@ -302,10 +345,12 @@
                        GAsyncResult *res,
                        GTask *task)
 {
+    MMPortQmi *self;
     PortOpenContext *ctx;
     QmiMessageWdaGetDataFormatOutput *output;
     g_autoptr(GError) error = NULL;
 
+    self = g_task_get_source_object (task);
     ctx = g_task_get_task_data (task);
     output = qmi_client_wda_get_data_format_finish (client, res, NULL);
     if (!output ||
@@ -316,7 +361,7 @@
          * When this happens, assume the device supports only raw-ip and be done
          * with it. */
         if (error && g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_MISSING_ARGUMENT)) {
-            mm_dbg ("Querying data format failed: '%s', assuming raw-ip is only supported", error->message);
+            mm_obj_dbg (self, "Querying data format failed: '%s', assuming raw-ip is only supported", error->message);
             ctx->llp = QMI_WDA_LINK_LAYER_PROTOCOL_RAW_IP;
             ctx->step++;
         } else {
@@ -406,12 +451,12 @@
     ctx = g_task_get_task_data (task);
     switch (ctx->step) {
     case PORT_OPEN_STEP_FIRST:
-        mm_dbg ("Opening QMI device...");
+        mm_obj_dbg (self, "Opening QMI device...");
         ctx->step++;
         /* Fall through */
 
     case PORT_OPEN_STEP_CHECK_OPENING:
-        mm_dbg ("Checking if QMI device already opening...");
+        mm_obj_dbg (self, "Checking if QMI device already opening...");
         if (self->priv->in_progress) {
             g_task_return_new_error (task,
                                      MM_CORE_ERROR,
@@ -424,7 +469,7 @@
         /* Fall through */
 
     case PORT_OPEN_STEP_CHECK_ALREADY_OPEN:
-        mm_dbg ("Checking if QMI device already open...");
+        mm_obj_dbg (self, "Checking if QMI device already open...");
         if (self->priv->qmi_device) {
             g_task_return_boolean (task, TRUE);
             g_object_unref (task);
@@ -445,7 +490,7 @@
          * that all callbacks go through the LAST step for completing. */
         self->priv->in_progress = TRUE;
 
-        mm_dbg ("Creating QMI device...");
+        mm_obj_dbg (self, "Creating QMI device...");
         qmi_device_new (file,
                         g_task_get_cancellable (task),
                         (GAsyncReadyCallback) qmi_device_new_ready,
@@ -458,7 +503,7 @@
 
     case PORT_OPEN_STEP_OPEN_WITHOUT_DATA_FORMAT:
         /* Now open the QMI device without any data format CTL flag */
-        mm_dbg ("Opening device without data format update...");
+        mm_obj_dbg (self, "Opening device without data format update...");
         qmi_device_open (ctx->device,
                          (QMI_DEVICE_OPEN_FLAGS_VERSION_INFO |
                           QMI_DEVICE_OPEN_FLAGS_PROXY),
@@ -469,7 +514,7 @@
         return;
 
     case PORT_OPEN_STEP_GET_KERNEL_DATA_FORMAT:
-        mm_dbg ("Querying kernel data format...");
+        mm_obj_dbg (self, "Querying kernel data format...");
         /* Try to gather expected data format from the sysfs file */
         ctx->kernel_data_format = qmi_device_get_expected_data_format (ctx->device, NULL);
         /* If data format cannot be retrieved, we fallback to 802.3 via CTL */
@@ -483,7 +528,7 @@
 
     case PORT_OPEN_STEP_ALLOCATE_WDA_CLIENT:
         /* Allocate WDA client */
-        mm_dbg ("Allocating WDA client...");
+        mm_obj_dbg (self, "Allocating WDA client...");
         qmi_device_allocate_client (ctx->device,
                                     QMI_SERVICE_WDA,
                                     QMI_CID_NONE,
@@ -496,7 +541,7 @@
     case PORT_OPEN_STEP_GET_WDA_DATA_FORMAT:
         /* If we have WDA client, query current data format */
         g_assert (ctx->wda);
-        mm_dbg ("Querying device data format...");
+        mm_obj_dbg (self, "Querying device data format...");
         qmi_client_wda_get_data_format (QMI_CLIENT_WDA (ctx->wda),
                                         NULL,
                                         10,
@@ -508,9 +553,9 @@
     case PORT_OPEN_STEP_CHECK_DATA_FORMAT:
         /* We now have the WDA data format and the kernel data format, if they're
          * equal, we're done */
-        mm_dbg ("Checking data format: kernel %s, device %s",
-                qmi_device_expected_data_format_get_string (ctx->kernel_data_format),
-                qmi_wda_link_layer_protocol_get_string (ctx->llp));
+        mm_obj_dbg (self, "Checking data format: kernel %s, device %s",
+                    qmi_device_expected_data_format_get_string (ctx->kernel_data_format),
+                    qmi_wda_link_layer_protocol_get_string (ctx->llp));
 
         if (ctx->kernel_data_format == QMI_DEVICE_EXPECTED_DATA_FORMAT_802_3 &&
             ctx->llp == QMI_WDA_LINK_LAYER_PROTOCOL_802_3) {
@@ -533,7 +578,7 @@
 
     case PORT_OPEN_STEP_SET_KERNEL_DATA_FORMAT:
         /* Update the data format to be expected by the kernel */
-        mm_dbg ("Updating kernel data format: %s", qmi_wda_link_layer_protocol_get_string (ctx->llp));
+        mm_obj_dbg (self, "Updating kernel data format: %s", qmi_wda_link_layer_protocol_get_string (ctx->llp));
         if (ctx->llp == QMI_WDA_LINK_LAYER_PROTOCOL_802_3) {
             ctx->kernel_data_format = QMI_DEVICE_EXPECTED_DATA_FORMAT_802_3;
             self->priv->llp_is_raw_ip = FALSE;
@@ -552,7 +597,7 @@
         return;
 
     case PORT_OPEN_STEP_CLOSE_BEFORE_OPEN_WITH_DATA_FORMAT:
-        mm_dbg ("Closing device to reopen it right away...");
+        mm_obj_dbg (self, "Closing device to reopen it right away...");
         qmi_device_close_async (ctx->device,
                                 5,
                                 g_task_get_cancellable (task),
@@ -562,7 +607,7 @@
 
     case PORT_OPEN_STEP_OPEN_WITH_DATA_FORMAT:
         /* Need to reopen setting 802.3 using CTL */
-        mm_dbg ("Reopening device with data format...");
+        mm_obj_dbg (self, "Reopening device with data format...");
         qmi_device_open (ctx->device,
                          (QMI_DEVICE_OPEN_FLAGS_VERSION_INFO |
                           QMI_DEVICE_OPEN_FLAGS_PROXY        |
@@ -576,7 +621,7 @@
 
     case PORT_OPEN_STEP_LAST:
         if (ctx->error) {
-            mm_dbg ("QMI port open operation failed: %s", ctx->error->message);
+            mm_obj_dbg (self, "QMI port open operation failed: %s", ctx->error->message);
 
             if (ctx->device) {
                 qmi_device_close_async (ctx->device,
@@ -591,7 +636,7 @@
             return;
         }
 
-        mm_dbg ("QMI port open operation finished successfully");
+        mm_obj_dbg (self, "QMI port open operation finished successfully");
 
         /* Store device in private info */
         g_assert (ctx->device);
@@ -721,7 +766,7 @@
     for (l = self->priv->services; l; l = g_list_next (l)) {
         ServiceInfo *info = l->data;
 
-        mm_dbg ("Releasing client for service '%s'...", qmi_service_get_string (info->service));
+        mm_obj_dbg (self, "Releasing client for service '%s'...", qmi_service_get_string (info->service));
         qmi_device_release_client (ctx->qmi_device,
                                    info->client,
                                    QMI_DEVICE_RELEASE_CLIENT_FLAGS_RELEASE_CID,
diff --git a/src/mm-port-qmi.h b/src/mm-port-qmi.h
index f8ea9ee..b4e8460 100644
--- a/src/mm-port-qmi.h
+++ b/src/mm-port-qmi.h
@@ -80,6 +80,10 @@
                                              GAsyncResult *res,
                                              GError **error);
 
+void     mm_port_qmi_release_client         (MMPortQmi     *self,
+                                             QmiService     service,
+                                             MMPortQmiFlag  flag);
+
 QmiClient *mm_port_qmi_peek_client (MMPortQmi *self,
                                     QmiService service,
                                     MMPortQmiFlag flag);
diff --git a/src/mm-port-serial-at.c b/src/mm-port-serial-at.c
index 67525af..c8e4782 100644
--- a/src/mm-port-serial-at.c
+++ b/src/mm-port-serial-at.c
@@ -22,7 +22,7 @@
 #include <string.h>
 
 #include "mm-port-serial-at.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 G_DEFINE_TYPE (MMPortSerialAt, mm_port_serial_at, MM_TYPE_PORT_SERIAL)
 
@@ -148,7 +148,7 @@
 
     /* Parse it; returns FALSE if there is nothing we can do with this
      * response yet. */
-    if (!self->priv->response_parser_fn (self->priv->response_parser_user_data, string, &inner_error)) {
+    if (!self->priv->response_parser_fn (self->priv->response_parser_user_data, string, self, &inner_error)) {
         /* Copy what we got back in the response buffer. */
         g_byte_array_append (response, (const guint8 *) string->str, string->len);
         g_string_free (string, TRUE);
@@ -435,10 +435,13 @@
 }
 
 static void
-debug_log (MMPortSerial *port, const char *prefix, const char *buf, gsize len)
+debug_log (MMPortSerial *self,
+           const gchar  *prefix,
+           const gchar  *buf,
+           gsize         len)
 {
     static GString *debug = NULL;
-    const char *s;
+    const  char    *s;
 
     if (!debug)
         debug = g_string_sized_new (256);
@@ -461,7 +464,7 @@
     }
 
     g_string_append_c (debug, '\'');
-    mm_dbg ("(%s): %s", mm_port_get_device (MM_PORT (port)), debug->str);
+    mm_obj_dbg (self, "%s", debug->str);
     g_string_truncate (debug, 0);
 }
 
@@ -497,7 +500,7 @@
     if (!self->priv->init_sequence)
         return;
 
-    mm_dbg ("(%s): running init sequence...", mm_port_get_device (MM_PORT (self)));
+    mm_obj_dbg (self, "running init sequence...");
 
     /* Just queue the init commands, don't wait for reply */
     for (i = 0; self->priv->init_sequence[i]; i++) {
diff --git a/src/mm-port-serial-at.h b/src/mm-port-serial-at.h
index 8e19409..f447d14 100644
--- a/src/mm-port-serial-at.h
+++ b/src/mm-port-serial-at.h
@@ -53,9 +53,10 @@
     MM_PORT_SERIAL_AT_FLAG_GPS_CONTROL = 1 << 3,
 } MMPortSerialAtFlag;
 
-typedef gboolean (*MMPortSerialAtResponseParserFn) (gpointer user_data,
-                                                    GString *response,
-                                                    GError **error);
+typedef gboolean (*MMPortSerialAtResponseParserFn) (gpointer   user_data,
+                                                    GString   *response,
+                                                    gpointer   log_object,
+                                                    GError   **error);
 
 typedef void (*MMPortSerialAtUnsolicitedMsgFn) (MMPortSerialAt *port,
                                                 GMatchInfo *match_info,
diff --git a/src/mm-port-serial-gps.c b/src/mm-port-serial-gps.c
index b316d05..ea40499 100644
--- a/src/mm-port-serial-gps.c
+++ b/src/mm-port-serial-gps.c
@@ -19,7 +19,7 @@
 #include <string.h>
 
 #include "mm-port-serial-gps.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 G_DEFINE_TYPE (MMPortSerialGps, mm_port_serial_gps, MM_TYPE_PORT_SERIAL)
 
@@ -135,10 +135,13 @@
 /*****************************************************************************/
 
 static void
-debug_log (MMPortSerial *port, const char *prefix, const char *buf, gsize len)
+debug_log (MMPortSerial *self,
+           const gchar  *prefix,
+           const gchar  *buf,
+           gsize         len)
 {
     static GString *debug = NULL;
-    const char *s;
+    const gchar    *s;
 
     if (!debug)
         debug = g_string_sized_new (256);
@@ -161,7 +164,7 @@
     }
 
     g_string_append_c (debug, '\'');
-    mm_dbg ("(%s): %s", mm_port_get_device (MM_PORT (port)), debug->str);
+    mm_obj_dbg (self, "%s", debug->str);
     g_string_truncate (debug, 0);
 }
 
diff --git a/src/mm-port-serial-qcdm.c b/src/mm-port-serial-qcdm.c
index e723204..e5bc94e 100644
--- a/src/mm-port-serial-qcdm.c
+++ b/src/mm-port-serial-qcdm.c
@@ -27,7 +27,7 @@
 #include "libqcdm/src/utils.h"
 #include "libqcdm/src/errors.h"
 #include "libqcdm/src/dm-commands.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 G_DEFINE_TYPE (MMPortSerialQcdm, mm_port_serial_qcdm, MM_TYPE_PORT_SERIAL)
 
@@ -206,10 +206,13 @@
 }
 
 static void
-debug_log (MMPortSerial *port, const char *prefix, const char *buf, gsize len)
+debug_log (MMPortSerial *self,
+           const gchar  *prefix,
+           const gchar  *buf,
+           gsize         len)
 {
     static GString *debug = NULL;
-    const char *s = buf;
+    const gchar    *s = buf;
 
     if (!debug)
         debug = g_string_sized_new (512);
@@ -219,7 +222,7 @@
     while (len--)
         g_string_append_printf (debug, " %02x", (guint8) (*s++ & 0xFF));
 
-    mm_dbg ("(%s): %s", mm_port_get_device (MM_PORT (port)), debug->str);
+    mm_obj_dbg (self, "%s", debug->str);
     g_string_truncate (debug, 0);
 }
 
diff --git a/src/mm-port-serial.c b/src/mm-port-serial.c
index 5e8db48..b4ba653 100644
--- a/src/mm-port-serial.c
+++ b/src/mm-port-serial.c
@@ -34,7 +34,7 @@
 #include <mm-errors-types.h>
 
 #include "mm-port-serial.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-helper-enums-types.h"
 
 static gboolean port_serial_queue_process          (gpointer data);
@@ -290,7 +290,7 @@
 static int
 parse_bits (guint i)
 {
-    int bits;
+    int bits = -1;
 
     switch (i) {
     case 5:
@@ -306,8 +306,7 @@
         bits = CS8;
         break;
     default:
-        mm_warn ("Invalid bits (%d). Valid values are 5, 6, 7, 8.", i);
-        bits = CS8;
+        g_assert_not_reached ();
     }
 
     return bits;
@@ -316,7 +315,7 @@
 static int
 parse_parity (char c)
 {
-    int parity;
+    int parity = -1;
 
     switch (c) {
     case 'n':
@@ -332,8 +331,7 @@
         parity = PARENB | PARODD;
         break;
     default:
-        mm_warn ("Invalid parity (%c). Valid values are n, e, o", c);
-        parity = 0;
+        g_assert_not_reached ();
     }
 
     return parity;
@@ -342,7 +340,7 @@
 static int
 parse_stopbits (guint i)
 {
-    int stopbits;
+    int stopbits = -1;
 
     switch (i) {
     case 1:
@@ -352,8 +350,7 @@
         stopbits = CSTOPB;
         break;
     default:
-        mm_warn ("Invalid stop bits (%d). Valid values are 1 and 2)", i);
-        stopbits = 0;
+        g_assert_not_reached ();
     }
 
     return stopbits;
@@ -401,11 +398,9 @@
     memset (&other, 0, sizeof (struct termios));
     errno = 0;
     if (tcgetattr (fd, &other) != 0)
-        mm_dbg ("(%s): couldn't get serial port attributes after setting them: %s",
-                mm_port_get_device (MM_PORT (self)), g_strerror (errno));
+        mm_obj_dbg (self, "couldn't get serial port attributes after setting them: %s", g_strerror (errno));
     else if (memcmp (options, &other, sizeof (struct termios)) != 0)
-        mm_dbg ("(%s): port attributes not fully set",
-                mm_port_get_device (MM_PORT (self)));
+        mm_obj_dbg (self, "port attributes not fully set");
 
 #undef MAX_TCSETATTR_RETRIES
 
@@ -433,19 +428,19 @@
     /* setup the requested flags */
     switch (flow_control) {
         case MM_FLOW_CONTROL_XON_XOFF:
-            mm_dbg ("(%s): enabling XON/XOFF flow control", mm_port_get_device (MM_PORT (self)));
+            mm_obj_dbg (self, "enabling XON/XOFF flow control");
             options->c_iflag |= (IXON | IXOFF | IXANY);
             break;
         case MM_FLOW_CONTROL_RTS_CTS:
-            mm_dbg ("(%s): enabling RTS/CTS flow control", mm_port_get_device (MM_PORT (self)));
+            mm_obj_dbg (self, "enabling RTS/CTS flow control");
             options->c_cflag |= (CRTSCTS);
             break;
         case MM_FLOW_CONTROL_NONE:
         case MM_FLOW_CONTROL_UNKNOWN:
             if (had_xon_xoff)
-                mm_dbg ("(%s): disabling XON/XOFF flow control", mm_port_get_device (MM_PORT (self)));
+                mm_obj_dbg (self, "disabling XON/XOFF flow control");
             if (had_rts_cts)
-                mm_dbg ("(%s): disabling RTS/CTS flow control", mm_port_get_device (MM_PORT (self)));
+                mm_obj_dbg (self, "disabling RTS/CTS flow control");
             break;
         default:
             g_assert_not_reached ();
@@ -467,13 +462,9 @@
     if (mm_port_get_subsys (MM_PORT (self)) != MM_PORT_SUBSYS_TTY)
         return TRUE;
 
-    mm_dbg ("(%s): setting up baudrate: %u",
-            mm_port_get_device (MM_PORT (self)),
-            self->priv->baud);
+    mm_obj_dbg (self, "setting up baudrate: %u", self->priv->baud);
     if (!parse_baudrate (self->priv->baud, &speed) || speed == B0) {
-        mm_warn ("(%s): baudrate invalid: %u; defaulting to 57600",
-                 mm_port_get_device (MM_PORT (self)),
-                 self->priv->baud);
+        mm_obj_warn (self, "baudrate invalid: %u; defaulting to 57600", self->priv->baud);
         speed = B57600;
     }
 
@@ -482,11 +473,8 @@
     stopbits = parse_stopbits (self->priv->stopbits);
 
     memset (&stbuf, 0, sizeof (struct termios));
-    if (tcgetattr (fd, &stbuf) != 0) {
-        mm_warn ("(%s): tcgetattr() error: %d",
-                 mm_port_get_device (MM_PORT (self)),
-                 errno);
-    }
+    if (tcgetattr (fd, &stbuf) != 0)
+        mm_obj_warn (self, "error getting serial port attributes: %s", g_strerror (errno));
 
     stbuf.c_cflag &= ~(CBAUD | CSIZE | CSTOPB | PARENB | PARODD | CRTSCTS);
     stbuf.c_iflag &= ~(IGNCR | ICRNL | IUCLC | INPCK | IXON | IXOFF | IXANY );
@@ -526,13 +514,10 @@
         gchar *str;
 
         str = mm_flow_control_build_string_from_mask (self->priv->flow_control);
-        mm_dbg ("(%s): flow control explicitly requested for device is: %s",
-                mm_port_get_device (MM_PORT (self)),
-                str ? str : "unknown");
+        mm_obj_dbg (self, "flow control explicitly requested for device is: %s", str ? str : "unknown");
         g_free (str);
     } else
-        mm_dbg ("(%s): no flow control explicitly requested for device",
-                mm_port_get_device (MM_PORT (self)));
+        mm_obj_dbg (self, "no flow control explicitly requested for device");
 
     set_flow_control_termios (self, self->priv->flow_control, &stbuf);
 
@@ -540,7 +525,10 @@
 }
 
 static void
-serial_debug (MMPortSerial *self, const char *prefix, const char *buf, gsize len)
+serial_debug (MMPortSerial *self,
+              const gchar  *prefix,
+              const gchar  *buf,
+              gsize         len)
 {
     g_return_if_fail (len > 0);
 
@@ -572,7 +560,7 @@
     /* Only print command the first time */
     if (ctx->started == FALSE) {
         ctx->started = TRUE;
-        serial_debug (self, "-->", (const char *) ctx->command->data, ctx->command->len);
+        serial_debug (self, "-->", (const gchar *) ctx->command->data, ctx->command->len);
     }
 
     if (self->priv->send_delay == 0 || mm_port_get_subsys (MM_PORT (self)) != MM_PORT_SUBSYS_TTY) {
@@ -619,7 +607,7 @@
                 g_signal_emit (self, signals[TIMED_OUT], 0, self->priv->n_consecutive_timeouts);
 
                 g_set_error (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_SEND_FAILED,
-                             "Sending command failed: '%s'", strerror (errno));
+                             "Sending command failed: '%s'", g_strerror (errno));
                 return FALSE;
             }
             break;
@@ -654,7 +642,7 @@
                 self->priv->n_consecutive_timeouts++;
                 g_signal_emit (self, signals[TIMED_OUT], 0, self->priv->n_consecutive_timeouts);
                 g_set_error (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_SEND_FAILED,
-                             "Sending command failed: '%s'", strerror (errno));
+                             "Sending command failed: '%s'", g_strerror (errno));
                 return FALSE;
             }
 
@@ -962,15 +950,12 @@
     gsize bytes_read;
     GIOStatus status = G_IO_STATUS_NORMAL;
     CommandContext *ctx;
-    const char *device;
     GError *error = NULL;
     gboolean iterate = TRUE;
     gboolean keep_source = G_SOURCE_CONTINUE;
 
     if (condition & G_IO_HUP) {
-        device = mm_port_get_device (MM_PORT (self));
-        mm_dbg ("(%s) unexpected port hangup!", device);
-
+        mm_obj_dbg (self, "unexpected port hangup!");
         if (self->priv->response->len)
             g_byte_array_remove_range (self->priv->response, 0, self->priv->response->len);
         port_serial_close_force (self);
@@ -998,11 +983,8 @@
                                               &bytes_read,
                                               &error);
             if (status == G_IO_STATUS_ERROR) {
-                if (error) {
-                    mm_warn ("(%s): read error: %s",
-                             mm_port_get_device (MM_PORT (self)),
-                             error->message);
-                }
+                if (error)
+                    mm_obj_warn (self, "read error: %s", error->message);
                 g_clear_error (&error);
             }
         } else if (self->priv->socket) {
@@ -1019,9 +1001,7 @@
                     status = G_IO_STATUS_AGAIN;
                 else
                     status = G_IO_STATUS_ERROR;
-                mm_warn ("(%s): receive error: %s",
-                         mm_port_get_device (MM_PORT (self)),
-                         error->message);
+                mm_obj_warn (self, "receive error: %s", error->message);
                 g_clear_error (&error);
             } else {
                 bytes_read = (gsize) sbytes_read;
@@ -1140,11 +1120,9 @@
     connected = mm_port_get_connected (MM_PORT (self));
 
     if (self->priv->fd >= 0 && ioctl (self->priv->fd, (connected ? TIOCNXCL : TIOCEXCL)) < 0) {
-        mm_warn ("(%s): could not %s serial port lock: (%d) %s",
-                 mm_port_get_device (MM_PORT (self)),
-                 connected ? "drop" : "re-acquire",
-                 errno,
-                 strerror (errno));
+        mm_obj_warn (self, "could not %s serial port lock: %s",
+                     connected ? "drop" : "re-acquire",
+                     g_strerror (errno));
         if (!connected) {
             // FIXME: do something here, maybe try again in a few seconds or
             // close the port and error out?
@@ -1200,7 +1178,7 @@
         goto success;
     }
 
-    mm_dbg ("(%s) opening serial port...", device);
+    mm_obj_dbg (self, "opening serial port...");
 
     g_get_current_time (&tv_start);
 
@@ -1224,7 +1202,6 @@
                          MM_SERIAL_ERROR,
                          (errno == ENODEV) ? MM_SERIAL_ERROR_OPEN_FAILED_NO_DEVICE : MM_SERIAL_ERROR_OPEN_FAILED,
                          "Could not open serial device %s: %s", device, strerror (errno_save));
-            mm_warn ("(%s) could not open serial device (%d)", device, errno_save);
             return FALSE;
         }
     }
@@ -1236,7 +1213,6 @@
             errno_save = errno;
             g_set_error (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_OPEN_FAILED,
                          "Could not lock serial device %s: %s", device, strerror (errno_save));
-            mm_warn ("(%s) could not lock serial device (%d)", device, errno_save);
             goto error;
         }
 
@@ -1250,21 +1226,20 @@
         if (ioctl (self->priv->fd, TIOCGSERIAL, &sinfo) == 0) {
             sinfo.closing_wait = ASYNC_CLOSING_WAIT_NONE;
             if (ioctl (self->priv->fd, TIOCSSERIAL, &sinfo) < 0)
-                mm_warn ("(%s): couldn't set serial port closing_wait to none: %s",
-                         device, g_strerror (errno));
+                mm_obj_warn (self, "couldn't set serial port closing_wait to none: %s", g_strerror (errno));
         }
     }
 
     g_warn_if_fail (MM_PORT_SERIAL_GET_CLASS (self)->config_fd);
     if (self->priv->fd >= 0 && !MM_PORT_SERIAL_GET_CLASS (self)->config_fd (self, self->priv->fd, error)) {
-        mm_dbg ("(%s) failed to configure serial device", device);
+        mm_obj_dbg (self, "failed to configure serial device");
         goto error;
     }
 
     g_get_current_time (&tv_end);
 
     if (tv_end.tv_sec - tv_start.tv_sec > 7)
-        mm_warn ("(%s): open blocked by driver for more than 7 seconds!", device);
+        mm_obj_warn (self, "open blocked by driver for more than 7 seconds!");
 
     if (mm_port_get_subsys (MM_PORT (self)) != MM_PORT_SUBSYS_UNIX) {
         /* Create new GIOChannel */
@@ -1330,7 +1305,7 @@
 
 success:
     self->priv->open_count++;
-    mm_dbg ("(%s) device open count is %d (open)", device, self->priv->open_count);
+    mm_obj_dbg (self, "device open count is %d (open)", self->priv->open_count);
 
     /* Run additional port config if just opened */
     if (self->priv->open_count == 1 && MM_PORT_SERIAL_GET_CLASS (self)->config)
@@ -1339,7 +1314,7 @@
     return TRUE;
 
 error:
-    mm_warn ("(%s) failed to open serial device", device);
+    mm_obj_warn (self, "failed to open serial device");
 
     if (self->priv->iochannel) {
         g_io_channel_unref (self->priv->iochannel);
@@ -1372,8 +1347,7 @@
 static void
 _close_internal (MMPortSerial *self, gboolean force)
 {
-    const char *device;
-    guint       i;
+    guint i;
 
     g_return_if_fail (MM_IS_PORT_SERIAL (self));
 
@@ -1384,9 +1358,7 @@
         self->priv->open_count--;
     }
 
-    device = mm_port_get_device (MM_PORT (self));
-
-    mm_dbg ("(%s) device open count is %d (close)", device, self->priv->open_count);
+    mm_obj_dbg (self, "device open count is %d (close)", self->priv->open_count);
 
     if (self->priv->open_count > 0)
         return;
@@ -1405,7 +1377,7 @@
         GTimeVal tv_start, tv_end;
         struct serial_struct sinfo = { 0 };
 
-        mm_dbg ("(%s) closing serial port...", device);
+        mm_obj_dbg (self, "closing serial port...");
 
         mm_port_set_connected (MM_PORT (self), FALSE);
 
@@ -1418,11 +1390,10 @@
              */
             if (ioctl (self->priv->fd, TIOCGSERIAL, &sinfo) == 0) {
                 if (sinfo.closing_wait != ASYNC_CLOSING_WAIT_NONE) {
-                    mm_warn ("(%s): serial port closing_wait was reset!", device);
+                    mm_obj_warn (self, "serial port closing_wait was reset!");
                     sinfo.closing_wait = ASYNC_CLOSING_WAIT_NONE;
                     if (ioctl (self->priv->fd, TIOCSSERIAL, &sinfo) < 0)
-                        mm_warn ("(%s): couldn't set serial port closing_wait to none: %s",
-                                 device, g_strerror (errno));
+                        mm_obj_warn (self, "couldn't set serial port closing_wait to none: %s", g_strerror (errno));
                 }
             }
 
@@ -1455,7 +1426,7 @@
 
         g_get_current_time (&tv_end);
 
-        mm_dbg ("(%s) serial port closed", device);
+        mm_obj_dbg (self, "serial port closed");
 
         /* Some ports don't respond to data and when close is called
          * the serial layer waits up to 30 second (closing_wait) for
@@ -1463,7 +1434,7 @@
          * Log that.  See GNOME bug #630670 for more details.
          */
         if (tv_end.tv_sec - tv_start.tv_sec > 7)
-            mm_warn ("(%s): close blocked by driver for more than 7 seconds!", device);
+            mm_obj_warn (self, "close blocked by driver for more than 7 seconds!");
     }
 
     /* Clear the command queue */
@@ -1517,7 +1488,7 @@
     if (self->priv->forced_close)
         return;
 
-    mm_dbg ("(%s) forced to close port", mm_port_get_device (MM_PORT (self)));
+    mm_obj_dbg (self, "forced to close port");
 
     /* Mark as having forced the close, so that we don't warn about incorrect
      * open counts */
@@ -1654,9 +1625,7 @@
         return;
     }
 
-    mm_dbg ("(%s) reopening port (%u)",
-            mm_port_get_device (MM_PORT (self)),
-            ctx->initial_open_count);
+    mm_obj_dbg (self, "reopening port (%u)", ctx->initial_open_count);
 
     for (i = 0; i < ctx->initial_open_count; i++)
         mm_port_serial_close (self);
@@ -1899,16 +1868,14 @@
 
     /* Return if current settings are already what we want */
     if (!set_flow_control_termios (self, flow_control, &options)) {
-        mm_dbg ("(%s): no need to change flow control settings: already %s",
-                mm_port_get_device (MM_PORT (self)), flow_control_str);
+        mm_obj_dbg (self, "no need to change flow control settings: already %s", flow_control_str);
         goto out;
     }
 
     if (!internal_tcsetattr (self, self->priv->fd, &options, &inner_error))
         goto out;
 
-    mm_dbg ("(%s): flow control settings updated to %s",
-            mm_port_get_device (MM_PORT (self)), flow_control_str);
+    mm_obj_dbg (self, "flow control settings updated to %s", flow_control_str);
 
  out:
     g_free (flow_control_str);
diff --git a/src/mm-port-serial.h b/src/mm-port-serial.h
index b30bad7..e643d14 100644
--- a/src/mm-port-serial.h
+++ b/src/mm-port-serial.h
@@ -93,12 +93,12 @@
 
     /* Called to configure the serial port after it's opened. Errors, if any,
      * should get ignored. */
-    void     (*config)            (MMPortSerial *self);
+    void (*config)                (MMPortSerial *self);
 
     void (*debug_log)             (MMPortSerial *self,
-                                   const char *prefix,
-                                   const char *buf,
-                                   gsize len);
+                                   const gchar  *prefix,
+                                   const gchar  *buf,
+                                   gsize         len);
 
     /* Signals */
     void (*buffer_full)           (MMPortSerial *port, const GByteArray *buffer);
diff --git a/src/mm-port.c b/src/mm-port.c
index 0156f6e..b9a8020 100644
--- a/src/mm-port.c
+++ b/src/mm-port.c
@@ -19,9 +19,13 @@
 #include <string.h>
 
 #include "mm-port.h"
-#include "mm-log.h"
+#include "mm-port-enums-types.h"
+#include "mm-log-object.h"
 
-G_DEFINE_TYPE (MMPort, mm_port, G_TYPE_OBJECT)
+static void log_object_iface_init (MMLogObjectInterface *iface);
+
+G_DEFINE_TYPE_EXTENDED (MMPort, mm_port, G_TYPE_OBJECT, 0,
+                        G_IMPLEMENT_INTERFACE (MM_TYPE_LOG_OBJECT, log_object_iface_init))
 
 enum {
     PROP_0,
@@ -88,10 +92,7 @@
     if (self->priv->connected != connected) {
         self->priv->connected = connected;
         g_object_notify (G_OBJECT (self), MM_PORT_CONNECTED);
-
-        mm_dbg ("(%s): port now %s",
-                self->priv->device,
-                connected ? "connected" : "disconnected");
+        mm_obj_dbg (self, "port now %s", connected ? "connected" : "disconnected");
     }
 }
 
@@ -105,6 +106,19 @@
 
 /*****************************************************************************/
 
+static gchar *
+log_object_build_id (MMLogObject *_self)
+{
+    MMPort *self;
+
+    self = MM_PORT (_self);
+    return g_strdup_printf ("%s/%s",
+                            mm_port_get_device (self),
+                            mm_modem_port_type_get_string (mm_port_get_port_type (self)));
+}
+
+/*****************************************************************************/
+
 static void
 mm_port_init (MMPort *self)
 {
@@ -195,6 +209,12 @@
 }
 
 static void
+log_object_iface_init (MMLogObjectInterface *iface)
+{
+    iface->build_id = log_object_build_id;
+}
+
+static void
 mm_port_class_init (MMPortClass *klass)
 {
     GObjectClass *object_class = G_OBJECT_CLASS (klass);
diff --git a/src/mm-serial-parsers.c b/src/mm-serial-parsers.c
index b7bb308..b511302 100644
--- a/src/mm-serial-parsers.c
+++ b/src/mm-serial-parsers.c
@@ -19,7 +19,7 @@
 
 #include "mm-error-helpers.h"
 #include "mm-serial-parsers.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 /* Clean up the response by removing control characters like <CR><LF> etc */
 static void
@@ -161,9 +161,10 @@
 }
 
 gboolean
-mm_serial_parser_v1_parse (gpointer data,
-                           GString *response,
-                           GError **error)
+mm_serial_parser_v1_parse (gpointer   data,
+                           GString   *response,
+                           gpointer   log_object,
+                           GError   **error)
 {
     MMSerialParserV1 *parser = (MMSerialParserV1 *) data;
     GMatchInfo *match_info;
@@ -188,7 +189,7 @@
                                   response,
                                   &local_error)) {
         g_assert (local_error != NULL);
-        mm_dbg ("Got response filtered in serial port: %s", local_error->message);
+        mm_obj_dbg (log_object, "response filtered in serial port: %s", local_error->message);
         g_propagate_error (error, local_error);
         response_clean (response);
         return TRUE;
@@ -238,7 +239,7 @@
         if (found) {
             str = g_match_info_fetch (match_info, 1);
             g_assert (str);
-            local_error = mm_mobile_equipment_error_for_code (atoi (str));
+            local_error = mm_mobile_equipment_error_for_code (atoi (str), log_object);
             goto done;
         }
         g_match_info_free (match_info);
@@ -251,7 +252,7 @@
     if (found) {
         str = g_match_info_fetch (match_info, 1);
         g_assert (str);
-        local_error = mm_mobile_equipment_error_for_code (atoi (str));
+        local_error = mm_mobile_equipment_error_for_code (atoi (str), log_object);
         goto done;
     }
     g_match_info_free (match_info);
@@ -263,7 +264,7 @@
     if (found) {
         str = g_match_info_fetch (match_info, 1);
         g_assert (str);
-        local_error = mm_message_error_for_code (atoi (str));
+        local_error = mm_message_error_for_code (atoi (str), log_object);
         goto done;
     }
     g_match_info_free (match_info);
@@ -275,7 +276,7 @@
     if (found) {
         str = g_match_info_fetch (match_info, 1);
         g_assert (str);
-        local_error = mm_mobile_equipment_error_for_string (str);
+        local_error = mm_mobile_equipment_error_for_string (str, log_object);
         goto done;
     }
     g_match_info_free (match_info);
@@ -287,7 +288,7 @@
     if (found) {
         str = g_match_info_fetch (match_info, 1);
         g_assert (str);
-        local_error = mm_message_error_for_string (str);
+        local_error = mm_message_error_for_string (str, log_object);
         goto done;
     }
     g_match_info_free (match_info);
@@ -299,7 +300,7 @@
     if (found) {
         str = g_match_info_fetch (match_info, 1);
         g_assert (str);
-        local_error = mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN);
+        local_error = mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN, log_object);
         goto done;
     }
     g_match_info_free (match_info);
@@ -309,7 +310,7 @@
                                 response->str, response->len,
                                 0, 0, &match_info, NULL);
     if (found) {
-        local_error = mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN);
+        local_error = mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN, log_object);
         goto done;
     }
     g_match_info_free (match_info);
@@ -337,7 +338,7 @@
             code = MM_CONNECTION_ERROR_NO_CARRIER;
         }
 
-        local_error = mm_connection_error_for_code (code);
+        local_error = mm_connection_error_for_code (code, log_object);
         goto done;
     }
     g_match_info_free (match_info);
@@ -361,7 +362,7 @@
         response_clean (response);
 
     if (local_error) {
-        mm_dbg ("Got failure code %d: %s", local_error->code, local_error->message);
+        mm_obj_dbg (log_object, "operation failure: %d (%s)", local_error->code, local_error->message);
         g_propagate_error (error, local_error);
     }
 
diff --git a/src/mm-serial-parsers.h b/src/mm-serial-parsers.h
index 641c5e0..523597b 100644
--- a/src/mm-serial-parsers.h
+++ b/src/mm-serial-parsers.h
@@ -24,6 +24,7 @@
                                                    GRegex *error);
 gboolean mm_serial_parser_v1_parse                (gpointer parser,
                                                    GString *response,
+                                                   gpointer log_object,
                                                    GError **error);
 void     mm_serial_parser_v1_destroy              (gpointer parser);
 gboolean mm_serial_parser_v1_is_known_error       (const GError *error);
diff --git a/src/mm-shared-qmi.c b/src/mm-shared-qmi.c
index 7c3575e..1b18719 100644
--- a/src/mm-shared-qmi.c
+++ b/src/mm-shared-qmi.c
@@ -25,7 +25,7 @@
 
 #include <libqmi-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-iface-modem.h"
 #include "mm-iface-modem-3gpp.h"
 #include "mm-iface-modem-location.h"
@@ -761,7 +761,7 @@
 
     for (i = 0; i < radio_interface_list->len; i++)
         ctx->capabilities_context.dms_capabilities |=
-            mm_modem_capability_from_qmi_radio_interface (g_array_index (radio_interface_list, QmiDmsRadioInterface, i));
+            mm_modem_capability_from_qmi_radio_interface (g_array_index (radio_interface_list, QmiDmsRadioInterface, i), self);
 
 out:
     if (output)
@@ -795,11 +795,11 @@
 
     output = qmi_client_nas_get_technology_preference_finish (client, res, &error);
     if (!output) {
-        mm_dbg ("QMI operation failed: %s", error->message);
+        mm_obj_dbg (self, "QMI operation failed: %s", error->message);
         g_error_free (error);
         priv->feature_nas_technology_preference = FEATURE_UNSUPPORTED;
     } else if (!qmi_message_nas_get_technology_preference_output_get_result (output, &error)) {
-        mm_dbg ("Couldn't get technology preference: %s", error->message);
+        mm_obj_dbg (self, "couldn't get technology preference: %s", error->message);
         g_error_free (error);
         priv->feature_nas_technology_preference = FEATURE_SUPPORTED;
     } else {
@@ -835,11 +835,11 @@
 
     output = qmi_client_nas_get_system_selection_preference_finish (client, res, &error);
     if (!output) {
-        mm_dbg ("QMI operation failed: %s", error->message);
+        mm_obj_dbg (self, "QMI operation failed: %s", error->message);
         g_error_free (error);
         priv->feature_nas_system_selection_preference = FEATURE_UNSUPPORTED;
     } else if (!qmi_message_nas_get_system_selection_preference_output_get_result (output, &error)) {
-        mm_dbg ("Couldn't get system selection preference: %s", error->message);
+        mm_obj_dbg (self, "couldn't get system selection preference: %s", error->message);
         g_error_free (error);
         priv->feature_nas_system_selection_preference = FEATURE_SUPPORTED;
     } else {
@@ -897,7 +897,7 @@
     case LOAD_CURRENT_CAPABILITIES_STEP_LAST:
         g_assert (priv->feature_nas_technology_preference       != FEATURE_UNKNOWN);
         g_assert (priv->feature_nas_system_selection_preference != FEATURE_UNKNOWN);
-        priv->current_capabilities = mm_modem_capability_from_qmi_capabilities_context (&ctx->capabilities_context);
+        priv->current_capabilities = mm_modem_capability_from_qmi_capabilities_context (&ctx->capabilities_context, self);
         g_task_return_int (task, priv->current_capabilities);
         g_object_unref (task);
         return;
@@ -997,7 +997,7 @@
     /* Build mask with all supported capabilities */
     mask = MM_MODEM_CAPABILITY_NONE;
     for (i = 0; i < priv->supported_radio_interfaces->len; i++)
-        mask |= mm_modem_capability_from_qmi_radio_interface (g_array_index (priv->supported_radio_interfaces, QmiDmsRadioInterface, i));
+        mask |= mm_modem_capability_from_qmi_radio_interface (g_array_index (priv->supported_radio_interfaces, QmiDmsRadioInterface, i), self);
 
     supported_combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemCapability), 3);
 
@@ -1192,7 +1192,7 @@
         if (mm_iface_modem_is_3gpp (self) && ((ctx->allowed & (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G)) == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G))) {
             QmiNasGsmWcdmaAcquisitionOrderPreference order;
 
-            order = mm_modem_mode_to_qmi_gsm_wcdma_acquisition_order_preference (ctx->preferred);
+            order = mm_modem_mode_to_qmi_gsm_wcdma_acquisition_order_preference (ctx->preferred, self);
             qmi_message_nas_set_system_selection_preference_input_set_gsm_wcdma_acquisition_order_preference (input, order, NULL);
         }
     }
@@ -1371,12 +1371,15 @@
                                                       GAsyncResult *res,
                                                       GTask        *task)
 {
+    MMSharedQmi                                     *self;
     LoadCurrentModesResult                          *result = NULL;
     QmiMessageNasGetSystemSelectionPreferenceOutput *output = NULL;
     GError                                          *error = NULL;
     QmiNasRatModePreference                          mode_preference_mask = 0;
     MMModemMode                                      allowed;
 
+    self = g_task_get_source_object (task);
+
     output = qmi_client_nas_get_system_selection_preference_finish (client, res, &error);
     if (!output || !qmi_message_nas_get_system_selection_preference_output_get_result (output, &error)) {
         g_task_return_error (task, error);
@@ -1416,7 +1419,7 @@
                 output,
                 &gsm_or_wcdma,
                 NULL))
-            result->preferred = mm_modem_mode_from_qmi_gsm_wcdma_acquisition_order_preference (gsm_or_wcdma);
+            result->preferred = mm_modem_mode_from_qmi_gsm_wcdma_acquisition_order_preference (gsm_or_wcdma, self);
     }
     /* Otherwise, rely on the acquisition order array TLV */
     else {
@@ -1541,7 +1544,7 @@
     /* Build all, based on the supported radio interfaces */
     mask_all = MM_MODEM_MODE_NONE;
     for (i = 0; i < priv->supported_radio_interfaces->len; i++)
-        mask_all |= mm_modem_mode_from_qmi_radio_interface (g_array_index (priv->supported_radio_interfaces, QmiDmsRadioInterface, i));
+        mask_all |= mm_modem_mode_from_qmi_radio_interface (g_array_index (priv->supported_radio_interfaces, QmiDmsRadioInterface, i), self);
     mode.allowed = mask_all;
     mode.preferred = MM_MODEM_MODE_NONE;
     all = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 1);
@@ -1554,77 +1557,72 @@
         return;
     }
 
-    combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 5);
+    combinations = g_array_new (FALSE, FALSE, sizeof (MMModemModeCombination));
+
+#define ADD_MODE_PREFERENCE(MODE1, MODE2, MODE3, MODE4) do {            \
+        mode.allowed = MODE1;                                           \
+        if (MODE2 != MM_MODEM_MODE_NONE) {                              \
+            mode.allowed |= MODE2;                                      \
+            if (MODE3 != MM_MODEM_MODE_NONE) {                          \
+                mode.allowed |= MODE3;                                  \
+                if (MODE4 != MM_MODEM_MODE_NONE)                        \
+                    mode.allowed |= MODE4;                              \
+            }                                                           \
+            if (priv->feature_nas_system_selection_preference != FEATURE_UNSUPPORTED) { \
+                if (MODE3 != MM_MODEM_MODE_NONE) {                      \
+                    if (MODE4 != MM_MODEM_MODE_NONE) {                  \
+                        mode.preferred = MODE4;                         \
+                        g_array_append_val (combinations, mode);        \
+                    }                                                   \
+                    mode.preferred = MODE3;                             \
+                    g_array_append_val (combinations, mode);            \
+                }                                                       \
+                mode.preferred = MODE2;                                 \
+                g_array_append_val (combinations, mode);                \
+                mode.preferred = MODE1;                                 \
+                g_array_append_val (combinations, mode);                \
+            } else {                                                    \
+                mode.preferred = MM_MODEM_MODE_NONE;                    \
+                g_array_append_val (combinations, mode);                \
+            }                                                           \
+        } else {                                                        \
+            mode.allowed = MODE1;                                       \
+            mode.preferred = MM_MODEM_MODE_NONE;                        \
+            g_array_append_val (combinations, mode);                    \
+        }                                                               \
+    } while (0)
 
     /* 2G-only, 3G-only */
-    mode.allowed = MM_MODEM_MODE_2G;
-    mode.preferred = MM_MODEM_MODE_NONE;
-    g_array_append_val (combinations, mode);
-    mode.allowed = MM_MODEM_MODE_3G;
-    mode.preferred = MM_MODEM_MODE_NONE;
-    g_array_append_val (combinations, mode);
+    ADD_MODE_PREFERENCE (MM_MODEM_MODE_2G, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE);
+    ADD_MODE_PREFERENCE (MM_MODEM_MODE_3G, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE);
 
     /* 4G-only mode is not possible in multimode GSM/UMTS+CDMA/EVDO+LTE
      * devices. This configuration may be selected as "LTE only" capability
      * instead. */
-    if (!priv->disable_4g_only_mode) {
-        mode.allowed = MM_MODEM_MODE_4G;
-        mode.preferred = MM_MODEM_MODE_NONE;
-        g_array_append_val (combinations, mode);
-    }
+    if (!priv->disable_4g_only_mode)
+        ADD_MODE_PREFERENCE (MM_MODEM_MODE_4G, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE);
 
-    /* 2G+3G */
-    mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
-    if (priv->feature_nas_system_selection_preference != FEATURE_UNSUPPORTED) {
-        mode.preferred = MM_MODEM_MODE_3G;
-        g_array_append_val (combinations, mode);
-        mode.preferred = MM_MODEM_MODE_2G;
-        g_array_append_val (combinations, mode);
-    } else {
-        mode.preferred = MM_MODEM_MODE_NONE;
-        g_array_append_val (combinations, mode);
-    }
+    /* 2G, 3G, 4G combinations */
+    ADD_MODE_PREFERENCE (MM_MODEM_MODE_2G, MM_MODEM_MODE_3G, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE);
+    ADD_MODE_PREFERENCE (MM_MODEM_MODE_2G, MM_MODEM_MODE_4G, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE);
+    ADD_MODE_PREFERENCE (MM_MODEM_MODE_3G, MM_MODEM_MODE_4G, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE);
+    ADD_MODE_PREFERENCE (MM_MODEM_MODE_2G, MM_MODEM_MODE_3G, MM_MODEM_MODE_4G,   MM_MODEM_MODE_NONE);
 
-    /* 2G+4G */
-    mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_4G);
+    /* 5G related mode combinations are only supported when NAS SSP is supported,
+     * as there is no 5G support in NAS TP. */
     if (priv->feature_nas_system_selection_preference != FEATURE_UNSUPPORTED) {
-        mode.preferred = MM_MODEM_MODE_4G;
-        g_array_append_val (combinations, mode);
-        mode.preferred = MM_MODEM_MODE_2G;
-        g_array_append_val (combinations, mode);
-    } else {
-        mode.preferred = MM_MODEM_MODE_NONE;
-        g_array_append_val (combinations, mode);
-    }
-
-    /* 3G+4G */
-    mode.allowed = (MM_MODEM_MODE_3G | MM_MODEM_MODE_4G);
-    if (priv->feature_nas_system_selection_preference != FEATURE_UNSUPPORTED) {
-        mode.preferred = MM_MODEM_MODE_3G;
-        g_array_append_val (combinations, mode);
-        mode.preferred = MM_MODEM_MODE_4G;
-        g_array_append_val (combinations, mode);
-    } else {
-        mode.preferred = MM_MODEM_MODE_NONE;
-        g_array_append_val (combinations, mode);
-    }
-
-    /* 2G+3G+4G */
-    mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G);
-    if (priv->feature_nas_system_selection_preference != FEATURE_UNSUPPORTED) {
-        mode.preferred = MM_MODEM_MODE_4G;
-        g_array_append_val (combinations, mode);
-        mode.preferred = MM_MODEM_MODE_3G;
-        g_array_append_val (combinations, mode);
-        mode.preferred = MM_MODEM_MODE_2G;
-        g_array_append_val (combinations, mode);
-    } else {
-        mode.preferred = MM_MODEM_MODE_NONE;
-        g_array_append_val (combinations, mode);
+        ADD_MODE_PREFERENCE (MM_MODEM_MODE_5G, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE);
+        ADD_MODE_PREFERENCE (MM_MODEM_MODE_2G, MM_MODEM_MODE_5G,   MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE);
+        ADD_MODE_PREFERENCE (MM_MODEM_MODE_3G, MM_MODEM_MODE_5G,   MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE);
+        ADD_MODE_PREFERENCE (MM_MODEM_MODE_4G, MM_MODEM_MODE_5G,   MM_MODEM_MODE_NONE, MM_MODEM_MODE_NONE);
+        ADD_MODE_PREFERENCE (MM_MODEM_MODE_2G, MM_MODEM_MODE_3G,   MM_MODEM_MODE_5G,   MM_MODEM_MODE_NONE);
+        ADD_MODE_PREFERENCE (MM_MODEM_MODE_2G, MM_MODEM_MODE_4G,   MM_MODEM_MODE_5G,   MM_MODEM_MODE_NONE);
+        ADD_MODE_PREFERENCE (MM_MODEM_MODE_3G, MM_MODEM_MODE_4G,   MM_MODEM_MODE_5G,   MM_MODEM_MODE_NONE);
+        ADD_MODE_PREFERENCE (MM_MODEM_MODE_2G, MM_MODEM_MODE_3G,   MM_MODEM_MODE_4G,   MM_MODEM_MODE_5G);
     }
 
     /* Filter out unsupported modes */
-    filtered = mm_filter_supported_modes (all, combinations);
+    filtered = mm_filter_supported_modes (all, combinations, self);
     g_array_unref (all);
     g_array_unref (combinations);
 
@@ -1679,7 +1677,7 @@
         &extended_qmi_lte_bands,
         NULL);
 
-    mm_bands = mm_modem_bands_from_qmi_band_capabilities (qmi_bands, qmi_lte_bands, extended_qmi_lte_bands);
+    mm_bands = mm_modem_bands_from_qmi_band_capabilities (qmi_bands, qmi_lte_bands, extended_qmi_lte_bands, self);
     if (mm_bands->len == 0) {
         g_clear_pointer (&mm_bands, g_array_unref);
         error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
@@ -1787,7 +1785,8 @@
     mm_bands = mm_modem_bands_from_qmi_band_preference (band_preference_mask,
                                                         lte_band_preference_mask,
                                                         extended_lte_band_preference_size ? extended_lte_band_preference : NULL,
-                                                        extended_lte_band_preference_size);
+                                                        extended_lte_band_preference_size,
+                                                        self);
 
     if (mm_bands->len == 0) {
         g_clear_pointer (&mm_bands, g_array_unref);
@@ -1902,7 +1901,8 @@
                                            &qmi_bands,
                                            &qmi_lte_bands,
                                            priv->feature_extended_lte_band_preference == FEATURE_SUPPORTED ? extended_qmi_lte_bands : NULL,
-                                           G_N_ELEMENTS (extended_qmi_lte_bands));
+                                           G_N_ELEMENTS (extended_qmi_lte_bands),
+                                           self);
 
     input = qmi_message_nas_set_system_selection_preference_input_new ();
     qmi_message_nas_set_system_selection_preference_input_set_band_preference (input, qmi_bands, NULL);
@@ -1946,14 +1946,17 @@
                                       GAsyncResult *res,
                                       GTask *task)
 {
+    MMSharedQmi                         *self;
     QmiMessageDmsSetOperatingModeOutput *output;
-    GError *error = NULL;
+    GError                              *error = NULL;
+
+    self = g_task_get_source_object (task);
 
     output = qmi_client_dms_set_operating_mode_finish (client, res, &error);
     if (!output || !qmi_message_dms_set_operating_mode_output_get_result (output, &error)) {
         g_task_return_error (task, error);
     } else {
-        mm_info ("Modem is being rebooted now");
+        mm_obj_info (self, "rebooting now");
         g_task_return_boolean (task, TRUE);
     }
 
@@ -2093,7 +2096,7 @@
         return;
     }
 
-    mm_dbg ("performing a factory reset...");
+    mm_obj_dbg (self, "performing a factory reset...");
     qmi_client_dms_restore_factory_defaults (QMI_CLIENT_DMS (client),
                                              input,
                                              10,
@@ -2381,7 +2384,7 @@
 
     /* Match generic configuration */
     config_fallback = g_key_file_get_string (ctx->keyfile, group, GENERIC_CONFIG_FALLBACK, NULL);
-    mm_dbg ("Fallback carrier configuration %sfound in group '%s'", config_fallback ? "" : "not ", group);
+    mm_obj_dbg (self, "fallback carrier configuration %sfound in group '%s'", config_fallback ? "" : "not ", group);
 
     /* First, try to match 6 MCCMNC digits (3-digit MNCs) */
     strncpy (mccmnc, ctx->imsi, 6);
@@ -2392,8 +2395,8 @@
         mccmnc[5] = '\0';
         ctx->config_requested = g_key_file_get_string (ctx->keyfile, group, mccmnc, NULL);
     }
-    mm_dbg ("Requested carrier configuration %sfound for '%s' in group '%s': %s",
-            ctx->config_requested ? "" : "not ", mccmnc, group, ctx->config_requested ? ctx->config_requested : "n/a");
+    mm_obj_dbg (self, "requested carrier configuration %sfound for '%s' in group '%s': %s",
+                ctx->config_requested ? "" : "not ", mccmnc, group, ctx->config_requested ? ctx->config_requested : "n/a");
 
     if (!ctx->config_requested && !config_fallback) {
         setup_carrier_config_abort (task, g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_NOT_FOUND,
@@ -2410,16 +2413,16 @@
 
             config = &g_array_index (priv->config_list, ConfigInfo, i);
             if (ctx->config_requested && !g_strcmp0 (ctx->config_requested, config->description)) {
-                mm_dbg ("Requested carrier configuration '%s' is available (version 0x%08x, size %u bytes)",
-                        config->description, config->version, config->total_size);
+                mm_obj_dbg (self, "requested carrier configuration '%s' is available (version 0x%08x, size %u bytes)",
+                            config->description, config->version, config->total_size);
                 if (ctx->config_requested_i < 0)
                     ctx->config_requested_i = i;
                 else
                     ctx->config_requested_i = select_newest_carrier_config (self, ctx->config_requested_i, i);
             }
             if (config_fallback && !g_strcmp0 (config_fallback, config->description)) {
-                mm_dbg ("Fallback carrier configuration '%s' is available (version 0x%08x, size %u bytes)",
-                        config->description, config->version, config->total_size);
+                mm_obj_dbg (self, "fallback carrier configuration '%s' is available (version 0x%08x, size %u bytes)",
+                            config->description, config->version, config->total_size);
                 if (config_fallback_i < 0)
                     config_fallback_i = i;
                 else
@@ -2444,8 +2447,8 @@
         g_assert (config_fallback_i >= 0);
 
         config = &g_array_index (priv->config_list, ConfigInfo, config_fallback_i);
-        mm_info ("Using fallback carrier configuration '%s' (version 0x%08x, size %u bytes)",
-                        config->description, config->version, config->total_size);
+        mm_obj_info (self, "using fallback carrier configuration '%s' (version 0x%08x, size %u bytes)",
+                     config->description, config->version, config->total_size);
 
         g_free (ctx->config_requested);
         ctx->config_requested = config_fallback;
@@ -2455,8 +2458,8 @@
         ConfigInfo *config;
 
         config = &g_array_index (priv->config_list, ConfigInfo, ctx->config_requested_i);
-        mm_dbg ("Using requested carrier configuration '%s' (version 0x%08x, size %u bytes)",
-                config->description, config->version, config->total_size);
+        mm_obj_dbg (self, "using requested carrier configuration '%s' (version 0x%08x, size %u bytes)",
+                    config->description, config->version, config->total_size);
     }
 
     ctx->step++;
@@ -2470,11 +2473,13 @@
 static void
 setup_carrier_config_step (GTask *task)
 {
+    MMSharedQmi               *self;
     SetupCarrierConfigContext *ctx;
     Private                   *priv;
 
-    ctx = g_task_get_task_data (task);
-    priv = get_private (g_task_get_source_object (task));
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
+    priv = get_private (self);
 
     switch (ctx->step) {
     case SETUP_CARRIER_CONFIG_STEP_FIRST:
@@ -2489,7 +2494,7 @@
         g_assert (ctx->config_requested_i >= 0);
         g_assert (priv->config_active_i >= 0 || priv->config_active_default);
         if (ctx->config_requested_i == priv->config_active_i) {
-            mm_info ("Carrier config switching not needed: already using '%s'", ctx->config_requested);
+            mm_obj_info (self, "carrier config switching not needed: already using '%s'", ctx->config_requested);
             ctx->step = SETUP_CARRIER_CONFIG_STEP_LAST;
             setup_carrier_config_step (task);
             return;
@@ -2506,8 +2511,8 @@
 
         requested_config = &g_array_index (priv->config_list, ConfigInfo, ctx->config_requested_i);
         active_config = (priv->config_active_default ? NULL : &g_array_index (priv->config_list, ConfigInfo, priv->config_active_i));
-        mm_warn ("Carrier config switching needed: '%s' -> '%s'",
-                 active_config ? active_config->description : DEFAULT_CONFIG_DESCRIPTION, requested_config->description);
+        mm_obj_warn (self, "carrier config switching needed: '%s' -> '%s'",
+                     active_config ? active_config->description : DEFAULT_CONFIG_DESCRIPTION, requested_config->description);
 
         type_and_id.config_type = requested_config->config_type;;
         type_and_id.id = requested_config->id;
@@ -2730,13 +2735,15 @@
                                 QmiIndicationPdcGetSelectedConfigOutput *output,
                                 GTask                                   *task)
 {
+    MMSharedQmi              *self;
     LoadCarrierConfigContext *ctx;
     GArray                   *active_id = NULL;
     GError                   *error = NULL;
     guint16                   error_code = 0;
     guint                     i;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     if (!qmi_indication_pdc_get_selected_config_output_get_indication_result (output, &error_code, &error)) {
         load_carrier_config_abort (task, error);
@@ -2753,7 +2760,7 @@
 
     qmi_indication_pdc_get_selected_config_output_get_active_id (output, &active_id, NULL);
     if (!active_id) {
-        mm_dbg ("no carrier config currently selected (default in use)");
+        mm_obj_dbg (self, "no carrier config currently selected (default in use)");
         ctx->config_active_default = TRUE;
         goto next;
     }
@@ -2889,13 +2896,15 @@
                          QmiIndicationPdcListConfigsOutput *output,
                          GTask                             *task)
 {
+    MMSharedQmi              *self;
     LoadCarrierConfigContext *ctx;
     GError                   *error = NULL;
     GArray                   *configs = NULL;
     guint                     i;
     guint16                   error_code = 0;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     if (!qmi_indication_pdc_list_configs_output_get_indication_result (output, &error_code, &error)) {
         load_carrier_config_abort (task, error);
@@ -2923,7 +2932,7 @@
     }
 
     /* Preallocate config list and request details for each */
-    mm_dbg ("found %u carrier configurations...", configs->len);
+    mm_obj_dbg (self, "found %u carrier configurations...", configs->len);
     ctx->config_list = g_array_sized_new (FALSE, TRUE, sizeof (ConfigInfo), configs->len);
     g_array_set_size (ctx->config_list, configs->len);
     g_array_set_clear_func (ctx->config_list, (GDestroyNotify) config_info_clear);
@@ -3828,15 +3837,15 @@
             output,
             &session_status,
             NULL)) {
-        mm_dbg ("[GPS] session status changed: '%s'",
-                qmi_pds_position_session_status_get_string (session_status));
+        mm_obj_dbg (self, "[GPS] session status changed: '%s'",
+                    qmi_pds_position_session_status_get_string (session_status));
     }
 
     if (qmi_indication_pds_event_report_output_get_nmea_position (
             output,
             &nmea,
             NULL)) {
-        mm_dbg ("[NMEA] %s", nmea);
+        mm_obj_dbg (self, "[NMEA] %s", nmea);
         mm_iface_modem_location_gps_update (MM_IFACE_MODEM_LOCATION (self), nmea);
     }
 }
@@ -3852,7 +3861,7 @@
     if (!nmea)
         return;
 
-    mm_dbg ("[NMEA] %s", nmea);
+    mm_obj_dbg (self, "[NMEA] %s", nmea);
     mm_iface_modem_location_gps_update (MM_IFACE_MODEM_LOCATION (self), nmea);
 }
 
@@ -4182,11 +4191,13 @@
                                         GAsyncResult *res,
                                         GTask        *task)
 {
+    MMSharedQmi                                  *self;
     SetGpsOperationModeContext                   *ctx;
     QmiMessagePdsSetDefaultTrackingSessionOutput *output;
     GError                                       *error = NULL;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     output = qmi_client_pds_set_default_tracking_session_finish (client, res, &error);
     if (!output) {
@@ -4208,13 +4219,13 @@
 
     switch (ctx->mode) {
         case GPS_OPERATION_MODE_AGPS_MSA:
-            mm_dbg ("MSA A-GPS operation mode enabled");
+            mm_obj_dbg (self, "MSA A-GPS operation mode enabled");
             break;
         case GPS_OPERATION_MODE_AGPS_MSB:
-            mm_dbg ("MSB A-GPS operation mode enabled");
+            mm_obj_dbg (self, "MSB A-GPS operation mode enabled");
             break;
         case GPS_OPERATION_MODE_STANDALONE:
-            mm_dbg ("Standalone mode enabled (A-GPS disabled)");
+            mm_obj_dbg (self, "standalone mode enabled (A-GPS disabled)");
             break;
         case GPS_OPERATION_MODE_UNKNOWN:
         default:
@@ -4229,6 +4240,7 @@
                                         GAsyncResult *res,
                                         GTask        *task)
 {
+    MMSharedQmi                                  *self;
     SetGpsOperationModeContext                   *ctx;
     QmiMessagePdsSetDefaultTrackingSessionInput  *input;
     QmiMessagePdsGetDefaultTrackingSessionOutput *output;
@@ -4238,6 +4250,9 @@
     guint32                                       interval;
     guint32                                       accuracy_threshold;
 
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
+
     output = qmi_client_pds_get_default_tracking_session_finish (client, res, &error);
     if (!output) {
         g_prefix_error (&error, "QMI operation failed: ");
@@ -4254,8 +4269,6 @@
         return;
     }
 
-    ctx  = g_task_get_task_data (task);
-
     qmi_message_pds_get_default_tracking_session_output_get_info (
         output,
         &session_operation,
@@ -4268,30 +4281,30 @@
 
     if (ctx->mode == GPS_OPERATION_MODE_AGPS_MSA) {
         if (session_operation == QMI_PDS_OPERATING_MODE_MS_ASSISTED) {
-            mm_dbg ("MSA A-GPS already enabled");
+            mm_obj_dbg (self, "MSA A-GPS already enabled");
             g_task_return_boolean (task, TRUE);
             g_object_unref (task);
             return;
         }
-        mm_dbg ("Need to enable MSA A-GPS");
+        mm_obj_dbg (self, "need to enable MSA A-GPS");
         session_operation = QMI_PDS_OPERATING_MODE_MS_ASSISTED;
     } else if (ctx->mode == GPS_OPERATION_MODE_AGPS_MSB) {
         if (session_operation == QMI_PDS_OPERATING_MODE_MS_BASED) {
-            mm_dbg ("MSB A-GPS already enabled");
+            mm_obj_dbg (self, "MSB A-GPS already enabled");
             g_task_return_boolean (task, TRUE);
             g_object_unref (task);
             return;
         }
-        mm_dbg ("Need to enable MSB A-GPS");
+        mm_obj_dbg (self, "need to enable MSB A-GPS");
         session_operation = QMI_PDS_OPERATING_MODE_MS_BASED;
     } else if (ctx->mode == GPS_OPERATION_MODE_STANDALONE) {
         if (session_operation == QMI_PDS_OPERATING_MODE_STANDALONE) {
-            mm_dbg ("A-GPS already disabled");
+            mm_obj_dbg (self, "A-GPS already disabled");
             g_task_return_boolean (task, TRUE);
             g_object_unref (task);
             return;
         }
-        mm_dbg ("Need to disable A-GPS");
+        mm_obj_dbg (self, "need to disable A-GPS");
         session_operation = QMI_PDS_OPERATING_MODE_STANDALONE;
     } else
         g_assert_not_reached ();
@@ -4333,11 +4346,13 @@
                                                QmiIndicationLocSetOperationModeOutput *output,
                                                GTask                                  *task)
 {
+    MMSharedQmi                *self;
     SetGpsOperationModeContext *ctx;
     QmiLocIndicationStatus      status;
     GError                     *error = NULL;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     if (!qmi_indication_loc_set_operation_mode_output_get_indication_status (output, &status, &error)) {
         g_prefix_error (&error, "QMI operation failed: ");
@@ -4354,13 +4369,13 @@
 
     switch (ctx->mode) {
         case GPS_OPERATION_MODE_AGPS_MSA:
-            mm_dbg ("MSA A-GPS operation mode enabled");
+            mm_obj_dbg (self, "MSA A-GPS operation mode enabled");
             break;
         case GPS_OPERATION_MODE_AGPS_MSB:
-            mm_dbg ("MSB A-GPS operation mode enabled");
+            mm_obj_dbg (self, "MSB A-GPS operation mode enabled");
             break;
         case GPS_OPERATION_MODE_STANDALONE:
-            mm_dbg ("Standalone mode enabled (A-GPS disabled)");
+            mm_obj_dbg (self, "standalone mode enabled (A-GPS disabled)");
             break;
         case GPS_OPERATION_MODE_UNKNOWN:
         default:
@@ -4414,13 +4429,15 @@
                                                QmiIndicationLocGetOperationModeOutput *output,
                                                GTask                                  *task)
 {
+    MMSharedQmi                        *self;
     SetGpsOperationModeContext         *ctx;
     QmiLocIndicationStatus              status;
     GError                             *error = NULL;
     QmiLocOperationMode                 mode = QMI_LOC_OPERATION_MODE_DEFAULT;
     QmiMessageLocSetOperationModeInput *input;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     if (!qmi_indication_loc_get_operation_mode_output_get_indication_status (output, &status, &error)) {
         g_prefix_error (&error, "QMI operation failed: ");
@@ -4439,30 +4456,30 @@
 
     if (ctx->mode == GPS_OPERATION_MODE_AGPS_MSA) {
         if (mode == QMI_LOC_OPERATION_MODE_MSA) {
-            mm_dbg ("MSA A-GPS already enabled");
+            mm_obj_dbg (self, "MSA A-GPS already enabled");
             g_task_return_boolean (task, TRUE);
             g_object_unref (task);
             return;
         }
-        mm_dbg ("Need to enable MSA A-GPS");
+        mm_obj_dbg (self, "need to enable MSA A-GPS");
         mode = QMI_LOC_OPERATION_MODE_MSA;
     } else if (ctx->mode == GPS_OPERATION_MODE_AGPS_MSB) {
         if (mode == QMI_LOC_OPERATION_MODE_MSB) {
-            mm_dbg ("MSB A-GPS already enabled");
+            mm_obj_dbg (self, "MSB A-GPS already enabled");
             g_task_return_boolean (task, TRUE);
             g_object_unref (task);
             return;
         }
-        mm_dbg ("Need to enable MSB A-GPS");
+        mm_obj_dbg (self, "need to enable MSB A-GPS");
         mode = QMI_LOC_OPERATION_MODE_MSB;
     } else if (ctx->mode == GPS_OPERATION_MODE_STANDALONE) {
         if (mode == QMI_LOC_OPERATION_MODE_STANDALONE) {
-            mm_dbg ("A-GPS already disabled");
+            mm_obj_dbg (self, "A-GPS already disabled");
             g_task_return_boolean (task, TRUE);
             g_object_unref (task);
             return;
         }
-        mm_dbg ("Need to disable A-GPS");
+        mm_obj_dbg (self, "need to disable A-GPS");
         mode = QMI_LOC_OPERATION_MODE_STANDALONE;
     } else
         g_assert_not_reached ();
@@ -5254,13 +5271,15 @@
 static void
 inject_xtra_data_next (GTask *task)
 {
+    MMSharedQmi                      *self;
     QmiMessageLocInjectXtraDataInput *input;
     InjectAssistanceDataContext      *ctx;
     goffset                           total_bytes_left;
     gsize                             count;
     GArray                           *data;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     g_assert (ctx->data_size >= ctx->i);
     total_bytes_left = ctx->data_size - ctx->i;
@@ -5295,8 +5314,8 @@
 
     ctx->i += count;
 
-    mm_info ("injecting xtra data: %" G_GSIZE_FORMAT " bytes (%u/%u)",
-             count, (guint) ctx->n_part, (guint) ctx->total_parts);
+    mm_obj_info (self, "injecting xtra data: %" G_GSIZE_FORMAT " bytes (%u/%u)",
+                 count, (guint) ctx->n_part, (guint) ctx->total_parts);
     qmi_client_loc_inject_xtra_data (ctx->client,
                                      input,
                                      10,
@@ -5401,13 +5420,15 @@
 static void
 inject_assistance_data_next (GTask *task)
 {
+    MMSharedQmi                                 *self;
     QmiMessageLocInjectPredictedOrbitsDataInput *input;
     InjectAssistanceDataContext                 *ctx;
     goffset                                      total_bytes_left;
     gsize                                        count;
     GArray                                      *data;
 
-    ctx = g_task_get_task_data (task);
+    self = g_task_get_source_object (task);
+    ctx  = g_task_get_task_data (task);
 
     g_assert (ctx->data_size >= ctx->i);
     total_bytes_left = ctx->data_size - ctx->i;
@@ -5446,8 +5467,8 @@
 
     ctx->i += count;
 
-    mm_info ("injecting predicted orbits data: %" G_GSIZE_FORMAT " bytes (%u/%u)",
-             count, (guint) ctx->n_part, (guint) ctx->total_parts);
+    mm_obj_info (self, "injecting predicted orbits data: %" G_GSIZE_FORMAT " bytes (%u/%u)",
+                 count, (guint) ctx->n_part, (guint) ctx->total_parts);
     qmi_client_loc_inject_predicted_orbits_data (ctx->client,
                                                  input,
                                                  10,
@@ -5498,7 +5519,7 @@
         ctx->total_parts++;
     g_assert (ctx->total_parts <= G_MAXUINT16);
 
-    mm_dbg ("Injecting gpsOneXTRA data (%" G_GOFFSET_FORMAT " bytes)...", ctx->data_size);
+    mm_obj_dbg (self, "injecting gpsOneXTRA data (%" G_GOFFSET_FORMAT " bytes)...", ctx->data_size);
 
     inject_assistance_data_next (task);
 }
diff --git a/src/mm-sim-mbim.c b/src/mm-sim-mbim.c
index a2aa1ea..f48bb31 100644
--- a/src/mm-sim-mbim.c
+++ b/src/mm-sim-mbim.c
@@ -26,7 +26,7 @@
 
 #include "mm-error-helpers.h"
 #include "mm-iface-modem.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-modem-helpers-mbim.h"
 #include "mm-sim-mbim.h"
 
@@ -382,10 +382,10 @@
                 /* Sending PIN failed, build a better error to report */
                 if (pin_type == MBIM_PIN_TYPE_PIN1 && pin_state == MBIM_PIN_STATE_LOCKED) {
                     g_error_free (error);
-                    error = mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_INCORRECT_PASSWORD);
+                    error = mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_INCORRECT_PASSWORD, self);
                 } else if (pin_type == MBIM_PIN_TYPE_PUK1 && pin_state == MBIM_PIN_STATE_LOCKED) {
                     g_error_free (error);
-                    error = mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_SIM_PUK);
+                    error = mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_SIM_PUK, self);
                 }
             }
         }
@@ -416,7 +416,7 @@
 
     task = g_task_new (self, NULL, callback, user_data);
 
-    mm_dbg ("Sending PIN...");
+    mm_obj_dbg (self, "sending PIN...");
     message = (mbim_message_pin_set_new (
                    MBIM_PIN_TYPE_PIN1,
                    MBIM_PIN_OPERATION_ENTER,
@@ -480,9 +480,9 @@
                 if (pin_type == MBIM_PIN_TYPE_PUK1 && pin_state == MBIM_PIN_STATE_LOCKED) {
                     g_error_free (error);
                     if (remaining_attempts == 0)
-                        error = mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_SIM_WRONG);
+                        error = mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_SIM_WRONG, self);
                     else
-                        error = mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_INCORRECT_PASSWORD);
+                        error = mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_INCORRECT_PASSWORD, self);
                 }
             }
         }
@@ -514,7 +514,7 @@
 
     task = g_task_new (self, NULL, callback, user_data);
 
-    mm_dbg ("Sending PUK...");
+    mm_obj_dbg (self, "sending PUK...");
     message = (mbim_message_pin_set_new (
                    MBIM_PIN_TYPE_PUK1,
                    MBIM_PIN_OPERATION_ENTER,
@@ -605,7 +605,7 @@
 
     task = g_task_new (self, NULL, callback, user_data);
 
-    mm_dbg ("%s PIN ...", enabled ? "Enabling" : "Disabling");
+    mm_obj_dbg (self, "%s PIN ...", enabled ? "enabling" : "disabling");
     message = (mbim_message_pin_set_new (
                    MBIM_PIN_TYPE_PIN1,
                    enabled ? MBIM_PIN_OPERATION_ENABLE : MBIM_PIN_OPERATION_DISABLE,
@@ -696,7 +696,7 @@
 
     task = g_task_new (self, NULL, callback, user_data);
 
-    mm_dbg ("Changing PIN");
+    mm_obj_dbg (self, "changing PIN...");
     message = (mbim_message_pin_set_new (
                    MBIM_PIN_TYPE_PIN1,
                    MBIM_PIN_OPERATION_CHANGE,
diff --git a/src/mm-sim-qmi.c b/src/mm-sim-qmi.c
index 9294a1f..6eb5854 100644
--- a/src/mm-sim-qmi.c
+++ b/src/mm-sim-qmi.c
@@ -25,7 +25,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-sim-qmi.h"
 
 G_DEFINE_TYPE (MMSimQmi, mm_sim_qmi, MM_TYPE_BASE_SIM)
@@ -298,7 +298,7 @@
     self = MM_SIM_QMI (_self);
     task = g_task_new (self, NULL, callback, user_data);
 
-    mm_dbg ("loading SIM identifier...");
+    mm_obj_dbg (self, "loading SIM identifier...");
     if (!self->priv->dms_uim_deprecated)
         dms_uim_get_iccid (self, task);
     else
@@ -423,7 +423,7 @@
     self = MM_SIM_QMI (_self);
     task = g_task_new (self, NULL, callback, user_data);
 
-    mm_dbg ("loading IMSI...");
+    mm_obj_dbg (self, "loading IMSI...");
     if (!self->priv->dms_uim_deprecated)
         dms_uim_get_imsi (self, task);
     else
@@ -540,7 +540,7 @@
                             QMI_SERVICE_NAS, &client))
         return;
 
-    mm_dbg ("loading SIM operator identifier...");
+    mm_obj_dbg (self, "loading SIM operator identifier...");
     qmi_client_nas_get_home_network (QMI_CLIENT_NAS (client),
                                      NULL,
                                      5,
@@ -589,7 +589,7 @@
                             QMI_SERVICE_NAS, &client))
         return;
 
-    mm_dbg ("loading SIM operator name...");
+    mm_obj_dbg (self, "loading SIM operator name...");
     qmi_client_nas_get_home_network (QMI_CLIENT_NAS (client),
                                      NULL,
                                      5,
@@ -733,7 +733,7 @@
         return;
     }
 
-    mm_dbg ("Sending PIN...");
+    mm_obj_dbg (self, "sending PIN...");
     input = qmi_message_dms_uim_verify_pin_input_new ();
     qmi_message_dms_uim_verify_pin_input_set_info (
         input,
@@ -763,7 +763,7 @@
 
     g_task_set_task_data (task, g_strdup (pin), g_free);
 
-    mm_dbg ("Verifying PIN...");
+    mm_obj_dbg (self, "verifying PIN...");
     if (!self->priv->dms_uim_deprecated)
         dms_uim_verify_pin (self, task);
     else
@@ -933,7 +933,7 @@
     ctx->new_pin = g_strdup (new_pin);
     g_task_set_task_data (task, ctx, (GDestroyNotify) unblock_pin_context_free);
 
-    mm_dbg ("Unblocking PIN...");
+    mm_obj_dbg (self, "unblocking PIN...");
     if (!self->priv->dms_uim_deprecated)
         dms_uim_unblock_pin (self, task);
     else
@@ -1103,7 +1103,7 @@
     ctx->new_pin = g_strdup (new_pin);
     g_task_set_task_data (task, ctx, (GDestroyNotify) change_pin_context_free);
 
-    mm_dbg ("Changing PIN...");
+    mm_obj_dbg (self, "changing PIN...");
     if (!self->priv->dms_uim_deprecated)
         dms_uim_change_pin (self, task);
     else
@@ -1272,7 +1272,7 @@
     ctx->enabled = enabled;
     g_task_set_task_data (task, ctx, (GDestroyNotify) enable_pin_context_free);
 
-    mm_dbg ("%s PIN...", enabled ? "Enabling" : "Disabling");
+    mm_obj_dbg (self, "%s PIN...", enabled ? "enabling" : "disabling");
     if (!self->priv->dms_uim_deprecated)
         dms_uim_enable_pin (self, task);
     else
diff --git a/src/mm-sleep-monitor.c b/src/mm-sleep-monitor.c
index c5aae5a..d3d181c 100644
--- a/src/mm-sleep-monitor.c
+++ b/src/mm-sleep-monitor.c
@@ -26,7 +26,7 @@
 #include <gio/gio.h>
 #include <gio/gunixfdlist.h>
 
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-utils.h"
 #include "mm-sleep-monitor.h"
 
@@ -57,7 +57,18 @@
 };
 static guint signals[LAST_SIGNAL] = {0};
 
-G_DEFINE_TYPE (MMSleepMonitor, mm_sleep_monitor, G_TYPE_OBJECT);
+static void log_object_iface_init (MMLogObjectInterface *iface);
+
+G_DEFINE_TYPE_EXTENDED (MMSleepMonitor, mm_sleep_monitor, G_TYPE_OBJECT, 0,
+                        G_IMPLEMENT_INTERFACE (MM_TYPE_LOG_OBJECT, log_object_iface_init))
+
+/*****************************************************************************/
+
+static gchar *
+log_object_build_id (MMLogObject *_self)
+{
+    return g_strdup ("sleep-monitor");
+}
 
 /********************************************************************/
 
@@ -65,7 +76,7 @@
 drop_inhibitor (MMSleepMonitor *self)
 {
     if (self->inhibit_fd >= 0) {
-        mm_dbg ("[sleep-monitor] dropping systemd sleep inhibitor");
+        mm_obj_dbg (self, "dropping systemd sleep inhibitor");
         close (self->inhibit_fd);
         self->inhibit_fd = -1;
         return TRUE;
@@ -86,15 +97,15 @@
 
     res = g_dbus_proxy_call_with_unix_fd_list_finish (sd_proxy, &fd_list, result, &error);
     if (!res) {
-        mm_warn ("[sleep-monitor] inhibit failed: %s", error->message);
+        mm_obj_warn (self, "inhibit failed: %s", error->message);
         g_error_free (error);
     } else {
         if (!fd_list || g_unix_fd_list_get_length (fd_list) != 1)
-            mm_warn ("[sleep-monitor] didn't get a single fd back");
+            mm_obj_warn (self, "didn't get a single fd back");
 
         self->inhibit_fd = g_unix_fd_list_get (fd_list, 0, NULL);
 
-        mm_dbg ("[sleep-monitor] inhibitor fd is %d", self->inhibit_fd);
+        mm_obj_dbg (self, "inhibitor fd is %d", self->inhibit_fd);
         g_object_unref (fd_list);
         g_variant_unref (res);
     }
@@ -105,7 +116,7 @@
 {
     g_assert (self->inhibit_fd == -1);
 
-    mm_dbg ("[sleep-monitor] taking systemd sleep inhibitor");
+    mm_obj_dbg (self, "taking systemd sleep inhibitor");
     g_dbus_proxy_call_with_unix_fd_list (self->sd_proxy,
                                          "Inhibit",
                                          g_variant_new ("(ssss)",
@@ -135,12 +146,13 @@
         return;
 
     g_variant_get (args, "(b)", &is_about_to_suspend);
-    mm_dbg ("[sleep-monitor] received PrepareForSleep signal: %d", is_about_to_suspend);
 
     if (is_about_to_suspend) {
+        mm_obj_info (self, "system is about to suspend");
         g_signal_emit (self, signals[SLEEPING], 0);
         drop_inhibitor (self);
     } else {
+        mm_obj_info (self, "system is resuming");
         take_inhibitor (self);
         g_signal_emit (self, signals[RESUMING], 0);
     }
@@ -175,7 +187,7 @@
 
     self->sd_proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
     if (!self->sd_proxy) {
-        mm_warn ("[sleep-monitor] failed to acquire logind proxy: %s", error->message);
+        mm_obj_warn (self, "failed to acquire logind proxy: %s", error->message);
         g_clear_error (&error);
         return;
     }
@@ -216,6 +228,12 @@
 }
 
 static void
+log_object_iface_init (MMLogObjectInterface *iface)
+{
+    iface->build_id = log_object_build_id;
+}
+
+static void
 mm_sleep_monitor_class_init (MMSleepMonitorClass *klass)
 {
     GObjectClass *gobject_class;
diff --git a/src/mm-sms-list.c b/src/mm-sms-list.c
index ec3adca..1a83221 100644
--- a/src/mm-sms-list.c
+++ b/src/mm-sms-list.c
@@ -27,9 +27,12 @@
 #include "mm-iface-modem-messaging.h"
 #include "mm-sms-list.h"
 #include "mm-base-sms.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
-G_DEFINE_TYPE (MMSmsList, mm_sms_list, G_TYPE_OBJECT);
+static void log_object_iface_init (MMLogObjectInterface *iface);
+
+G_DEFINE_TYPE_EXTENDED (MMSmsList, mm_sms_list, G_TYPE_OBJECT, 0,
+                        G_IMPLEMENT_INTERFACE (MM_TYPE_LOG_OBJECT, log_object_iface_init))
 
 enum {
     PROP_0,
@@ -280,8 +283,7 @@
                             (GCompareFunc)cmp_sms_by_concat_reference);
     if (l) {
         /* Try to take the part */
-        mm_dbg ("Found existing multipart SMS object with reference '%u': adding new part",
-                concat_reference);
+        mm_obj_dbg (self, "found existing multipart SMS object with reference '%u': adding new part", concat_reference);
         return mm_base_sms_multipart_take_part (MM_BASE_SMS (l->data), part, error);
     }
 
@@ -296,9 +298,9 @@
     if (!sms)
         return FALSE;
 
-    mm_dbg ("Creating new multipart SMS object: need to receive %u parts with reference '%u'",
-            mm_sms_part_get_concat_max (part),
-            concat_reference);
+    mm_obj_dbg (self, "creating new multipart SMS object: need to receive %u parts with reference '%u'",
+                mm_sms_part_get_concat_max (part),
+                concat_reference);
     self->priv->list = g_list_prepend (self->priv->list, sms);
     g_signal_emit (self, signals[SIGNAL_ADDED], 0,
                    mm_base_sms_get_path (sms),
@@ -349,33 +351,41 @@
     /* Did we just get a part of a multi-part SMS? */
     if (mm_sms_part_should_concat (part)) {
         if (mm_sms_part_get_index (part) != SMS_PART_INVALID_INDEX)
-            mm_dbg ("SMS part at '%s/%u' is from a multipart SMS (reference: '%u', sequence: '%u/%u')",
-                    mm_sms_storage_get_string (storage),
-                    mm_sms_part_get_index (part),
-                    mm_sms_part_get_concat_reference (part),
-                    mm_sms_part_get_concat_sequence (part),
-                    mm_sms_part_get_concat_max (part));
+            mm_obj_dbg (self, "SMS part at '%s/%u' is from a multipart SMS (reference: '%u', sequence: '%u/%u')",
+                        mm_sms_storage_get_string (storage),
+                        mm_sms_part_get_index (part),
+                        mm_sms_part_get_concat_reference (part),
+                        mm_sms_part_get_concat_sequence (part),
+                        mm_sms_part_get_concat_max (part));
         else
-            mm_dbg ("SMS part (not stored) is from a multipart SMS (reference: '%u', sequence: '%u/%u')",
-                    mm_sms_part_get_concat_reference (part),
-                    mm_sms_part_get_concat_sequence (part),
-                    mm_sms_part_get_concat_max (part));
+            mm_obj_dbg (self, "SMS part (not stored) is from a multipart SMS (reference: '%u', sequence: '%u/%u')",
+                        mm_sms_part_get_concat_reference (part),
+                        mm_sms_part_get_concat_sequence (part),
+                        mm_sms_part_get_concat_max (part));
 
         return take_multipart (self, part, state, storage, error);
     }
 
     /* Otherwise, we build a whole new single-part MMSms just from this part */
     if (mm_sms_part_get_index (part) != SMS_PART_INVALID_INDEX)
-        mm_dbg ("SMS part at '%s/%u' is from a singlepart SMS",
-                mm_sms_storage_get_string (storage),
-                mm_sms_part_get_index (part));
+        mm_obj_dbg (self, "SMS part at '%s/%u' is from a singlepart SMS",
+                    mm_sms_storage_get_string (storage),
+                    mm_sms_part_get_index (part));
     else
-        mm_dbg ("SMS part (not stored) is from a singlepart SMS");
+        mm_obj_dbg (self, "SMS part (not stored) is from a singlepart SMS");
     return take_singlepart (self, part, state, storage, error);
 }
 
 /*****************************************************************************/
 
+static gchar *
+log_object_build_id (MMLogObject *_self)
+{
+    return g_strdup ("sms-list");
+}
+
+/*****************************************************************************/
+
 MMSmsList *
 mm_sms_list_new (MMBaseModem *modem)
 {
@@ -397,6 +407,10 @@
     case PROP_MODEM:
         g_clear_object (&self->priv->modem);
         self->priv->modem = g_value_dup_object (value);
+        if (self->priv->modem) {
+            /* Set owner ID */
+            mm_log_object_set_owner_id (MM_LOG_OBJECT (self), mm_log_object_get_id (MM_LOG_OBJECT (self->priv->modem)));
+        }
         break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -444,6 +458,12 @@
 }
 
 static void
+log_object_iface_init (MMLogObjectInterface *iface)
+{
+    iface->build_id = log_object_build_id;
+}
+
+static void
 mm_sms_list_class_init (MMSmsListClass *klass)
 {
     GObjectClass *object_class = G_OBJECT_CLASS (klass);
diff --git a/src/mm-sms-mbim.c b/src/mm-sms-mbim.c
index e20a83d..5ad3e51 100644
--- a/src/mm-sms-mbim.c
+++ b/src/mm-sms-mbim.c
@@ -28,7 +28,7 @@
 #include "mm-iface-modem-messaging.h"
 #include "mm-sms-mbim.h"
 #include "mm-base-modem.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 #include "mm-sms-part-3gpp.h"
 
 G_DEFINE_TYPE (MMSmsMbim, mm_sms_mbim, MM_TYPE_BASE_SMS)
@@ -138,6 +138,7 @@
 static void
 sms_send_next_part (GTask *task)
 {
+    MMSmsMbim *self;
     SmsSendContext *ctx;
     MbimMessage *message;
     guint8 *pdu;
@@ -146,7 +147,9 @@
     GError *error = NULL;
     MbimSmsPduSendRecord send_record;
 
+    self = g_task_get_source_object (task);
     ctx = g_task_get_task_data (task);
+
     if (!ctx->current) {
         /* Done we are */
         g_task_return_boolean (task, TRUE);
@@ -155,7 +158,7 @@
     }
 
     /* Get PDU */
-    pdu = mm_sms_part_3gpp_get_submit_pdu ((MMSmsPart *)ctx->current->data, &pdulen, &msgstart, &error);
+    pdu = mm_sms_part_3gpp_get_submit_pdu ((MMSmsPart *)ctx->current->data, &pdulen, &msgstart, self, &error);
     if (!pdu) {
         g_task_return_error (task, error);
         g_object_unref (task);
@@ -237,11 +240,14 @@
                       GAsyncResult *res,
                       GTask *task)
 {
+    MMSmsMbim *self;
     SmsDeletePartsContext *ctx;
     MbimMessage *response;
     GError *error = NULL;
 
+    self = g_task_get_source_object (task);
     ctx = g_task_get_task_data (task);
+
     response = mbim_device_command_finish (device, res, &error);
     if (response &&
         mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error))
@@ -252,9 +258,9 @@
 
     if (error) {
         ctx->n_failed++;
-        mm_dbg ("Couldn't delete SMS part with index %u: '%s'",
-                mm_sms_part_get_index ((MMSmsPart *)ctx->current->data),
-                error->message);
+        mm_obj_dbg (self, "couldn't delete SMS part with index %u: %s",
+                    mm_sms_part_get_index ((MMSmsPart *)ctx->current->data),
+                    error->message);
         g_error_free (error);
     }
 
diff --git a/src/mm-sms-part-3gpp.c b/src/mm-sms-part-3gpp.c
index 3a59cdc..183d286 100644
--- a/src/mm-sms-part-3gpp.c
+++ b/src/mm-sms-part-3gpp.c
@@ -240,17 +240,21 @@
 }
 
 static char *
-sms_decode_text (const guint8 *text, int len, MMSmsEncoding encoding, int bit_offset)
+sms_decode_text (const guint8 *text,
+                 int           len,
+                 MMSmsEncoding encoding,
+                 int           bit_offset,
+                 gpointer      log_object)
 {
     char *utf8;
     guint8 *unpacked;
     guint32 unpacked_len;
 
     if (encoding == MM_SMS_ENCODING_GSM7) {
-        mm_dbg ("Converting SMS part text from GSM-7 to UTF-8...");
+        mm_obj_dbg (log_object, "converting SMS part text from GSM-7 to UTF-8...");
         unpacked = mm_charset_gsm_unpack ((const guint8 *) text, len, bit_offset, &unpacked_len);
         utf8 = (char *) mm_charset_gsm_unpacked_to_utf8 (unpacked, unpacked_len);
-        mm_dbg ("   Got UTF-8 text: '%s'", utf8);
+        mm_obj_dbg (log_object, "   got UTF-8 text: '%s'", utf8);
         g_free (unpacked);
     } else if (encoding == MM_SMS_ENCODING_UCS2) {
         /* Despite 3GPP TS 23.038 specifies that Unicode SMS messages are
@@ -266,19 +270,19 @@
          * the SMS message in UTF-16BE, and if that fails, fall back to decode
          * in UCS-2BE.
          */
-        mm_dbg ("Converting SMS part text from UTF-16BE to UTF-8...");
+        mm_obj_dbg (log_object, "converting SMS part text from UTF-16BE to UTF-8...");
         utf8 = g_convert ((const gchar *) text, len, "UTF8", "UTF16BE", NULL, NULL, NULL);
         if (!utf8) {
-            mm_dbg ("Converting SMS part text from UCS-2BE to UTF8...");
+            mm_obj_dbg (log_object, "converting SMS part text from UCS-2BE to UTF8...");
             utf8 = g_convert ((const gchar *) text, len, "UTF8", "UCS-2BE", NULL, NULL, NULL);
         }
         if (!utf8) {
-            mm_warn ("Couldn't convert SMS part contents from UTF-16BE/UCS-2BE to UTF-8: not decoding any text");
+            mm_obj_warn (log_object, "couldn't convert SMS part contents from UTF-16BE/UCS-2BE to UTF-8: not decoding any text");
             utf8 = g_strdup ("");
         } else
-            mm_dbg ("   Got UTF-8 text: '%s'", utf8);
+            mm_obj_dbg (log_object, "   got UTF-8 text: '%s'", utf8);
     } else {
-        mm_warn ("Unexpected encoding '%s': not decoding any text", mm_sms_encoding_get_string (encoding));
+        mm_obj_warn (log_object, "unexpected encoding: %s; not decoding any text", mm_sms_encoding_get_string (encoding));
         utf8 = g_strdup ("");
     }
 
@@ -343,9 +347,10 @@
 }
 
 MMSmsPart *
-mm_sms_part_3gpp_new_from_pdu (guint index,
-                               const gchar *hexpdu,
-                               GError **error)
+mm_sms_part_3gpp_new_from_pdu (guint         index,
+                               const gchar  *hexpdu,
+                               gpointer      log_object,
+                               GError      **error)
 {
     gsize pdu_len;
     guint8 *pdu;
@@ -361,17 +366,18 @@
         return NULL;
     }
 
-    part = mm_sms_part_3gpp_new_from_binary_pdu (index, pdu, pdu_len, error);
+    part = mm_sms_part_3gpp_new_from_binary_pdu (index, pdu, pdu_len, log_object, error);
     g_free (pdu);
 
     return part;
 }
 
 MMSmsPart *
-mm_sms_part_3gpp_new_from_binary_pdu (guint index,
-                                      const guint8 *pdu,
-                                      gsize pdu_len,
-                                      GError **error)
+mm_sms_part_3gpp_new_from_binary_pdu (guint         index,
+                                      const guint8  *pdu,
+                                      gsize          pdu_len,
+                                      gpointer       log_object,
+                                      GError       **error)
 {
     MMSmsPart *sms_part;
     guint8 pdu_type;
@@ -392,9 +398,9 @@
     sms_part = mm_sms_part_new (index, MM_SMS_PDU_TYPE_UNKNOWN);
 
     if (index != SMS_PART_INVALID_INDEX)
-        mm_dbg ("Parsing PDU (%u)...", index);
+        mm_obj_dbg (log_object, "parsing PDU (%u)...", index);
     else
-        mm_dbg ("Parsing PDU...");
+        mm_obj_dbg (log_object, "parsing PDU...");
 
 #define PDU_SIZE_CHECK(required_size, check_descr_str)                 \
     if (pdu_len < required_size) {                                     \
@@ -421,10 +427,10 @@
         /* SMSC may not be given in DELIVER PDUs */
         mm_sms_part_take_smsc (sms_part,
                                sms_decode_address (&pdu[1], 2 * (smsc_addr_size_bytes - 1)));
-        mm_dbg ("  SMSC address parsed: '%s'", mm_sms_part_get_smsc (sms_part));
+        mm_obj_dbg (log_object, "  SMSC address parsed: '%s'", mm_sms_part_get_smsc (sms_part));
         offset += smsc_addr_size_bytes;
     } else
-        mm_dbg ("  No SMSC address given");
+        mm_obj_dbg (log_object, "  no SMSC address given");
 
 
     /* ---------------------------------------------------------------------- */
@@ -434,15 +440,15 @@
     pdu_type = (pdu[offset] & SMS_TP_MTI_MASK);
     switch (pdu_type) {
     case SMS_TP_MTI_SMS_DELIVER:
-        mm_dbg ("  Deliver type PDU detected");
+        mm_obj_dbg (log_object, "  deliver type PDU detected");
         mm_sms_part_set_pdu_type (sms_part, MM_SMS_PDU_TYPE_DELIVER);
         break;
     case SMS_TP_MTI_SMS_SUBMIT:
-        mm_dbg ("  Submit type PDU detected");
+        mm_obj_dbg (log_object, "  submit type PDU detected");
         mm_sms_part_set_pdu_type (sms_part, MM_SMS_PDU_TYPE_SUBMIT);
         break;
     case SMS_TP_MTI_SMS_STATUS_REPORT:
-        mm_dbg ("  Status report type PDU detected");
+        mm_obj_dbg (log_object, "  status report type PDU detected");
         mm_sms_part_set_pdu_type (sms_part, MM_SMS_PDU_TYPE_STATUS_REPORT);
         break;
     default:
@@ -475,7 +481,7 @@
         pdu_type == SMS_TP_MTI_SMS_SUBMIT) {
         PDU_SIZE_CHECK (offset + 1, "cannot read message reference");
 
-        mm_dbg ("  message reference: %u", (guint)pdu[offset]);
+        mm_obj_dbg (log_object, "  message reference: %u", (guint)pdu[offset]);
         mm_sms_part_set_message_reference (sms_part, pdu[offset]);
         offset++;
     }
@@ -495,7 +501,7 @@
     mm_sms_part_take_number (sms_part,
                              sms_decode_address (&pdu[offset],
                                                  tp_addr_size_digits));
-    mm_dbg ("  Number parsed: '%s'", mm_sms_part_get_number (sms_part));
+    mm_obj_dbg (log_object, "  number parsed: %s", mm_sms_part_get_number (sms_part));
     offset += (1 + tp_addr_size_bytes); /* +1 due to the Type of Address byte */
 
     /* ---------------------------------------------------------------------- */
@@ -531,20 +537,20 @@
         if (validity_format) {
             switch (validity_format) {
             case 0x10:
-                mm_dbg ("  validity available, format relative");
+                mm_obj_dbg (log_object, "  validity available, format relative");
                 mm_sms_part_set_validity_relative (sms_part,
                                                    relative_to_validity (pdu[offset]));
                 offset++;
                 break;
             case 0x08:
                 /* TODO: support enhanced format; GSM 03.40 */
-                mm_dbg ("  validity available, format enhanced (not implemented)");
+                mm_obj_dbg (log_object, "  validity available, format enhanced (not implemented)");
                 /* 7 bytes for enhanced validity */
                 offset += 7;
                 break;
             case 0x18:
                 /* TODO: support absolute format; GSM 03.40 */
-                mm_dbg ("  validity available, format absolute (not implemented)");
+                mm_obj_dbg (log_object, "  validity available, format absolute (not implemented)");
                 /* 7 bytes for absolute validity */
                 offset += 7;
                 break;
@@ -574,7 +580,7 @@
         offset += 7;
 
         /* ----- TP-STATUS (1 byte) ------ */
-        mm_dbg ("  delivery state: %u", (guint)pdu[offset]);
+        mm_obj_dbg (log_object, "  delivery state: %u", (guint)pdu[offset]);
         mm_sms_part_set_delivery_state (sms_part, pdu[offset]);
         offset++;
 
@@ -599,7 +605,7 @@
 
     if (tp_pid_offset > 0) {
         PDU_SIZE_CHECK (tp_pid_offset + 1, "cannot read TP-PID");
-        mm_dbg ("  PID: %u", (guint)pdu[tp_pid_offset]);
+        mm_obj_dbg (log_object, "  PID: %u", (guint)pdu[tp_pid_offset]);
     }
 
     /* Grab user data encoding and message class */
@@ -610,17 +616,17 @@
         user_data_encoding = sms_encoding_type (pdu[tp_dcs_offset]);
         switch (user_data_encoding) {
         case MM_SMS_ENCODING_GSM7:
-            mm_dbg ("  user data encoding is GSM7");
+            mm_obj_dbg (log_object, "  user data encoding is GSM7");
             break;
         case MM_SMS_ENCODING_UCS2:
-            mm_dbg ("  user data encoding is UCS2");
+            mm_obj_dbg (log_object, "  user data encoding is UCS2");
             break;
         case MM_SMS_ENCODING_8BIT:
-            mm_dbg ("  user data encoding is 8bit");
+            mm_obj_dbg (log_object, "  user data encoding is 8bit");
             break;
         case MM_SMS_ENCODING_UNKNOWN:
         default:
-            mm_dbg ("  user data encoding is unknown");
+            mm_obj_dbg (log_object, "  user data encoding is unknown");
             break;
         }
         mm_sms_part_set_encoding (sms_part, user_data_encoding);
@@ -639,13 +645,13 @@
 
         PDU_SIZE_CHECK (tp_user_data_len_offset + 1, "cannot read TP-UDL");
         tp_user_data_size_elements = pdu[tp_user_data_len_offset];
-        mm_dbg ("  user data length: %u elements", tp_user_data_size_elements);
+        mm_obj_dbg (log_object, "  user data length: %u elements", tp_user_data_size_elements);
 
         if (user_data_encoding == MM_SMS_ENCODING_GSM7)
             tp_user_data_size_bytes = (7 * (tp_user_data_size_elements + 1 )) / 8;
         else
             tp_user_data_size_bytes = tp_user_data_size_elements;
-        mm_dbg ("  user data length: %u bytes", tp_user_data_size_bytes);
+        mm_obj_dbg (log_object, "  user data length: %u bytes", tp_user_data_size_bytes);
 
         tp_user_data_offset = tp_user_data_len_offset + 1;
         PDU_SIZE_CHECK (tp_user_data_offset + tp_user_data_size_bytes, "cannot read TP-UD");
@@ -722,12 +728,13 @@
         case MM_SMS_ENCODING_GSM7:
         case MM_SMS_ENCODING_UCS2:
             /* Otherwise if it's 7-bit or UCS2 we can decode it */
-            mm_dbg ("Decoding SMS text with '%u' elements", tp_user_data_size_elements);
+            mm_obj_dbg (log_object, "decoding SMS text with %u elements", tp_user_data_size_elements);
             mm_sms_part_take_text (sms_part,
                                    sms_decode_text (&pdu[tp_user_data_offset],
                                                     tp_user_data_size_elements,
                                                     user_data_encoding,
-                                                    bit_offset));
+                                                    bit_offset,
+                                                    log_object));
             g_warn_if_fail (mm_sms_part_get_text (sms_part) != NULL);
             break;
 
@@ -737,7 +744,7 @@
             {
                 GByteArray *raw;
 
-                mm_dbg ("Skipping SMS text: Unknown encoding (0x%02X)", user_data_encoding);
+                mm_obj_dbg (log_object, "skipping SMS text: unknown encoding (0x%02X)", user_data_encoding);
 
                 PDU_SIZE_CHECK (tp_user_data_offset + tp_user_data_size_bytes, "cannot read user data");
 
@@ -815,6 +822,7 @@
 mm_sms_part_3gpp_get_submit_pdu (MMSmsPart *part,
                                  guint *out_pdulen,
                                  guint *out_msgstart,
+                                 gpointer log_object,
                                  GError **error)
 {
     guint8 *pdu;
@@ -834,13 +842,13 @@
         return NULL;
     }
 
-    mm_dbg ("Creating PDU for part...");
+    mm_obj_dbg (log_object, "creating PDU for part...");
 
     /* Build up the PDU */
     pdu = g_malloc0 (PDU_SIZE);
 
     if (mm_sms_part_get_smsc (part)) {
-        mm_dbg ("  adding SMSC to PDU...");
+        mm_obj_dbg (log_object, "  adding SMSC to PDU...");
         len = mm_sms_part_3gpp_encode_address (mm_sms_part_get_smsc (part), pdu, PDU_SIZE, TRUE);
         if (len == 0) {
             g_set_error (error,
@@ -863,13 +871,13 @@
 
     /* TP-VP present; format RELATIVE */
     if (mm_sms_part_get_validity_relative (part) > 0) {
-        mm_dbg ("  adding validity to PDU...");
+        mm_obj_dbg (log_object, "  adding validity to PDU...");
         pdu[offset] |= 0x10;
     }
 
     /* Concatenation sequence only found in multipart SMS */
     if (mm_sms_part_get_concat_sequence (part)) {
-        mm_dbg ("  adding UDHI to PDU...");
+        mm_obj_dbg (log_object, "  adding UDHI to PDU...");
         pdu[offset] |= 0x40; /* UDHI */
     }
 
@@ -878,7 +886,7 @@
     if (mm_sms_part_get_delivery_report_request (part) &&
         (!mm_sms_part_get_concat_sequence (part) ||
          mm_sms_part_get_concat_max (part) == mm_sms_part_get_concat_sequence (part))) {
-        mm_dbg ("  requesting delivery report...");
+        mm_obj_dbg (log_object, "  requesting delivery report...");
         pdu[offset] |= 0x20;
     }
 
@@ -910,24 +918,24 @@
     pdu[offset] = 0x00;
 
     if (mm_sms_part_get_class (part) >= 0 && mm_sms_part_get_class (part) <= 3) {
-        mm_dbg ("  using class %d...", mm_sms_part_get_class (part));
+        mm_obj_dbg (log_object, "  using class %d...", mm_sms_part_get_class (part));
         pdu[offset] |= SMS_DCS_CLASS_VALID;
         pdu[offset] |= mm_sms_part_get_class (part);
     }
 
     switch (mm_sms_part_get_encoding (part)) {
     case MM_SMS_ENCODING_UCS2:
-        mm_dbg ("  using UCS2 encoding...");
+        mm_obj_dbg (log_object, "  using UCS2 encoding...");
         pdu[offset] |= SMS_DCS_CODING_UCS2;
         break;
     case MM_SMS_ENCODING_GSM7:
-        mm_dbg ("  using GSM7 encoding...");
+        mm_obj_dbg (log_object, "  using GSM7 encoding...");
         pdu[offset] |= SMS_DCS_CODING_DEFAULT;  /* GSM */
         break;
     case MM_SMS_ENCODING_8BIT:
     case MM_SMS_ENCODING_UNKNOWN:
     default:
-        mm_dbg ("  using 8bit encoding...");
+        mm_obj_dbg (log_object, "  using 8bit encoding...");
         pdu[offset] |= SMS_DCS_CODING_8BIT;
         break;
     }
@@ -946,7 +954,7 @@
 
     /* Build UDH */
     if (mm_sms_part_get_concat_sequence (part)) {
-        mm_dbg ("  adding UDH header in PDU... (reference: %u, max: %u, sequence: %u)",
+        mm_obj_dbg (log_object, "  adding UDH header in PDU... (reference: %u, max: %u, sequence: %u)",
                 mm_sms_part_get_concat_reference (part),
                 mm_sms_part_get_concat_max (part),
                 mm_sms_part_get_concat_sequence (part));
@@ -986,9 +994,9 @@
          * If we had UDH, add 7 septets
          */
         *udl_ptr = mm_sms_part_get_concat_sequence (part) ? (7 + unlen) : unlen;
-        mm_dbg ("  user data length is '%u' septets (%s UDH)",
-                *udl_ptr,
-                mm_sms_part_get_concat_sequence (part) ? "with" : "without");
+        mm_obj_dbg (log_object, "  user data length is %u septets (%s UDH)",
+                    *udl_ptr,
+                    mm_sms_part_get_concat_sequence (part) ? "with" : "without");
 
         packed = mm_charset_gsm_pack (unpacked, unlen, shift, &packlen);
         g_free (unpacked);
@@ -1005,16 +1013,16 @@
         g_free (packed);
         offset += packlen;
     } else if (mm_sms_part_get_encoding (part) == MM_SMS_ENCODING_UCS2) {
-        GByteArray *array;
+        g_autoptr(GByteArray) array = NULL;
+        g_autoptr(GError)     inner_error = NULL;
 
         /* Try to guess a good value for the array */
         array = g_byte_array_sized_new (strlen (mm_sms_part_get_text (part)) * 2);
-        if (!mm_modem_charset_byte_array_append (array, mm_sms_part_get_text (part), FALSE, MM_MODEM_CHARSET_UCS2)) {
-            g_byte_array_free (array, TRUE);
-            g_set_error_literal (error,
-                                 MM_MESSAGE_ERROR,
-                                 MM_MESSAGE_ERROR_INVALID_PDU_PARAMETER,
-                                 "Failed to convert message text to UCS2");
+        if (!mm_modem_charset_byte_array_append (array, mm_sms_part_get_text (part), FALSE, MM_MODEM_CHARSET_UCS2, &inner_error)) {
+            g_set_error (error,
+                         MM_MESSAGE_ERROR,
+                         MM_MESSAGE_ERROR_INVALID_PDU_PARAMETER,
+                         "Failed to convert message text to UCS2: %s", inner_error->message);
             goto error;
         }
 
@@ -1022,13 +1030,12 @@
          * If we had UDH, add 6 octets
          */
         *udl_ptr = mm_sms_part_get_concat_sequence (part) ? (6 + array->len) : array->len;
-        mm_dbg ("  user data length is '%u' octets (%s UDH)",
-                *udl_ptr,
-                mm_sms_part_get_concat_sequence (part) ? "with" : "without");
+        mm_obj_dbg (log_object, "  user data length is %u octets (%s UDH)",
+                    *udl_ptr,
+                    mm_sms_part_get_concat_sequence (part) ? "with" : "without");
 
         memcpy (&pdu[offset], array->data, array->len);
         offset += array->len;
-        g_byte_array_free (array, TRUE);
     } else if (mm_sms_part_get_encoding (part) == MM_SMS_ENCODING_8BIT) {
         const GByteArray *data;
 
@@ -1038,7 +1045,7 @@
          * If we had UDH, add 6 octets
          */
         *udl_ptr = mm_sms_part_get_concat_sequence (part) ? (6 + data->len) : data->len;
-        mm_dbg ("  binary user data length is '%u' octets (%s UDH)",
+        mm_obj_dbg (log_object, "  binary user data length is %u octets (%s UDH)",
                 *udl_ptr,
                 mm_sms_part_get_concat_sequence (part) ? "with" : "without");
 
@@ -1057,8 +1064,9 @@
 }
 
 gchar **
-mm_sms_part_3gpp_util_split_text (const gchar *text,
-                                  MMSmsEncoding *encoding)
+mm_sms_part_3gpp_util_split_text (const gchar   *text,
+                                  MMSmsEncoding *encoding,
+                                  gpointer       log_object)
 {
     gchar **out;
     guint n_chunks;
@@ -1093,7 +1101,8 @@
     /* Check if we can do GSM encoding */
     if (!mm_charset_can_convert_to (text, MM_MODEM_CHARSET_GSM)) {
         /* If cannot do it in GSM encoding, do it in UCS-2 */
-        GByteArray *array;
+        g_autoptr(GByteArray) array = NULL;
+        g_autoptr(GError) error = NULL;
 
         *encoding = MM_SMS_ENCODING_UCS2;
 
@@ -1103,8 +1112,9 @@
         if (!mm_modem_charset_byte_array_append (array,
                                                  text,
                                                  FALSE,
-                                                 MM_MODEM_CHARSET_UCS2)) {
-            g_byte_array_unref (array);
+                                                 MM_MODEM_CHARSET_UCS2,
+                                                 &error)) {
+            mm_obj_warn (log_object, "failed to append UCS2: %s", error->message);
             return NULL;
         }
 
@@ -1132,10 +1142,10 @@
                 out[i] = sms_decode_text (&array->data[j],
                                           MIN (array->len - j, 134),
                                           MM_SMS_ENCODING_UCS2,
-                                          0);
+                                          0,
+                                          log_object);
             }
         }
-        g_byte_array_unref (array);
     } else {
         /* Do it with GSM encoding */
         *encoding = MM_SMS_ENCODING_GSM7;
diff --git a/src/mm-sms-part-3gpp.h b/src/mm-sms-part-3gpp.h
index bd6a242..bef416f 100644
--- a/src/mm-sms-part-3gpp.h
+++ b/src/mm-sms-part-3gpp.h
@@ -22,31 +22,31 @@
 
 #include "mm-sms-part.h"
 
-MMSmsPart *mm_sms_part_3gpp_new_from_pdu  (guint index,
-                                           const gchar *hexpdu,
-                                           GError **error);
-
-MMSmsPart *mm_sms_part_3gpp_new_from_binary_pdu (guint index,
-                                                 const guint8 *pdu,
-                                                 gsize pdu_len,
-                                                 GError **error);
-
-guint8    *mm_sms_part_3gpp_get_submit_pdu (MMSmsPart *part,
-                                            guint *out_pdulen,
-                                            guint *out_msgstart,
-                                            GError **error);
+MMSmsPart *mm_sms_part_3gpp_new_from_pdu        (guint          index,
+                                                 const gchar   *hexpdu,
+                                                 gpointer       log_object,
+                                                 GError       **error);
+MMSmsPart *mm_sms_part_3gpp_new_from_binary_pdu (guint          index,
+                                                 const guint8  *pdu,
+                                                 gsize          pdu_len,
+                                                 gpointer       log_object,
+                                                 GError       **error);
+guint8    *mm_sms_part_3gpp_get_submit_pdu      (MMSmsPart     *part,
+                                                 guint         *out_pdulen,
+                                                 guint         *out_msgstart,
+                                                 gpointer       log_object,
+                                                 GError       **error);
 
 /* For testcases only */
 
-guint mm_sms_part_3gpp_encode_address (const gchar *address,
-                                       guint8 *buf,
-                                       gsize buflen,
-                                       gboolean is_smsc);
-
-gchar **mm_sms_part_3gpp_util_split_text (const gchar *text,
-                                          MMSmsEncoding *encoding);
-
-GByteArray **mm_sms_part_3gpp_util_split_data (const guint8 *data,
-                                               gsize data_len);
+guint       mm_sms_part_3gpp_encode_address   (const gchar   *address,
+                                               guint8        *buf,
+                                               gsize          buflen,
+                                               gboolean       is_smsc);
+gchar      **mm_sms_part_3gpp_util_split_text (const gchar   *text,
+                                               MMSmsEncoding *encoding,
+                                               gpointer       log_object);
+GByteArray **mm_sms_part_3gpp_util_split_data (const guint8  *data,
+                                               gsize          data_len);
 
 #endif /* MM_SMS_PART_3GPP_H */
diff --git a/src/mm-sms-part-cdma.c b/src/mm-sms-part-cdma.c
index 0f40f65..2903e84 100644
--- a/src/mm-sms-part-cdma.c
+++ b/src/mm-sms-part-cdma.c
@@ -24,7 +24,7 @@
 
 #include "mm-charsets.h"
 #include "mm-sms-part-cdma.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 /*
  * Documentation that you may want to have around:
@@ -312,9 +312,10 @@
 /*****************************************************************************/
 
 MMSmsPart *
-mm_sms_part_cdma_new_from_pdu (guint index,
-                               const gchar *hexpdu,
-                               GError **error)
+mm_sms_part_cdma_new_from_pdu (guint         index,
+                               const gchar  *hexpdu,
+                               gpointer      log_object,
+                               GError      **error)
 {
     gsize pdu_len;
     guint8 *pdu;
@@ -330,7 +331,7 @@
         return NULL;
     }
 
-    part = mm_sms_part_cdma_new_from_binary_pdu (index, pdu, pdu_len, error);
+    part = mm_sms_part_cdma_new_from_binary_pdu (index, pdu, pdu_len, log_object, error);
     g_free (pdu);
 
     return part;
@@ -343,16 +344,17 @@
 } __attribute__((packed));
 
 static void
-read_teleservice_id (MMSmsPart *sms_part,
-                     const struct Parameter *parameter)
+read_teleservice_id (MMSmsPart              *sms_part,
+                     const struct Parameter *parameter,
+                     gpointer                log_object)
 {
     guint16 teleservice_id;
 
     g_assert (parameter->parameter_id == PARAMETER_ID_TELESERVICE_ID);
 
     if (parameter->parameter_len != 2) {
-        mm_dbg ("        invalid teleservice ID length found (%u != 2): ignoring",
-                parameter->parameter_len);
+        mm_obj_dbg (log_object, "        invalid teleservice ID length found (%u != 2): ignoring",
+                    parameter->parameter_len);
         return;
     }
 
@@ -370,29 +372,30 @@
     case MM_SMS_CDMA_TELESERVICE_ID_CATPT:
         break;
     default:
-        mm_dbg ("        invalid teleservice ID found (%u): ignoring", teleservice_id);
+        mm_obj_dbg (log_object, "        invalid teleservice ID found (%u): ignoring", teleservice_id);
         return;
     }
 
-    mm_dbg ("        teleservice ID: %s (%u)",
-            mm_sms_cdma_teleservice_id_get_string (teleservice_id),
-            teleservice_id);
+    mm_obj_dbg (log_object, "        teleservice ID: %s (%u)",
+                mm_sms_cdma_teleservice_id_get_string (teleservice_id),
+                teleservice_id);
 
     mm_sms_part_set_cdma_teleservice_id (sms_part,
                                          (MMSmsCdmaTeleserviceId)teleservice_id);
 }
 
 static void
-read_service_category (MMSmsPart *sms_part,
-                       const struct Parameter *parameter)
+read_service_category (MMSmsPart              *sms_part,
+                       const struct Parameter *parameter,
+                       gpointer                log_object)
 {
     guint16 service_category;
 
     g_assert (parameter->parameter_id == PARAMETER_ID_SERVICE_CATEGORY);
 
     if (parameter->parameter_len != 2) {
-        mm_dbg ("        invalid service category length found (%u != 2): ignoring",
-                parameter->parameter_len);
+        mm_obj_dbg (log_object, "        invalid service category length found (%u != 2): ignoring",
+                    parameter->parameter_len);
         return;
     }
 
@@ -438,20 +441,21 @@
     case MM_SMS_CDMA_SERVICE_CATEGORY_CMAS_TEST:
         break;
     default:
-        mm_dbg ("        invalid service category found (%u): ignoring", service_category);
+        mm_obj_dbg (log_object, "        invalid service category found (%u): ignoring", service_category);
         return;
     }
 
-    mm_dbg ("        service category: %s (%u)",
-            mm_sms_cdma_service_category_get_string (service_category),
-            service_category);
+    mm_obj_dbg (log_object, "        service category: %s (%u)",
+                mm_sms_cdma_service_category_get_string (service_category),
+                service_category);
 
     mm_sms_part_set_cdma_service_category (sms_part,
-                                         (MMSmsCdmaServiceCategory)service_category);
+                                           (MMSmsCdmaServiceCategory)service_category);
 }
 
 static guint8
-dtmf_to_ascii (guint8 dtmf)
+dtmf_to_ascii (guint8   dtmf,
+               gpointer log_object)
 {
     static const gchar dtmf_to_ascii_digits[13] = {
         '\0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '*', '#' };
@@ -459,13 +463,14 @@
     if (dtmf > 0 && dtmf < 13)
         return dtmf_to_ascii_digits[dtmf];
 
-    mm_dbg ("        invalid dtmf digit: %u", dtmf);
+    mm_obj_dbg (log_object, "        invalid dtmf digit: %u", dtmf);
     return '\0';
 }
 
 static void
-read_address (MMSmsPart *sms_part,
-              const struct Parameter *parameter)
+read_address (MMSmsPart              *sms_part,
+              const struct Parameter *parameter,
+              gpointer                log_object)
 {
     guint8 digit_mode;
     guint8 number_mode;
@@ -487,9 +492,9 @@
 
 #define PARAMETER_SIZE_CHECK(required_size)                             \
     if (parameter->parameter_len < required_size) {                     \
-        mm_dbg ("        cannot read address, need at least %u bytes (got %u)", \
-                required_size,                                          \
-                parameter->parameter_len);                              \
+        mm_obj_dbg (log_object, "        cannot read address, need at least %u bytes (got %u)", \
+                    required_size,                                      \
+                    parameter->parameter_len);                          \
         return;                                                         \
     }
 
@@ -502,10 +507,10 @@
     g_assert (digit_mode <= 1);
     switch (digit_mode) {
     case DIGIT_MODE_DTMF:
-        mm_dbg ("        digit mode: dtmf");
+        mm_obj_dbg (log_object, "        digit mode: dtmf");
         break;
     case DIGIT_MODE_ASCII:
-        mm_dbg ("        digit mode: ascii");
+        mm_obj_dbg (log_object, "        digit mode: ascii");
         break;
     default:
         g_assert_not_reached ();
@@ -516,10 +521,10 @@
     OFFSETS_UPDATE (1);
     switch (number_mode) {
     case NUMBER_MODE_DIGIT:
-        mm_dbg ("        number mode: digit");
+        mm_obj_dbg (log_object, "        number mode: digit");
         break;
     case NUMBER_MODE_DATA_NETWORK_ADDRESS:
-        mm_dbg ("        number mode: data network address");
+        mm_obj_dbg (log_object, "        number mode: data network address");
         break;
     default:
         g_assert_not_reached ();
@@ -532,25 +537,25 @@
         OFFSETS_UPDATE (3);
         switch (number_type) {
         case NUMBER_TYPE_UNKNOWN:
-            mm_dbg ("        number type: unknown");
+            mm_obj_dbg (log_object, "        number type: unknown");
             break;
         case NUMBER_TYPE_INTERNATIONAL:
-            mm_dbg ("        number type: international");
+            mm_obj_dbg (log_object, "        number type: international");
             break;
         case NUMBER_TYPE_NATIONAL:
-            mm_dbg ("        number type: national");
+            mm_obj_dbg (log_object, "        number type: national");
             break;
         case NUMBER_TYPE_NETWORK_SPECIFIC:
-            mm_dbg ("        number type: specific");
+            mm_obj_dbg (log_object, "        number type: specific");
             break;
         case NUMBER_TYPE_SUBSCRIBER:
-            mm_dbg ("        number type: subscriber");
+            mm_obj_dbg (log_object, "        number type: subscriber");
             break;
         case NUMBER_TYPE_ABBREVIATED:
-            mm_dbg ("        number type: abbreviated");
+            mm_obj_dbg (log_object, "        number type: abbreviated");
             break;
         default:
-            mm_dbg ("        number type unknown (%u)", number_type);
+            mm_obj_dbg (log_object, "        number type unknown (%u)", number_type);
             break;
         }
     } else
@@ -564,22 +569,22 @@
         OFFSETS_UPDATE (4);
         switch (numbering_plan) {
         case NUMBERING_PLAN_UNKNOWN:
-            mm_dbg ("        numbering plan: unknown");
+            mm_obj_dbg (log_object, "        numbering plan: unknown");
             break;
         case NUMBERING_PLAN_ISDN:
-            mm_dbg ("        numbering plan: isdn");
+            mm_obj_dbg (log_object, "        numbering plan: isdn");
             break;
         case NUMBERING_PLAN_DATA:
-            mm_dbg ("        numbering plan: data");
+            mm_obj_dbg (log_object, "        numbering plan: data");
             break;
         case NUMBERING_PLAN_TELEX:
-            mm_dbg ("        numbering plan: telex");
+            mm_obj_dbg (log_object, "        numbering plan: telex");
             break;
         case NUMBERING_PLAN_PRIVATE:
-            mm_dbg ("        numbering plan: private");
+            mm_obj_dbg (log_object, "        numbering plan: private");
             break;
         default:
-            mm_dbg ("        numbering plan unknown (%u)", numbering_plan);
+            mm_obj_dbg (log_object, "        numbering plan unknown (%u)", numbering_plan);
             break;
         }
     } else
@@ -589,7 +594,7 @@
     PARAMETER_SIZE_CHECK (byte_offset + 2);
     num_fields = read_bits (&parameter->parameter_value[byte_offset], bit_offset, 8);
     OFFSETS_UPDATE (8);
-    mm_dbg ("        num fields: %u", num_fields);
+    mm_obj_dbg (log_object, "        num fields: %u", num_fields);
 
     /* Address string */
 
@@ -598,7 +603,7 @@
         PARAMETER_SIZE_CHECK (byte_offset + 1 + ((bit_offset + (num_fields * 4)) / 8));
         number = g_malloc (num_fields + 1);
         for (i = 0; i < num_fields; i++) {
-            number[i] = dtmf_to_ascii (read_bits (&parameter->parameter_value[byte_offset], bit_offset, 4));
+            number[i] = dtmf_to_ascii (read_bits (&parameter->parameter_value[byte_offset], bit_offset, 4), log_object);
             OFFSETS_UPDATE (4);
         }
         number[i] = '\0';
@@ -634,9 +639,9 @@
         }
         number = g_string_free (str, FALSE);
     } else
-        mm_dbg ("        data network address number type unknown (%u)", number_type);
+        mm_obj_dbg (log_object, "        data network address number type unknown (%u)", number_type);
 
-    mm_dbg ("        address: %s", number);
+    mm_obj_dbg (log_object, "        address: %s", number);
 
     mm_sms_part_set_number (sms_part, number);
     g_free (number);
@@ -646,28 +651,30 @@
 }
 
 static void
-read_bearer_reply_option (MMSmsPart *sms_part,
-                          const struct Parameter *parameter)
+read_bearer_reply_option (MMSmsPart              *sms_part,
+                          const struct Parameter *parameter,
+                          gpointer                log_object)
 {
     guint8 sequence;
 
     g_assert (parameter->parameter_id == PARAMETER_ID_BEARER_REPLY_OPTION);
 
     if (parameter->parameter_len != 1) {
-        mm_dbg ("        invalid bearer reply option length found (%u != 1): ignoring",
+        mm_obj_dbg (log_object, "        invalid bearer reply option length found (%u != 1): ignoring",
                 parameter->parameter_len);
         return;
     }
 
     sequence = read_bits (&parameter->parameter_value[0], 0, 6);
-    mm_dbg ("        sequence: %u", sequence);
+    mm_obj_dbg (log_object, "        sequence: %u", sequence);
 
     mm_sms_part_set_message_reference (sms_part, sequence);
 }
 
 static void
-read_cause_codes (MMSmsPart *sms_part,
-                  const struct Parameter *parameter)
+read_cause_codes (MMSmsPart              *sms_part,
+                  const struct Parameter *parameter,
+                  gpointer                log_object)
 {
     guint8 sequence;
     guint8 error_class;
@@ -677,38 +684,39 @@
     g_assert (parameter->parameter_id == PARAMETER_ID_BEARER_REPLY_OPTION);
 
     if (parameter->parameter_len != 1 && parameter->parameter_len != 2) {
-        mm_dbg ("        invalid cause codes length found (%u): ignoring",
+        mm_obj_dbg (log_object, "        invalid cause codes length found (%u): ignoring",
                 parameter->parameter_len);
         return;
     }
 
     sequence = read_bits (&parameter->parameter_value[0], 0, 6);
-    mm_dbg ("        sequence: %u", sequence);
+    mm_obj_dbg (log_object, "        sequence: %u", sequence);
 
     error_class = read_bits (&parameter->parameter_value[0], 6, 2);
-    mm_dbg ("        error class: %u", error_class);
+    mm_obj_dbg (log_object, "        error class: %u", error_class);
 
     if (error_class != ERROR_CLASS_NO_ERROR) {
         if (parameter->parameter_len != 2) {
-            mm_dbg ("        invalid cause codes length found (%u != 2): ignoring",
+            mm_obj_dbg (log_object, "        invalid cause codes length found (%u != 2): ignoring",
                     parameter->parameter_len);
             return;
         }
         cause_code = parameter->parameter_value[1];
-        mm_dbg ("        cause code: %u", cause_code);
+        mm_obj_dbg (log_object, "        cause code: %u", cause_code);
     } else
         cause_code = 0;
 
     delivery_state = cause_code_to_delivery_state (error_class, cause_code);
-    mm_dbg ("        delivery state: %s", mm_sms_delivery_state_get_string (delivery_state));
+    mm_obj_dbg (log_object, "        delivery state: %s", mm_sms_delivery_state_get_string (delivery_state));
 
     mm_sms_part_set_message_reference (sms_part, sequence);
     mm_sms_part_set_delivery_state (sms_part, delivery_state);
 }
 
 static void
-read_bearer_data_message_identifier (MMSmsPart *sms_part,
-                                     const struct Parameter *subparameter)
+read_bearer_data_message_identifier (MMSmsPart              *sms_part,
+                                     const struct Parameter *subparameter,
+                                     gpointer                log_object)
 {
     guint8 message_type;
     guint16 message_id;
@@ -717,7 +725,7 @@
     g_assert (subparameter->parameter_id == SUBPARAMETER_ID_MESSAGE_ID);
 
     if (subparameter->parameter_len != 3) {
-        mm_dbg ("        invalid message identifier length found (%u): ignoring",
+        mm_obj_dbg (log_object, "        invalid message identifier length found (%u): ignoring",
                 subparameter->parameter_len);
         return;
     }
@@ -725,49 +733,50 @@
     message_type = read_bits (&subparameter->parameter_value[0], 0, 4);
     switch (message_type) {
     case TELESERVICE_MESSAGE_TYPE_UNKNOWN:
-        mm_dbg ("            message type: unknown");
+        mm_obj_dbg (log_object, "            message type: unknown");
         break;
     case TELESERVICE_MESSAGE_TYPE_DELIVER:
-        mm_dbg ("            message type: deliver");
+        mm_obj_dbg (log_object, "            message type: deliver");
         mm_sms_part_set_pdu_type (sms_part, MM_SMS_PDU_TYPE_CDMA_DELIVER);
         break;
     case TELESERVICE_MESSAGE_TYPE_SUBMIT:
-        mm_dbg ("            message type: submit");
+        mm_obj_dbg (log_object, "            message type: submit");
         mm_sms_part_set_pdu_type (sms_part, MM_SMS_PDU_TYPE_CDMA_SUBMIT);
         break;
     case TELESERVICE_MESSAGE_TYPE_CANCELLATION:
-        mm_dbg ("            message type: cancellation");
+        mm_obj_dbg (log_object, "            message type: cancellation");
         mm_sms_part_set_pdu_type (sms_part, MM_SMS_PDU_TYPE_CDMA_CANCELLATION);
         break;
     case TELESERVICE_MESSAGE_TYPE_DELIVERY_ACKNOWLEDGEMENT:
-        mm_dbg ("            message type: delivery acknowledgement");
+        mm_obj_dbg (log_object, "            message type: delivery acknowledgement");
         mm_sms_part_set_pdu_type (sms_part, MM_SMS_PDU_TYPE_CDMA_DELIVERY_ACKNOWLEDGEMENT);
         break;
     case TELESERVICE_MESSAGE_TYPE_USER_ACKNOWLEDGEMENT:
-        mm_dbg ("            message type: user acknowledgement");
+        mm_obj_dbg (log_object, "            message type: user acknowledgement");
         mm_sms_part_set_pdu_type (sms_part, MM_SMS_PDU_TYPE_CDMA_USER_ACKNOWLEDGEMENT);
         break;
     case TELESERVICE_MESSAGE_TYPE_READ_ACKNOWLEDGEMENT:
-        mm_dbg ("            message type: read acknowledgement");
+        mm_obj_dbg (log_object, "            message type: read acknowledgement");
         mm_sms_part_set_pdu_type (sms_part, MM_SMS_PDU_TYPE_CDMA_READ_ACKNOWLEDGEMENT);
         break;
     default:
-        mm_dbg ("            message type unknown (%u)", message_type);
+        mm_obj_dbg (log_object, "            message type unknown (%u)", message_type);
         break;
     }
 
     message_id = ((read_bits (&subparameter->parameter_value[0], 4, 8) << 8) |
                   (read_bits (&subparameter->parameter_value[1], 4, 8)));
     message_id = GUINT16_FROM_BE (message_id);
-    mm_dbg ("            message id: %u", (guint) message_id);
+    mm_obj_dbg (log_object, "            message id: %u", (guint) message_id);
 
     header_ind = read_bits (&subparameter->parameter_value[2], 4, 1);
-    mm_dbg ("            header indicator: %u", header_ind);
+    mm_obj_dbg (log_object, "            header indicator: %u", header_ind);
 }
 
 static void
-read_bearer_data_user_data (MMSmsPart *sms_part,
-                            const struct Parameter *subparameter)
+read_bearer_data_user_data (MMSmsPart              *sms_part,
+                            const struct Parameter *subparameter,
+                            gpointer                log_object)
 {
     guint8 message_encoding;
     guint8 message_type = 0;
@@ -785,7 +794,7 @@
 
 #define SUBPARAMETER_SIZE_CHECK(required_size)                             \
     if (subparameter->parameter_len < required_size) {                  \
-        mm_dbg ("        cannot read user data, need at least %u bytes (got %u)", \
+        mm_obj_dbg (log_object, "        cannot read user data, need at least %u bytes (got %u)", \
                 required_size,                                          \
                 subparameter->parameter_len);                           \
         return;                                                         \
@@ -797,21 +806,21 @@
     SUBPARAMETER_SIZE_CHECK (1);
     message_encoding = read_bits (&subparameter->parameter_value[byte_offset], bit_offset, 5);
     OFFSETS_UPDATE (5);
-    mm_dbg ("            message encoding: %s", encoding_to_string (message_encoding));
+    mm_obj_dbg (log_object, "            message encoding: %s", encoding_to_string (message_encoding));
 
     /* Message type, only if extended protocol message */
     if (message_encoding == ENCODING_EXTENDED_PROTOCOL_MESSAGE) {
         SUBPARAMETER_SIZE_CHECK (2);
         message_type = read_bits (&subparameter->parameter_value[byte_offset], bit_offset, 8);
         OFFSETS_UPDATE (8);
-        mm_dbg ("            message type: %u", message_type);
+        mm_obj_dbg (log_object, "            message type: %u", message_type);
     }
 
     /* Number of fields */
     SUBPARAMETER_SIZE_CHECK (byte_offset + 1 + ((bit_offset + 8) / 8));
     num_fields = read_bits (&subparameter->parameter_value[byte_offset], bit_offset, 8);
     OFFSETS_UPDATE (8);
-    mm_dbg ("            num fields: %u", num_fields);
+    mm_obj_dbg (log_object, "            num fields: %u", num_fields);
 
     /* Now, process actual text or data */
     switch (message_encoding) {
@@ -828,7 +837,7 @@
             OFFSETS_UPDATE (8);
         }
 
-        mm_dbg ("            data: (%u bytes)", num_fields);
+        mm_obj_dbg (log_object, "            data: (%u bytes)", num_fields);
         mm_sms_part_take_data (sms_part, data);
         break;
     }
@@ -846,7 +855,7 @@
         }
         text[i] = '\0';
 
-        mm_dbg ("            text: '%s'", text);
+        mm_obj_dbg (log_object, "            text: '%s'", text);
         mm_sms_part_take_text (sms_part, text);
         break;
     }
@@ -867,9 +876,9 @@
 
         text = g_convert (latin, -1, "UTF-8", "ISO−8859−1", NULL, NULL, NULL);
         if (!text) {
-            mm_dbg ("            text/data: ignored (latin to UTF-8 conversion error)");
+            mm_obj_dbg (log_object, "            text/data: ignored (latin to UTF-8 conversion error)");
         } else {
-            mm_dbg ("            text: '%s'", text);
+            mm_obj_dbg (log_object, "            text: '%s'", text);
             mm_sms_part_take_text (sms_part, text);
         }
 
@@ -896,9 +905,9 @@
 
         text = g_convert (utf16, num_bytes, "UTF-8", "UCS-2BE", NULL, NULL, NULL);
         if (!text) {
-            mm_dbg ("            text/data: ignored (UTF-16 to UTF-8 conversion error)");
+            mm_obj_dbg (log_object, "            text/data: ignored (UTF-16 to UTF-8 conversion error)");
         } else {
-            mm_dbg ("            text: '%s'", text);
+            mm_obj_dbg (log_object, "            text: '%s'", text);
             mm_sms_part_take_text (sms_part, text);
         }
 
@@ -907,7 +916,7 @@
     }
 
     default:
-        mm_dbg ("            text/data: ignored (unsupported encoding)");
+        mm_obj_dbg (log_object, "            text/data: ignored (unsupported encoding)");
     }
 
 #undef OFFSETS_UPDATE
@@ -915,16 +924,17 @@
 }
 
 static void
-read_bearer_data (MMSmsPart *sms_part,
-                  const struct Parameter *parameter)
+read_bearer_data (MMSmsPart              *sms_part,
+                  const struct Parameter *parameter,
+                  gpointer                log_object)
 {
     guint offset;
 
 #define PARAMETER_SIZE_CHECK(required_size)                             \
     if (parameter->parameter_len < required_size) {                     \
-        mm_dbg ("        cannot read bearer data, need at least %u bytes (got %u)", \
-                required_size,                                          \
-                parameter->parameter_len);                              \
+        mm_obj_dbg (log_object, "        cannot read bearer data, need at least %u bytes (got %u)", \
+                    required_size,                                      \
+                    parameter->parameter_len);                          \
         return;                                                         \
     }
 
@@ -941,81 +951,81 @@
 
         switch (subparameter->parameter_id) {
         case SUBPARAMETER_ID_MESSAGE_ID:
-            mm_dbg ("        reading message ID...");
-            read_bearer_data_message_identifier (sms_part, subparameter);
+            mm_obj_dbg (log_object, "        reading message ID...");
+            read_bearer_data_message_identifier (sms_part, subparameter, log_object);
             break;
         case SUBPARAMETER_ID_USER_DATA:
-            mm_dbg ("        reading user data...");
-            read_bearer_data_user_data (sms_part, subparameter);
+            mm_obj_dbg (log_object, "        reading user data...");
+            read_bearer_data_user_data (sms_part, subparameter, log_object);
             break;
         case SUBPARAMETER_ID_USER_RESPONSE_CODE:
-            mm_dbg ("        skipping user response code...");
+            mm_obj_dbg (log_object, "        skipping user response code...");
             break;
         case SUBPARAMETER_ID_MESSAGE_CENTER_TIME_STAMP:
-            mm_dbg ("        skipping message center timestamp...");
+            mm_obj_dbg (log_object, "        skipping message center timestamp...");
             break;
         case SUBPARAMETER_ID_VALIDITY_PERIOD_ABSOLUTE:
-            mm_dbg ("        skipping absolute validity period...");
+            mm_obj_dbg (log_object, "        skipping absolute validity period...");
             break;
         case SUBPARAMETER_ID_VALIDITY_PERIOD_RELATIVE:
-            mm_dbg ("        skipping relative validity period...");
+            mm_obj_dbg (log_object, "        skipping relative validity period...");
             break;
         case SUBPARAMETER_ID_DEFERRED_DELIVERY_TIME_ABSOLUTE:
-            mm_dbg ("        skipping absolute deferred delivery time...");
+            mm_obj_dbg (log_object, "        skipping absolute deferred delivery time...");
             break;
         case SUBPARAMETER_ID_DEFERRED_DELIVERY_TIME_RELATIVE:
-            mm_dbg ("        skipping relative deferred delivery time...");
+            mm_obj_dbg (log_object, "        skipping relative deferred delivery time...");
             break;
         case SUBPARAMETER_ID_PRIORITY_INDICATOR:
-            mm_dbg ("        skipping priority indicator...");
+            mm_obj_dbg (log_object, "        skipping priority indicator...");
             break;
         case SUBPARAMETER_ID_PRIVACY_INDICATOR:
-            mm_dbg ("        skipping privacy indicator...");
+            mm_obj_dbg (log_object, "        skipping privacy indicator...");
             break;
         case SUBPARAMETER_ID_REPLY_OPTION:
-            mm_dbg ("        skipping reply option...");
+            mm_obj_dbg (log_object, "        skipping reply option...");
             break;
         case SUBPARAMETER_ID_NUMBER_OF_MESSAGES:
-            mm_dbg ("        skipping number of messages...");
+            mm_obj_dbg (log_object, "        skipping number of messages...");
             break;
         case SUBPARAMETER_ID_ALERT_ON_MESSAGE_DELIVERY:
-            mm_dbg ("        skipping alert on message delivery...");
+            mm_obj_dbg (log_object, "        skipping alert on message delivery...");
             break;
         case SUBPARAMETER_ID_LANGUAGE_INDICATOR:
-            mm_dbg ("        skipping language indicator...");
+            mm_obj_dbg (log_object, "        skipping language indicator...");
             break;
         case SUBPARAMETER_ID_CALL_BACK_NUMBER:
-            mm_dbg ("        skipping call back number...");
+            mm_obj_dbg (log_object, "        skipping call back number...");
             break;
         case SUBPARAMETER_ID_MESSAGE_DISPLAY_MODE:
-            mm_dbg ("        skipping message display mode...");
+            mm_obj_dbg (log_object, "        skipping message display mode...");
             break;
         case SUBPARAMETER_ID_MULTIPLE_ENCODING_USER_DATA:
-            mm_dbg ("        skipping multiple encoding user data...");
+            mm_obj_dbg (log_object, "        skipping multiple encoding user data...");
             break;
         case SUBPARAMETER_ID_MESSAGE_DEPOSIT_INDEX:
-            mm_dbg ("        skipping message deposit index...");
+            mm_obj_dbg (log_object, "        skipping message deposit index...");
             break;
         case SUBPARAMETER_ID_SERVICE_CATEGORY_PROGRAM_DATA:
-            mm_dbg ("        skipping service category program data...");
+            mm_obj_dbg (log_object, "        skipping service category program data...");
             break;
         case SUBPARAMETER_ID_SERVICE_CATEGORY_PROGRAM_RESULT:
-            mm_dbg ("        skipping service category program result...");
+            mm_obj_dbg (log_object, "        skipping service category program result...");
             break;
         case SUBPARAMETER_ID_MESSAGE_STATUS:
-            mm_dbg ("        skipping message status...");
+            mm_obj_dbg (log_object, "        skipping message status...");
             break;
         case SUBPARAMETER_ID_TP_FAILURE_CAUSE:
-            mm_dbg ("        skipping TP failure case...");
+            mm_obj_dbg (log_object, "        skipping TP failure case...");
             break;
         case SUBPARAMETER_ID_ENHANCED_VMN:
-            mm_dbg ("        skipping enhanced vmn...");
+            mm_obj_dbg (log_object, "        skipping enhanced vmn...");
             break;
         case SUBPARAMETER_ID_ENHANCED_VMN_ACK:
-            mm_dbg ("        skipping enhanced vmn ack...");
+            mm_obj_dbg (log_object, "        skipping enhanced vmn ack...");
             break;
         default:
-            mm_dbg ("    unknown subparameter found: '%u' (ignoring)",
+            mm_obj_dbg (log_object, "    unknown subparameter found: '%u' (ignoring)",
                     subparameter->parameter_id);
             break;
         }
@@ -1025,10 +1035,11 @@
 }
 
 MMSmsPart *
-mm_sms_part_cdma_new_from_binary_pdu (guint index,
-                                      const guint8 *pdu,
-                                      gsize pdu_len,
-                                      GError **error)
+mm_sms_part_cdma_new_from_binary_pdu (guint          index,
+                                      const guint8  *pdu,
+                                      gsize          pdu_len,
+                                      gpointer       log_object,
+                                      GError       **error)
 {
     MMSmsPart *sms_part;
     guint offset;
@@ -1038,9 +1049,9 @@
     sms_part = mm_sms_part_new (index, MM_SMS_PDU_TYPE_UNKNOWN);
 
     if (index != SMS_PART_INVALID_INDEX)
-        mm_dbg ("Parsing CDMA PDU (%u)...", index);
+        mm_obj_dbg (log_object, "parsing CDMA PDU (%u)...", index);
     else
-        mm_dbg ("Parsing CDMA PDU...");
+        mm_obj_dbg (log_object, "parsing CDMA PDU...");
 
 #define PDU_SIZE_CHECK(required_size, check_descr_str)                 \
     if (pdu_len < required_size) {                                     \
@@ -1088,47 +1099,47 @@
 
         switch (parameter->parameter_id) {
         case PARAMETER_ID_TELESERVICE_ID:
-            mm_dbg ("    reading teleservice ID...");
-            read_teleservice_id (sms_part, parameter);
+            mm_obj_dbg (log_object, "    reading teleservice ID...");
+            read_teleservice_id (sms_part, parameter, log_object);
             break;
         case PARAMETER_ID_SERVICE_CATEGORY:
-            mm_dbg ("    reading service category...");
-            read_service_category (sms_part, parameter);
+            mm_obj_dbg (log_object, "    reading service category...");
+            read_service_category (sms_part, parameter, log_object);
             break;
         case PARAMETER_ID_ORIGINATING_ADDRESS:
-            mm_dbg ("    reading originating address...");
+            mm_obj_dbg (log_object, "    reading originating address...");
             if (mm_sms_part_get_number (sms_part))
-                mm_dbg ("        cannot read originating address; an address field was already read");
+                mm_obj_dbg (log_object, "        cannot read originating address; an address field was already read");
             else
-                read_address (sms_part, parameter);
+                read_address (sms_part, parameter, log_object);
             break;
         case PARAMETER_ID_ORIGINATING_SUBADDRESS:
-            mm_dbg ("    skipping originating subaddress...");
+            mm_obj_dbg (log_object, "    skipping originating subaddress...");
             break;
         case PARAMETER_ID_DESTINATION_ADDRESS:
-            mm_dbg ("    reading destination address...");
+            mm_obj_dbg (log_object, "    reading destination address...");
             if (mm_sms_part_get_number (sms_part))
-                mm_dbg ("        cannot read destination address; an address field was already read");
+                mm_obj_dbg (log_object, "        cannot read destination address; an address field was already read");
             else
-                read_address (sms_part, parameter);
+                read_address (sms_part, parameter, log_object);
             break;
         case PARAMETER_ID_DESTINATION_SUBADDRESS:
-            mm_dbg ("    skipping destination subaddress...");
+            mm_obj_dbg (log_object, "    skipping destination subaddress...");
             break;
         case PARAMETER_ID_BEARER_REPLY_OPTION:
-            mm_dbg ("    reading bearer reply option...");
-            read_bearer_reply_option (sms_part, parameter);
+            mm_obj_dbg (log_object, "    reading bearer reply option...");
+            read_bearer_reply_option (sms_part, parameter, log_object);
             break;
         case PARAMETER_ID_CAUSE_CODES:
-            mm_dbg ("    reading cause codes...");
-            read_cause_codes (sms_part, parameter);
+            mm_obj_dbg (log_object, "    reading cause codes...");
+            read_cause_codes (sms_part, parameter, log_object);
             break;
         case PARAMETER_ID_BEARER_DATA:
-            mm_dbg ("    reading bearer data...");
-            read_bearer_data (sms_part, parameter);
+            mm_obj_dbg (log_object, "    reading bearer data...");
+            read_bearer_data (sms_part, parameter, log_object);
             break;
         default:
-            mm_dbg ("    unknown parameter found: '%u' (ignoring)",
+            mm_obj_dbg (log_object, "    unknown parameter found: '%u' (ignoring)",
                     parameter->parameter_id);
             break;
         }
@@ -1138,15 +1149,15 @@
     switch (message_type) {
     case MESSAGE_TYPE_POINT_TO_POINT:
         if (mm_sms_part_get_cdma_teleservice_id (sms_part) == MM_SMS_CDMA_TELESERVICE_ID_UNKNOWN)
-            mm_dbg ("    mandatory parameter missing: teleservice ID not found or invalid in point-to-point message");
+            mm_obj_dbg (log_object, "    mandatory parameter missing: teleservice ID not found or invalid in point-to-point message");
         break;
     case MESSAGE_TYPE_BROADCAST:
         if (mm_sms_part_get_cdma_service_category (sms_part) == MM_SMS_CDMA_SERVICE_CATEGORY_UNKNOWN)
-            mm_dbg ("    mandatory parameter missing: service category not found or invalid in broadcast message");
+            mm_obj_dbg (log_object, "    mandatory parameter missing: service category not found or invalid in broadcast message");
         break;
     case MESSAGE_TYPE_ACKNOWLEDGE:
         if (mm_sms_part_get_message_reference (sms_part) == 0)
-            mm_dbg ("    mandatory parameter missing: cause codes not found or invalid in acknowledge message");
+            mm_obj_dbg (log_object, "    mandatory parameter missing: cause codes not found or invalid in acknowledge message");
         break;
     default:
         break;
@@ -1197,7 +1208,8 @@
 /*****************************************************************************/
 
 static guint8
-dtmf_from_ascii (guint8 ascii)
+dtmf_from_ascii (guint8   ascii,
+                 gpointer log_object)
 {
     if (ascii >= '1' && ascii <= '9')
         return ascii - '0';
@@ -1208,19 +1220,20 @@
     if (ascii == '#')
         return 12;
 
-    mm_dbg ("        invalid ascii digit in dtmf conversion: %c", ascii);
+    mm_obj_dbg (log_object, "        invalid ascii digit in dtmf conversion: %c", ascii);
     return 0;
 }
 
 static gboolean
-write_teleservice_id (MMSmsPart *part,
-                      guint8 *pdu,
-                      guint *absolute_offset,
-                      GError **error)
+write_teleservice_id (MMSmsPart  *part,
+                      guint8     *pdu,
+                      guint      *absolute_offset,
+                      gpointer    log_object,
+                      GError    **error)
 {
     guint16 aux16;
 
-    mm_dbg ("    writing teleservice ID...");
+    mm_obj_dbg (log_object, "    writing teleservice ID...");
 
     if (mm_sms_part_get_cdma_teleservice_id (part) != MM_SMS_CDMA_TELESERVICE_ID_WMT) {
         g_set_error (error,
@@ -1232,9 +1245,9 @@
         return FALSE;
     }
 
-    mm_dbg ("        teleservice ID: %s (%u)",
-            mm_sms_cdma_teleservice_id_get_string (MM_SMS_CDMA_TELESERVICE_ID_WMT),
-            MM_SMS_CDMA_TELESERVICE_ID_WMT);
+    mm_obj_dbg (log_object, "        teleservice ID: %s (%u)",
+                mm_sms_cdma_teleservice_id_get_string (MM_SMS_CDMA_TELESERVICE_ID_WMT),
+                MM_SMS_CDMA_TELESERVICE_ID_WMT);
 
     /* Teleservice ID: WMT always */
     pdu[0] = PARAMETER_ID_TELESERVICE_ID;
@@ -1247,10 +1260,11 @@
 }
 
 static gboolean
-write_destination_address (MMSmsPart *part,
-                           guint8 *pdu,
-                           guint *absolute_offset,
-                           GError **error)
+write_destination_address (MMSmsPart  *part,
+                           guint8     *pdu,
+                           guint      *absolute_offset,
+                           gpointer    log_object,
+                           GError    **error)
 {
     const gchar *number;
     guint bit_offset;
@@ -1258,7 +1272,7 @@
     guint n_digits;
     guint i;
 
-    mm_dbg ("    writing destination address...");
+    mm_obj_dbg (log_object, "    writing destination address...");
 
 #define OFFSETS_UPDATE(n_bits) do { \
         bit_offset += n_bits;       \
@@ -1278,12 +1292,12 @@
     bit_offset = 0;
 
     /* Digit mode: DTMF always */
-    mm_dbg ("        digit mode: dtmf");
+    mm_obj_dbg (log_object, "        digit mode: dtmf");
     write_bits (&pdu[byte_offset], bit_offset, 1, DIGIT_MODE_DTMF);
     OFFSETS_UPDATE (1);
 
     /* Number mode: DIGIT always */
-    mm_dbg ("        number mode: digit");
+    mm_obj_dbg (log_object, "        number mode: digit");
     write_bits (&pdu[byte_offset], bit_offset, 1, NUMBER_MODE_DIGIT);
     OFFSETS_UPDATE (1);
 
@@ -1298,16 +1312,16 @@
                      n_digits);
         return FALSE;
     }
-    mm_dbg ("        num fields: %u", n_digits);
+    mm_obj_dbg (log_object, "        num fields: %u", n_digits);
     write_bits (&pdu[byte_offset], bit_offset, 8, n_digits);
     OFFSETS_UPDATE (8);
 
     /* Actual DTMF encoded number */
-    mm_dbg ("        address: %s", number);
+    mm_obj_dbg (log_object, "        address: %s", number);
     for (i = 0; i < n_digits; i++) {
         guint8 dtmf;
 
-        dtmf = dtmf_from_ascii (number[i]);
+        dtmf = dtmf_from_ascii (number[i], log_object);
         if (!dtmf) {
             g_set_error (error,
                          MM_CORE_ERROR,
@@ -1339,15 +1353,16 @@
 }
 
 static gboolean
-write_bearer_data_message_identifier (MMSmsPart *part,
-                                      guint8 *pdu,
-                                      guint *parameter_offset,
-                                      GError **error)
+write_bearer_data_message_identifier (MMSmsPart  *part,
+                                      guint8     *pdu,
+                                      guint      *parameter_offset,
+                                      gpointer    log_object,
+                                      GError    **error)
 {
     pdu[0] = SUBPARAMETER_ID_MESSAGE_ID;
     pdu[1] = 3; /* subparameter_len, always 3 */
 
-    mm_dbg ("        writing message identifier: submit");
+    mm_obj_dbg (log_object, "        writing message identifier: submit");
 
     /* Message type */
     write_bits (&pdu[2], 0, 4, TELESERVICE_MESSAGE_TYPE_SUBMIT);
@@ -1362,14 +1377,16 @@
 
 static void
 decide_best_encoding (const gchar *text,
+                      gpointer     log_object,
                       GByteArray **out,
-                      guint *num_fields,
-                      guint *num_bits_per_field,
-                      Encoding *encoding)
+                      guint       *num_fields,
+                      guint       *num_bits_per_field,
+                      Encoding    *encoding)
 {
     guint ascii_unsupported = 0;
     guint i;
     guint len;
+    g_autoptr(GError) error = NULL;
 
     len = strlen (text);
 
@@ -1394,10 +1411,12 @@
     /* Check if we can do Latin encoding */
     if (mm_charset_can_convert_to (text, MM_MODEM_CHARSET_8859_1)) {
         *out = g_byte_array_sized_new (len);
-        mm_modem_charset_byte_array_append (*out,
-                                            text,
-                                            FALSE,
-                                            MM_MODEM_CHARSET_8859_1);
+        if (!mm_modem_charset_byte_array_append (*out,
+                                                 text,
+                                                 FALSE,
+                                                 MM_MODEM_CHARSET_8859_1,
+                                                 &error))
+            mm_obj_warn (log_object, "failed to convert to latin encoding: %s", error->message);
         *num_fields = (*out)->len;
         *num_bits_per_field = 8;
         *encoding = ENCODING_LATIN;
@@ -1406,20 +1425,23 @@
 
     /* If no Latin and no ASCII, default to UTF-16 */
     *out = g_byte_array_sized_new (len * 2);
-    mm_modem_charset_byte_array_append (*out,
-                                        text,
-                                        FALSE,
-                                        MM_MODEM_CHARSET_UCS2);
+    if (!mm_modem_charset_byte_array_append (*out,
+                                             text,
+                                             FALSE,
+                                             MM_MODEM_CHARSET_UCS2,
+                                             &error))
+        mm_obj_warn (log_object, "failed to convert to UTF-16 encoding: %s", error->message);
     *num_fields = (*out)->len / 2;
     *num_bits_per_field = 16;
     *encoding = ENCODING_UNICODE;
 }
 
 static gboolean
-write_bearer_data_user_data (MMSmsPart *part,
-                             guint8 *pdu,
-                             guint *parameter_offset,
-                             GError **error)
+write_bearer_data_user_data (MMSmsPart  *part,
+                             guint8     *pdu,
+                             guint      *parameter_offset,
+                             gpointer    log_object,
+                             GError    **error)
 {
     const gchar *text;
     const GByteArray *data;
@@ -1433,7 +1455,7 @@
     const GByteArray *aux;
     guint num_bits_per_iter;
 
-    mm_dbg ("        writing user data...");
+    mm_obj_dbg (log_object, "        writing user data...");
 
 #define OFFSETS_UPDATE(n_bits) do { \
         bit_offset += n_bits;       \
@@ -1456,6 +1478,7 @@
     /* Text or Data */
     if (text) {
         decide_best_encoding (text,
+                              log_object,
                               &converted,
                               &num_fields,
                               &num_bits_per_field,
@@ -1469,7 +1492,7 @@
     }
 
     /* Message encoding*/
-    mm_dbg ("            message encoding: %s", encoding_to_string (encoding));
+    mm_obj_dbg (log_object, "            message encoding: %s", encoding_to_string (encoding));
     write_bits (&pdu[byte_offset], bit_offset, 5, encoding);
     OFFSETS_UPDATE (5);
 
@@ -1484,16 +1507,16 @@
                      num_fields);
         return FALSE;
     }
-    mm_dbg ("            num fields: %u", num_fields);
+    mm_obj_dbg (log_object, "            num fields: %u", num_fields);
     write_bits (&pdu[byte_offset], bit_offset, 8, num_fields);
     OFFSETS_UPDATE (8);
 
     /* For ASCII-7, write 7 bits in each iteration; for the remaining ones
      * go byte per byte */
     if (text)
-        mm_dbg ("            text: '%s'", text);
+        mm_obj_dbg (log_object, "            text: '%s'", text);
     else
-        mm_dbg ("            data: (%u bytes)", num_fields);
+        mm_obj_dbg (log_object, "            data: (%u bytes)", num_fields);
     num_bits_per_iter = num_bits_per_field < 8 ? num_bits_per_field : 8;
     for (i = 0; i < aux->len; i++) {
         write_bits (&pdu[byte_offset], bit_offset, num_bits_per_iter, aux->data[i]);
@@ -1522,24 +1545,25 @@
 }
 
 static gboolean
-write_bearer_data (MMSmsPart *part,
-                   guint8 *pdu,
-                   guint *absolute_offset,
-                   GError **error)
+write_bearer_data (MMSmsPart  *part,
+                   guint8     *pdu,
+                   guint      *absolute_offset,
+                   gpointer    log_object,
+                   GError    **error)
 {
     GError *inner_error = NULL;
     guint offset = 0;
 
-    mm_dbg ("    writing bearer data...");
+    mm_obj_dbg (log_object, "    writing bearer data...");
 
     pdu[0] = PARAMETER_ID_BEARER_DATA;
     /* Write parameter length at the end */
 
     offset = 2;
-    if (!write_bearer_data_message_identifier (part, &pdu[offset], &offset, &inner_error))
-        mm_dbg ("Error writing message identifier: %s", inner_error->message);
-    else if (!write_bearer_data_user_data (part, &pdu[offset], &offset, &inner_error))
-        mm_dbg ("Error writing user data: %s", inner_error->message);
+    if (!write_bearer_data_message_identifier (part, &pdu[offset], &offset, log_object, &inner_error))
+        mm_obj_dbg (log_object, "error writing message identifier: %s", inner_error->message);
+    else if (!write_bearer_data_user_data (part, &pdu[offset], &offset, log_object, &inner_error))
+        mm_obj_dbg (log_object, "error writing user data: %s", inner_error->message);
 
     if (inner_error) {
         g_propagate_error (error, inner_error);
@@ -1564,9 +1588,10 @@
 }
 
 guint8 *
-mm_sms_part_cdma_get_submit_pdu (MMSmsPart *part,
-                                 guint *out_pdulen,
-                                 GError **error)
+mm_sms_part_cdma_get_submit_pdu (MMSmsPart  *part,
+                                 guint      *out_pdulen,
+                                 gpointer    log_object,
+                                 GError    **error)
 {
     GError *inner_error = NULL;
     guint offset = 0;
@@ -1584,7 +1609,7 @@
         return NULL;
     }
 
-    mm_dbg ("Creating PDU for part...");
+    mm_obj_dbg (log_object, "creating PDU for part...");
 
     /* Current max size estimations:
      *  Message type: 1 byte
@@ -1597,12 +1622,12 @@
     /* First byte: SMS message type */
     pdu[offset++] = MESSAGE_TYPE_POINT_TO_POINT;
 
-    if (!write_teleservice_id (part, &pdu[offset], &offset, &inner_error))
-        mm_dbg ("Error writing Teleservice ID: %s", inner_error->message);
-    else if (!write_destination_address (part, &pdu[offset], &offset, &inner_error))
-        mm_dbg ("Error writing destination address: %s", inner_error->message);
-    else if (!write_bearer_data (part, &pdu[offset], &offset, &inner_error))
-        mm_dbg ("Error writing bearer data: %s", inner_error->message);
+    if (!write_teleservice_id (part, &pdu[offset], &offset, log_object, &inner_error))
+        mm_obj_dbg (log_object, "error writing teleservice ID: %s", inner_error->message);
+    else if (!write_destination_address (part, &pdu[offset], &offset, log_object, &inner_error))
+        mm_obj_dbg (log_object, "error writing destination address: %s", inner_error->message);
+    else if (!write_bearer_data (part, &pdu[offset], &offset, log_object, &inner_error))
+        mm_obj_dbg (log_object, "error writing bearer data: %s", inner_error->message);
 
     if (inner_error) {
         g_propagate_error (error, inner_error);
diff --git a/src/mm-sms-part-cdma.h b/src/mm-sms-part-cdma.h
index 7331c89..804f67b 100644
--- a/src/mm-sms-part-cdma.h
+++ b/src/mm-sms-part-cdma.h
@@ -21,17 +21,18 @@
 
 #include "mm-sms-part.h"
 
-MMSmsPart *mm_sms_part_cdma_new_from_pdu  (guint index,
-                                           const gchar *hexpdu,
-                                           GError **error);
-
-MMSmsPart *mm_sms_part_cdma_new_from_binary_pdu (guint index,
-                                                 const guint8 *pdu,
-                                                 gsize pdu_len,
-                                                 GError **error);
-
-guint8 *mm_sms_part_cdma_get_submit_pdu (MMSmsPart *part,
-                                         guint *out_pdulen,
-                                         GError **error);
+MMSmsPart *mm_sms_part_cdma_new_from_pdu        (guint         index,
+                                                 const gchar   *hexpdu,
+                                                 gpointer       log_object,
+                                                 GError       **error);
+MMSmsPart *mm_sms_part_cdma_new_from_binary_pdu (guint          index,
+                                                 const guint8  *pdu,
+                                                 gsize          pdu_len,
+                                                 gpointer       log_object,
+                                                 GError       **error);
+guint8    *mm_sms_part_cdma_get_submit_pdu      (MMSmsPart     *part,
+                                                 guint         *out_pdulen,
+                                                 gpointer       log_object,
+                                                 GError       **error);
 
 #endif /* MM_SMS_PART_CDMA_H */
diff --git a/src/mm-sms-qmi.c b/src/mm-sms-qmi.c
index fabd417..6f3fe0d 100644
--- a/src/mm-sms-qmi.c
+++ b/src/mm-sms-qmi.c
@@ -31,7 +31,7 @@
 #include "mm-base-modem.h"
 #include "mm-sms-part-3gpp.h"
 #include "mm-sms-part-cdma.h"
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 G_DEFINE_TYPE (MMSmsQmi, mm_sms_qmi, MM_TYPE_BASE_SMS)
 
@@ -190,6 +190,7 @@
 static void
 sms_store_next_part (GTask *task)
 {
+    MMSmsQmi *self;
     SmsStoreContext *ctx;
     QmiMessageWmsRawWriteInput *input;
     guint8 *pdu = NULL;
@@ -198,6 +199,7 @@
     GArray *array;
     GError *error = NULL;
 
+    self = g_task_get_source_object (task);
     ctx = g_task_get_task_data (task);
 
     if (!ctx->current) {
@@ -209,9 +211,9 @@
 
     /* Get PDU */
     if (MM_SMS_PART_IS_3GPP ((MMSmsPart *)ctx->current->data))
-        pdu = mm_sms_part_3gpp_get_submit_pdu ((MMSmsPart *)ctx->current->data, &pdulen, &msgstart, &error);
+        pdu = mm_sms_part_3gpp_get_submit_pdu ((MMSmsPart *)ctx->current->data, &pdulen, &msgstart, self, &error);
     else if (MM_SMS_PART_IS_CDMA ((MMSmsPart *)ctx->current->data))
-        pdu = mm_sms_part_cdma_get_submit_pdu ((MMSmsPart *)ctx->current->data, &pdulen, &error);
+        pdu = mm_sms_part_cdma_get_submit_pdu ((MMSmsPart *)ctx->current->data, &pdulen, self, &error);
 
     if (!pdu) {
         if (error)
@@ -329,11 +331,14 @@
                     GAsyncResult *res,
                     GTask *task)
 {
+    MMSmsQmi *self;
     SmsSendContext *ctx;
     QmiMessageWmsRawSendOutput *output = NULL;
     GError *error = NULL;
     guint16 message_id;
 
+    self = g_task_get_source_object (task);
+
     output = qmi_client_wms_raw_send_finish (client, res, &error);
     if (!output) {
         g_prefix_error (&error, "QMI operation failed: ");
@@ -351,11 +356,11 @@
                 &rp_cause,
                 &tp_cause,
                 NULL)) {
-            mm_warn ("Couldn't send SMS; RP cause (%u): '%s'; TP cause (%u): '%s'",
-                     rp_cause,
-                     qmi_wms_gsm_umts_rp_cause_get_string (rp_cause),
-                     tp_cause,
-                     qmi_wms_gsm_umts_tp_cause_get_string (tp_cause));
+            mm_obj_warn (self, "couldn't send SMS; RP cause (%u): %s; TP cause (%u): %s",
+                         rp_cause,
+                         qmi_wms_gsm_umts_rp_cause_get_string (rp_cause),
+                         tp_cause,
+                         qmi_wms_gsm_umts_tp_cause_get_string (tp_cause));
         }
         qmi_message_wms_raw_send_output_unref (output);
 
@@ -381,6 +386,7 @@
 static void
 sms_send_generic (GTask *task)
 {
+    MMSmsQmi *self;
     SmsSendContext *ctx;
     QmiMessageWmsRawSendInput *input;
     guint8 *pdu = NULL;
@@ -389,13 +395,14 @@
     GArray *array;
     GError *error = NULL;
 
+    self = g_task_get_source_object (task);
     ctx = g_task_get_task_data (task);
 
     /* Get PDU */
     if (MM_SMS_PART_IS_3GPP ((MMSmsPart *)ctx->current->data))
-        pdu = mm_sms_part_3gpp_get_submit_pdu ((MMSmsPart *)ctx->current->data, &pdulen, &msgstart, &error);
+        pdu = mm_sms_part_3gpp_get_submit_pdu ((MMSmsPart *)ctx->current->data, &pdulen, &msgstart, self, &error);
     else if (MM_SMS_PART_IS_CDMA ((MMSmsPart *)ctx->current->data))
-        pdu = mm_sms_part_cdma_get_submit_pdu ((MMSmsPart *)ctx->current->data, &pdulen, &error);
+        pdu = mm_sms_part_cdma_get_submit_pdu ((MMSmsPart *)ctx->current->data, &pdulen, self, &error);
 
     if (!pdu) {
         if (error)
@@ -442,11 +449,13 @@
                          GAsyncResult *res,
                          GTask *task)
 {
+    MMSmsQmi *self;
     SmsSendContext *ctx;
     QmiMessageWmsSendFromMemoryStorageOutput *output = NULL;
     GError *error = NULL;
     guint16 message_id;
 
+    self = g_task_get_source_object (task);
     ctx = g_task_get_task_data (task);
 
     output = qmi_client_wms_send_from_memory_storage_finish (client, res, &error);
@@ -454,8 +463,7 @@
         if (g_error_matches (error,
                              QMI_CORE_ERROR,
                              QMI_CORE_ERROR_UNSUPPORTED)) {
-            mm_dbg ("Couldn't send SMS from storage: '%s'; trying generic send...",
-                    error->message);
+            mm_obj_dbg (self, "couldn't send SMS from storage: %s; trying generic send...", error->message);
             g_error_free (error);
             ctx->from_storage = FALSE;
             sms_send_next_part (task);
@@ -473,8 +481,7 @@
         if (g_error_matches (error,
                              QMI_PROTOCOL_ERROR,
                              QMI_PROTOCOL_ERROR_INVALID_QMI_COMMAND)) {
-            mm_dbg ("Couldn't send SMS from storage: '%s'; trying generic send...",
-                    error->message);
+            mm_obj_dbg (self, "couldn't send SMS from storage: %s; trying generic send...", error->message);
             g_error_free (error);
             ctx->from_storage = FALSE;
             sms_send_next_part (task);
@@ -489,29 +496,29 @@
                     &rp_cause,
                     &tp_cause,
                     NULL)) {
-                mm_warn ("Couldn't send SMS; RP cause (%u): '%s'; TP cause (%u): '%s'",
-                         rp_cause,
-                         qmi_wms_gsm_umts_rp_cause_get_string (rp_cause),
-                         tp_cause,
-                         qmi_wms_gsm_umts_tp_cause_get_string (tp_cause));
+                mm_obj_warn (self, "couldn't send SMS; RP cause (%u): %s; TP cause (%u): %s",
+                             rp_cause,
+                             qmi_wms_gsm_umts_rp_cause_get_string (rp_cause),
+                             tp_cause,
+                             qmi_wms_gsm_umts_tp_cause_get_string (tp_cause));
             }
 
             if (qmi_message_wms_send_from_memory_storage_output_get_cdma_cause_code (
                     output,
                     &cdma_cause_code,
                     NULL)) {
-                mm_warn ("Couldn't send SMS; cause code (%u): '%s'",
-                         cdma_cause_code,
-                         qmi_wms_cdma_cause_code_get_string (cdma_cause_code));
+                mm_obj_warn (self, "couldn't send SMS; cause code (%u): %s",
+                             cdma_cause_code,
+                             qmi_wms_cdma_cause_code_get_string (cdma_cause_code));
             }
 
             if (qmi_message_wms_send_from_memory_storage_output_get_cdma_error_class (
                     output,
                     &cdma_error_class,
                     NULL)) {
-                mm_warn ("Couldn't send SMS; error class (%u): '%s'",
-                         cdma_error_class,
-                         qmi_wms_cdma_error_class_get_string (cdma_error_class));
+                mm_obj_warn (self, "couldn't send SMS; error class (%u): %s",
+                             cdma_error_class,
+                             qmi_wms_cdma_error_class_get_string (cdma_error_class));
             }
 
             g_prefix_error (&error, "Couldn't write SMS part: ");
@@ -658,24 +665,26 @@
                    GAsyncResult *res,
                    GTask *task)
 {
+    MMSmsQmi *self;
     SmsDeletePartsContext *ctx;
     QmiMessageWmsDeleteOutput *output = NULL;
     GError *error = NULL;
 
+    self = g_task_get_source_object (task);
     ctx = g_task_get_task_data (task);
 
     output = qmi_client_wms_delete_finish (client, res, &error);
     if (!output) {
         ctx->n_failed++;
-        mm_dbg ("QMI operation failed: Couldn't delete SMS part with index %u: '%s'",
-                mm_sms_part_get_index ((MMSmsPart *)ctx->current->data),
-                error->message);
+        mm_obj_dbg (self, "QMI operation failed: couldn't delete SMS part with index %u: %s",
+                    mm_sms_part_get_index ((MMSmsPart *)ctx->current->data),
+                    error->message);
         g_error_free (error);
     } else if (!qmi_message_wms_delete_output_get_result (output, &error)) {
         ctx->n_failed++;
-        mm_dbg ("Couldn't delete SMS part with index %u: '%s'",
-                mm_sms_part_get_index ((MMSmsPart *)ctx->current->data),
-                error->message);
+        mm_obj_dbg (self, "couldn't delete SMS part with index %u: %s",
+                    mm_sms_part_get_index ((MMSmsPart *)ctx->current->data),
+                    error->message);
         g_error_free (error);
     }
 
diff --git a/src/mm-utils.h b/src/mm-utils.h
index 395c39e..cdb123c 100644
--- a/src/mm-utils.h
+++ b/src/mm-utils.h
@@ -20,7 +20,7 @@
 #include <glib.h>
 #include <glib-object.h>
 
-#include "mm-log.h"
+#include "mm-log-object.h"
 
 /*****************************************************************************/
 
@@ -32,7 +32,7 @@
     _singleton_instance_weak_ref_cb (gpointer data,                     \
                                      GObject *where_the_object_was)     \
     {                                                                   \
-        mm_dbg ("disposing %s singleton (%p)", G_STRINGIFY (TYPE), singleton_instance); \
+        mm_obj_dbg (singleton_instance, "singleton disposed");          \
         singleton_instance = NULL;                                      \
     }                                                                   \
     static inline void                                                  \
@@ -47,7 +47,7 @@
     {                                                                   \
         if (singleton_instance) {                                       \
             if (G_OBJECT (singleton_instance)->ref_count > 1)           \
-                mm_dbg ("disown %s singleton (%p)", G_STRINGIFY (TYPE), singleton_instance); \
+                mm_obj_dbg (singleton_instance, "singleton disowned");  \
             g_object_unref (singleton_instance);                        \
         }                                                               \
     }
@@ -70,9 +70,9 @@
             g_assert (!_already_created || (MM_DEFINE_SINGLETON_ALLOW_MULTIPLE));        \
             _already_created = TRUE;                                                     \
             singleton_instance = (g_object_new (GTYPE, ##__VA_ARGS__, NULL));            \
-            g_assert (singleton_instance);                                               \
-            mm_singleton_instance_weak_ref_register ();                                  \
-            mm_dbg ("create %s singleton (%p)", G_STRINGIFY (TYPE), singleton_instance); \
+            g_assert (singleton_instance);                              \
+            mm_singleton_instance_weak_ref_register ();                 \
+            mm_obj_dbg (singleton_instance, "singleton created");       \
         }                                                               \
         return singleton_instance;                                      \
     }                                                                   \
diff --git a/src/tests/test-at-serial-port.c b/src/tests/test-at-serial-port.c
index c864701..2147df4 100644
--- a/src/tests/test-at-serial-port.c
+++ b/src/tests/test-at-serial-port.c
@@ -18,7 +18,7 @@
 #include <glib.h>
 
 #include "mm-port-serial-at.h"
-#include "mm-log.h"
+#include "mm-log-test.h"
 
 typedef struct {
     const gchar *original;
@@ -64,26 +64,6 @@
     }
 }
 
-void
-_mm_log (const char *loc,
-         const char *func,
-         guint32 level,
-         const char *fmt,
-         ...)
-{
-    va_list args;
-    gchar *msg;
-
-    if (!g_test_verbose ())
-        return;
-
-    va_start (args, fmt);
-    msg = g_strdup_vprintf (fmt, args);
-    va_end (args);
-    g_print ("%s\n", msg);
-    g_free (msg);
-}
-
 int main (int argc, char **argv)
 {
     g_test_init (&argc, &argv, NULL);
diff --git a/src/tests/test-charsets.c b/src/tests/test-charsets.c
index 01a5b7a..5c9e187 100644
--- a/src/tests/test-charsets.c
+++ b/src/tests/test-charsets.c
@@ -18,7 +18,7 @@
 #include <locale.h>
 
 #include "mm-modem-helpers.h"
-#include "mm-log.h"
+#include "mm-log-test.h"
 
 static void
 common_test_gsm7 (const gchar *in_utf8)
@@ -408,26 +408,6 @@
     }
 }
 
-void
-_mm_log (const char *loc,
-         const char *func,
-         guint32 level,
-         const char *fmt,
-         ...)
-{
-    va_list args;
-    gchar *msg;
-
-    if (!g_test_verbose ())
-        return;
-
-    va_start (args, fmt);
-    msg = g_strdup_vprintf (fmt, args);
-    va_end (args);
-    g_print ("%s\n", msg);
-    g_free (msg);
-}
-
 int main (int argc, char **argv)
 {
     setlocale (LC_ALL, "");
diff --git a/src/tests/test-error-helpers.c b/src/tests/test-error-helpers.c
index 228dfc0..ddff9a0 100644
--- a/src/tests/test-error-helpers.c
+++ b/src/tests/test-error-helpers.c
@@ -38,7 +38,7 @@
                                                                             \
           enum_value = g_enum_get_value (enum_class, i);                    \
           if (enum_value) {                                                 \
-              error = mm_## ERROR_SMALL ## _for_code ((MM##ERROR_CAMEL)i);  \
+              error = mm_## ERROR_SMALL ## _for_code ((MM##ERROR_CAMEL)i, NULL); \
               g_assert_error (error, MM_ ## ERROR_CAPS, i);                 \
               g_error_free (error);                                         \
           }                                                                 \
@@ -52,26 +52,6 @@
 
 /*****************************************************************************/
 
-void
-_mm_log (const char *loc,
-         const char *func,
-         guint32 level,
-         const char *fmt,
-         ...)
-{
-    va_list args;
-    gchar *msg;
-
-    if (!g_test_verbose ())
-        return;
-
-    va_start (args, fmt);
-    msg = g_strdup_vprintf (fmt, args);
-    va_end (args);
-    g_print ("%s\n", msg);
-    g_free (msg);
-}
-
 int main (int argc, char **argv)
 {
     setlocale (LC_ALL, "");
diff --git a/src/tests/test-modem-helpers-qmi.c b/src/tests/test-modem-helpers-qmi.c
index d6b491c..fbd6cdb 100644
--- a/src/tests/test-modem-helpers-qmi.c
+++ b/src/tests/test-modem-helpers-qmi.c
@@ -21,7 +21,7 @@
 
 #include "mm-enums-types.h"
 #include "mm-modem-helpers-qmi.h"
-#include "mm-log.h"
+#include "mm-log-test.h"
 
 static void
 test_capabilities_expected (MMQmiCapabilitiesContext *ctx,
@@ -31,7 +31,7 @@
     gchar *expected_str;
     gchar *built_str;
 
-    built = mm_modem_capability_from_qmi_capabilities_context (ctx);
+    built = mm_modem_capability_from_qmi_capabilities_context (ctx, NULL);
 
     expected_str = mm_modem_capability_build_string_from_mask (expected);
     built_str = mm_modem_capability_build_string_from_mask (built);
@@ -309,26 +309,6 @@
 
 /*****************************************************************************/
 
-void
-_mm_log (const char *loc,
-         const char *func,
-         guint32 level,
-         const char *fmt,
-         ...)
-{
-    va_list args;
-    gchar *msg;
-
-    if (!g_test_verbose ())
-        return;
-
-    va_start (args, fmt);
-    msg = g_strdup_vprintf (fmt, args);
-    va_end (args);
-    g_print ("%s\n", msg);
-    g_free (msg);
-}
-
 int main (int argc, char **argv)
 {
     setlocale (LC_ALL, "");
diff --git a/src/tests/test-modem-helpers.c b/src/tests/test-modem-helpers.c
index bd74744..78b3cd1 100644
--- a/src/tests/test-modem-helpers.c
+++ b/src/tests/test-modem-helpers.c
@@ -22,7 +22,7 @@
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
 #include "mm-modem-helpers.h"
-#include "mm-log.h"
+#include "mm-log-test.h"
 
 #define g_assert_cmpfloat_tolerance(val1, val2, tolerance)  \
     g_assert_cmpfloat (fabs (val1 - val2), <, tolerance)
@@ -37,7 +37,7 @@
     MMFlowControl  mask;
     GError        *error = NULL;
 
-    mask = mm_parse_ifc_test_response (str, &error);
+    mask = mm_parse_ifc_test_response (str, NULL, &error);
     g_assert_no_error (error);
     g_assert_cmpuint (mask, ==, expected);
 }
@@ -486,7 +486,7 @@
 
     g_debug ("Testing %s +COPS response...", desc);
 
-    results = mm_3gpp_parse_cops_test_response (reply, cur_charset, &error);
+    results = mm_3gpp_parse_cops_test_response (reply, cur_charset, NULL, &error);
     g_assert (results);
     g_assert_no_error (error);
     g_assert_cmpuint (g_list_length (results), ==, expected_results_len);
@@ -916,7 +916,7 @@
     GList *results;
     GError *error = NULL;
 
-    results = mm_3gpp_parse_cops_test_response (reply, MM_MODEM_CHARSET_GSM, &error);
+    results = mm_3gpp_parse_cops_test_response (reply, MM_MODEM_CHARSET_GSM, NULL, &error);
     g_assert (results == NULL);
     g_assert_no_error (error);
 }
@@ -928,7 +928,7 @@
    GList *results;
     GError *error = NULL;
 
-    results = mm_3gpp_parse_cops_test_response (reply, MM_MODEM_CHARSET_GSM, &error);
+    results = mm_3gpp_parse_cops_test_response (reply, MM_MODEM_CHARSET_GSM, NULL, &error);
     g_assert (results == NULL);
     g_assert_no_error (error);
 }
@@ -1094,6 +1094,7 @@
     guint regex_num;
     gboolean cgreg;
     gboolean cereg;
+    gboolean c5greg;
 } CregResult;
 
 static void
@@ -1109,7 +1110,7 @@
     MMModemAccessTechnology access_tech = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
     gulong lac = 0, ci = 0;
     GError *error = NULL;
-    gboolean success, cgreg = FALSE, cereg = FALSE;
+    gboolean success, cgreg = FALSE, cereg = FALSE, c5greg = FALSE;
     guint regex_num = 0;
     GPtrArray *array;
 
@@ -1129,7 +1130,7 @@
 
         if (g_regex_match (r, reply, 0, &info)) {
             g_debug ("  matched with %d", i);
-            regex_num = i + 1;
+            regex_num = i;
             break;
         }
         g_match_info_free (info);
@@ -1143,19 +1144,18 @@
     g_assert (info != NULL);
     g_assert_cmpuint (regex_num, ==, result->regex_num);
 
-    success = mm_3gpp_parse_creg_response (info, &state, &lac, &ci, &access_tech, &cgreg, &cereg, &error);
+    success = mm_3gpp_parse_creg_response (info, NULL, &state, &lac, &ci, &access_tech, &cgreg, &cereg, &c5greg, &error);
+
     g_match_info_free (info);
     g_assert (success);
     g_assert_no_error (error);
     g_assert_cmpuint (state, ==, result->state);
-    g_assert (lac == result->lac);
-    g_assert (ci == result->ci);
-
-    g_debug ("  access_tech (%d) == result->act (%d)",
-             access_tech, result->act);
+    g_assert_cmpuint (lac, ==, result->lac);
+    g_assert_cmpuint (ci, ==, result->ci);
     g_assert_cmpuint (access_tech, ==, result->act);
     g_assert_cmpuint (cgreg, ==, result->cgreg);
     g_assert_cmpuint (cereg, ==, result->cereg);
+    g_assert_cmpuint (c5greg, ==, result->c5greg);
 }
 
 static void
@@ -1163,7 +1163,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "+CREG: 1,3";
-    const CregResult result = { 3, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 2, FALSE, FALSE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_DENIED, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 1, FALSE, FALSE, FALSE };
 
     test_creg_match ("CREG=1", TRUE, reply, data, &result);
 }
@@ -1173,7 +1173,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "\r\n+CREG: 3\r\n";
-    const CregResult result = { 3, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 1, FALSE, FALSE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_DENIED, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 0, FALSE, FALSE, FALSE };
 
     test_creg_match ("CREG=1", FALSE, reply, data, &result);
 }
@@ -1182,8 +1182,8 @@
 test_creg2_mercury_solicited (void *f, gpointer d)
 {
     RegTestData *data = (RegTestData *) d;
-    const char *reply = "+CREG: 0,1,84CD,00D30173";
-    const CregResult result = { 1, 0x84cd, 0xd30173, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 4, FALSE, FALSE };
+    const char *reply = "+CREG: 1,1,84CD,00D30173";
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x84cd, 0xd30173, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 3, FALSE, FALSE, FALSE };
 
     test_creg_match ("Sierra Mercury CREG=2", TRUE, reply, data, &result);
 }
@@ -1193,7 +1193,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "\r\n+CREG: 1,84CD,00D30156\r\n";
-    const CregResult result = { 1, 0x84cd, 0xd30156, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 3, FALSE, FALSE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x84cd, 0xd30156, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 2, FALSE, FALSE, FALSE };
 
     test_creg_match ("Sierra Mercury CREG=2", FALSE, reply, data, &result);
 }
@@ -1203,7 +1203,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "+CREG: 2,1,\"CE00\",\"01CEAD8F\"";
-    const CregResult result = { 1, 0xce00, 0x01cead8f, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 4, FALSE, FALSE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0xce00, 0x01cead8f, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 3, FALSE, FALSE, FALSE };
 
     test_creg_match ("Sony Ericsson K850i CREG=2", TRUE, reply, data, &result);
 }
@@ -1213,7 +1213,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "\r\n+CREG: 1,\"CE00\",\"00005449\"\r\n";
-    const CregResult result = { 1, 0xce00, 0x5449, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 3, FALSE, FALSE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0xce00, 0x5449, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 2, FALSE, FALSE, FALSE };
 
     test_creg_match ("Sony Ericsson K850i CREG=2", FALSE, reply, data, &result);
 }
@@ -1223,7 +1223,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "+CREG: 2,0,00,0";
-    const CregResult result = { 0, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 4, FALSE, FALSE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_IDLE, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 3, FALSE, FALSE, FALSE };
 
     test_creg_match ("Huawei E160G unregistered CREG=2", TRUE, reply, data, &result);
 }
@@ -1233,7 +1233,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "+CREG: 2,1,8BE3,2BAF";
-    const CregResult result = { 1, 0x8be3, 0x2baf, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 4, FALSE, FALSE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x8be3, 0x2baf, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 3, FALSE, FALSE, FALSE };
 
     test_creg_match ("Huawei E160G CREG=2", TRUE, reply, data, &result);
 }
@@ -1242,8 +1242,8 @@
 test_creg2_e160g_unsolicited (void *f, gpointer d)
 {
     RegTestData *data = (RegTestData *) d;
-    const char *reply = "\r\n+CREG: 2,8BE3,2BAF\r\n";
-    const CregResult result = { 2, 0x8be3, 0x2baf, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 3, FALSE, FALSE };
+    const char *reply = "\r\n+CREG: 1,8BE3,2BAF\r\n";
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x8be3, 0x2baf, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 2, FALSE, FALSE, FALSE };
 
     test_creg_match ("Huawei E160G CREG=2", FALSE, reply, data, &result);
 }
@@ -1253,7 +1253,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "+CREG: 2,1,\"8BE3\",\"00002BAF\"";
-    const CregResult result = { 1, 0x8BE3, 0x2BAF, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 4, FALSE, FALSE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x8BE3, 0x2BAF, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 3, FALSE, FALSE, FALSE };
 
     /* Test leading zeros in the CI */
     test_creg_match ("Sony Ericsson TM-506 CREG=2", TRUE, reply, data, &result);
@@ -1264,7 +1264,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "\r\n+CREG: 2,,\r\n";
-    const CregResult result = { 2, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 3, FALSE, FALSE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 2, FALSE, FALSE, FALSE };
 
     test_creg_match ("Novatel XU870 unregistered CREG=2", FALSE, reply, data, &result);
 }
@@ -1274,7 +1274,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "+CREG:002,001,\"18d8\",\"ffff\"";
-    const CregResult result = { 1, 0x18D8, 0xFFFF, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 5, FALSE, FALSE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x18D8, 0xFFFF, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 4, FALSE, FALSE, FALSE };
 
     test_creg_match ("Iridium, CREG=2", TRUE, reply, data, &result);
 }
@@ -1284,7 +1284,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "+CREG:2,1,0001,0010";
-    const CregResult result = { 1, 0x0001, 0x0010, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 4, FALSE, FALSE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x0001, 0x0010, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 3, FALSE, FALSE, FALSE };
 
     test_creg_match ("solicited CREG=2 with no leading zeros in integer fields", TRUE, reply, data, &result);
 }
@@ -1294,7 +1294,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "+CREG:002,001,\"0001\",\"0010\"";
-    const CregResult result = { 1, 0x0001, 0x0010, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 5, FALSE, FALSE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x0001, 0x0010, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 4, FALSE, FALSE, FALSE };
 
     test_creg_match ("solicited CREG=2 with leading zeros in integer fields", TRUE, reply, data, &result);
 }
@@ -1304,7 +1304,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "\r\n+CREG: 1,0001,0010,0\r\n";
-    const CregResult result = { 1, 0x0001, 0x0010, MM_MODEM_ACCESS_TECHNOLOGY_GSM, 6, FALSE, FALSE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x0001, 0x0010, MM_MODEM_ACCESS_TECHNOLOGY_GSM, 5, FALSE, FALSE, FALSE };
 
     test_creg_match ("unsolicited CREG=2 with no leading zeros in integer fields", FALSE, reply, data, &result);
 }
@@ -1314,7 +1314,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "\r\n+CREG: 001,\"0001\",\"0010\",000\r\n";
-    const CregResult result = { 1, 0x0001, 0x0010, MM_MODEM_ACCESS_TECHNOLOGY_GSM, 7, FALSE, FALSE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x0001, 0x0010, MM_MODEM_ACCESS_TECHNOLOGY_GSM, 6, FALSE, FALSE, FALSE };
 
     test_creg_match ("unsolicited CREG=2 with leading zeros in integer fields", FALSE, reply, data, &result);
 }
@@ -1324,8 +1324,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const gchar *reply = "\r\n+CREG: 2,6,\"8B37\",\"0A265185\",7\r\n";
-    /* NOTE: '6' means registered for "SMS only", home network; we just assume UNKNOWN in this case */
-    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME_SMS_ONLY, 0x8B37, 0x0A265185, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 8, FALSE, FALSE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME_SMS_ONLY, 0x8B37, 0x0A265185, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 7, FALSE, FALSE, FALSE };
 
     test_creg_match ("Ublox Toby-L2 solicited while on LTE", TRUE, reply, data, &result);
 }
@@ -1335,8 +1334,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const gchar *reply = "\r\n+CREG: 6,\"8B37\",\"0A265185\",7\r\n";
-    /* NOTE: '6' means registered for "SMS only", home network; we just assume UNKNOWN in this case */
-    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME_SMS_ONLY, 0x8B37, 0x0A265185, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 6, FALSE, FALSE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME_SMS_ONLY, 0x8B37, 0x0A265185, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 5, FALSE, FALSE, FALSE };
 
     test_creg_match ("Ublox Toby-L2 unsolicited while on LTE", FALSE, reply, data, &result);
 }
@@ -1346,7 +1344,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "+CGREG: 1,3";
-    const CregResult result = { 3, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 2, TRUE, FALSE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_DENIED, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 1, TRUE, FALSE, FALSE };
 
     test_creg_match ("CGREG=1", TRUE, reply, data, &result);
 }
@@ -1356,7 +1354,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "\r\n+CGREG: 3\r\n";
-    const CregResult result = { 3, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 1, TRUE, FALSE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_DENIED, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 0, TRUE, FALSE, FALSE };
 
     test_creg_match ("CGREG=1", FALSE, reply, data, &result);
 }
@@ -1366,7 +1364,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "+CGREG: 2,1,\"8BE3\",\"00002B5D\",3";
-    const CregResult result = { 1, 0x8BE3, 0x2B5D, MM_MODEM_ACCESS_TECHNOLOGY_EDGE, 8, TRUE, FALSE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x8BE3, 0x2B5D, MM_MODEM_ACCESS_TECHNOLOGY_EDGE, 7, TRUE, FALSE, FALSE };
 
     test_creg_match ("Ericsson F3607gw CGREG=2", TRUE, reply, data, &result);
 }
@@ -1376,7 +1374,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "\r\n+CGREG: 1,\"8BE3\",\"00002B5D\",3\r\n";
-    const CregResult result = { 1, 0x8BE3, 0x2B5D, MM_MODEM_ACCESS_TECHNOLOGY_EDGE, 6, TRUE, FALSE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x8BE3, 0x2B5D, MM_MODEM_ACCESS_TECHNOLOGY_EDGE, 5, TRUE, FALSE, FALSE };
 
     test_creg_match ("Ericsson F3607gw CGREG=2", FALSE, reply, data, &result);
 }
@@ -1386,7 +1384,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "\r\n+CREG: 2,5,\"0502\",\"0404736D\"\r\n";
-    const CregResult result = { 5, 0x0502, 0x0404736D, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 4, FALSE, FALSE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING, 0x0502, 0x0404736D, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 3, FALSE, FALSE, FALSE };
 
     test_creg_match ("Sony-Ericsson MD400 CREG=2", FALSE, reply, data, &result);
 }
@@ -1396,7 +1394,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "\r\n+CGREG: 5,\"0502\",\"0404736D\",2\r\n";
-    const CregResult result = { 5, 0x0502, 0x0404736D, MM_MODEM_ACCESS_TECHNOLOGY_UMTS, 6, TRUE, FALSE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING, 0x0502, 0x0404736D, MM_MODEM_ACCESS_TECHNOLOGY_UMTS, 5, TRUE, FALSE, FALSE };
 
     test_creg_match ("Sony-Ericsson MD400 CGREG=2", FALSE, reply, data, &result);
 }
@@ -1406,7 +1404,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "\r\n+CREG: 5\r\n\r\n+CGREG: 0\r\n";
-    const CregResult result = { 5, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 1, FALSE, FALSE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 0, FALSE, FALSE, FALSE };
 
     test_creg_match ("Multi CREG/CGREG", FALSE, reply, data, &result);
 }
@@ -1416,7 +1414,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "\r\n+CGREG: 0\r\n\r\n+CREG: 5\r\n";
-    const CregResult result = { 0, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 1, TRUE, FALSE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_IDLE, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 0, TRUE, FALSE, FALSE };
 
     test_creg_match ("Multi CREG/CGREG #2", FALSE, reply, data, &result);
 }
@@ -1426,7 +1424,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "\r\n+CGREG: 2,1, 81ED, 1A9CEB\r\n";
-    const CregResult result = { 1, 0x81ED, 0x1A9CEB, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 4, TRUE, FALSE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x81ED, 0x1A9CEB, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 3, TRUE, FALSE, FALSE };
 
     /* Tests random spaces in response */
     test_creg_match ("Alcatel One-Touch X220D CGREG=2", FALSE, reply, data, &result);
@@ -1437,7 +1435,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "\r\n+CREG: 2,1,000B,2816, B, C2816\r\n";
-    const CregResult result = { 1, 0x000B, 0x2816, MM_MODEM_ACCESS_TECHNOLOGY_GSM, 9, FALSE, FALSE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x000B, 0x2816, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 8, FALSE, FALSE, FALSE };
 
     test_creg_match ("Samsung Wave S8500 CREG=2", FALSE, reply, data, &result);
 }
@@ -1447,7 +1445,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "\r\n+CREG: 2,1,  0 5, 2715\r\n";
-    const CregResult result = { 1, 0x0000, 0x2715, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 4, FALSE, FALSE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x0000, 0x2715, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 3, FALSE, FALSE, FALSE };
 
     test_creg_match ("Qualcomm Gobi 1000 CREG=2", TRUE, reply, data, &result);
 }
@@ -1457,7 +1455,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "\r\n+CGREG: 1,\"1422\",\"00000142\",3,\"00\"\r\n";
-    const CregResult result = { 1, 0x1422, 0x0142, MM_MODEM_ACCESS_TECHNOLOGY_EDGE, 10, TRUE, FALSE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x1422, 0x0142, MM_MODEM_ACCESS_TECHNOLOGY_EDGE, 9, TRUE, FALSE, FALSE };
 
     test_creg_match ("CGREG=2 with RAC", FALSE, reply, data, &result);
 }
@@ -1467,7 +1465,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "+CEREG: 1,3";
-    const CregResult result = { 3, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 2, FALSE, TRUE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_DENIED, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 1, FALSE, TRUE, FALSE };
 
     test_creg_match ("CEREG=1", TRUE, reply, data, &result);
 }
@@ -1477,7 +1475,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "\r\n+CEREG: 3\r\n";
-    const CregResult result = { 3, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 1, FALSE, TRUE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_DENIED, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 0, FALSE, TRUE, FALSE };
 
     test_creg_match ("CEREG=1", FALSE, reply, data, &result);
 }
@@ -1487,7 +1485,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "\r\n+CEREG: 2,1, 1F00, 79D903 ,7\r\n";
-    const CregResult result = { 1, 0x1F00, 0x79D903, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 8, FALSE, TRUE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x1F00, 0x79D903, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 7, FALSE, TRUE, FALSE };
 
     test_creg_match ("CEREG=2", TRUE, reply, data, &result);
 }
@@ -1497,7 +1495,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "\r\n+CEREG: 1, 1F00, 79D903 ,7\r\n";
-    const CregResult result = { 1, 0x1F00, 0x79D903, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 6, FALSE, TRUE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x1F00, 0x79D903, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 5, FALSE, TRUE, FALSE };
 
     test_creg_match ("CEREG=2", FALSE, reply, data, &result);
 }
@@ -1507,7 +1505,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "\r\n+CEREG: 1, 2, 0001, 00000100, 7\r\n";
-    const CregResult result = { 2, 0x0001, 0x00000100, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 8, FALSE, TRUE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING, 0x0001, 0x00000100, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 7, FALSE, TRUE, FALSE };
 
     test_creg_match ("Altair LTE CEREG=2", FALSE, reply, data, &result);
 }
@@ -1517,7 +1515,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "\r\n+CEREG: 2, 0001, 00000100, 7\r\n";
-    const CregResult result = { 2, 0x0001, 0x00000100, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 6, FALSE, TRUE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING, 0x0001, 0x00000100, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 5, FALSE, TRUE, FALSE };
 
     test_creg_match ("Altair LTE CEREG=2", FALSE, reply, data, &result);
 }
@@ -1527,7 +1525,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "\r\n+CEREG: 2,1, 1F00, 20 ,79D903 ,7\r\n";
-    const CregResult result = { 1, 0x1F00, 0x79D903, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 13, FALSE, TRUE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x1F00, 0x79D903, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 11, FALSE, TRUE, FALSE };
 
     test_creg_match ("Novatel LTE E362 CEREG=2", TRUE, reply, data, &result);
 }
@@ -1537,7 +1535,7 @@
 {
     RegTestData *data = (RegTestData *) d;
     const char *reply = "\r\n+CEREG: 1, 1F00, 20 ,79D903 ,7\r\n";
-    const CregResult result = { 1, 0x1F00, 0x79D903, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 12, FALSE, TRUE };
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x1F00, 0x79D903, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 10, FALSE, TRUE, FALSE };
 
     test_creg_match ("Novatel LTE E362 CEREG=2", FALSE, reply, data, &result);
 }
@@ -1546,8 +1544,8 @@
 test_cgreg2_thuraya_solicited (void *f, gpointer d)
 {
     RegTestData *data = (RegTestData *) d;
-    const char *reply = "+CGREG: 1, \"0426\", \"F0,0F\"";
-    const CregResult result = { 1, 0x0426, 0x00F0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 11, TRUE, FALSE };
+    const char *reply = "+CGREG: 2, 1, \"0426\", \"F00F\"";
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x0426, 0xF00F, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 3, TRUE, FALSE, FALSE };
 
     test_creg_match ("Thuraya solicited CREG=2", TRUE, reply, data, &result);
 }
@@ -1556,12 +1554,52 @@
 test_cgreg2_thuraya_unsolicited (void *f, gpointer d)
 {
     RegTestData *data = (RegTestData *) d;
-    const char *reply = "\r\n+CGREG: 1, \"0426\", \"F0,0F\"\r\n";
-    const CregResult result = { 1, 0x0426, 0x00F0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 11, TRUE, FALSE };
+    const char *reply = "\r\n+CGREG: 1, \"0426\", \"F00F\"\r\n";
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x0426, 0xF00F, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 2, TRUE, FALSE, FALSE };
 
     test_creg_match ("Thuraya unsolicited CREG=2", FALSE, reply, data, &result);
 }
 
+static void
+test_c5greg1_solicited (void *f, gpointer d)
+{
+    RegTestData *data = (RegTestData *) d;
+    const char *reply = "+C5GREG: 1,3";
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_DENIED, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 1, FALSE, FALSE, TRUE };
+
+    test_creg_match ("C5GREG=1", TRUE, reply, data, &result);
+}
+
+static void
+test_c5greg1_unsolicited (void *f, gpointer d)
+{
+    RegTestData *data = (RegTestData *) d;
+    const char *reply = "\r\n+C5GREG: 3\r\n";
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_DENIED, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 0, FALSE, FALSE, TRUE };
+
+    test_creg_match ("C5GREG=1", FALSE, reply, data, &result);
+}
+
+static void
+test_c5greg2_solicited (void *f, gpointer d)
+{
+    RegTestData *data = (RegTestData *) d;
+    const char *reply = "+C5GREG: 2,1,1F00,79D903,11,6,ABCDEF";
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x1F00, 0x79D903, MM_MODEM_ACCESS_TECHNOLOGY_5GNR, 13, FALSE, FALSE, TRUE };
+
+    test_creg_match ("C5GREG=2", TRUE, reply, data, &result);
+}
+
+static void
+test_c5greg2_unsolicited (void *f, gpointer d)
+{
+    RegTestData *data = (RegTestData *) d;
+    const char *reply = "\r\n+C5GREG: 1,1F00,79D903,11,6,ABCDEF\r\n";
+    const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0x1F00, 0x79D903, MM_MODEM_ACCESS_TECHNOLOGY_5GNR, 12, FALSE, FALSE, TRUE };
+
+    test_creg_match ("C5GREG=2", FALSE, reply, data, &result);
+}
+
 /*****************************************************************************/
 /* Test CSCS responses */
 
@@ -1911,6 +1949,7 @@
     g_debug ("%s... ", item->desc);
     devid = mm_create_device_identifier (item->vid,
                                          item->pid,
+                                         NULL,
                                          item->ati,
                                          item->ati1,
                                          item->gsn,
@@ -1937,7 +1976,7 @@
     MM3gppCmerInd   inds = MM_3GPP_CMER_IND_NONE;
     GError         *error = NULL;
 
-    ret = mm_3gpp_parse_cmer_test_response (str, &modes, &inds, &error);
+    ret = mm_3gpp_parse_cmer_test_response (str, NULL, &modes, &inds, &error);
     g_assert_no_error (error);
     g_assert (ret);
 
@@ -2439,7 +2478,7 @@
 
     g_debug ("Testing %s +CGDCONT test response...", desc);
 
-    results = mm_3gpp_parse_cgdcont_test_response (reply, &error);
+    results = mm_3gpp_parse_cgdcont_test_response (reply, NULL, &error);
     g_assert (results);
     g_assert_no_error (error);
     g_assert_cmpuint (g_list_length (results), ==, expected_results_len);
@@ -2858,11 +2897,12 @@
 
         test = &cid_selection_tests[i];
 
-        context_format_list = test->cgdcont_test ? mm_3gpp_parse_cgdcont_test_response (test->cgdcont_test, NULL) : NULL;
+        context_format_list = test->cgdcont_test ? mm_3gpp_parse_cgdcont_test_response (test->cgdcont_test, NULL, NULL) : NULL;
         context_list = test->cgdcont_query ? mm_3gpp_parse_cgdcont_read_response (test->cgdcont_query, NULL) : NULL;
 
         cid = mm_3gpp_select_best_cid (test->apn, test->ip_family,
                                        context_list, context_format_list,
+                                       NULL,
                                        &cid_reused, &cid_overwritten);
 
         g_assert_cmpuint (cid, ==, test->expected_cid);
@@ -2899,10 +2939,12 @@
     GArray *mem1 = NULL;
     GArray *mem2 = NULL;
     GArray *mem3 = NULL;
+    GError *error = NULL;
 
     g_debug ("Testing Cinterion +CPMS=? response...");
 
-    g_assert (mm_3gpp_parse_cpms_test_response (reply, &mem1, &mem2, &mem3));
+    g_assert (mm_3gpp_parse_cpms_test_response (reply, &mem1, &mem2, &mem3, &error));
+    g_assert_no_error (error);
     g_assert_cmpuint (mem1->len, ==, 2);
     g_assert (is_storage_supported (mem1, MM_SMS_STORAGE_ME));
     g_assert (is_storage_supported (mem1, MM_SMS_STORAGE_MT));
@@ -2927,10 +2969,12 @@
     GArray *mem1 = NULL;
     GArray *mem2 = NULL;
     GArray *mem3 = NULL;
+    GError *error = NULL;
 
     g_debug ("Testing Huawei MU609 +CPMS=? response...");
 
-    g_assert (mm_3gpp_parse_cpms_test_response (reply, &mem1, &mem2, &mem3));
+    g_assert (mm_3gpp_parse_cpms_test_response (reply, &mem1, &mem2, &mem3, &error));
+    g_assert_no_error (error);
     g_assert_cmpuint (mem1->len, ==, 1);
     g_assert (is_storage_supported (mem1, MM_SMS_STORAGE_ME));
     g_assert_cmpuint (mem2->len, ==, 1);
@@ -2951,10 +2995,12 @@
     GArray *mem1 = NULL;
     GArray *mem2 = NULL;
     GArray *mem3 = NULL;
+    GError *error = NULL;
 
     g_debug ("Testing Nokia C6 response...");
 
-    g_assert (mm_3gpp_parse_cpms_test_response (reply, &mem1, &mem2, &mem3));
+    g_assert (mm_3gpp_parse_cpms_test_response (reply, &mem1, &mem2, &mem3, &error));
+    g_assert_no_error (error);
     g_assert_cmpuint (mem1->len, ==, 0);
     g_assert_cmpuint (mem2->len, ==, 0);
     g_assert_cmpuint (mem3->len, ==, 0);
@@ -2976,10 +3022,12 @@
     GArray *mem1 = NULL;
     GArray *mem2 = NULL;
     GArray *mem3 = NULL;
+    GError *error = NULL;
 
     g_debug ("Testing mixed +CPMS=? response...");
 
-    g_assert (mm_3gpp_parse_cpms_test_response (reply, &mem1, &mem2, &mem3));
+    g_assert (mm_3gpp_parse_cpms_test_response (reply, &mem1, &mem2, &mem3, &error));
+    g_assert_no_error (error);
     g_assert_cmpuint (mem1->len, ==, 2);
     g_assert (is_storage_supported (mem1, MM_SMS_STORAGE_ME));
     g_assert (is_storage_supported (mem1, MM_SMS_STORAGE_MT));
@@ -3001,10 +3049,12 @@
     GArray *mem1 = NULL;
     GArray *mem2 = NULL;
     GArray *mem3 = NULL;
+    GError *error = NULL;
 
     g_debug ("Testing mixed +CPMS=? response with spaces...");
 
-    g_assert (mm_3gpp_parse_cpms_test_response (reply, &mem1, &mem2, &mem3));
+    g_assert (mm_3gpp_parse_cpms_test_response (reply, &mem1, &mem2, &mem3, &error));
+    g_assert_no_error (error);
     g_assert_cmpuint (mem1->len, ==, 2);
     g_assert (is_storage_supported (mem1, MM_SMS_STORAGE_ME));
     g_assert (is_storage_supported (mem1, MM_SMS_STORAGE_MT));
@@ -3030,10 +3080,12 @@
     GArray *mem1 = NULL;
     GArray *mem2 = NULL;
     GArray *mem3 = NULL;
+    GError *error = NULL;
 
     g_debug ("Testing mixed +CPMS=? response...");
 
-    g_assert (mm_3gpp_parse_cpms_test_response (reply, &mem1, &mem2, &mem3));
+    g_assert (mm_3gpp_parse_cpms_test_response (reply, &mem1, &mem2, &mem3, &error));
+    g_assert_no_error (error);
     g_assert_cmpuint (mem1->len, ==, 0);
     g_assert_cmpuint (mem2->len, ==, 0);
     g_assert_cmpuint (mem3->len, ==, 0);
@@ -3422,7 +3474,7 @@
 
     /* Only 2G supported */
     all = build_mode_all (MM_MODEM_MODE_2G);
-    filtered = mm_filter_supported_modes (all, combinations);
+    filtered = mm_filter_supported_modes (all, combinations, NULL);
     g_assert_cmpuint (filtered->len, ==, 1);
     g_assert (find_mode_combination (filtered, MM_MODEM_MODE_2G, MM_MODEM_MODE_NONE));
     g_array_unref (filtered);
@@ -3430,7 +3482,7 @@
 
     /* Only 3G supported */
     all = build_mode_all (MM_MODEM_MODE_3G);
-    filtered = mm_filter_supported_modes (all, combinations);
+    filtered = mm_filter_supported_modes (all, combinations, NULL);
     g_assert_cmpuint (filtered->len, ==, 1);
     g_assert (find_mode_combination (filtered, MM_MODEM_MODE_3G, MM_MODEM_MODE_NONE));
     g_array_unref (filtered);
@@ -3438,7 +3490,7 @@
 
     /* 2G and 3G supported */
     all = build_mode_all (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
-    filtered = mm_filter_supported_modes (all, combinations);
+    filtered = mm_filter_supported_modes (all, combinations, NULL);
     g_assert_cmpuint (filtered->len, ==, 3);
     g_assert (find_mode_combination (filtered, MM_MODEM_MODE_2G, MM_MODEM_MODE_NONE));
     g_assert (find_mode_combination (filtered, MM_MODEM_MODE_3G, MM_MODEM_MODE_NONE));
@@ -3448,7 +3500,7 @@
 
     /* 3G and 4G supported */
     all = build_mode_all (MM_MODEM_MODE_3G | MM_MODEM_MODE_4G);
-    filtered = mm_filter_supported_modes (all, combinations);
+    filtered = mm_filter_supported_modes (all, combinations, NULL);
     g_assert_cmpuint (filtered->len, ==, 3);
     g_assert (find_mode_combination (filtered, MM_MODEM_MODE_3G, MM_MODEM_MODE_NONE));
     g_assert (find_mode_combination (filtered, MM_MODEM_MODE_4G, MM_MODEM_MODE_NONE));
@@ -3458,7 +3510,7 @@
 
     /* 2G, 3G and 4G supported */
     all = build_mode_all (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G);
-    filtered = mm_filter_supported_modes (all, combinations);
+    filtered = mm_filter_supported_modes (all, combinations, NULL);
     g_assert_cmpuint (filtered->len, ==, 6);
     g_assert (find_mode_combination (filtered, MM_MODEM_MODE_2G, MM_MODEM_MODE_NONE));
     g_assert (find_mode_combination (filtered, MM_MODEM_MODE_3G, MM_MODEM_MODE_NONE));
@@ -3473,98 +3525,6 @@
 }
 
 /*****************************************************************************/
-
-static gboolean
-find_capability_combination (GArray *capabilities,
-                             MMModemCapability capability)
-{
-    guint i;
-
-    for (i = 0; i < capabilities->len; i++) {
-        MMModemCapability capability_i;
-
-        capability_i = g_array_index (capabilities, MMModemCapability, i);
-        if (capability_i == capability)
-            return TRUE;
-    }
-
-    return FALSE;
-}
-
-static void
-test_supported_capability_filter (void *f, gpointer d)
-{
-    MMModemCapability capability;
-    GArray *combinations;
-    GArray *filtered;
-
-    combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemCapability), 6);
-
-    /* GSM/UMTS only */
-    capability = MM_MODEM_CAPABILITY_GSM_UMTS;
-    g_array_append_val (combinations, capability);
-    /* CDMA/EVDO only */
-    capability = MM_MODEM_CAPABILITY_CDMA_EVDO;
-    g_array_append_val (combinations, capability);
-    /* GSM/UMTS and CDMA/EVDO */
-    capability = (MM_MODEM_CAPABILITY_CDMA_EVDO | MM_MODEM_CAPABILITY_GSM_UMTS);
-    g_array_append_val (combinations, capability);
-    /* GSM/UMTS+LTE */
-    capability = (MM_MODEM_CAPABILITY_GSM_UMTS | MM_MODEM_CAPABILITY_LTE);
-    g_array_append_val (combinations, capability);
-    /* CDMA/EVDO+LTE */
-    capability = (MM_MODEM_CAPABILITY_CDMA_EVDO | MM_MODEM_CAPABILITY_LTE);
-    g_array_append_val (combinations, capability);
-    /* GSM/UMTS+CDMA/EVDO+LTE */
-    capability = (MM_MODEM_CAPABILITY_GSM_UMTS | MM_MODEM_CAPABILITY_CDMA_EVDO | MM_MODEM_CAPABILITY_LTE);
-    g_array_append_val (combinations, capability);
-
-    /* Only GSM-UMTS supported */
-    filtered = mm_filter_supported_capabilities (MM_MODEM_CAPABILITY_GSM_UMTS, combinations);
-    g_assert_cmpuint (filtered->len, ==, 1);
-    g_assert (find_capability_combination (filtered, MM_MODEM_CAPABILITY_GSM_UMTS));
-    g_array_unref (filtered);
-
-    /* Only CDMA-EVDO supported */
-    filtered = mm_filter_supported_capabilities (MM_MODEM_CAPABILITY_CDMA_EVDO, combinations);
-    g_assert_cmpuint (filtered->len, ==, 1);
-    g_assert (find_capability_combination (filtered, MM_MODEM_CAPABILITY_CDMA_EVDO));
-    g_array_unref (filtered);
-
-    /* GSM-UMTS and CDMA-EVDO supported */
-    filtered = mm_filter_supported_capabilities ((MM_MODEM_CAPABILITY_CDMA_EVDO |
-                                                  MM_MODEM_CAPABILITY_GSM_UMTS),
-                                                 combinations);
-    g_assert_cmpuint (filtered->len, ==, 3);
-    g_assert (find_capability_combination (filtered, MM_MODEM_CAPABILITY_CDMA_EVDO));
-    g_assert (find_capability_combination (filtered, MM_MODEM_CAPABILITY_GSM_UMTS));
-    g_assert (find_capability_combination (filtered, (MM_MODEM_CAPABILITY_GSM_UMTS |
-                                                      MM_MODEM_CAPABILITY_CDMA_EVDO)));
-    g_array_unref (filtered);
-
-    /* GSM-UMTS, CDMA-EVDO and LTE supported */
-    filtered = mm_filter_supported_capabilities ((MM_MODEM_CAPABILITY_CDMA_EVDO |
-                                                  MM_MODEM_CAPABILITY_GSM_UMTS |
-                                                  MM_MODEM_CAPABILITY_LTE),
-                                                 combinations);
-    g_assert_cmpuint (filtered->len, ==, 6);
-    g_assert (find_capability_combination (filtered, MM_MODEM_CAPABILITY_CDMA_EVDO));
-    g_assert (find_capability_combination (filtered, MM_MODEM_CAPABILITY_GSM_UMTS));
-    g_assert (find_capability_combination (filtered, (MM_MODEM_CAPABILITY_GSM_UMTS |
-                                                      MM_MODEM_CAPABILITY_CDMA_EVDO)));
-    g_assert (find_capability_combination (filtered, (MM_MODEM_CAPABILITY_GSM_UMTS |
-                                                      MM_MODEM_CAPABILITY_LTE)));
-    g_assert (find_capability_combination (filtered, (MM_MODEM_CAPABILITY_CDMA_EVDO |
-                                                      MM_MODEM_CAPABILITY_LTE)));
-    g_assert (find_capability_combination (filtered, (MM_MODEM_CAPABILITY_GSM_UMTS |
-                                                      MM_MODEM_CAPABILITY_CDMA_EVDO |
-                                                      MM_MODEM_CAPABILITY_LTE)));
-    g_array_unref (filtered);
-
-    g_array_unref (combinations);
-}
-
-/*****************************************************************************/
 /* Test +CCLK responses */
 
 typedef struct {
@@ -4000,6 +3960,7 @@
         MMSignal *lte  = NULL;
 
         success = mm_3gpp_cesq_response_to_signal_info (cesq_response_tests[i].str,
+                                                        NULL,
                                                         &gsm, &umts, &lte,
                                                         &error);
         g_assert_no_error (error);
@@ -4222,7 +4183,7 @@
     GError   *error = NULL;
     gboolean  result;
 
-    result = mm_3gpp_parse_ccwa_service_query_response (response, &status, &error);
+    result = mm_3gpp_parse_ccwa_service_query_response (response, NULL, &status, &error);
 
     if (expected_error) {
         g_assert (!result);
@@ -4280,7 +4241,7 @@
     GList      *call_info_list = NULL;
     GList      *l;
 
-    result = mm_3gpp_parse_clcc_response (str, &call_info_list, &error);
+    result = mm_3gpp_parse_clcc_response (str, NULL, &call_info_list, &error);
     g_assert_no_error (error);
     g_assert (result);
 
@@ -4501,26 +4462,6 @@
 
 /*****************************************************************************/
 
-void
-_mm_log (const char *loc,
-         const char *func,
-         guint32 level,
-         const char *fmt,
-         ...)
-{
-    va_list args;
-    gchar *msg;
-
-    if (!g_test_verbose ())
-        return;
-
-    va_start (args, fmt);
-    msg = g_strdup_vprintf (fmt, args);
-    va_end (args);
-    g_print ("%s\n", msg);
-    g_free (msg);
-}
-
 #define TESTCASE(t, d) g_test_create_case (#t, 0, d, NULL, (GTestFixtureFunc) t, NULL)
 
 int main (int argc, char **argv)
@@ -4633,6 +4574,11 @@
     g_test_suite_add (suite, TESTCASE (test_cereg2_novatel_lte_solicited, reg_data));
     g_test_suite_add (suite, TESTCASE (test_cereg2_novatel_lte_unsolicited, reg_data));
 
+    g_test_suite_add (suite, TESTCASE (test_c5greg1_solicited, reg_data));
+    g_test_suite_add (suite, TESTCASE (test_c5greg1_unsolicited, reg_data));
+    g_test_suite_add (suite, TESTCASE (test_c5greg2_solicited, reg_data));
+    g_test_suite_add (suite, TESTCASE (test_c5greg2_unsolicited, reg_data));
+
     g_test_suite_add (suite, TESTCASE (test_creg_cgreg_multi_unsolicited, reg_data));
     g_test_suite_add (suite, TESTCASE (test_creg_cgreg_multi2_unsolicited, reg_data));
 
@@ -4718,8 +4664,6 @@
 
     g_test_suite_add (suite, TESTCASE (test_supported_mode_filter, NULL));
 
-    g_test_suite_add (suite, TESTCASE (test_supported_capability_filter, NULL));
-
     g_test_suite_add (suite, TESTCASE (test_cclk_response, NULL));
 
     g_test_suite_add (suite, TESTCASE (test_crsm_response, NULL));
diff --git a/src/tests/test-qcdm-serial-port.c b/src/tests/test-qcdm-serial-port.c
index c5233f9..0b14282 100644
--- a/src/tests/test-qcdm-serial-port.c
+++ b/src/tests/test-qcdm-serial-port.c
@@ -34,7 +34,7 @@
 #include "libqcdm/src/utils.h"
 #include "libqcdm/src/com.h"
 #include "libqcdm/src/errors.h"
-#include "mm-log.h"
+#include "mm-log-test.h"
 
 typedef struct {
     int master;
@@ -437,26 +437,6 @@
     }
 }
 
-void
-_mm_log (const char *loc,
-         const char *func,
-         guint32 level,
-         const char *fmt,
-         ...)
-{
-    va_list args;
-    gchar *msg;
-
-    if (!g_test_verbose ())
-        return;
-
-    va_start (args, fmt);
-    msg = g_strdup_vprintf (fmt, args);
-    va_end (args);
-    g_print ("%s\n", msg);
-    g_free (msg);
-}
-
 typedef void (*TCFunc) (TestData *, gconstpointer);
 #define TESTCASE_PTY(s, t) g_test_add (s, TestData, NULL, (TCFunc)test_pty_create, (TCFunc)t, (TCFunc)test_pty_cleanup);
 
diff --git a/src/tests/test-sms-part-3gpp.c b/src/tests/test-sms-part-3gpp.c
index d915240..c3d59d8 100644
--- a/src/tests/test-sms-part-3gpp.c
+++ b/src/tests/test-sms-part-3gpp.c
@@ -24,7 +24,7 @@
 #include <libmm-glib.h>
 
 #include "mm-sms-part-3gpp.h"
-#include "mm-log.h"
+#include "mm-log-test.h"
 
 /********************* PDU PARSER TESTS *********************/
 
@@ -41,7 +41,7 @@
     MMSmsPart *part;
     GError *error = NULL;
 
-    part = mm_sms_part_3gpp_new_from_pdu (0, hexpdu, &error);
+    part = mm_sms_part_3gpp_new_from_pdu (0, hexpdu, NULL, &error);
     g_assert_no_error (error);
     g_assert (part != NULL);
 
@@ -339,7 +339,7 @@
     };
 
     hexpdu = mm_utils_bin2hexstr (pdu, sizeof (pdu));
-    part = mm_sms_part_3gpp_new_from_pdu (0, hexpdu, &error);
+    part = mm_sms_part_3gpp_new_from_pdu (0, hexpdu, NULL, &error);
     g_assert (part == NULL);
     /* We don't care for the specific error type */
     g_assert (error != NULL);
@@ -531,7 +531,7 @@
         MMSmsEncoding encoding = MM_SMS_ENCODING_UNKNOWN;
 
         /* Detect best encoding */
-        out = mm_sms_part_3gpp_util_split_text (text, &encoding);
+        out = mm_sms_part_3gpp_util_split_text (text, &encoding, NULL);
         g_strfreev (out);
         mm_sms_part_set_text (part, text);
         mm_sms_part_set_encoding (part, encoding);
@@ -544,6 +544,7 @@
     pdu = mm_sms_part_3gpp_get_submit_pdu (part,
                                            &len,
                                            &msgstart,
+                                           NULL,
                                            &error);
     mm_sms_part_free (part);
 
@@ -719,7 +720,7 @@
     MMSmsEncoding out_encoding = MM_SMS_ENCODING_UNKNOWN;
     guint i;
 
-    out = mm_sms_part_3gpp_util_split_text (text, &out_encoding);
+    out = mm_sms_part_3gpp_util_split_text (text, &out_encoding, NULL);
 
     g_assert (out != NULL);
     g_assert (out_encoding != MM_SMS_ENCODING_UNKNOWN);
@@ -840,26 +841,6 @@
 
 /************************************************************/
 
-void
-_mm_log (const char *loc,
-         const char *func,
-         guint32 level,
-         const char *fmt,
-         ...)
-{
-    va_list args;
-    gchar *msg;
-
-    if (!g_test_verbose ())
-        return;
-
-    va_start (args, fmt);
-    msg = g_strdup_vprintf (fmt, args);
-    va_end (args);
-    g_print ("%s\n", msg);
-    g_free (msg);
-}
-
 int main (int argc, char **argv)
 {
     setlocale (LC_ALL, "");
diff --git a/src/tests/test-sms-part-cdma.c b/src/tests/test-sms-part-cdma.c
index e155926..af01b5f 100644
--- a/src/tests/test-sms-part-cdma.c
+++ b/src/tests/test-sms-part-cdma.c
@@ -23,7 +23,7 @@
 #include <libmm-glib.h>
 
 #include "mm-sms-part-cdma.h"
-#include "mm-log.h"
+#include "mm-log-test.h"
 
 /********************* PDU PARSER TESTS *********************/
 
@@ -38,8 +38,7 @@
     MMSmsPart *part;
     GError *error = NULL;
 
-    mm_dbg (" ");
-    part = mm_sms_part_cdma_new_from_pdu (0, hexpdu, &error);
+    part = mm_sms_part_cdma_new_from_pdu (0, hexpdu, NULL, &error);
     g_assert_no_error (error);
     g_assert (part != NULL);
 
@@ -88,8 +87,7 @@
     MMSmsPart *part;
     GError *error = NULL;
 
-    mm_dbg (" ");
-    part = mm_sms_part_cdma_new_from_pdu (0, hexpdu, &error);
+    part = mm_sms_part_cdma_new_from_pdu (0, hexpdu, NULL, &error);
     g_assert (part == NULL);
     /* We don't care for the specific error type */
     g_assert (error != NULL);
@@ -396,7 +394,7 @@
         mm_sms_part_take_data (part, data_bytearray);
     }
 
-    pdu = mm_sms_part_cdma_get_submit_pdu (part, &len, &error);
+    pdu = mm_sms_part_cdma_get_submit_pdu (part, &len, NULL, &error);
     mm_sms_part_free (part);
 
     if (g_test_verbose ())
@@ -504,26 +502,6 @@
 
 /************************************************************/
 
-void
-_mm_log (const char *loc,
-         const char *func,
-         guint32 level,
-         const char *fmt,
-         ...)
-{
-    va_list args;
-    gchar *msg;
-
-    if (!g_test_verbose ())
-        return;
-
-    va_start (args, fmt);
-    msg = g_strdup_vprintf (fmt, args);
-    va_end (args);
-    g_print ("%s\n", msg);
-    g_free (msg);
-}
-
 int main (int argc, char **argv)
 {
     setlocale (LC_ALL, "");
diff --git a/src/tests/test-udev-rules.c b/src/tests/test-udev-rules.c
index 3398e41..cdc962e 100644
--- a/src/tests/test-udev-rules.c
+++ b/src/tests/test-udev-rules.c
@@ -23,7 +23,7 @@
 #include <libmm-glib.h>
 
 #include "mm-kernel-device-generic-rules.h"
-#include "mm-log.h"
+#include "mm-log-test.h"
 
 /************************************************************/
 
@@ -43,26 +43,6 @@
 
 /************************************************************/
 
-void
-_mm_log (const char *loc,
-         const char *func,
-         guint32 level,
-         const char *fmt,
-         ...)
-{
-    va_list args;
-    gchar *msg;
-
-    if (!g_test_verbose ())
-        return;
-
-    va_start (args, fmt);
-    msg = g_strdup_vprintf (fmt, args);
-    va_end (args);
-    g_print ("%s\n", msg);
-    g_free (msg);
-}
-
 int main (int argc, char **argv)
 {
     setlocale (LC_ALL, "");
diff --git a/test/mmrules.c b/test/mmrules.c
index 17976d2..3538f44 100644
--- a/test/mmrules.c
+++ b/test/mmrules.c
@@ -23,7 +23,7 @@
 #include <glib.h>
 #include <gio/gio.h>
 
-#include <mm-log.h>
+#include <mm-log-test.h>
 #include <mm-kernel-device-generic-rules.h>
 
 #define PROGRAM_NAME    "mmrules"
@@ -50,26 +50,6 @@
     { NULL }
 };
 
-void
-_mm_log (const char *loc,
-         const char *func,
-         guint32 level,
-         const char *fmt,
-         ...)
-{
-    va_list args;
-    gchar *msg;
-
-    if (!verbose_flag)
-        return;
-
-    va_start (args, fmt);
-    msg = g_strdup_vprintf (fmt, args);
-    va_end (args);
-    g_print ("%s\n", msg);
-    g_free (msg);
-}
-
 static void
 print_version_and_exit (void)
 {
diff --git a/test/mmsmspdu.c b/test/mmsmspdu.c
index c5e9693..3a56ffc 100644
--- a/test/mmsmspdu.c
+++ b/test/mmsmspdu.c
@@ -26,7 +26,7 @@
 #include <ModemManager.h>
 #define _LIBMM_INSIDE_MM
 #include <libmm-glib.h>
-#include "mm-log.h"
+#include "mm-log-test.h"
 #include "mm-sms-part-3gpp.h"
 
 #define PROGRAM_NAME    "mmsmspdu"
@@ -163,26 +163,6 @@
     }
 }
 
-void
-_mm_log (const char *loc,
-         const char *func,
-         guint32     level,
-         const char *fmt,
-         ...)
-{
-    va_list args;
-    gchar *msg;
-
-    if (!verbose_flag)
-        return;
-
-    va_start (args, fmt);
-    msg = g_strdup_vprintf (fmt, args);
-    va_end (args);
-    g_print ("%s\n", msg);
-    g_free (msg);
-}
-
 static void
 print_version_and_exit (void)
 {
@@ -219,7 +199,7 @@
         exit (EXIT_FAILURE);
     }
 
-    part = mm_sms_part_3gpp_new_from_pdu (0, pdu, &error);
+    part = mm_sms_part_3gpp_new_from_pdu (0, pdu, NULL, &error);
     if (!part) {
         g_printerr ("error: couldn't parse PDU: %s\n", error->message);
         exit (EXIT_FAILURE);
diff --git a/test/mmtty.c b/test/mmtty.c
index 966225c..28df628 100644
--- a/test/mmtty.c
+++ b/test/mmtty.c
@@ -23,7 +23,7 @@
 #include <glib.h>
 #include <gio/gio.h>
 
-#include <mm-log.h>
+#include <mm-log-test.h>
 #include <mm-port-serial.h>
 #include <mm-port-serial-at.h>
 #include <mm-serial-parsers.h>
@@ -83,26 +83,6 @@
     }
 }
 
-void
-_mm_log (const char *loc,
-         const char *func,
-         guint32 level,
-         const char *fmt,
-         ...)
-{
-    va_list args;
-    gchar *msg;
-
-    if (!verbose_flag)
-        return;
-
-    va_start (args, fmt);
-    msg = g_strdup_vprintf (fmt, args);
-    va_end (args);
-    g_print ("%s\n", msg);
-    g_free (msg);
-}
-
 static void
 print_version_and_exit (void)
 {