1 /* 2 * uqmi -- tiny QMI support implementation 3 * 4 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the 18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301 USA. 20 */ 21 22 static int uim_slot = 0; 23 24 #define cmd_uim_verify_pin1_cb no_cb 25 static enum qmi_cmd_result 26 cmd_uim_verify_pin1_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg) 27 { 28 struct qmi_uim_verify_pin_request data = { 29 QMI_INIT_SEQUENCE(session, 30 .session_type = QMI_UIM_SESSION_TYPE_CARD_SLOT_1, 31 .application_identifier_n = 0 32 ), 33 QMI_INIT_SEQUENCE(info, 34 .pin_id = QMI_UIM_PIN_ID_PIN1, 35 .pin_value = arg 36 ) 37 }; 38 qmi_set_uim_verify_pin_request(msg, &data); 39 return QMI_CMD_REQUEST; 40 } 41 42 #define cmd_uim_verify_pin2_cb no_cb 43 static enum qmi_cmd_result 44 cmd_uim_verify_pin2_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg) 45 { 46 struct qmi_uim_verify_pin_request data = { 47 QMI_INIT_SEQUENCE(session, 48 .session_type = QMI_UIM_SESSION_TYPE_CARD_SLOT_1, 49 .application_identifier_n = 0 50 ), 51 QMI_INIT_SEQUENCE(info, 52 .pin_id = QMI_UIM_PIN_ID_PIN2, 53 .pin_value = arg 54 ) 55 }; 56 qmi_set_uim_verify_pin_request(msg, &data); 57 return QMI_CMD_REQUEST; 58 } 59 60 static void cmd_uim_get_sim_state_cb(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg) 61 { 62 struct qmi_uim_get_card_status_response res; 63 void * const card_table = blobmsg_open_table(&status, NULL); 64 static const char *card_application_states[] = { 65 [QMI_UIM_CARD_APPLICATION_STATE_UNKNOWN] = "unknown", 66 [QMI_UIM_CARD_APPLICATION_STATE_DETECTED] = "detected", 67 [QMI_UIM_CARD_APPLICATION_STATE_PIN1_OR_UPIN_PIN_REQUIRED] = "pin-required", 68 [QMI_UIM_CARD_APPLICATION_STATE_PUK1_OR_UPIN_PUK_REQUIRED] = "puk-required", 69 [QMI_UIM_CARD_APPLICATION_STATE_CHECK_PERSONALIZATION_STATE] = "check-personalization-state", 70 [QMI_UIM_CARD_APPLICATION_STATE_PIN1_BLOCKED] = "pin1-blocked", 71 [QMI_UIM_CARD_APPLICATION_STATE_ILLEGAL] = "illegal", 72 [QMI_UIM_CARD_APPLICATION_STATE_READY] = "ready", 73 }; 74 75 qmi_parse_uim_get_card_status_response(msg, &res); 76 77 for (int i = 0; i < res.data.card_status.cards_n; ++i) { 78 if (res.data.card_status.cards[i].card_state != QMI_UIM_CARD_STATE_PRESENT) 79 continue; 80 81 uint8_t card_application_state = QMI_UIM_CARD_APPLICATION_STATE_UNKNOWN; 82 uint8_t pin1_state = res.data.card_status.cards[i].upin_state; 83 uint8_t pin1_retries = res.data.card_status.cards[i].upin_retries; 84 uint8_t puk1_retries = res.data.card_status.cards[i].upuk_retries; 85 uint8_t pin2_state; 86 uint8_t pin2_retries; 87 uint8_t puk2_retries; 88 bool has_pin2 = false; 89 90 for (int j = 0; j < res.data.card_status.cards[i].applications_n; ++j) { 91 if (res.data.card_status.cards[i].applications[j].type == QMI_UIM_CARD_APPLICATION_TYPE_UNKNOWN) 92 continue; 93 94 card_application_state = pin1_state = res.data.card_status.cards[i].applications[j].state; 95 96 if (!res.data.card_status.cards[i].applications[j].upin_replaces_pin1) { 97 pin1_state = res.data.card_status.cards[i].applications[j].pin1_state; 98 pin1_retries = res.data.card_status.cards[i].applications[j].pin1_retries; 99 puk1_retries = res.data.card_status.cards[i].applications[j].puk1_retries; 100 } 101 102 pin2_state = res.data.card_status.cards[i].applications[j].pin2_state; 103 pin2_retries = res.data.card_status.cards[i].applications[j].pin2_retries; 104 puk2_retries = res.data.card_status.cards[i].applications[j].puk2_retries; 105 has_pin2 = true; 106 107 break; /* handle first application only for now */ 108 } 109 110 if (card_application_state > QMI_UIM_CARD_APPLICATION_STATE_READY) 111 card_application_state = QMI_UIM_CARD_APPLICATION_STATE_UNKNOWN; 112 113 blobmsg_add_u32(&status, "card_slot", i + 1); /* Slot is idx + 1 */ 114 blobmsg_add_string(&status, "card_application_state", card_application_states[card_application_state]); 115 blobmsg_add_string(&status, "pin1_status", get_pin_status(pin1_state)); 116 blobmsg_add_u32(&status, "pin1_verify_tries", pin1_retries); 117 blobmsg_add_u32(&status, "pin1_unlock_tries", puk1_retries); 118 if (has_pin2) { 119 blobmsg_add_string(&status, "pin2_status", get_pin_status(pin2_state)); 120 blobmsg_add_u32(&status, "pin2_verify_tries", pin2_retries); 121 blobmsg_add_u32(&status, "pin2_unlock_tries", puk2_retries); 122 } 123 124 break; /* handle only first preset SIM card for now */ 125 } 126 127 blobmsg_close_table(&status, card_table); 128 } 129 130 static enum qmi_cmd_result 131 cmd_uim_get_sim_state_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg) 132 { 133 qmi_set_uim_get_card_status_request(msg); 134 return QMI_CMD_REQUEST; 135 } 136 137 #define cmd_uim_slot_cb no_cb 138 static enum qmi_cmd_result 139 cmd_uim_slot_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg) 140 { 141 char *err; 142 int value = strtoul(arg, &err, 10); 143 if ((err && *err) || value < 1 || value > 2) { 144 uqmi_add_error("Invalid UIM-Slot value. Allowed: [1,2]"); 145 return QMI_CMD_EXIT; 146 } 147 148 uim_slot = value; 149 150 return QMI_CMD_DONE; 151 } 152 153 #define cmd_uim_power_off_cb no_cb 154 static enum qmi_cmd_result 155 cmd_uim_power_off_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg) 156 { 157 struct qmi_uim_power_off_sim_request data = { 158 QMI_INIT(slot, uim_slot) 159 }; 160 161 if (!uim_slot) { 162 uqmi_add_error("UIM-Slot not set. Use --uim-slot <slot> to set it."); 163 return QMI_CMD_EXIT; 164 } 165 166 qmi_set_uim_power_off_sim_request(msg, &data); 167 return QMI_CMD_REQUEST; 168 } 169 170 #define cmd_uim_power_on_cb no_cb 171 static enum qmi_cmd_result 172 cmd_uim_power_on_prepare(struct qmi_dev *qmi, struct qmi_request *req, struct qmi_msg *msg, char *arg) 173 { 174 struct qmi_uim_power_on_sim_request data = { 175 QMI_INIT(slot, uim_slot) 176 }; 177 178 if (!uim_slot) { 179 uqmi_add_error("UIM-Slot not set. Use --uim-slot <slot> to set it."); 180 return QMI_CMD_EXIT; 181 } 182 183 qmi_set_uim_power_on_sim_request(msg, &data); 184 return QMI_CMD_REQUEST; 185 } 186
This page was automatically generated by LXR 0.3.1. • OpenWrt