From a3d9123ca0e0632ce3da72cb2dad2ea999498bc8 Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Mon, 17 Aug 2009 16:56:32 -0500 Subject: Refactor ECC Support: Update when EFecc is read We should start with a default set of ECC numbers which are always available according to 22.101, even if no SIM present. Then when EFecc is read, we update the EmergencyNumbers property. According to 22.101 the 112 and 911 numbers must always be available. Since these numbers can also be stored on the SIM itself, we must avoid duplication. --- src/voicecall.c | 84 +++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 61 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/voicecall.c b/src/voicecall.c index 43d35ed8..c88e672a 100644 --- a/src/voicecall.c +++ b/src/voicecall.c @@ -49,6 +49,7 @@ struct voicecalls_data { GSList *release_list; GSList *multiparty_list; GSList *en_list; /* emergency number list */ + GSList *new_en_list; /* Emergency numbers being read from SIM */ struct ofono_voicecall_ops *ops; int flags; DBusMessage *pending; @@ -102,6 +103,13 @@ static gint call_compare(gconstpointer a, gconstpointer b) return 0; } +static void add_to_en_list(GSList **l, const char **list) +{ + int i = 0; + while (list[i]) + *l = g_slist_prepend(*l, g_strdup(list[i++])); +} + static const char *call_status_to_string(int status) { switch (status) { @@ -1676,7 +1684,7 @@ out: calls->pending = NULL; } -static gboolean in_default_en_list(char *en) +static gboolean in_default_en_list(const char *en) { int i = 0; while (default_en_list[i]) @@ -1706,17 +1714,35 @@ static void emit_en_list_changed(struct ofono_modem *modem) g_strfreev(list); } -static void add_to_list(GSList **l, const char **list) +static void set_new_ecc(struct ofono_modem *modem) { + struct voicecalls_data *calls = modem->voicecalls; + GSList *l; int i = 0; - while (list[i]) - *l = g_slist_prepend(*l, g_strdup(list[i++])); -} -static void construct_en_list(GSList **en_list) -{ - if (!*en_list) - add_to_list(en_list, default_en_list_no_sim); + g_slist_foreach(calls->en_list, (GFunc)g_free, NULL); + g_slist_free(calls->en_list); + calls->en_list = NULL; + + calls->en_list = calls->new_en_list; + calls->new_en_list = NULL; + + while (default_en_list[i]) { + GSList *l; + + for (l = calls->en_list; l; l = l->next) + if (!strcmp(l->data, default_en_list[i])) + break; + + if (l == NULL) + calls->en_list = g_slist_prepend(calls->en_list, + g_strdup(default_en_list[i])); + + i++; + } + + calls->en_list = g_slist_reverse(calls->en_list); + emit_en_list_changed(modem); } static void ecc_read_cb(struct ofono_modem *modem, int ok, @@ -1725,28 +1751,33 @@ static void ecc_read_cb(struct ofono_modem *modem, int ok, void *userdata) { struct voicecalls_data *calls = modem->voicecalls; - char *en; - static record_length_read; + int total; + char en[7]; + + DBG("%d", ok); + + if (!ok) + goto check; - if (!ok || structure != OFONO_SIM_FILE_STRUCTURE_FIXED || + if (structure != OFONO_SIM_FILE_STRUCTURE_FIXED || record_length < 4 || total_length < record_length) { ofono_error("Unable to read emergency numbers from SIM"); - construct_en_list(&calls->en_list); return; } - en = g_malloc(7); + total = total_length / record_length; extract_bcd_number(data, 3, en); - if (!in_default_en_list(en)) { - calls->en_list = g_slist_prepend(calls->en_list, en); - emit_en_list_changed(modem); - } else - g_free(en); + calls->new_en_list = g_slist_prepend(calls->new_en_list, g_strdup(en)); - record_length_read += record_length; - if (record_length_read == total_length) - construct_en_list(&calls->en_list); + if (record != total) + return; + +check: + if (calls->new_en_list == NULL) + return; + + set_new_ecc(modem); } static gboolean ecc_load(struct ofono_modem *modem) @@ -1789,7 +1820,14 @@ int ofono_voicecall_register(struct ofono_modem *modem, struct ofono_voicecall_o ofono_modem_add_interface(modem, VOICECALL_MANAGER_INTERFACE); - add_to_list(&modem->voicecalls->en_list, default_en_list); + /* Start out with the 22.101 mandated numbers, if we have a SIM and + * the SIM contains EFecc, then we update the list once we've read them + */ + add_to_en_list(&modem->voicecalls->en_list, default_en_list_no_sim); + add_to_en_list(&modem->voicecalls->en_list, default_en_list); + + /* TODO: We don't need to wait for the sim ready signal + */ ofono_sim_ready_notify_register(modem, ecc_load); if (ofono_sim_get_ready(modem)) ecc_load(modem); -- cgit v1.2.3