All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC sim-ready-v1 PATCH 0/3] ofono_sim_ready_notify
@ 2010-10-18 15:40 Pekka.Pessi
  2010-10-18 15:40 ` [RFC sim-ready-v1 PATCH 1/3] sim: add ofono_sim_ready_notify Pekka.Pessi
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Pekka.Pessi @ 2010-10-18 15:40 UTC (permalink / raw)
  To: ofono

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

Hi all,

Here is my 2nd stab at the ofono_sim_ready_notify().

Main difference from Denis's and Kristen's patch is that the modem
driver now has a way to indicate that is ready or not: if SIM is not
ready, the ofono_sim_driver indicates that with query_passwd_state
callback returning OFONO_SIM_PASSWORD_INVALID. A separate enum and a
string value for PinRequired property for that case would probably be
nice, however, it is not very clear to me how the modems handle the
transition from PIN-locked SIM to SIM-locked modem.

After the driver determines that the SIM is ready, it calls
ofono_sim_ready_notify().

The patches has now been tested with the PIN and PUK codes with mbm and
the new isimodem sim driver by Jukka Saunamaki. IFX seems to be
identical in PIN and PUK cases, too.

The isimodem driver demonstrates also the case where PIN is disabled but
SIM is not ready yet when oFono tries to initialize the modem. The
isimodem driver tries to read some CPHS information in order to
determine if the modem is ready. I'm not sure how that kind of probing
should be implemented in atmodem driver.

--Pekka


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [RFC sim-ready-v1 PATCH 1/3] sim: add ofono_sim_ready_notify
  2010-10-18 15:40 [RFC sim-ready-v1 PATCH 0/3] ofono_sim_ready_notify Pekka.Pessi
@ 2010-10-18 15:40 ` Pekka.Pessi
  2010-10-18 15:40   ` [RFC sim-ready-v1 PATCH 2/3] isimodem/sim: added PIN and SIM state handling Pekka.Pessi
  2010-10-19  9:43 ` [RFC sim-ready-v1 PATCH 0/3] ofono_sim_ready_notify Marcel Holtmann
  2010-10-22 18:54 ` Denis Kenzior
  2 siblings, 1 reply; 8+ messages in thread
From: Pekka.Pessi @ 2010-10-18 15:40 UTC (permalink / raw)
  To: ofono

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

From: Pekka Pessi <Pekka.Pessi@nokia.com>

If SIM is not ready, the ofono_sim_driver indicates that with
query_passwd_state callback returning OFONO_SIM_PASSWORD_INVALID.

After the driver determines that SIM is ready, it calls
ofono_sim_ready_notify().

Based on patches by Kristen Accardi and Denis Kenzior.
---
 include/sim.h |    2 ++
 src/sim.c     |   26 ++++++++++++++++++++++++++
 2 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/include/sim.h b/include/sim.h
index 7860e24..f4171d1 100644
--- a/include/sim.h
+++ b/include/sim.h
@@ -188,6 +188,8 @@ enum ofono_sim_state ofono_sim_get_state(struct ofono_sim *sim);
 
 void ofono_sim_inserted_notify(struct ofono_sim *sim, ofono_bool_t inserted);
 
+void ofono_sim_ready_notify(struct ofono_sim *sim);
+
 /* This will queue an operation to read all available records with id from the
  * SIM.  Callback cb will be called every time a record has been read, or once
  * if an error has occurred.  For transparent files, the callback will only
diff --git a/src/sim.c b/src/sim.c
index 695562f..b0462c8 100644
--- a/src/sim.c
+++ b/src/sim.c
@@ -86,6 +86,8 @@ struct ofono_sim {
 	unsigned char *efimg;
 	unsigned short efimg_length;
 
+	gboolean waiting_ready;
+
 	enum ofono_sim_state state;
 	struct ofono_watchlist *state_watches;
 
@@ -1407,6 +1409,14 @@ static void sim_pin_query_cb(const struct ofono_error *error,
 		goto checkdone;
 	}
 
+	if (pin_type == OFONO_SIM_PASSWORD_INVALID) {
+		DBG("Waiting for ready notification");
+
+		sim->waiting_ready = TRUE;
+
+		return;
+	}
+
 	if (sim->pin_type != pin_type) {
 		sim->pin_type = pin_type;
 		pin_name = sim_passwd_name(pin_type);
@@ -1431,6 +1441,8 @@ checkdone:
 
 static void sim_pin_check(struct ofono_sim *sim)
 {
+	sim->waiting_ready = FALSE;
+
 	if (!sim->driver->query_passwd_state) {
 		sim_initialize_after_pin(sim);
 		return;
@@ -1439,6 +1451,20 @@ static void sim_pin_check(struct ofono_sim *sim)
 	sim->driver->query_passwd_state(sim, sim_pin_query_cb, sim);
 }
 
+void ofono_sim_ready_notify(struct ofono_sim *sim)
+{
+	DBG("");
+
+	if (sim == NULL)
+		return;
+
+	if (sim->state != OFONO_SIM_STATE_INSERTED)
+		return;
+
+	if (sim->waiting_ready)
+		sim_pin_check(sim);
+}
+
 static void sim_efli_read_cb(int ok, int length, int record,
 				const unsigned char *data,
 				int record_length, void *userdata)
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [RFC sim-ready-v1 PATCH 2/3] isimodem/sim: added PIN and SIM state handling
  2010-10-18 15:40 ` [RFC sim-ready-v1 PATCH 1/3] sim: add ofono_sim_ready_notify Pekka.Pessi
@ 2010-10-18 15:40   ` Pekka.Pessi
  2010-10-18 15:40     ` [RFC sim-ready-v1 PATCH 3/3] atmodem/sim: use ofono_sim_ready_notify Pekka.Pessi
  0 siblings, 1 reply; 8+ messages in thread
From: Pekka.Pessi @ 2010-10-18 15:40 UTC (permalink / raw)
  To: ofono

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

From: Jukka Saunamaki <jukka.saunamaki@nokia.com>

Using ofono_sim_ready_notify().
---
 drivers/isimodem/debug.c |   30 +++
 drivers/isimodem/debug.h |    3 +
 drivers/isimodem/sim.c   |  558 +++++++++++++++++++++++++++++++++++++++++++---
 drivers/isimodem/sim.h   |   50 ++++-
 4 files changed, 605 insertions(+), 36 deletions(-)

diff --git a/drivers/isimodem/debug.c b/drivers/isimodem/debug.c
index c724b41..f649b9d 100644
--- a/drivers/isimodem/debug.c
+++ b/drivers/isimodem/debug.c
@@ -48,6 +48,7 @@ const char *pn_resource_name(int value)
 		_(PN_CALL);
 		_(PN_SMS);
 		_(PN_SIM);
+		_(PN_SECURITY);
 		_(PN_MTC);
 		_(PN_GSS);
 		_(PN_GPDS);
@@ -377,18 +378,41 @@ const char *sim_message_id_name(enum sim_message_id value)
 		_(SIM_IMSI_RESP_READ_IMSI);
 		_(SIM_SERV_PROV_NAME_REQ);
 		_(SIM_SERV_PROV_NAME_RESP);
