diff --git a/src/mm-base-call.c b/src/mm-base-call.c
index c28ce47661d0f24a3b84691bebd348a2be7e0dd4..9e0673de5fbb7eaff126243dc33c46a96bc6477d 100644
--- a/src/mm-base-call.c
+++ b/src/mm-base-call.c
@@ -539,18 +539,42 @@ mm_base_call_get_path (MMBaseCall *self)
     return self->priv->path;
 }
 
+/* Define the states in which we want to handle in-call events */
+#define MM_CALL_STATE_IS_IN_CALL(state)         \
+    (state == MM_CALL_STATE_DIALING ||          \
+     state == MM_CALL_STATE_RINGING_OUT ||      \
+     state == MM_CALL_STATE_ACTIVE)
+
 void
-mm_base_call_change_state (MMBaseCall *self,
-                           MMCallState new_state,
-                           MMCallStateReason reason)
+mm_base_call_change_state (MMBaseCall        *self,
+                           MMCallState        new_state,
+                           MMCallStateReason  reason)
 {
-    MMCallState old_state;
+    MMCallState  old_state;
+    GError      *error = NULL;
 
     old_state = mm_gdbus_call_get_state (MM_GDBUS_CALL (self));
 
     if (old_state == new_state)
         return;
 
+    /* Setup/cleanup unsolicited events  based on state transitions to/from ACTIVE */
+    if (!MM_CALL_STATE_IS_IN_CALL (old_state) && MM_CALL_STATE_IS_IN_CALL (new_state)) {
+        mm_dbg ("Setting up in-call unsolicited events...");
+        if (MM_BASE_CALL_GET_CLASS (self)->setup_unsolicited_events &&
+            !MM_BASE_CALL_GET_CLASS (self)->setup_unsolicited_events (self, &error)) {
+            mm_warn ("Couldn't setup in-call unsolicited events: %s", error->message);
+            g_error_free (error);
+        }
+    } else if (MM_CALL_STATE_IS_IN_CALL (old_state) && !MM_CALL_STATE_IS_IN_CALL (new_state)) {
+        mm_dbg ("Cleaning up in-call unsolicited events...");
+        if (MM_BASE_CALL_GET_CLASS (self)->cleanup_unsolicited_events &&
+            !MM_BASE_CALL_GET_CLASS (self)->cleanup_unsolicited_events (self, &error)) {
+            mm_warn ("Couldn't cleanup in-call unsolicited events: %s", error->message);
+            g_error_free (error);
+        }
+    }
+
     mm_gdbus_call_set_state (MM_GDBUS_CALL (self), new_state);
     mm_gdbus_call_set_state_reason (MM_GDBUS_CALL (self), reason);
     mm_gdbus_call_emit_state_changed (MM_GDBUS_CALL (self), old_state, new_state, reason);
diff --git a/src/mm-base-call.h b/src/mm-base-call.h
index 938e4581619a4f2919651fe8b0d9e2608b2446ee..02c6d72a1263d8cb685942e8fb642865f849d0b8 100644
--- a/src/mm-base-call.h
+++ b/src/mm-base-call.h
@@ -79,6 +79,12 @@ struct _MMBaseCallClass {
     gboolean (* send_dtmf_finish) (MMBaseCall *self,
                                    GAsyncResult *res,
                                    GError **error);
+
+    /* Setup/cleanup in-call unsolicited events */
+    gboolean (* setup_unsolicited_events)   (MMBaseCall  *self,
+                                             GError     **error);
+    gboolean (* cleanup_unsolicited_events) (MMBaseCall  *self,
+                                             GError     **error);
 };
 
 GType mm_base_call_get_type (void);