summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenis Kenzior <denkenz@gmail.com>2009-07-13 16:12:22 -0500
committerDenis Kenzior <denkenz@gmail.com>2009-07-14 15:45:05 -0500
commit5ea1326b00d330fdb0ab3697f60a3143ff380c90 (patch)
tree78647f2eaf1c2679c50b8a10e7ed960632b231d8
parentf2440ebd82510d65478bb0d38bd937a212ad69bf (diff)
downloadofono-5ea1326b00d330fdb0ab3697f60a3143ff380c90.tar.bz2
Move SPDI to network.c
-rw-r--r--src/network.c68
-rw-r--r--src/sim.c126
-rw-r--r--src/sim.h2
-rw-r--r--src/simutil.c92
-rw-r--r--src/simutil.h9
5 files changed, 157 insertions, 140 deletions
diff --git a/src/network.c b/src/network.c
index 629fc007..6ed30e10 100644
--- a/src/network.c
+++ b/src/network.c
@@ -66,6 +66,7 @@ struct network_registration_data {
int signal_strength;
char *spname;
GSList *pnn_list;
+ struct sim_spdi *spdi;
};
static void operator_list_callback(const struct ofono_error *error, int total,
@@ -352,9 +353,12 @@ static char *get_operator_display_name(struct ofono_modem *modem)
return name;
}
- home_or_spdi =
- (netreg->status == NETWORK_REGISTRATION_STATUS_REGISTERED) ||
- ofono_operator_in_spdi(modem, netreg->current_operator);
+ if (netreg->status == NETWORK_REGISTRATION_STATUS_REGISTERED)
+ home_or_spdi = TRUE;
+ else
+ home_or_spdi = sim_spdi_lookup(netreg->spdi,
+ netreg->current_operator->mcc,
+ netreg->current_operator->mnc);
if (home_or_spdi)
if (netreg->flags & NETWORK_REGISTRATION_FLAG_HOME_SHOW_PLMN)
@@ -1136,6 +1140,43 @@ static void sim_pnn_read_cb(struct ofono_modem *modem, int ok,
}
}
+static void sim_spdi_read_cb(struct ofono_modem *modem, int ok,
+ enum ofono_sim_file_structure structure,
+ int length, int record,
+ const unsigned char *data,
+ int record_length, void *userdata)
+{
+ struct network_registration_data *netreg = modem->network_registration;
+
+ if (!ok)
+ return;
+
+ if (structure != OFONO_SIM_FILE_STRUCTURE_TRANSPARENT)
+ return;
+
+ netreg->spdi = sim_spdi_new(data, length);
+
+ if (!netreg->current_operator)
+ return;
+
+ if (netreg->status == NETWORK_REGISTRATION_STATUS_ROAMING) {
+ DBusConnection *conn = dbus_gsm_connection();
+ const char *operator;
+
+ if (!sim_spdi_lookup(netreg->spdi,
+ netreg->current_operator->mcc,
+ netreg->current_operator->mnc))
+ return;
+
+ operator = get_operator_display_name(modem);
+
+ dbus_gsm_signal_property_changed(conn, modem->path,
+ NETWORK_REGISTRATION_INTERFACE,
+ "Operator", DBUS_TYPE_STRING,
+ &operator);
+ }
+}
+
static void sim_spn_read_cb(struct ofono_modem *modem, int ok,
enum ofono_sim_file_structure structure,
int length, int record,
@@ -1143,8 +1184,6 @@ static void sim_spn_read_cb(struct ofono_modem *modem, int ok,
int record_length, void *userdata)
{
struct network_registration_data *netreg = modem->network_registration;
- DBusConnection *conn = dbus_gsm_connection();
- const char *operator;
unsigned char dcbyte;
char *spn;
@@ -1183,21 +1222,26 @@ static void sim_spn_read_cb(struct ofono_modem *modem, int ok,
return;
}
+ netreg->spname = spn;
+ ofono_sim_read(modem, SIM_EFSPDI_FILEID, sim_spdi_read_cb, NULL);
+
if (dcbyte & SIM_EFSPN_DC_HOME_PLMN_BIT)
netreg->flags |= NETWORK_REGISTRATION_FLAG_HOME_SHOW_PLMN;
if (!(dcbyte & SIM_EFSPN_DC_ROAMING_SPN_BIT))
netreg->flags |= NETWORK_REGISTRATION_FLAG_ROAMING_SHOW_SPN;
- if (!netreg->current_operator)
- return;
+ if (netreg->current_operator) {
+ DBusConnection *conn = dbus_gsm_connection();
+ const char *operator;
- operator = get_operator_display_name(modem);
+ operator = get_operator_display_name(modem);
- dbus_gsm_signal_property_changed(conn, modem->path,
- NETWORK_REGISTRATION_INTERFACE,
- "Operator", DBUS_TYPE_STRING,
- &operator);
+ dbus_gsm_signal_property_changed(conn, modem->path,
+ NETWORK_REGISTRATION_INTERFACE,
+ "Operator", DBUS_TYPE_STRING,
+ &operator);
+ }
}
static void sim_ready(struct ofono_modem *modem)
diff --git a/src/sim.c b/src/sim.c
index 36c3e818..e22cac83 100644
--- a/src/sim.c
+++ b/src/sim.c
@@ -245,132 +245,6 @@ check:
}
}
-struct sim_operator {
- char mcc[OFONO_MAX_MCC_LENGTH + 1];
- char mnc[OFONO_MAX_MNC_LENGTH + 1];
-};
-
-static void parse_mcc_mnc(struct sim_operator *oper, const guint8 *bcd)
-{
- char *mcc = oper->mcc;
- char *mnc = oper->mnc;
- guint8 digit;
-
- digit = (bcd[0] >> 0) & 0xf;
- if (digit != 0xf)
- *mcc ++ = '0' + digit;
- digit = (bcd[0] >> 4) & 0xf;
- if (digit != 0xf)
- *mcc ++ = '0' + digit;
- digit = (bcd[1] >> 0) & 0xf;
- if (digit != 0xf)
- *mcc ++ = '0' + digit;
- digit = (bcd[2] >> 0) & 0xf;
- if (digit != 0xf)
- *mnc ++ = '0' + digit;
- digit = (bcd[2] >> 4) & 0xf;
- if (digit != 0xf)
- *mnc ++ = '0' + digit;
- digit = (bcd[1] >> 4) & 0xf;
- if (digit != 0xf)
- *mnc ++ = '0' + digit;
-}
-
-static struct sim_operator *sim_operator_alloc(const guint8 *bcd)
-{
- struct sim_operator *spdi = g_new0(struct sim_operator, 1);
-
- parse_mcc_mnc(spdi, bcd);
-
- return spdi;
-}
-
-static gint spdi_operator_compare(gconstpointer a, gconstpointer b)
-{
- const struct sim_operator *opa = a;
- const struct sim_operator *opb = b;
- gint r;
-
- if ((r = strcmp(opa->mcc, opb->mcc)))
- return r;
-
- return strcmp(opa->mnc, opb->mnc);
-}
-
-gboolean ofono_operator_in_spdi(struct ofono_modem *modem,
- const struct ofono_network_operator *op)
-{
- struct sim_manager_data *sim = modem->sim_manager;
- struct sim_operator spdi_op;
-
- if (!sim)
- return FALSE;
-
- g_strlcpy(spdi_op.mcc, op->mcc, sizeof(spdi_op.mcc));
- g_strlcpy(spdi_op.mnc, op->mnc, sizeof(spdi_op.mnc));
-
- return g_slist_find_custom(sim->spdi,
- &spdi_op, spdi_operator_compare) != NULL;
-}
-
-static void sim_spdi_read_cb(const struct ofono_error *error,
- const unsigned char *spdidata,
- int length, void *data)
-{
- struct ofono_modem *modem = data;
- struct sim_manager_data *sim = modem->sim_manager;
- const guint8 *plmn_list;
- GSList *l;
-
- if (error->type != OFONO_ERROR_TYPE_NO_ERROR || length <= 5)
- return;
-
- plmn_list = ber_tlv_find_by_tag(spdidata, 0x80, length, &length);
- if (!plmn_list) {
- ofono_debug("Couldn't parse the EF-SPDI contents as a TLV");
- return;
- }
-
- for (length /= 3; length --; plmn_list += 3) {
- if ((plmn_list[0] & plmn_list[1] & plmn_list[2]) == 0xff)
- continue;
-
- sim->spdi = g_slist_insert_sorted(sim->spdi,
- sim_operator_alloc(plmn_list),
- spdi_operator_compare);
- }
-
- if (sim->spdi)
- for (l = sim->update_spn_notify; l; l = l->next)
- sim_spn_notify(modem, l->data);
-}
-
-static void sim_spdi_info_cb(const struct ofono_error *error, int length,
- enum ofono_sim_file_structure structure,
- int dummy, void *data)
-{
- struct ofono_modem *modem = data;
- struct sim_manager_data *sim = modem->sim_manager;
-
- if (error->type != OFONO_ERROR_TYPE_NO_ERROR || length <= 5 ||
- structure != OFONO_SIM_FILE_STRUCTURE_TRANSPARENT)
- return;
-
- sim->ops->read_file_transparent(modem, SIM_EFSPDI_FILEID, 0, length,
- sim_spdi_read_cb, modem);
-}
-
-static gboolean sim_retrieve_spdi(void *user_data)
-{
- struct ofono_modem *modem = user_data;
- struct sim_manager_data *sim = modem->sim_manager;
-
- sim->ops->read_file_info(modem, SIM_EFSPDI_FILEID,
- sim_spdi_info_cb, modem);
-
- return FALSE;
-}
-
struct opl_operator {
struct sim_operator mcc_mnc;
guint16 lac_tac_low;
diff --git a/src/sim.h b/src/sim.h
index df29be29..b0c02bf4 100644
--- a/src/sim.h
+++ b/src/sim.h
@@ -30,8 +30,6 @@ typedef void (*ofono_sim_file_read_cb_t)(struct ofono_modem *modem, int ok,
void ofono_sim_manager_init(struct ofono_modem *modem);
void ofono_sim_manager_exit(struct ofono_modem *modem);
-gboolean ofono_operator_in_spdi(struct ofono_modem *modem,
- const struct ofono_network_operator *op);
const char *ofono_sim_get_imsi(struct ofono_modem *modem);
int ofono_sim_ready_notify_register(struct ofono_modem *modem,
diff --git a/src/simutil.c b/src/simutil.c
index 253970bc..57d040b4 100644
--- a/src/simutil.c
+++ b/src/simutil.c
@@ -27,9 +27,15 @@
#include <glib.h>
+#include "driver.h"
#include "simutil.h"
#include "util.h"
+struct spdi_operator {
+ char mcc[OFONO_MAX_MCC_LENGTH + 1];
+ char mnc[OFONO_MAX_MNC_LENGTH + 1];
+};
+
/* Parse ASN.1 Basic Encoding Rules TLVs per ISO/IEC 7816 */
const guint8 *ber_tlv_find_by_tag(const guint8 *pdu, guint8 in_tag,
int in_len, int *out_len)
@@ -156,3 +162,89 @@ void sim_pnn_operator_free(struct sim_pnn_operator *oper)
g_free(oper->shortname);
g_free(oper->longname);
}
+
+static void parse_mcc_mnc(const guint8 *bcd, char *mcc, char *mnc)
+{
+ guint8 digit;
+
+ digit = (bcd[0] >> 0) & 0xf;
+ if (digit != 0xf)
+ *mcc ++ = '0' + digit;
+ digit = (bcd[0] >> 4) & 0xf;
+ if (digit != 0xf)
+ *mcc ++ = '0' + digit;
+ digit = (bcd[1] >> 0) & 0xf;
+ if (digit != 0xf)
+ *mcc ++ = '0' + digit;
+ digit = (bcd[2] >> 0) & 0xf;
+ if (digit != 0xf)
+ *mnc ++ = '0' + digit;
+ digit = (bcd[2] >> 4) & 0xf;
+ if (digit != 0xf)
+ *mnc ++ = '0' + digit;
+ digit = (bcd[1] >> 4) & 0xf;
+ if (digit != 0xf)
+ *mnc ++ = '0' + digit;
+}
+
+static gint spdi_operator_compare(gconstpointer a, gconstpointer b)
+{
+ const struct spdi_operator *opa = a;
+ const struct spdi_operator *opb = b;
+ gint r;
+
+ if (r = strcmp(opa->mcc, opb->mcc))
+ return r;
+
+ return strcmp(opa->mnc, opb->mnc);
+}
+
+struct sim_spdi *sim_spdi_new(const guint8 *tlv, int length)
+{
+ const guint8 *plmn_list;
+ struct sim_spdi *spdi;
+ struct spdi_operator *oper;
+ int tlv_length;
+
+ if (length <= 5)
+ return NULL;
+
+ plmn_list = ber_tlv_find_by_tag(tlv, 0x80, length, &tlv_length);
+
+ if (!plmn_list)
+ return NULL;
+
+ spdi = g_new0(struct sim_spdi, 1);
+
+ for (tlv_length /= 3; tlv_length--; plmn_list += 3) {
+ if ((plmn_list[0] & plmn_list[1] & plmn_list[2]) == 0xff)
+ continue;
+
+ oper = g_new0(struct spdi_operator, 1);
+
+ parse_mcc_mnc(plmn_list, oper->mcc, oper->mnc);
+ spdi->operators = g_slist_insert_sorted(spdi->operators, oper,
+ spdi_operator_compare);
+ }
+
+ return spdi;
+}
+
+gboolean sim_spdi_lookup(struct sim_spdi *spdi,
+ const char *mcc, const char *mnc)
+{
+ struct spdi_operator spdi_op;
+
+ g_strlcpy(spdi_op.mcc, mcc, sizeof(spdi_op.mcc));
+ g_strlcpy(spdi_op.mnc, mnc, sizeof(spdi_op.mnc));
+
+ return g_slist_find_custom(spdi->operators, &spdi_op,
+ spdi_operator_compare) != NULL;
+}
+
+void sim_spdi_free(struct sim_spdi *spdi)
+{
+ g_slist_foreach(spdi->operators, (GFunc)g_free, NULL);
+ g_slist_free(spdi->operators);
+ g_free(spdi);
+}
diff --git a/src/simutil.h b/src/simutil.h
index 92c956c7..eff2d99e 100644
--- a/src/simutil.h
+++ b/src/simutil.h
@@ -38,6 +38,10 @@ struct sim_pnn_operator {
char *info;
};
+struct sim_spdi {
+ GSList *operators;
+};
+
void sim_pnn_operator_free(struct sim_pnn_operator *oper);
const guint8 *ber_tlv_find_by_tag(const guint8 *pdu, guint8 in_tag,
@@ -45,3 +49,8 @@ const guint8 *ber_tlv_find_by_tag(const guint8 *pdu, guint8 in_tag,
char *sim_network_name_parse(const unsigned char *buffer, int length,
gboolean *add_ci);
struct sim_pnn_operator *sim_pnn_operator_parse(const guint8 *tlv, int length);
+
+struct sim_spdi *sim_spdi_new(const guint8 *tlv, int length);
+gboolean sim_spdi_lookup(struct sim_spdi *spdi,
+ const char *mcc, const char *mnc);
+void sim_spdi_free(struct sim_spdi *spdi);