From ee02b14836d7e30b45ee6fd62da6a8135c94c9dd Mon Sep 17 00:00:00 2001 From: Andrzej Zaborowski Date: Thu, 17 Sep 2009 22:43:22 +0200 Subject: [PATCH] Do PIN authentication This adds checking whether PIN is required during SIM initialisation and delaying the sim ready notifications until after correct PIN is given. --- drivers/atmodem/sim.c | 241 +++++++++++++++++++++++++++++++++++ include/sim.h | 19 +++ include/types.h | 20 +++ src/sim.c | 286 +++++++++++++++++++++++++++++++++++++++++- src/simutil.c | 36 ++++++ src/simutil.h | 3 + 6 files changed, 604 insertions(+), 1 deletion(-) diff --git a/drivers/atmodem/sim.c b/drivers/atmodem/sim.c index c629ec1d..b6f34c20 100644 --- a/drivers/atmodem/sim.c +++ b/drivers/atmodem/sim.c @@ -398,6 +398,242 @@ error: CALLBACK_WITH_FAILURE(cb, NULL, data); } +static struct { + enum ofono_passwd_type type; + const char *name; +} const at_sim_name[] = { + { OFONO_PASSWD_SIM_PIN, "SIM PIN" }, + { OFONO_PASSWD_SIM_PUK, "SIM PUK" }, + { OFONO_PASSWD_PHSIM_PIN, "PH-SIM PIN" }, + { OFONO_PASSWD_PHFSIM_PIN, "PH-FSIM PIN" }, + { OFONO_PASSWD_PHFSIM_PUK, "PH-FSIM PUK" }, + { OFONO_PASSWD_SIM_PIN2, "SIM PIN2" }, + { OFONO_PASSWD_SIM_PUK2, "SIM PUK2" }, + { OFONO_PASSWD_PHNET_PIN, "PH-NET PIN" }, + { OFONO_PASSWD_PHNET_PUK, "PH-NET PUK" }, + { OFONO_PASSWD_PHNETSUB_PIN, "PH-NETSUB PIN" }, + { OFONO_PASSWD_PHNETSUB_PUK, "PH-NETSUB PUK" }, + { OFONO_PASSWD_PHSP_PIN, "PH-SP PIN" }, + { OFONO_PASSWD_PHSP_PUK, "PH-SP PUK" }, + { OFONO_PASSWD_PHCORP_PIN, "PH-CORP PIN" }, + { OFONO_PASSWD_PHCORP_PUK, "PH-CORP PUK" }, +}; + +static void at_cpin_cb(gboolean ok, GAtResult *result, gpointer user_data) +{ + struct cb_data *cbd = user_data; + GAtResultIter iter; + ofono_sim_passwd_cb_t cb = cbd->cb; + struct ofono_error error; + const char *pin_required; + int pin_type; + int i; + int len = sizeof(at_sim_name) / sizeof(*at_sim_name); + + dump_response("at_cpin_cb", ok, result); + decode_at_error(&error, g_at_result_final_response(result)); + + if (!ok) { + cb(&error, -1, cbd->data); + return; + } + + g_at_result_iter_init(&iter, result); + + if (!g_at_result_iter_next(&iter, "+CPIN:")) { + CALLBACK_WITH_FAILURE(cb, -1, cbd->data); + return; + } + + g_at_result_iter_next_unquoted_string(&iter, &pin_required); + + pin_type = -1; + if (!strcmp(pin_required, "READY")) + pin_type = OFONO_PASSWD_NONE; + else + for (i = 0; i < len; i++) + if (!strcmp(pin_required, at_sim_name[i].name)) { + pin_type = at_sim_name[i].type; + break; + } + + if (pin_type == -1) { + CALLBACK_WITH_FAILURE(cb, -1, cbd->data); + return; + } + + ofono_debug("crsm_pin_cb: %s", pin_required); + + cb(&error, pin_type, cbd->data); +} + +static void at_pin_query(struct ofono_sim *sim, ofono_sim_passwd_cb_t cb, + void *data) +{ + GAtChat *chat = ofono_sim_get_data(sim); + struct cb_data *cbd = cb_data_new(cb, data); + + if (!cbd) + goto error; + + if (g_at_chat_send(chat, "AT+CPIN?", NULL, + at_cpin_cb, cbd, g_free) > 0) + return; + +error: + if (cbd) + g_free(cbd); + + CALLBACK_WITH_FAILURE(cb, -1, data); +} + +static void at_lock_unlock_cb(gboolean ok, GAtResult *result, + gpointer user_data) +{ + struct cb_data *cbd = user_data; + ofono_sim_lock_unlock_cb_t cb = cbd->cb; + struct ofono_error error; + + dump_response("at_lock_unlock_cb", ok, result); + decode_at_error(&error, g_at_result_final_response(result)); + + cb(&error, cbd->data); +} + +static void at_pin_send(struct ofono_sim *sim, const char *passwd, + ofono_sim_lock_unlock_cb_t cb, void *data) +{ + GAtChat *chat = ofono_sim_get_data(sim); + struct cb_data *cbd = cb_data_new(cb, data); + char buf[64]; + int ret; + + if (!cbd) + goto error; + + snprintf(buf, sizeof(buf), "AT+CPIN=\"%s\"", passwd); + + ret = g_at_chat_send(chat, buf, NULL, at_lock_unlock_cb, cbd, g_free); + + memset(buf, 0, sizeof(buf)); + + if (ret > 0) + return; + +error: + if (cbd) + g_free(cbd); + + CALLBACK_WITH_FAILURE(cb, data); +} + +static void at_pin_send_puk(struct ofono_sim *sim, const char *puk, + const char *passwd, + ofono_sim_lock_unlock_cb_t cb, void *data) +{ + GAtChat *chat = ofono_sim_get_data(sim); + struct cb_data *cbd = cb_data_new(cb, data); + char buf[64]; + int ret; + + if (!cbd) + goto error; + + snprintf(buf, sizeof(buf), "AT+CPIN=\"%s\",\"%s\"", puk, passwd); + + ret = g_at_chat_send(chat, buf, NULL, at_lock_unlock_cb, cbd, g_free); + + memset(buf, 0, sizeof(buf)); + + if (ret > 0) + return; + +error: + if (cbd) + g_free(cbd); + + CALLBACK_WITH_FAILURE(cb, data); +} + +static const char *const at_clck_cpwd_fac[] = { + [OFONO_PASSWD_SIM_PIN] = "SC", + [OFONO_PASSWD_SIM_PIN2] = "P2", + [OFONO_PASSWD_PHSIM_PIN] = "PS", + [OFONO_PASSWD_PHFSIM_PIN] = "PF", + [OFONO_PASSWD_PHNET_PIN] = "PN", + [OFONO_PASSWD_PHNETSUB_PIN] = "PU", + [OFONO_PASSWD_PHSP_PIN] = "PP", + [OFONO_PASSWD_PHCORP_PIN] = "PC", +}; + +static void at_pin_enable(struct ofono_sim *sim, int passwd_type, int enable, + const char *passwd, + ofono_sim_lock_unlock_cb_t cb, void *data) +{ + GAtChat *chat = ofono_sim_get_data(sim); + struct cb_data *cbd = cb_data_new(cb, data); + char buf[64]; + int ret; + int len = sizeof(at_clck_cpwd_fac) / sizeof(*at_clck_cpwd_fac); + + if (!cbd) + goto error; + + if (passwd_type < 0 || passwd_type >= len || + !at_clck_cpwd_fac[passwd_type]) + goto error; + + snprintf(buf, sizeof(buf), "AT+CLCK=\"%s\",%i,\"%s\"", + at_clck_cpwd_fac[passwd_type], enable ? 1 : 0, passwd); + + ret = g_at_chat_send(chat, buf, NULL, at_lock_unlock_cb, cbd, g_free); + + memset(buf, 0, sizeof(buf)); + + if (ret > 0) + return; + +error: + if (cbd) + g_free(cbd); + + CALLBACK_WITH_FAILURE(cb, data); +} + +static void at_change_passwd(struct ofono_sim *sim, int passwd_type, + const char *old, const char *new, + ofono_sim_lock_unlock_cb_t cb, void *data) +{ + GAtChat *chat = ofono_sim_get_data(sim); + struct cb_data *cbd = cb_data_new(cb, data); + char buf[64]; + int ret; + int len = sizeof(at_clck_cpwd_fac) / sizeof(*at_clck_cpwd_fac); + + if (!cbd) + goto error; + + if (passwd_type < 0 || passwd_type >= len || + !at_clck_cpwd_fac[passwd_type]) + goto error; + + snprintf(buf, sizeof(buf), "AT+CPWD=\"%s\",\"%s\",\"%s\"", + at_clck_cpwd_fac[passwd_type], old, new); + + ret = g_at_chat_send(chat, buf, NULL, at_lock_unlock_cb, cbd, g_free); + + memset(buf, 0, sizeof(buf)); + + if (ret > 0) + return; + +error: + if (cbd) + g_free(cbd); + + CALLBACK_WITH_FAILURE(cb, data); +} + static gboolean at_sim_register(gpointer user) { struct ofono_sim *sim = user; @@ -434,6 +670,11 @@ static struct ofono_sim_driver driver = { .write_file_linear = at_sim_update_record, .write_file_cyclic = at_sim_update_cyclic, .read_imsi = at_read_imsi, + .query_passwd_state = at_pin_query, + .send_passwd = at_pin_send, + .reset_passwd = at_pin_send_puk, + .lock = at_pin_enable, + .change_passwd = at_change_passwd, }; void at_sim_init() diff --git a/include/sim.h b/include/sim.h index 1da486c7..751ae101 100644 --- a/include/sim.h +++ b/include/sim.h @@ -64,6 +64,12 @@ typedef void (*ofono_sim_file_read_cb_t)(int ok, typedef void (*ofono_sim_file_write_cb_t)(int ok, void *userdata); +typedef void (*ofono_sim_passwd_cb_t)(const struct ofono_error *error, + int passwd_type, void *data); + +typedef void (*ofono_sim_lock_unlock_cb_t)(const struct ofono_error *error, + void *data); + struct ofono_sim_driver { const char *name; int (*probe)(struct ofono_sim *sim, unsigned int vendor, void *data); @@ -90,6 +96,19 @@ struct ofono_sim_driver { ofono_sim_write_cb_t cb, void *data); void (*read_imsi)(struct ofono_sim *sim, ofono_sim_imsi_cb_t cb, void *data); + void (*query_passwd_state)(struct ofono_sim *sim, + ofono_sim_passwd_cb_t cb, void *data); + void (*send_passwd)(struct ofono_sim *sim, const char *passwd, + ofono_sim_lock_unlock_cb_t cb, void *data); + void (*reset_passwd)(struct ofono_sim *sim, const char *puk, + const char *passwd, + ofono_sim_lock_unlock_cb_t cb, void *data); + void (*change_passwd)(struct ofono_sim *sim, int passwd_type, + const char *old, const char *new, + ofono_sim_lock_unlock_cb_t cb, void *data); + void (*lock)(struct ofono_sim *sim, int passwd_type, int enable, + const char *passwd, + ofono_sim_lock_unlock_cb_t cb, void *data); }; int ofono_sim_driver_register(const struct ofono_sim_driver *d); diff --git a/include/types.h b/include/types.h index 6a9681d0..82a3216a 100644 --- a/include/types.h +++ b/include/types.h @@ -91,6 +91,26 @@ struct ofono_call { int clip_validity; }; +enum ofono_passwd_type { + OFONO_PASSWD_NONE = 0, + + OFONO_PASSWD_SIM_PIN, + OFONO_PASSWD_SIM_PUK, + OFONO_PASSWD_PHSIM_PIN, + OFONO_PASSWD_PHFSIM_PIN, + OFONO_PASSWD_PHFSIM_PUK, + OFONO_PASSWD_SIM_PIN2, + OFONO_PASSWD_SIM_PUK2, + OFONO_PASSWD_PHNET_PIN, + OFONO_PASSWD_PHNET_PUK, + OFONO_PASSWD_PHNETSUB_PIN, + OFONO_PASSWD_PHNETSUB_PUK, + OFONO_PASSWD_PHSP_PIN, + OFONO_PASSWD_PHSP_PUK, + OFONO_PASSWD_PHCORP_PIN, + OFONO_PASSWD_PHCORP_PUK, +}; + #ifdef __cplusplus } #endif diff --git a/src/sim.c b/src/sim.c index 1669d94c..2ff2550b 100644 --- a/src/sim.c +++ b/src/sim.c @@ -55,6 +55,7 @@ static GSList *g_drivers = NULL; static gboolean sim_op_next(gpointer user_data); static gboolean sim_op_retrieve_next(gpointer user); static void sim_own_numbers_update(struct ofono_sim *sim); +static void sim_pin_check(struct ofono_sim *sim); struct sim_file_op { int id; @@ -77,6 +78,7 @@ struct ofono_sim { GSList *service_numbers; gboolean sdn_ready; gboolean ready; + int pin_type; char **language_prefs; GQueue *simop_q; gint simop_source; @@ -89,6 +91,7 @@ struct ofono_sim { const struct ofono_sim_driver *driver; void *driver_data; struct ofono_atom *atom; + DBusMessage *pending; }; struct msisdn_set_request { @@ -98,6 +101,12 @@ struct msisdn_set_request { DBusMessage *msg; }; +struct pin_enable_request { + struct ofono_sim *sim; + int type; + char *passwd; +}; + struct service_number { char *id; struct ofono_phone_number ph; @@ -167,6 +176,7 @@ static DBusMessage *sim_get_properties(DBusConnection *conn, DBusMessageIter dict; char **own_numbers; char **service_numbers; + const char *pin_name; reply = dbus_message_new_method_return(msg); if (!reply) @@ -206,6 +216,11 @@ static DBusMessage *sim_get_properties(DBusConnection *conn, DBUS_TYPE_STRING, &sim->language_prefs); + pin_name = sim_passwd_name(sim->pin_type); + ofono_dbus_dict_append(&dict, "PinRequired", + DBUS_TYPE_STRING, + (void *) &pin_name); + dbus_message_iter_close_container(&iter, &dict); return reply; @@ -354,10 +369,234 @@ error: return __ofono_error_invalid_args(msg); } +static void sim_enable_pin_cb(const struct ofono_error *error, void *data) +{ + struct ofono_sim *sim = data; + DBusMessage *reply; + + if (error->type != OFONO_ERROR_TYPE_NO_ERROR) + reply = __ofono_error_failed(sim->pending); + else + reply = dbus_message_new_method_return(sim->pending); + + __ofono_dbus_pending_reply(&sim->pending, reply); +} + +static void sim_change_pin_cb(const struct ofono_error *error, void *data) +{ + struct pin_enable_request *req = data; + struct ofono_sim *sim = req->sim; + + if (error->type != OFONO_ERROR_TYPE_NO_ERROR) { + __ofono_dbus_pending_reply(&sim->pending, + __ofono_error_failed(sim->pending)); + goto cleanup; + } + + if (!sim->driver->lock) { + __ofono_dbus_pending_reply(&sim->pending, + dbus_message_new_method_return(sim->pending)); + goto cleanup; + } + + sim->driver->lock(sim, req->type, 1, req->passwd, + sim_enable_pin_cb, sim); + +cleanup: + memset(req->passwd, 0, strlen(req->passwd)); + g_free(req->passwd); + g_free(req); +} + +static DBusMessage *sim_change_pin(DBusConnection *conn, DBusMessage *msg, + void *data) +{ + struct ofono_sim *sim = data; + struct pin_enable_request *req; + DBusMessageIter iter; + enum ofono_passwd_type type; + const char *typestr; + const char *old; + const char *new; + + if (sim->pending) + return __ofono_error_busy(msg); + + if (!dbus_message_iter_init(msg, &iter)) + return __ofono_error_invalid_args(msg); + + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return __ofono_error_invalid_args(msg); + + dbus_message_iter_get_basic(&iter, &typestr); + + type = sim_string_to_passwd(typestr); + if (type == OFONO_PASSWD_NONE) + return __ofono_error_invalid_format(msg); + + dbus_message_iter_next(&iter); + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return __ofono_error_invalid_args(msg); + + dbus_message_iter_get_basic(&iter, &old); + + if (!is_valid_pin(old)) + return __ofono_error_invalid_format(msg); + + dbus_message_iter_next(&iter); + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return __ofono_error_invalid_args(msg); + + dbus_message_iter_get_basic(&iter, &new); + + if (new[0] != '\0' && strcmp(new, old)) { + if (!sim->driver->change_passwd) + return __ofono_error_not_implemented(msg); + + if (!is_valid_pin(new)) + return __ofono_error_invalid_format(msg); + + req = g_new0(struct pin_enable_request, 1); + + req->sim = sim; + req->type = type; + req->passwd = g_strdup(new); + + sim->pending = dbus_message_ref(msg); + + sim->driver->change_passwd(sim, type, old, new, + sim_change_pin_cb, req); + } else { + if (!sim->driver->lock) + return __ofono_error_not_implemented(msg); + + sim->pending = dbus_message_ref(msg); + sim->driver->lock(sim, type, new[0] != '\0', + old, sim_enable_pin_cb, sim); + } + + return NULL; +} + +static void sim_enter_pin_cb(const struct ofono_error *error, void *data) +{ + struct ofono_sim *sim = data; + DBusMessage *reply; + + if (error->type != OFONO_ERROR_TYPE_NO_ERROR) + reply = __ofono_error_failed(sim->pending); + else + reply = dbus_message_new_method_return(sim->pending); + + __ofono_dbus_pending_reply(&sim->pending, reply); + + sim_pin_check(sim); +} + +static DBusMessage *sim_enter_pin(DBusConnection *conn, DBusMessage *msg, + void *data) +{ + struct ofono_sim *sim = data; + DBusMessageIter iter; + const char *typestr; + int type; + const char *pin; + + if (!sim->driver->send_passwd) + return __ofono_error_not_implemented(msg); + + if (sim->pending) + return __ofono_error_busy(msg); + + if (!dbus_message_iter_init(msg, &iter)) + return __ofono_error_invalid_args(msg); + + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return __ofono_error_invalid_args(msg); + + dbus_message_iter_get_basic(&iter, &typestr); + + type = sim_string_to_passwd(typestr); + if (type == OFONO_PASSWD_NONE || type != sim->pin_type) + return __ofono_error_invalid_format(msg); + + dbus_message_iter_next(&iter); + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return __ofono_error_invalid_args(msg); + + dbus_message_iter_get_basic(&iter, &pin); + + if (!is_valid_pin(pin)) + return __ofono_error_invalid_format(msg); + + sim->pending = dbus_message_ref(msg); + sim->driver->send_passwd(sim, pin, sim_enter_pin_cb, sim); + + return NULL; +} + +static DBusMessage *sim_reset_pin(DBusConnection *conn, DBusMessage *msg, + void *data) +{ + struct ofono_sim *sim = data; + DBusMessageIter iter; + const char *typestr; + int type; + const char *puk; + const char *pin; + + if (!sim->driver->reset_passwd) + return __ofono_error_not_implemented(msg); + + if (sim->pending) + return __ofono_error_busy(msg); + + if (!dbus_message_iter_init(msg, &iter)) + return __ofono_error_invalid_args(msg); + + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return __ofono_error_invalid_args(msg); + + dbus_message_iter_get_basic(&iter, &typestr); + + type = sim_string_to_passwd(typestr); + if (type == OFONO_PASSWD_NONE || type != sim->pin_type) + return __ofono_error_invalid_format(msg); + + dbus_message_iter_next(&iter); + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return __ofono_error_invalid_args(msg); + + dbus_message_iter_get_basic(&iter, &puk); + + if (!is_valid_pin(puk)) + return __ofono_error_invalid_format(msg); + + dbus_message_iter_next(&iter); + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return __ofono_error_invalid_args(msg); + + dbus_message_iter_get_basic(&iter, &pin); + + if (!is_valid_pin(pin)) + return __ofono_error_invalid_format(msg); + + sim->pending = dbus_message_ref(msg); + sim->driver->reset_passwd(sim, puk, pin, sim_enter_pin_cb, sim); + + return NULL; +} + static GDBusMethodTable sim_methods[] = { { "GetProperties", "", "a{sv}", sim_get_properties }, { "SetProperty", "sv", "", sim_set_property, G_DBUS_METHOD_FLAG_ASYNC }, + { "ChangePin", "sss", "", sim_change_pin, + G_DBUS_METHOD_FLAG_ASYNC }, + { "EnterPin", "ss", "", sim_enter_pin, + G_DBUS_METHOD_FLAG_ASYNC }, + { "ResetPin", "sss", "", sim_reset_pin, + G_DBUS_METHOD_FLAG_ASYNC }, { } }; @@ -613,6 +852,51 @@ static void sim_retrieve_imsi(struct ofono_sim *sim) sim->driver->read_imsi(sim, sim_imsi_cb, sim); } +static void sim_pin_check_done(struct ofono_sim *sim) +{ + sim_retrieve_imsi(sim); +} + +static void sim_pin_query_cb(const struct ofono_error *error, int pin_type, + void *data) +{ + struct ofono_sim *sim = data; + DBusConnection *conn = ofono_dbus_get_connection(); + const char *path = __ofono_atom_get_path(sim->atom); + const char *pin_name; + + if (error->type != OFONO_ERROR_TYPE_NO_ERROR) { + ofono_error("Querying PIN authentication state failed"); + + goto checkdone; + } + + if (sim->pin_type != pin_type) { + sim->pin_type = pin_type; + pin_name = sim_passwd_name(pin_type); + + ofono_dbus_signal_property_changed(conn, path, + SIM_MANAGER_INTERFACE, + "PinRequired", + DBUS_TYPE_STRING, + &pin_name); + } + +checkdone: + if (pin_type == OFONO_PASSWD_NONE) + sim_pin_check_done(sim); +} + +static void sim_pin_check(struct ofono_sim *sim) +{ + if (!sim->driver->query_passwd_state) { + sim_pin_check_done(sim); + return; + } + + sim->driver->query_passwd_state(sim, sim_pin_query_cb, sim); +} + static void sim_efli_read_cb(int ok, enum ofono_sim_file_structure structure, int length, int record, @@ -1465,7 +1749,7 @@ void ofono_sim_register(struct ofono_sim *sim) * in the EFust */ sim_retrieve_efli_and_efpl(sim); - sim_retrieve_imsi(sim); + sim_pin_check(sim); } void ofono_sim_remove(struct ofono_sim *sim) diff --git a/src/simutil.c b/src/simutil.c index b80e014d..e1b0f2aa 100644 --- a/src/simutil.c +++ b/src/simutil.c @@ -488,3 +488,39 @@ void sim_adn_build(unsigned char *data, int length, /* Ext1 unused */ *data++ = 0xff; } + +static const char *const passwd_name[] = { + [OFONO_PASSWD_NONE] = "none", + [OFONO_PASSWD_SIM_PIN] = "pin", + [OFONO_PASSWD_SIM_PUK] = "puk", + [OFONO_PASSWD_PHSIM_PIN] = "phone", + [OFONO_PASSWD_PHFSIM_PIN] = "firstphone", + [OFONO_PASSWD_PHFSIM_PUK] = "firstphonepuk", + [OFONO_PASSWD_SIM_PIN2] = "pin2", + [OFONO_PASSWD_SIM_PUK2] = "puk2", + [OFONO_PASSWD_PHNET_PIN] = "network", + [OFONO_PASSWD_PHNET_PUK] = "networkpuk", + [OFONO_PASSWD_PHNETSUB_PIN] = "netsub", + [OFONO_PASSWD_PHNETSUB_PUK] = "netsubpuk", + [OFONO_PASSWD_PHSP_PIN] = "service", + [OFONO_PASSWD_PHSP_PUK] = "servicepuk", + [OFONO_PASSWD_PHCORP_PIN] = "corp", + [OFONO_PASSWD_PHCORP_PUK] = "corppuk", +}; + +const char *sim_passwd_name(enum ofono_passwd_type type) +{ + return passwd_name[type]; +} + +enum ofono_passwd_type sim_string_to_passwd(const char *name) +{ + int len = sizeof(passwd_name) / sizeof(*passwd_name); + int i; + + for (i = 0; i < len; i++) + if (!strcmp(passwd_name[i], name)) + return i; + + return OFONO_PASSWD_NONE; +} diff --git a/src/simutil.h b/src/simutil.h index 2cd3b738..df84416f 100644 --- a/src/simutil.h +++ b/src/simutil.h @@ -93,3 +93,6 @@ gboolean sim_adn_parse(const unsigned char *data, int length, void sim_adn_build(unsigned char *data, int length, const struct ofono_phone_number *ph, const char *identifier); + +const char *sim_passwd_name(enum ofono_passwd_type type); +enum ofono_passwd_type sim_string_to_passwd(const char *name);