From b4cbe8d41a30b3672b7a585c2aae131e845e91fd Mon Sep 17 00:00:00 2001 From: Christophe Ronco Date: Tue, 10 Jan 2017 09:38:45 +0100 Subject: [PATCH] qmimodem: add pin_send feature Add ability to send PIN to a QMI modem using QMI_UIM_VERIFY_PIN command. This has been tested on MC7304 and MC7430 modems. --- drivers/qmimodem/sim.c | 65 ++++++++++++++++++++++++++++++++++++++++++ drivers/qmimodem/uim.h | 11 +++++++ 2 files changed, 76 insertions(+) diff --git a/drivers/qmimodem/sim.c b/drivers/qmimodem/sim.c index 201217e6..8e5042db 100644 --- a/drivers/qmimodem/sim.c +++ b/drivers/qmimodem/sim.c @@ -498,6 +498,70 @@ static void qmi_query_pin_retries(struct ofono_sim *sim, g_free(cbd); } +static void pin_send_cb(struct qmi_result *result, void *user_data) +{ + struct cb_data *cbd = user_data; + ofono_sim_lock_unlock_cb_t cb = cbd->cb; + + DBG(""); + + if (qmi_result_set_error(result, NULL)) { + CALLBACK_WITH_FAILURE(cb, cbd->data); + return; + } + + CALLBACK_WITH_SUCCESS(cb, cbd->data); +} + +static void qmi_pin_send(struct ofono_sim *sim, const char *passwd, + ofono_sim_lock_unlock_cb_t cb, void *user_data) +{ + struct sim_data *data = ofono_sim_get_data(sim); + struct cb_data *cbd = cb_data_new(cb, user_data); + int passwd_len; + struct qmi_param *param; + struct qmi_uim_param_message_info *info_data; + unsigned char session_info_data[2]; + + DBG(""); + + if (!passwd) + goto error; + + passwd_len = strlen(passwd); + + if (passwd_len <= 0 || passwd_len > 0xFF) + goto error; + + param = qmi_param_new(); + if (!param) + goto error; + + /* param info */ + info_data = alloca(2 + passwd_len); + info_data->pin_id = 0x01; /* PIN 1 */ + info_data->length = (uint8_t) passwd_len; + memcpy(info_data->pin_value, passwd, passwd_len); + qmi_param_append(param, QMI_UIM_PARAM_MESSAGE_INFO, 2 + passwd_len, + info_data); + /* param Session Information */ + session_info_data[0] = 0x6; + session_info_data[1] = 0x0; + qmi_param_append(param, QMI_UIM_PARAM_MESSAGE_SESSION_INFO, 2, + session_info_data); + + if (qmi_service_send(data->uim, QMI_UIM_VERIFY_PIN, param, + pin_send_cb, cbd, g_free) > 0) + return; + + qmi_param_free(param); + +error: + CALLBACK_WITH_FAILURE(cb, cbd->data); + + g_free(cbd); +} + static void get_card_status_cb(struct qmi_result *result, void *user_data) { struct ofono_sim *sim = user_data; @@ -649,6 +713,7 @@ static struct ofono_sim_driver driver = { .read_imsi = qmi_read_imsi, .query_passwd_state = qmi_query_passwd_state, .query_pin_retries = qmi_query_pin_retries, + .send_passwd = qmi_pin_send, }; void qmi_sim_init(void) diff --git a/drivers/qmimodem/uim.h b/drivers/qmimodem/uim.h index 8f123e7d..cd10e684 100644 --- a/drivers/qmimodem/uim.h +++ b/drivers/qmimodem/uim.h @@ -25,6 +25,8 @@ #define QMI_UIM_WRITE_RECORD 35 /* Write a record */ #define QMI_UIM_GET_FILE_ATTRIBUTES 36 /* Get file attributes */ +#define QMI_UIM_VERIFY_PIN 38 /* Verify PIN */ + #define QMI_UIM_EVENT_REGISTRATION 46 /* Register for indications */ #define QMI_UIM_GET_CARD_STATUS 47 /* Get card status */ @@ -91,3 +93,12 @@ struct qmi_uim_file_attributes { uint16_t raw_len; uint8_t raw_value[0]; } __attribute__((__packed__)); + +/* Verify PIN parameter */ +#define QMI_UIM_PARAM_MESSAGE_SESSION_INFO 0x01 +#define QMI_UIM_PARAM_MESSAGE_INFO 0x02 +struct qmi_uim_param_message_info { + uint8_t pin_id; + uint8_t length; + uint8_t pin_value[0]; +} __attribute__((__packed__));