diff --git a/src/sim.c b/src/sim.c index 5559be48..8701e0ec 100644 --- a/src/sim.c +++ b/src/sim.c @@ -272,6 +272,7 @@ static DBusMessage *sim_get_properties(DBusConnection *conn, char **service_numbers; char **locked_pins; const char *pin_name; + dbus_bool_t present = sim->state != OFONO_SIM_STATE_NOT_PRESENT; reply = dbus_message_new_method_return(msg); if (!reply) @@ -283,6 +284,11 @@ static DBusMessage *sim_get_properties(DBusConnection *conn, OFONO_PROPERTIES_ARRAY_SIGNATURE, &dict); + ofono_dbus_dict_append(&dict, "Present", DBUS_TYPE_BOOLEAN, &present); + + if (!present) + goto done; + if (sim->imsi) ofono_dbus_dict_append(&dict, "SubscriberIdentity", DBUS_TYPE_STRING, &sim->imsi); @@ -336,6 +342,7 @@ static DBusMessage *sim_get_properties(DBusConnection *conn, DBUS_TYPE_STRING, (void *) &pin_name); +done: dbus_message_iter_close_container(&iter, &dict); return reply; @@ -1011,6 +1018,8 @@ static void sim_imsi_cb(const struct ofono_error *error, const char *imsi, void *data) { struct ofono_sim *sim = data; + DBusConnection *conn = ofono_dbus_get_connection(); + const char *path = __ofono_atom_get_path(sim->atom); if (error->type != OFONO_ERROR_TYPE_NO_ERROR) { ofono_error("Unable to read IMSI, emergency calls only"); @@ -1019,6 +1028,11 @@ static void sim_imsi_cb(const struct ofono_error *error, const char *imsi, sim->imsi = g_strdup(imsi); + ofono_dbus_signal_property_changed(conn, path, + OFONO_SIM_MANAGER_INTERFACE, + "SubscriberIdentity", + DBUS_TYPE_STRING, &sim->imsi); + /* Read CPHS-support bits, this is still part of the SIM * initialisation but no order is specified for it. */ ofono_sim_read(sim, SIM_EF_CPHS_INFORMATION_FILEID, @@ -1779,6 +1793,62 @@ const unsigned char *ofono_sim_get_cphs_service_table(struct ofono_sim *sim) return sim->cphs_service_table; } +static void sim_inserted_update(struct ofono_sim *sim) +{ + dbus_bool_t present = sim->state != OFONO_SIM_STATE_NOT_PRESENT; + DBusConnection *conn = ofono_dbus_get_connection(); + const char *path = __ofono_atom_get_path(sim->atom); + + ofono_dbus_signal_property_changed(conn, path, + OFONO_SIM_MANAGER_INTERFACE, "Present", + DBUS_TYPE_BOOLEAN, &present); +} + +static void sim_free_state(struct ofono_sim *sim) +{ + if (sim->simop_source) { + g_source_remove(sim->simop_source); + sim->simop_source = 0; + } + + if (sim->simop_q) { + /* Note: users of ofono_sim_read/write must not assume that + * the callback happens for operations still in progress. */ + g_queue_foreach(sim->simop_q, (GFunc)sim_file_op_free, NULL); + g_queue_free(sim->simop_q); + sim->simop_q = NULL; + } + + if (sim->imsi) { + g_free(sim->imsi); + sim->imsi = NULL; + } + + if (sim->own_numbers) { + g_slist_foreach(sim->own_numbers, (GFunc)g_free, NULL); + g_slist_free(sim->own_numbers); + sim->own_numbers = NULL; + } + + if (sim->service_numbers) { + g_slist_foreach(sim->service_numbers, + (GFunc)service_number_free, NULL); + g_slist_free(sim->service_numbers); + sim->service_numbers = NULL; + } + + if (sim->efli) { + g_free(sim->efli); + sim->efli = NULL; + sim->efli_length = 0; + } + + if (sim->language_prefs) { + g_strfreev(sim->language_prefs); + sim->language_prefs = NULL; + } +} + void ofono_sim_inserted_notify(struct ofono_sim *sim, ofono_bool_t inserted) { ofono_sim_state_event_notify_cb_t notify; @@ -1794,6 +1864,8 @@ void ofono_sim_inserted_notify(struct ofono_sim *sim, ofono_bool_t inserted) if (!__ofono_atom_get_registered(sim->atom)) return; + sim_inserted_update(sim); + for (l = sim->state_watches->items; l; l = l->next) { struct ofono_watchlist_item *item = l->data; notify = item->notify; @@ -1801,8 +1873,11 @@ void ofono_sim_inserted_notify(struct ofono_sim *sim, ofono_bool_t inserted) notify(item->notify_data, sim->state); } - if (!inserted) + if (!inserted) { + sim_free_state(sim); + return; + } /* Perform SIM initialization according to 3GPP 31.102 Section 5.1.1.2 * The assumption here is that if sim manager is being initialized, @@ -1964,45 +2039,7 @@ static void sim_remove(struct ofono_atom *atom) if (sim->driver && sim->driver->remove) sim->driver->remove(sim); - if (sim->imsi) { - g_free(sim->imsi); - sim->imsi = NULL; - } - - if (sim->own_numbers) { - g_slist_foreach(sim->own_numbers, (GFunc)g_free, NULL); - g_slist_free(sim->own_numbers); - sim->own_numbers = NULL; - } - - if (sim->service_numbers) { - g_slist_foreach(sim->service_numbers, - (GFunc)service_number_free, NULL); - g_slist_free(sim->service_numbers); - sim->service_numbers = NULL; - } - - if (sim->efli) { - g_free(sim->efli); - sim->efli = NULL; - sim->efli_length = 0; - } - - if (sim->language_prefs) { - g_strfreev(sim->language_prefs); - sim->language_prefs = NULL; - } - - if (sim->simop_source) { - g_source_remove(sim->simop_source); - sim->simop_source = 0; - } - - if (sim->simop_q) { - g_queue_foreach(sim->simop_q, (GFunc)sim_file_op_free, NULL); - g_queue_free(sim->simop_q); - sim->simop_q = NULL; - } + sim_free_state(sim); g_free(sim); }