All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrzej Zaborowski <andrew.zaborowski@intel.com>
To: ofono@ofono.org
Subject: Re: [PATCH] [RFC] Do the PIN check in SIMManager
Date: Thu, 17 Sep 2009 20:57:21 +0200	[thread overview]
Message-ID: <fb249edb0909171157w3b00b220o2538793c09016d81@mail.gmail.com> (raw)
In-Reply-To: <fb249edb0909071941k4b95beb6o586af6bcb7765992@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 602 bytes --]

And here's a version that implements most of what's specified in
doc/sim-api.txt.  There are two caveats: when you re-enable SIM PIN
authentication, you have to give the old password from before it was
changed to "", i.e to disable and enable SIM PIN, do:
SimManager.ChangePin("pin", "1234", "")
SimManager.ChangePin("pin", "1234", "1234")

rather than the more logical

SimManager.ChangePin("pin", "1234", "")
SimManager.ChangePin("pin, "", "1234)

The other problem is that if changing the password succeeds but
enabling authentiation fails, ChangePin still returns failure.

Regards

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0002-Do-PIN-authentication.patch --]
[-- Type: text/x-patch, Size: 20303 bytes --]

From 7209a4406224a0c4f8ad1c241ea355ee00e1fb5b Mon Sep 17 00:00:00 2001
From: Andrzej Zaborowski <andrew.zaborowski@intel.com>
Date: Thu, 17 Sep 2009 22:43:22 +0200
Subject: [PATCH 2/2] 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 deletions(-)

diff --git a/drivers/atmodem/sim.c b/drivers/atmodem/sim.c
index c629ec1..b6f34c2 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 1da486c..751ae10 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 6a9681d..82a3216 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 3f26678..962f366 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,
@@ -1469,7 +1753,7 @@ void ofono_sim_register(struct ofono_sim *sim)
 	 * in the EFust
 	 */
 	sim_retrieve_efli(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 b80e014..e1b0f2a 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 2cd3b73..df84416 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);
-- 
1.6.1


  reply	other threads:[~2009-09-17 18:57 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-09-05  7:25 [PATCH] [RFC] Do the PIN check in SIMManager Andrzej Zaborowski
2009-09-07  9:53 ` Santtu Lakkala
2009-09-08  2:41   ` Andrzej Zaborowski
2009-09-17 18:57     ` Andrzej Zaborowski [this message]
2009-09-22  5:12       ` Denis Kenzior
2009-09-23 20:47         ` andrzej zaborowski
2009-09-23 20:02           ` Denis Kenzior

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=fb249edb0909171157w3b00b220o2538793c09016d81@mail.gmail.com \
    --to=andrew.zaborowski@intel.com \
    --cc=ofono@ofono.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.