+		_(SIM_DYNAMIC_FLAGS_REQ);
+		_(SIM_DYNAMIC_FLAGS_RESP);
 		_(SIM_READ_FIELD_REQ);
 		_(SIM_READ_FIELD_RESP);
 		_(SIM_SMS_REQ);
 		_(SIM_SMS_RESP);
+		_(SIM_STATUS_REQ);
+		_(SIM_STATUS_RESP);
 		_(SIM_PB_REQ_SIM_PB_READ);
 		_(SIM_PB_RESP_SIM_PB_READ);
+		_(SIM_SERVER_READY_IND);
 		_(SIM_IND);
 		_(SIM_COMMON_MESSAGE);
 	}
 	return "SIM_<UNKNOWN>";
 }
 
+const char *sec_message_id_name(enum sec_message_id value)
+{
+	switch (value) {
+		_(SEC_CODE_STATE_REQ);
+		_(SEC_CODE_STATE_OK_RESP);
+		_(SEC_CODE_STATE_FAIL_RESP);
+		_(SEC_CODE_CHANGE_REQ);
+		_(SEC_CODE_CHANGE_OK_RESP);
+		_(SEC_CODE_CHANGE_FAIL_RESP);
+		_(SEC_CODE_VERIFY_REQ);
+		_(SEC_CODE_VERIFY_OK_RESP);
+		_(SEC_CODE_VERIFY_FAIL_RESP);
+		_(SEC_STATE_REQ);
+		_(SEC_STATE_RESP);
+	}
+	return "SEC_<UNKNOWN>";
+}
+
 const char *sim_subblock_name(enum sim_subblock value)
 {
 	switch (value) {
@@ -1069,6 +1093,12 @@ void sim_debug(const void *restrict buf, size_t len, void *data)
 	hex_dump(sim_message_id_name(m[0]), m, len);
 }
 
+void sec_debug(const void *restrict buf, size_t len, void *data)
+{
+	const uint8_t *m = buf;
+	hex_dump(sec_message_id_name(m[0]), m, len);
+}
+
 void info_debug(const void *restrict buf, size_t len, void *data)
 {
 	const uint8_t *m = buf;
diff --git a/drivers/isimodem/debug.h b/drivers/isimodem/debug.h
index dbdc4de..0127010 100644
--- a/drivers/isimodem/debug.h
+++ b/drivers/isimodem/debug.h
@@ -49,6 +49,8 @@ const char *sim_isi_cause_name(enum sim_isi_cause value);
 const char *sim_message_id_name(enum sim_message_id value);
 const char *sim_subblock_name(enum sim_subblock value);
 
+const char *sec_message_id_name(enum sec_message_id value);
+
 const char *info_isi_cause_name(enum info_isi_cause value);
 const char *info_message_id_name(enum info_message_id value);
 const char *info_subblock_name(enum info_subblock value);
@@ -78,6 +80,7 @@ void ss_debug(const void *restrict buf, size_t len, void *data);
 void mtc_debug(const void *restrict buf, size_t len, void *data);
 void sms_debug(const void *restrict buf, size_t len, void *data);
 void sim_debug(const void *restrict buf, size_t len, void *data);
+void sec_debug(const void *restrict buf, size_t len, void *data);
 void info_debug(const void *restrict buf, size_t len, void *data);
 void call_debug(const void *restrict buf, size_t len, void *data);
 void net_debug(const void *restrict buf, size_t len, void *data);
diff --git a/drivers/isimodem/sim.c b/drivers/isimodem/sim.c
index d978c85..4f19196 100644
--- a/drivers/isimodem/sim.c
+++ b/drivers/isimodem/sim.c
@@ -45,7 +45,9 @@
 
 struct sim_data {
 	GIsiClient *client;
-	gboolean registered;
+	GIsiClient *sec_client;
+	enum ofono_sim_password_type passwd_state;
+	gboolean ready;
 };
 
 struct file_info {
@@ -320,6 +322,7 @@ static gboolean imsi_resp_cb(GIsiClient *client,
 	goto out;
 
 error:
+	DBG("IMSI error");
 	CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
 
 out:
@@ -336,12 +339,12 @@ static void isi_read_imsi(struct ofono_sim *sim,
 		SIM_IMSI_REQ_READ_IMSI,
 		READ_IMSI
 	};
+	DBG("");
 
 	if (!cbd)
 		goto error;
 
-	if (g_isi_request_make(sd->client, msg, sizeof(msg),
-				SIM_TIMEOUT,
+	if (g_isi_request_make(sd->client, msg, sizeof(msg), SIM_TIMEOUT,
 				imsi_resp_cb, cbd))
 		return;
 
@@ -350,50 +353,325 @@ error:
 	g_free(cbd);
 }
 
-static void isi_sim_register(struct ofono_sim *sim)
+static void isi_query_passwd_state(struct ofono_sim *sim,
+					ofono_sim_passwd_cb_t cb, void *data)
 {
 	struct sim_data *sd = ofono_sim_get_data(sim);
+	enum ofono_sim_password_type passwd_state = sd->passwd_state;
 
-	if (!sd->registered) {
-		sd->registered = TRUE;
-		ofono_sim_register(sim);
-		ofono_sim_inserted_notify(sim, TRUE);
+	DBG("passwd_state %u", passwd_state);
+
+	if (passwd_state == OFONO_SIM_PASSWORD_INVALID) {
+		CALLBACK_WITH_FAILURE(cb, -1, data);
+		return;
 	}
+
+	if (!sd->ready && passwd_state == OFONO_SIM_PASSWORD_NONE)
+		passwd_state = OFONO_SIM_PASSWORD_INVALID;
+
+	CALLBACK_WITH_SUCCESS(cb, sd->passwd_state, data);
 }
 
-static gboolean read_hplmn_resp_cb(GIsiClient *client,
+static gboolean sec_code_verify_resp(GIsiClient *client,
 					const void *restrict data, size_t len,
 					uint16_t object, void *opaque)
 {
 	const unsigned char *msg = data;
-	struct ofono_sim *sim = opaque;
+	struct isi_cb_data *cbd = opaque;
+	ofono_sim_lock_unlock_cb_t cb = cbd->cb;
+	struct ofono_sim *sim = cbd->user;
+	struct sim_data *sd = ofono_sim_get_data(sim);
 
-	if (!msg) {
-		DBG("ISI client error: %d", g_isi_client_error(client));
-		return TRUE;
+	DBG("");
+
+	if (len >= 1 && msg[0] == SEC_CODE_VERIFY_OK_RESP) {
+		sd->passwd_state = OFONO_SIM_PASSWORD_NONE;
+		CALLBACK_WITH_SUCCESS(cb, cbd->data);
+		goto done;
 	}
 
-	if (len < 3 || msg[0] != SIM_NETWORK_INFO_RESP || msg[1] != READ_HPLMN)
-		return FALSE;
+	if (len >= 2 && msg[0] == SEC_CODE_VERIFY_FAIL_RESP &&
+			msg[1] == SEC_CAUSE_CODE_BLOCKED)
+		sd->passwd_state = OFONO_SIM_PASSWORD_SIM_PUK;
 
-	if (msg[2] != SIM_SERV_NOTREADY)
-		isi_sim_register(sim);
+	DBG("verify failure %s", !msg ? "(timeout)" : "");
+	CALLBACK_WITH_FAILURE(cb, cbd->data);
+
+done:
+	g_free(cbd);
 
 	return TRUE;
 }
 
+static void isi_send_passwd(struct ofono_sim *sim, const char *passwd,
+				ofono_sim_lock_unlock_cb_t cb, void *data)
+{
+	struct sim_data *sd = ofono_sim_get_data(sim);
+	struct isi_cb_data *cbd = isi_cb_data_new(sim, cb, data);
+
+	unsigned char msg[2 + SEC_CODE_MAX_LENGTH + 1] = {
+		SEC_CODE_VERIFY_REQ,
+		SEC_CODE_PIN,
+	};
+	int len = 2 + strlen(passwd) + 1;
+
+	DBG("");
+
+	if (!cbd)
+		goto error;
+
+	strcpy((char *)msg + 2, passwd);
 
-static void isi_read_hplmn(struct ofono_sim *sim)
+	if (g_isi_request_make(sd->sec_client, msg, len, SIM_TIMEOUT,
+				sec_code_verify_resp, cbd))
+		return;
+
+error:
+	g_free(cbd);
+
+	CALLBACK_WITH_FAILURE(cb, data);
+}
+
+static void isi_reset_passwd(struct ofono_sim *sim,
+				const char *puk, const char *passwd,
+				ofono_sim_lock_unlock_cb_t cb, void *data)
 {
 	struct sim_data *sd = ofono_sim_get_data(sim);
+	struct isi_cb_data *cbd = isi_cb_data_new(sim, cb, data);
+	enum ofono_sim_password_type passwd_type = OFONO_SIM_PASSWORD_SIM_PIN;
+	unsigned char msg[2 + 2 * (SEC_CODE_MAX_LENGTH + 1)] = {
+		SEC_CODE_VERIFY_REQ,
+	};
 
-	const unsigned char req[] = {
-		SIM_NETWORK_INFO_REQ,
-		READ_HPLMN, 0
+	DBG("");
+
+	if (!cbd)
+		goto error;
+
+	if (passwd_type == OFONO_SIM_PASSWORD_SIM_PIN)
+		msg[1] = SEC_CODE_PIN;
+	else if (passwd_type == OFONO_SIM_PASSWORD_SIM_PIN2)
+		msg[1] = SEC_CODE_PIN2;
+	else
+		goto error;
+
+	strcpy((char *)&msg[2], puk);
+	strcpy((char *)&msg[2 + SEC_CODE_MAX_LENGTH + 1], passwd);
+
+	if (g_isi_request_make(sd->sec_client, msg, sizeof(msg), SIM_TIMEOUT,
+				sec_code_verify_resp, cbd))
+		return;
+
+error:
+	g_free(cbd);
+
+	CALLBACK_WITH_FAILURE(cb, data);
+}
+
+
+/* ISI callback: Enable/disable PIN */
+static gboolean pin_enable_resp_cb(GIsiClient *client,
+				const void *restrict data,
+				size_t len, uint16_t object, void *opaque)
+{
+	const unsigned char *msg = data;
+	struct isi_cb_data *cbd = opaque;
+	ofono_sim_lock_unlock_cb_t cb = cbd->cb;
+
+	DBG("");
+
+	if (len < 1 || msg[0] != SEC_CODE_STATE_OK_RESP)
+		CALLBACK_WITH_FAILURE(cb, cbd->data);
+	else
+		CALLBACK_WITH_SUCCESS(cb, cbd->data);
+
+	g_free(cbd);
+
+	return TRUE;
+}
+
+static void isi_lock(struct ofono_sim *sim,
+		enum ofono_sim_password_type passwd_type,
+		int enable, const char *passwd,
+		ofono_sim_lock_unlock_cb_t cb, void *data)
+{
+	struct sim_data *sd = ofono_sim_get_data(sim);
+	struct isi_cb_data *cbd = isi_cb_data_new(sim, cb, data);
+	unsigned char msg[3 + SEC_CODE_MAX_LENGTH + 1] = {
+		SEC_CODE_STATE_REQ,
 	};
 
-	g_isi_request_make(sd->client, req, sizeof(req), SIM_TIMEOUT,
-				read_hplmn_resp_cb, sim);
+	if (!cbd)
+		goto error;
+
+	DBG("enable %d pintype %d pass %s", enable, passwd_type, passwd);
+
+	if (passwd_type == OFONO_SIM_PASSWORD_SIM_PIN)
+		msg[1] = SEC_CODE_PIN;
+	else if (passwd_type == OFONO_SIM_PASSWORD_SIM_PIN2)
+		msg[1] = SEC_CODE_PIN2;
+	else
+		goto error;
+
+	if (enable)
+		msg[2] = SEC_CODE_ENABLE;
+	else
+		msg[2] = SEC_CODE_DISABLE;
+
+	strcpy((char *)&msg[3], passwd);
+
+	if (g_isi_request_make(sd->sec_client, msg, sizeof(msg),
+				SIM_TIMEOUT, pin_enable_resp_cb, cbd))
+		return;
+
+error:
+	g_free(cbd);
+
+	CALLBACK_WITH_FAILURE(cb, data);
+}
+
+
+
+/* ISI callback: PIN state (enabled/disabled) query */
+static gboolean sec_code_change_resp(GIsiClient *client,
+					const void *restrict data, size_t len,
+					uint16_t object, void *opaque)
+{
+	const unsigned char *msg = data;
+	struct isi_cb_data *cbd = opaque;
+	ofono_sim_lock_unlock_cb_t cb = cbd->cb;
+
+	if (len < 1)
+		goto failure;
+
+	if (msg[0] != SEC_CODE_CHANGE_OK_RESP) {
+		if (msg[0] == SEC_CODE_CHANGE_FAIL_RESP && len >= 2)
+			DBG("SEC_CODE_CHANGE_FAIL_RESP(cause=%02x)", msg[1]);
+		goto failure;
+	}
+
+	CALLBACK_WITH_SUCCESS(cb, cbd->data);
+
+	goto done;
+
+failure:
+	CALLBACK_WITH_FAILURE(cb, cbd->data);
+
+done:
+	g_free(cbd);
+
+	return TRUE;
+}
+
+
+static void isi_change_passwd(struct ofono_sim *sim,
+				enum ofono_sim_password_type passwd_type,
+				const char *old, const char *new,
+				ofono_sim_lock_unlock_cb_t cb, void *data)
+{
+	struct sim_data *sd = ofono_sim_get_data(sim);
+	struct isi_cb_data *cbd = isi_cb_data_new(sim, cb, data);
+	unsigned char msg[2 + 2 * (SEC_CODE_MAX_LENGTH + 1)] = {
+		SEC_CODE_CHANGE_REQ,
+	};
+
+	DBG("passwd_type %d", passwd_type);
+
+	if (!cbd)
+		goto error;
+
+	if (passwd_type == OFONO_SIM_PASSWORD_SIM_PIN)
+		msg[1] = SEC_CODE_PIN;
+	else if (passwd_type == OFONO_SIM_PASSWORD_SIM_PIN2)
+		msg[1] = SEC_CODE_PIN2;
+	else
+		goto error;
+
+	strcpy((char *)&msg[2], old);
+	strcpy((char *)&msg[2 + SEC_CODE_MAX_LENGTH + 1], new);
+
+	if (g_isi_request_make(sd->sec_client, msg, sizeof(msg),
+				SIM_TIMEOUT, sec_code_change_resp, cbd))
+		return;
+
+error:
+	g_free(cbd);
+
+	CALLBACK_WITH_FAILURE(cb, data);
+}
+
+
+/* ISI callback: PIN state (enabled/disabled) query */
+static gboolean sec_code_state_resp_cb(GIsiClient *client,
+					const void *restrict data, size_t len,
+					uint16_t object, void *opaque)
+{
+	const unsigned char *msg = data;
+	struct isi_cb_data *cbd = opaque;
+	ofono_sim_locked_cb_t cb = cbd->cb;
+	int locked;
+
+	if (msg == NULL || len < 4)
+		goto failure;
+
+	if (msg[0] != SEC_CODE_STATE_OK_RESP)
+		goto failure;
+
+	DBG("sec state: %02x", msg[1]);
+
+	if (msg[1] == SEC_CODE_ENABLE)
+		locked = 1;
+	else if (msg[1] == SEC_CODE_DISABLE)
+		locked = 0;
+	else
+		goto failure;
+
+	CALLBACK_WITH_SUCCESS(cb, locked, cbd->data);
+
+	goto done;
+
+failure:
+	CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
+
+done:
+	g_free(cbd);
+
+	return TRUE;
+}
+
+static void isi_query_locked(struct ofono_sim *sim,
+				enum ofono_sim_password_type passwd_type,
+				ofono_sim_locked_cb_t cb, void *data)
+{
+	struct sim_data *sd = ofono_sim_get_data(sim);
+	struct isi_cb_data *cbd = isi_cb_data_new(sim, cb, data);
+
+	unsigned char msg[] = {
+		SEC_CODE_STATE_REQ,
+		0,
+		SEC_CODE_STATE_QUERY
+	};
+
+	DBG("");
+
+	if (!cbd)
+		goto error;
+
+	if (passwd_type == OFONO_SIM_PASSWORD_SIM_PIN)
+		msg[1] = SEC_CODE_PIN;
+	else if (passwd_type == OFONO_SIM_PASSWORD_SIM_PIN2)
+		msg[1] = SEC_CODE_PIN2;
+	else
+		goto error;
+
+	if (g_isi_request_make(sd->sec_client, msg, sizeof(msg),
+				SIM_TIMEOUT, sec_code_state_resp_cb, cbd))
+		return;
+
+error:
+	g_free(cbd);
+
+	CALLBACK_WITH_FAILURE(cb, -1, data);
 }
 
 static void sim_ind_cb(GIsiClient *client,
@@ -404,19 +682,200 @@ static void sim_ind_cb(GIsiClient *client,
 	struct sim_data *sd = ofono_sim_get_data(sim);
 	const unsigned char *msg = data;
 
-	if (sd->registered)
+	uint8_t servicetype;
+	uint8_t status;
+	uint8_t state;
+	uint8_t cause;
+
+	DBG("");
+	if (!msg || len < 5 ||
+		(msg[0] != SIM_IND && msg[0] != SIM_SERVER_READY_IND))
 		return;
 
+	servicetype = msg[1];
+	status = msg[2];
+	state = msg[3];
+	cause = msg[4];
+
+	if (servicetype == SIM_ST_PIN &&
+		status == SIM_SERV_PIN_VERIFY_REQUIRED) {
+		sd->passwd_state = OFONO_SIM_PASSWORD_SIM_PIN;
+		sd->ready = FALSE;
+		ofono_sim_inserted_notify(sim, TRUE);
+	} else if (status == SIM_SERV_SIM_BLOCKED) {
+		sd->passwd_state = OFONO_SIM_PASSWORD_SIM_PUK;
+		sd->ready = FALSE;
+		ofono_sim_inserted_notify(sim, TRUE);
+	} else if (servicetype == SIM_ST_INFO &&
+		status == SIM_SERV_INIT_OK) {
+		sd->passwd_state = OFONO_SIM_PASSWORD_NONE;
+		ofono_sim_inserted_notify(sim, TRUE);
+	} else if (status == SIM_SERV_SIM_DISCONNECTED) {
+		sd->passwd_state = OFONO_SIM_PASSWORD_INVALID;
+		sd->ready = FALSE;
+		ofono_sim_inserted_notify(sim, FALSE);
+	}
+}
+
+static void sim_server_ready_ind_cb(GIsiClient *client,
+					const void *restrict data, size_t len,
+					uint16_t object, void *opaque)
+{
+	struct ofono_sim *sim = opaque;
+	struct sim_data *sd = ofono_sim_get_data(sim);
+	const unsigned char *msg = data;
+
+	DBG("");
+
+	if (!msg || len < 5 || msg[0] != SIM_SERVER_READY_IND)
+		return;
+
+	sd->ready = TRUE;
+
+	ofono_sim_ready_notify(sim);
+}
+
+static gboolean isi_sim_read_dyn_flags_resp(GIsiClient *client,
+				const void *restrict data, size_t len,
+				uint16_t object, void *opaque)
+{
+	const unsigned char *msg = data;
+	struct ofono_sim *sim = opaque;
+	struct sim_data *sd = ofono_sim_get_data(sim);
+
+	if (!msg)
+		return TRUE;
+
+	if (len < 2 || msg[0] != SIM_DYNAMIC_FLAGS_RESP)
+		return FALSE;
+
+	if (msg[1] != READ_DYN_FLAGS || msg[2] == SIM_SERV_NOTREADY)
+		return TRUE;
+
+	sd->ready = TRUE;
+
+	ofono_sim_ready_notify(sim);
+
+	return TRUE;
+}
+
+static void isi_sim_read_dyn_flags_req(struct ofono_sim *sim)
+{
+	struct sim_data *sd = ofono_sim_get_data(sim);
+
+	unsigned char req[] = {
+		SIM_DYNAMIC_FLAGS_REQ,
+		READ_DYN_FLAGS,
+		0
+	};
+
+	g_isi_send(sd->client, req, sizeof(req), SIM_TIMEOUT,
+			isi_sim_read_dyn_flags_resp, sim, NULL);
+}
+
+static gboolean sec_state_resp_cb(GIsiClient *client,
+				const void *restrict data, size_t len,
+				uint16_t object, void *opaque)
+{
+	const unsigned char *msg = data;
+	struct ofono_sim *sim = opaque;
+	struct sim_data *sd = ofono_sim_get_data(sim);
+	ofono_bool_t inserted = FALSE;
+
+	DBG("");
+
+	if (!msg) {
+		DBG("ISI client error: %d", g_isi_client_error(client));
+		return TRUE;
+	}
+	if (len < 2 || msg[0] != SEC_STATE_RESP)
+		return FALSE;
+
+	if (!sd)
+		return TRUE;
+
 	switch (msg[1]) {
-	case SIM_ST_PIN:
-		isi_sim_register(sim);
+	case SEC_STARTUP_OK:
+		DBG("SEC_STARTUP_OK");
+		sd->passwd_state = OFONO_SIM_PASSWORD_NONE;
+		inserted = TRUE;
+		/* Check if SIM server is already ready */
+		isi_sim_read_dyn_flags_req(sim);
+		break;
+	case SEC_CAUSE_PIN_REQUIRED:
+		DBG("SEC_CAUSE_PIN_REQUIRED");
+		sd->passwd_state = OFONO_SIM_PASSWORD_SIM_PIN;
+		inserted = TRUE;
+		break;
+	case SEC_CAUSE_PUK_REQUIRED:
+		DBG("SEC_CAUSE_PUK_REQUIRED");
+		sd->passwd_state = OFONO_SIM_PASSWORD_SIM_PUK;
+		inserted = TRUE;
 		break;
-	case SIM_ST_INFO:
-		isi_read_hplmn(sim);
+	case SEC_CAUSE_NO_SIM:
+		DBG("SEC_CAUSE_NO_SIM");
+		break;
+	case SEC_CAUSE_INVALID_SIM:
+		DBG("SEC_CAUSE_INVALID_SIM");
+		break;
+	case SEC_CAUSE_SIM_REJECTED:
+		DBG("SEC_CAUSE_SIM_REJECTED");
+		break;
+	default:
 		break;
 	}
+
+	ofono_sim_inserted_notify(sim, inserted);
+
+	return TRUE;
+}
+
+static void isi_sec_state_req(struct ofono_sim *sim)
+{
+	struct sim_data *sd = ofono_sim_get_data(sim);
+
+	unsigned char req[] = {
+		SEC_STATE_REQ,
+		0,
+		0
+	};
+
+	g_isi_request_make(sd->sec_client, req, sizeof(req), SIM_TIMEOUT,
+			sec_state_resp_cb, sim);
+}
+
+static gboolean sim_status_resp_cb(GIsiClient *client,
+					const void *restrict data, size_t len,
+					uint16_t object, void *opaque)
+{
+	const unsigned char *msg = data;
+	struct ofono_sim *sim = opaque;
+
+	if (!msg || len < 3)
+		return TRUE;
+
+	if (msg[0] == SIM_STATUS_RESP && msg[1] == SIM_ST_CARD_STATUS &&
+			msg[2] != SIM_SERV_SIM_DISCONNECTED)
+		/* We probably have a SIM. Now get PIN/PUK status  */
+		isi_sec_state_req(sim); /* Try Sec-server first */
+
+	return TRUE;
 }
 
+static void isi_sim_status_req(struct ofono_sim *sim)
+{
+	struct sim_data *sd = ofono_sim_get_data(sim);
+
+	const unsigned char req[] = {
+		SIM_STATUS_REQ,
+		SIM_ST_CARD_STATUS
+	};
+
+	g_isi_request_make(sd->client, req, sizeof(req), SIM_TIMEOUT,
+			sim_status_resp_cb, sim);
+}
+
+
 static void sim_reachable_cb(GIsiClient *client, gboolean alive,
 				uint16_t object, void *opaque)
 {
@@ -434,9 +893,13 @@ static void sim_reachable_cb(GIsiClient *client, gboolean alive,
 		g_isi_version_minor(client));
 
 	g_isi_subscribe(client, SIM_IND, sim_ind_cb, opaque);
+	g_isi_subscribe(client, SIM_SERVER_READY_IND,
+			sim_server_ready_ind_cb, opaque);
 
-	/* Check if SIM is ready. */
-	isi_read_hplmn(sim);
+	ofono_sim_register(sim);
+
+	/* Check if we have a SIM */
+	isi_sim_status_req(sim);
 }
 
 static int isi_sim_probe(struct ofono_sim *sim, unsigned int vendor,
@@ -444,23 +907,41 @@ static int isi_sim_probe(struct ofono_sim *sim, unsigned int vendor,
 {
 	GIsiModem *idx = user;
 	struct sim_data *sd = g_try_new0(struct sim_data, 1);
+	GIsiClient *client = NULL;
+	GIsiClient *sec_client = NULL;
 	const char *debug = getenv("OFONO_ISI_DEBUG");
 
 	if (!sd)
-		return -ENOMEM;
+		goto error;
 
-	sd->client = g_isi_client_create(idx, PN_SIM);
-	if (!sd->client)
-		return -ENOMEM;
+	client = g_isi_client_create(idx, PN_SIM);
+	if (!client)
+		goto error;
+
+	sec_client = g_isi_client_create(idx, PN_SECURITY);
+	if (!sec_client)
+		goto error;
+
+	sd->client = client;
+	sd->sec_client = sec_client;
+	sd->passwd_state = OFONO_SIM_PASSWORD_INVALID;
 
 	ofono_sim_set_data(sim, sd);
 
-	if (debug && (strcmp(debug, "all") == 0 || strcmp(debug, "sim") == 0))
+	if (debug && (!strcmp(debug, "all") || !strcmp(debug, "sim"))) {
 		g_isi_client_set_debug(sd->client, sim_debug, NULL);
+		g_isi_client_set_debug(sd->sec_client, sec_debug, NULL);
+	}
 
 	g_isi_verify(sd->client, sim_reachable_cb, sim);
 
 	return 0;
+
+error:
+	g_isi_client_destroy(client);
+	g_isi_client_destroy(sec_client);
+
+	return -ENOMEM;
 }
 
 static void isi_sim_remove(struct ofono_sim *sim)
@@ -472,6 +953,7 @@ static void isi_sim_remove(struct ofono_sim *sim)
 
 	ofono_sim_set_data(sim, NULL);
 	g_isi_client_destroy(data->client);
+	g_isi_client_destroy(data->sec_client);
 	g_free(data);
 }
 
@@ -487,6 +969,12 @@ static struct ofono_sim_driver driver = {
 	.write_file_linear	= isi_write_file_linear,
 	.write_file_cyclic	= isi_write_file_cyclic,
 	.read_imsi		= isi_read_imsi,
+	.query_passwd_state	= isi_query_passwd_state,
+	.send_passwd		= isi_send_passwd,
+	.reset_passwd		= isi_reset_passwd,
+	.lock			= isi_lock,
+	.change_passwd		= isi_change_passwd,
+	.query_locked		= isi_query_locked,
 };
 
 void isi_sim_init()
diff --git a/drivers/isimodem/sim.h b/drivers/isimodem/sim.h
index f1d9f47..f416666 100644
--- a/drivers/isimodem/sim.h
+++ b/drivers/isimodem/sim.h
@@ -27,9 +27,12 @@ extern "C" {
 #endif
 
 #define PN_SIM			0x09
+#define PN_SECURITY             0x08
 #define SIM_TIMEOUT		5
 #define SIM_MAX_IMSI_LENGTH	15
 
+#define SEC_CODE_MAX_LENGTH	0x0A
+
 enum sim_isi_cause {
 	SIM_SERV_NOT_AVAIL = 0x00,
 	SIM_SERV_OK = 0x01,
@@ -131,29 +134,74 @@ enum sim_message_id {
 	SIM_IMSI_RESP_READ_IMSI = 0x1E,
 	SIM_SERV_PROV_NAME_REQ = 0x21,
 	SIM_SERV_PROV_NAME_RESP = 0x22,
+	SIM_DYNAMIC_FLAGS_REQ = 0x29,
+	SIM_DYNAMIC_FLAGS_RESP = 0x2A,
 	SIM_READ_FIELD_REQ = 0xBA,
 	SIM_READ_FIELD_RESP = 0xBB,
 	SIM_SMS_REQ = 0xBC,
 	SIM_SMS_RESP = 0xBD,
+	SIM_STATUS_REQ = 0xC0,
+	SIM_STATUS_RESP = 0xC1,
 	SIM_PB_REQ_SIM_PB_READ = 0xDC,
 	SIM_PB_RESP_SIM_PB_READ = 0xDD,
+	SIM_SERVER_READY_IND = 0xED,
 	SIM_IND = 0xEF,
 	SIM_COMMON_MESSAGE = 0xF0
 };
 
 enum sim_service_type {
+	SIM_ST_CARD_STATUS = 0x00,
 	SIM_ST_PIN = 0x01,
 	SIM_ST_ALL_SERVICES = 0x05,
 	SIM_ST_INFO = 0x0D,
-	SIM_ST_READ_SERV_PROV_NAME = 0x2C,
 	SIM_PB_READ = 0x0F,
+	SIM_ST_READ_SERV_PROV_NAME = 0x2C,
 	READ_IMSI = 0x2D,
 	READ_HPLMN = 0x2F,
+	READ_DYN_FLAGS = 0x35,
 	READ_PARAMETER = 0x52,
 	UPDATE_PARAMETER = 0x53,
 	ICC = 0x66,
 };
 
+enum sec_message_id {
+	SEC_CODE_STATE_REQ = 0x01,
+	SEC_CODE_STATE_OK_RESP = 0x02,
+	SEC_CODE_STATE_FAIL_RESP = 0x03,
+	SEC_CODE_CHANGE_REQ = 0x04,
+	SEC_CODE_CHANGE_OK_RESP = 0x05,
+	SEC_CODE_CHANGE_FAIL_RESP = 0x06,
+	SEC_CODE_VERIFY_REQ = 0x07,
+	SEC_CODE_VERIFY_OK_RESP = 0x08,
+	SEC_CODE_VERIFY_FAIL_RESP = 0x09,
+	SEC_STATE_REQ = 0x11,
+	SEC_STATE_RESP = 0x12,
+};
+
+enum sec_code_id_info {
+	SEC_CODE_PIN = 0x02,
+	SEC_CODE_PUK = 0x03,
+	SEC_CODE_PIN2 = 0x04,
+	SEC_CODE_PUK2 = 0x05,
+};
+
+enum sec_code_state_info {
+	SEC_CODE_DISABLE = 0x00,
+	SEC_CODE_ENABLE = 0x01,
+	SEC_CODE_STATE_QUERY = 0x04,
+};
+
+enum sec_state_cause_info {
+	SEC_CAUSE_PIN_REQUIRED = 0x02,
+	SEC_CAUSE_PUK_REQUIRED = 0x03,
+	SEC_STARTUP_OK = 0x05,
+	SEC_STARTUP_ONGOING = 0x07,
+	SEC_CAUSE_CODE_BLOCKED = 0x08,
+	SEC_CAUSE_NO_SIM = 0x16,
+	SEC_CAUSE_SIM_REJECTED = 0x1A,
+	SEC_CAUSE_INVALID_SIM = 0x1E,
+};
+
 #ifdef __cplusplus
 };
 #endif
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [RFC sim-ready-v1 PATCH 3/3] atmodem/sim: use ofono_sim_ready_notify
  2010-10-18 15:40   ` [RFC sim-ready-v1 PATCH 2/3] isimodem/sim: added PIN and SIM state handling Pekka.Pessi
@ 2010-10-18 15:40     ` Pekka.Pessi
  2010-10-22 18:55       ` Denis Kenzior
  0 siblings, 1 reply; 8+ messages in thread
From: Pekka.Pessi @ 2010-10-18 15:40 UTC (permalink / raw)
  To: ofono

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

From: Pekka Pessi <Pekka.Pessi@nokia.com>

After a PIN or PUK code is entered, the driver will wait for a ready
notification.  While waiting the query_passwd_state callback will return
OFONO_SIM_PASSWORD_INVALID. When the SIM gets ready or a timeout occurs,
ofono_sim_ready_notify() is called and the core will again query the SIM
password state.

By default the driver don't trust the modem to do the right thing and
adds a delay of 1000 milliseconds after entering the PIN/PUK.  It is
possible to remove the delay by adding a suitable quirk in
at_wait_for_ready().

However, the delay seems to be SIM-card-specific and 1000 ms might not
be enough. Finding a suitable default value might require experimenting
with a number of different SIM cards and modems.

Currently, identical quirks are applied in PIN or PUK cases. If a
different quirk was needed for PUK, at_pin_send_puk_cb() could be
reintroduced.
---
 drivers/atmodem/sim.c |  139 +++++++++++++++++++++++++------------------------
 1 files changed, 70 insertions(+), 69 deletions(-)

diff --git a/drivers/atmodem/sim.c b/drivers/atmodem/sim.c
index 94658f2..e566053 100644
--- a/drivers/atmodem/sim.c
+++ b/drivers/atmodem/sim.c
@@ -44,10 +44,13 @@
 #define EF_STATUS_INVALIDATED 0
 #define EF_STATUS_VALID 1
 
+#define READY_TIMEOUT		5000	/* milliseconds */
+
 struct sim_data {
 	GAtChat *chat;
 	unsigned int vendor;
 	guint ready_id;
+	guint ready_source;
 };
 
 static const char *crsm_prefix[] = { "+CRSM:", NULL };
@@ -506,6 +509,9 @@ static void at_cpin_cb(gboolean ok, GAtResult *result, gpointer user_data)
 		return;
 	}
 
+	if (sd->ready_source)
+		pin_type = OFONO_SIM_PASSWORD_INVALID;
+
 	DBG("crsm_pin_cb: %s", pin_required);
 
 	cb(&error, pin_type, cbd->data);
@@ -532,12 +538,25 @@ error:
 	CALLBACK_WITH_FAILURE(cb, -1, data);
 }
 
+static gboolean ready_notify_unregister(gpointer user_data)
+{
+	struct ofono_sim *sim = user_data;
+	struct sim_data *sd = ofono_sim_get_data(sim);
+
+	sd->ready_source = 0;
+
+	g_at_chat_unregister(sd->chat, sd->ready_id);
+	sd->ready_id = 0;
+
+	ofono_sim_ready_notify(sim);
+
+	return FALSE;
+}
+
 static void at_xsim_notify(GAtResult *result, gpointer user_data)
 {
-	struct cb_data *cbd = user_data;
-	struct sim_data *sd = cbd->user;
-	ofono_sim_lock_unlock_cb_t cb = cbd->cb;
-	struct ofono_error error = { .type = OFONO_ERROR_TYPE_NO_ERROR };
+	struct ofono_sim *sim = user_data;
+	struct sim_data *sd = ofono_sim_get_data(sim);
 	GAtResultIter iter;
 	int state;
 
@@ -557,37 +576,29 @@ static void at_xsim_notify(GAtResult *result, gpointer user_data)
 		return;
 	}
 
-	cb(&error, cbd->data);
+	if (sd->ready_source == 0)
+		return;
 
-	g_at_chat_unregister(sd->chat, sd->ready_id);
-	sd->ready_id = 0;
+	g_source_remove(sd->ready_source);
+	sd->ready_source = g_timeout_add(0, ready_notify_unregister, sim);
 }
 
 static void at_epev_notify(GAtResult *result, gpointer user_data)
 {
-	struct cb_data *cbd = user_data;
-	struct sim_data *sd = cbd->user;
-	ofono_sim_lock_unlock_cb_t cb = cbd->cb;
-	struct ofono_error error = { .type = OFONO_ERROR_TYPE_NO_ERROR };
+	struct ofono_sim *sim = user_data;
+	struct sim_data *sd = ofono_sim_get_data(sim);
 
-	cb(&error, cbd->data);
+	if (sd->ready_source == 0)
+		return;
 
-	g_at_chat_unregister(sd->chat, sd->ready_id);
-	sd->ready_id = 0;
+	g_source_remove(sd->ready_source);
+	sd->ready_source = g_timeout_add(0, ready_notify_unregister, sim);
 }
 
-static void at_pin_send_cb(gboolean ok, GAtResult *result,
-				gpointer user_data)
+static void at_wait_for_ready(struct ofono_sim *sim)
 {
-	struct cb_data *cbd = user_data;
-	struct sim_data *sd = cbd->user;
-	ofono_sim_lock_unlock_cb_t cb = cbd->cb;
-	struct ofono_error error;
-
-	decode_at_error(&error, g_at_result_final_response(result));
-
-	if (!ok)
-		goto done;
+	struct sim_data *sd = ofono_sim_get_data(sim);
+	guint timeout = READY_TIMEOUT;
 
 	switch (sd->vendor) {
 	case OFONO_VENDOR_IFX:
@@ -598,24 +609,46 @@ static void at_pin_send_cb(gboolean ok, GAtResult *result,
 		 */
 		sd->ready_id = g_at_chat_register(sd->chat, "+XSIM",
 							at_xsim_notify,
-							FALSE, cbd, g_free);
-		return;
+							FALSE, sim, NULL);
+		break;
+
 	case OFONO_VENDOR_MBM:
 		/*
 		 * On the MBM modem, AT+CPIN? keeps returning SIM PIN
 		 * for a moment after successful AT+CPIN="..", but then
-		 * sends *EPEV when that changes.
+		 * sends *EPEV when that changes. Sometimes.
 		 */
 		sd->ready_id = g_at_chat_register(sd->chat, "*EPEV",
 							at_epev_notify,
-							FALSE, cbd, g_free);
-		return;
+							FALSE, sim, NULL);
+		break;
+
+	default:
+		/* By default wait for 1000 ms */
+		timeout = 1000;
 	}
 
-done:
-	cb(&error, cbd->data);
+	if (sd->ready_source)
+		g_source_remove(sd->ready_source);
 
-	g_free(cbd);
+	sd->ready_source = g_timeout_add(timeout,
+					ready_notify_unregister, sim);
+}
+
+static void at_pin_send_cb(gboolean ok, GAtResult *result,
+				gpointer user_data)
+{
+	struct cb_data *cbd = user_data;
+	struct ofono_sim *sim = cbd->user;
+	ofono_sim_lock_unlock_cb_t cb = cbd->cb;
+	struct ofono_error error;
+
+	decode_at_error(&error, g_at_result_final_response(result));
+
+	if (ok)
+		at_wait_for_ready(sim);
+
+	cb(&error, cbd->data);
 }
 
 static void at_pin_send(struct ofono_sim *sim, const char *passwd,
@@ -629,12 +662,12 @@ static void at_pin_send(struct ofono_sim *sim, const char *passwd,
 	if (!cbd)
 		goto error;
 
-	cbd->user = sd;
+	cbd->user = sim;
 
 	snprintf(buf, sizeof(buf), "AT+CPIN=\"%s\"", passwd);
 
 	ret = g_at_chat_send(sd->chat, buf, none_prefix,
-				at_pin_send_cb, cbd, NULL);
+				at_pin_send_cb, cbd, g_free);
 
 	memset(buf, 0, sizeof(buf));
 
@@ -647,38 +680,6 @@ error:
 	CALLBACK_WITH_FAILURE(cb, data);
 }
 
-static void at_pin_send_puk_cb(gboolean ok, GAtResult *result,
-				gpointer user_data)
-{
-	struct cb_data *cbd = user_data;
-	struct sim_data *sd = cbd->user;
-	ofono_sim_lock_unlock_cb_t cb = cbd->cb;
-	struct ofono_error error;
-
-	decode_at_error(&error, g_at_result_final_response(result));
-
-	if (!ok)
-		goto done;
-
-	switch (sd->vendor) {
-	case OFONO_VENDOR_IFX:
-		/*
-		 * On the IFX modem, AT+CPIN? can return READY too
-		 * early and so use +XSIM notification to detect
-		 * the ready state of the SIM.
-		 */
-		sd->ready_id = g_at_chat_register(sd->chat, "+XSIM",
-							at_xsim_notify,
-							FALSE, cbd, g_free);
-		return;
-	}
-
-done:
-	cb(&error, cbd->data);
-
-	g_free(cbd);
-}
-
 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)
@@ -691,12 +692,12 @@ static void at_pin_send_puk(struct ofono_sim *sim, const char *puk,
 	if (!cbd)
 		goto error;
 
-	cbd->user = sd;
+	cbd->user = sim;
 
 	snprintf(buf, sizeof(buf), "AT+CPIN=\"%s\",\"%s\"", puk, passwd);
 
 	ret = g_at_chat_send(sd->chat, buf, none_prefix,
-				at_pin_send_puk_cb, cbd, NULL);
+				at_pin_send_cb, cbd, g_free);
 
 	memset(buf, 0, sizeof(buf));
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [RFC sim-ready-v1 PATCH 0/3] ofono_sim_ready_notify
  2010-10-18 15:40 [RFC sim-ready-v1 PATCH 0/3] ofono_sim_ready_notify Pekka.Pessi
  2010-10-18 15:40 ` [RFC sim-ready-v1 PATCH 1/3] sim: add ofono_sim_ready_notify Pekka.Pessi
@ 2010-10-19  9:43 ` Marcel Holtmann
  2010-10-19  9:56   ` Pekka Pessi
  2010-10-22 18:54 ` Denis Kenzior
  2 siblings, 1 reply; 8+ messages in thread
From: Marcel Holtmann @ 2010-10-19  9:43 UTC (permalink / raw)
  To: ofono

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

Hi Pekka,

> Here is my 2nd stab at the ofono_sim_ready_notify().
> 
> Main difference from Denis's and Kristen's patch is that the modem
> driver now has a way to indicate that is ready or not: if SIM is not
> ready, the ofono_sim_driver indicates that with query_passwd_state
> callback returning OFONO_SIM_PASSWORD_INVALID. A separate enum and a
> string value for PinRequired property for that case would probably be
> nice, however, it is not very clear to me how the modems handle the
> transition from PIN-locked SIM to SIM-locked modem.
> 
> After the driver determines that the SIM is ready, it calls
> ofono_sim_ready_notify().
> 
> The patches has now been tested with the PIN and PUK codes with mbm and
> the new isimodem sim driver by Jukka Saunamaki. IFX seems to be
> identical in PIN and PUK cases, too.
> 
> The isimodem driver demonstrates also the case where PIN is disabled but
> SIM is not ready yet when oFono tries to initialize the modem. The
> isimodem driver tries to read some CPHS information in order to
> determine if the modem is ready. I'm not sure how that kind of probing
> should be implemented in atmodem driver.

so how do we handle AT command based modems that have no extra
indication of SIM ready state? Are we stuck with quirks in the atmodem
SIM driver or can we push these into the modem plugins?

Regards

Marcel



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC sim-ready-v1 PATCH 0/3] ofono_sim_ready_notify
  2010-10-19  9:43 ` [RFC sim-ready-v1 PATCH 0/3] ofono_sim_ready_notify Marcel Holtmann
@ 2010-10-19  9:56   ` Pekka Pessi
  0 siblings, 0 replies; 8+ messages in thread
From: Pekka Pessi @ 2010-10-19  9:56 UTC (permalink / raw)
  To: ofono

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

Hi Marcel,

2010/10/19 Marcel Holtmann <marcel@holtmann.org>:
> so how do we handle AT command based modems that have no extra
> indication of SIM ready state? Are we stuck with quirks in the atmodem
> SIM driver or can we push these into the modem plugins?

I forgot to mention that in 0 patch, but I added a dummy delay as the
default way to handle the problem in atmodem sim driver:

>>By default the driver don't trust the modem to do the right thing and
>>adds a delay of 1000 milliseconds after entering the PIN/PUK.  It is
>>possible to remove the delay by adding a suitable quirk in
>>at_wait_for_ready().

I wonder if the delay is long enough. Someone complained in
bugs.meego.com that Nokia Test Network SIM cards are so slow they
don't work with the oFono in Meego 1.1 (0.26 with n900 plugin
patches), but they probably are not the slowest SIMs that you can
find.

-- 
Pekka.Pessi mail at nokia.com

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC sim-ready-v1 PATCH 0/3] ofono_sim_ready_notify
  2010-10-18 15:40 [RFC sim-ready-v1 PATCH 0/3] ofono_sim_ready_notify Pekka.Pessi
  2010-10-18 15:40 ` [RFC sim-ready-v1 PATCH 1/3] sim: add ofono_sim_ready_notify Pekka.Pessi
  2010-10-19  9:43 ` [RFC sim-ready-v1 PATCH 0/3] ofono_sim_ready_notify Marcel Holtmann
@ 2010-10-22 18:54 ` Denis Kenzior
  2 siblings, 0 replies; 8+ messages in thread
From: Denis Kenzior @ 2010-10-22 18:54 UTC (permalink / raw)
  To: ofono

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

Hi Pekka,

On 10/18/2010 10:40 AM, Pekka.Pessi(a)nokia.com wrote:
> Hi all,
> 
> Here is my 2nd stab at the ofono_sim_ready_notify().
> 
> Main difference from Denis's and Kristen's patch is that the modem
> driver now has a way to indicate that is ready or not: if SIM is not
> ready, the ofono_sim_driver indicates that with query_passwd_state
> callback returning OFONO_SIM_PASSWORD_INVALID. A separate enum and a

I really question the need for this.  The core should simply wait for
ready in both cases.  If the modem driver knows the modem is ready, then
it can simply call ofono_sim_ready_notify after the cpin query callback.
 Reusing OFONO_SIM_PASSWORD_INVALID seems really unclean...

> string value for PinRequired property for that case would probably be
> nice, however, it is not very clear to me how the modems handle the
> transition from PIN-locked SIM to SIM-locked modem.

Having recently peeked at 22.022, it seems pretty clear that all other
personalization types depend on the knowledge of the IMSI.  EFimsi
requires PIN entry, so the modems must all go through the PIN check
first before all other locks.

> 
> After the driver determines that the SIM is ready, it calls
> ofono_sim_ready_notify().
> 

Can you guys try the patch from
http://lists.ofono.org/pipermail/ofono/2010-August/004203.html

Does this one still work as well?

Regards,
-Denis

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC sim-ready-v1 PATCH 3/3] atmodem/sim: use ofono_sim_ready_notify
  2010-10-18 15:40     ` [RFC sim-ready-v1 PATCH 3/3] atmodem/sim: use ofono_sim_ready_notify Pekka.Pessi
@ 2010-10-22 18:55       ` Denis Kenzior
  0 siblings, 0 replies; 8+ messages in thread
From: Denis Kenzior @ 2010-10-22 18:55 UTC (permalink / raw)
  To: ofono

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

Hi Pekka,

> By default the driver don't trust the modem to do the right thing and
> adds a delay of 1000 milliseconds after entering the PIN/PUK.  It is
> possible to remove the delay by adding a suitable quirk in
> at_wait_for_ready().
> 
> However, the delay seems to be SIM-card-specific and 1000 ms might not
> be enough. Finding a suitable default value might require experimenting
> with a number of different SIM cards and modems.

I really don't like this aspect.  Perhaps polling +CIMI, +CPBS / +CPMS
might be a better idea?

Regards,
-Denis

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2010-10-22 18:55 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-10-18 15:40 [RFC sim-ready-v1 PATCH 0/3] ofono_sim_ready_notify Pekka.Pessi
2010-10-18 15:40 ` [RFC sim-ready-v1 PATCH 1/3] sim: add ofono_sim_ready_notify Pekka.Pessi
2010-10-18 15:40   ` [RFC sim-ready-v1 PATCH 2/3] isimodem/sim: added PIN and SIM state handling Pekka.Pessi
2010-10-18 15:40     ` [RFC sim-ready-v1 PATCH 3/3] atmodem/sim: use ofono_sim_ready_notify Pekka.Pessi
2010-10-22 18:55       ` Denis Kenzior
2010-10-19  9:43 ` [RFC sim-ready-v1 PATCH 0/3] ofono_sim_ready_notify Marcel Holtmann
2010-10-19  9:56   ` Pekka Pessi
2010-10-22 18:54 ` Denis Kenzior

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.