---
 src/modem.c |   48 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 48 insertions(+), 0 deletions(-)

diff --git a/src/modem.c b/src/modem.c
index b935328..6dfa73a 100644
--- a/src/modem.c
+++ b/src/modem.c
@@ -52,6 +52,7 @@ enum ofono_property_type {
 struct ofono_modem {
        char                    *path;
        GSList                  *atoms;
+       GSList                  *pre_sim_atoms;
        struct ofono_watchlist  *atom_watches;
        GSList                  *interface_list;
        unsigned int            call_ids;
@@ -64,6 +65,7 @@ struct ofono_modem {
        struct ofono_sim        *sim;
        unsigned int            sim_watch;
        unsigned int            sim_ready_watch;
+       unsigned int            sim_removed_watch;
        const struct ofono_modem_driver *driver;
        void                    *driver_data;
        char                    *driver_type;
@@ -300,6 +302,7 @@ void __ofono_atom_free(struct ofono_atom *atom)
        struct ofono_modem *modem = atom->modem;
 
        modem->atoms = g_slist_remove(modem->atoms, atom);
+       modem->pre_sim_atoms = g_slist_remove(modem->pre_sim_atoms, atom);
 
        __ofono_atom_unregister(atom);
 
@@ -329,7 +332,35 @@ static void remove_all_atoms(struct ofono_modem *modem)
        }
 
        g_slist_free(modem->atoms);
+       g_slist_free(modem->pre_sim_atoms);
        modem->atoms = NULL;
+       modem->pre_sim_atoms = NULL;
+}
+
+static void remove_post_sim_atoms(struct ofono_modem *modem)
+{
+       GSList *l;
+       struct ofono_atom *atom;
+
+       if (modem == NULL)
+               return;
+
+       for (l = modem->atoms; l; l = l->next) {
+               atom = l->data;
+
+               if (g_slist_find(modem->pre_sim_atoms, atom))
+                       continue;
+
+               __ofono_atom_unregister(atom);
+
+               if (atom->destruct)
+                       atom->destruct(atom);
+
+               g_free(atom);
+       }
+
+       g_slist_free(modem->atoms);
+       modem->atoms = g_slist_copy(modem->pre_sim_atoms);
 }
 
 static DBusMessage *modem_get_properties(DBusConnection *conn,
@@ -1121,12 +1152,25 @@ static void modem_sim_ready(void *user)
 {
        struct ofono_modem *modem = user;
 
+       if (modem->pre_sim_atoms == NULL)
+               modem->pre_sim_atoms = g_slist_copy(modem->atoms);
+
        if (modem->driver->post_sim)
                modem->driver->post_sim(modem);
 
        __ofono_history_probe_drivers(modem);
 }
 
+static void modem_sim_removed(void *user)
+{
+       struct ofono_modem *modem = user;
+
+       if (modem->pre_sim_atoms == NULL)
+               return;
+
+       remove_post_sim_atoms(modem);
+}
+
 static void sim_watch(struct ofono_atom *atom,
                        enum ofono_atom_watch_condition cond, void *data)
 {
@@ -1134,6 +1178,7 @@ static void sim_watch(struct ofono_atom *atom,
 
        if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED) {
                modem->sim_ready_watch = 0;
+               modem->sim_removed_watch = 0;
                return;
        }
 
@@ -1141,6 +1186,9 @@ static void sim_watch(struct ofono_atom *atom,
        modem->sim_ready_watch = ofono_sim_add_ready_watch(modem->sim,
                                                        modem_sim_ready,
                                                        modem, NULL);
+       modem->sim_removed_watch = ofono_sim_add_removed_watch(modem->sim,
+                                                       modem_sim_removed,
+                                                       modem, NULL);
 
        if (ofono_sim_get_ready(modem->sim))
                modem_sim_ready(modem);
-- 
1.6.1

_______________________________________________
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono

Reply via email to