4 * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
28 #include <core_object.h>
39 #include "imc_common.h"
42 #define DISABLE_FLAG 2
44 #define IMC_SIM_ACCESS_READ_BINARY 176
45 #define IMC_SIM_ACCESS_READ_RECORD 178
46 #define IMC_SIM_ACCESS_GET_RESPONSE 192
47 #define IMC_SIM_ACCESS_UPDATE_BINARY 214
48 #define IMC_SIM_ACCESS_UPDATE_RECORD 220
50 #define IMC_SIM_READ_FILE(co, cb, cb_data, fileId, ret) \
52 ImcSimMetaInfo file_meta = {0, }; \
53 ImcRespCbData *resp_cb_data = NULL; \
55 file_meta.file_id = fileId; \
56 file_meta.file_result = TEL_SIM_RESULT_FAILURE; \
58 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, &file_meta, sizeof(ImcSimMetaInfo)); \
60 ret = __imc_sim_get_response(co, resp_cb_data); \
61 dbg("Request reading '%s' - [%s]", #fileId, (ret == TEL_RETURN_SUCCESS ? "SUCCESS" : "FAILURE")); \
65 IMC_SIM_FILE_TYPE_DEDICATED = 0x00, /**< Dedicated */
66 IMC_SIM_FILE_TYPE_TRANSPARENT = 0x01, /**< Transparent -binary type*/
67 IMC_SIM_FILE_TYPE_LINEAR_FIXED = 0x02, /**< Linear fixed - record type*/
68 IMC_SIM_FILE_TYPE_CYCLIC = 0x04, /**< Cyclic - record type*/
69 IMC_SIM_FILE_TYPE_INVALID_TYPE = 0xFF /**< Invalid type */
73 IMC_SIM_CURR_SEC_OP_PIN1_VERIFY,
74 IMC_SIM_CURR_SEC_OP_PIN2_VERIFY,
75 IMC_SIM_CURR_SEC_OP_PUK1_VERIFY,
76 IMC_SIM_CURR_SEC_OP_PUK2_VERIFY,
77 IMC_SIM_CURR_SEC_OP_SIM_VERIFY,
78 IMC_SIM_CURR_SEC_OP_ADM_VERIFY,
79 IMC_SIM_CURR_SEC_OP_PIN1_CHANGE,
80 IMC_SIM_CURR_SEC_OP_PIN2_CHANGE,
81 IMC_SIM_CURR_SEC_OP_PIN1_ENABLE,
82 IMC_SIM_CURR_SEC_OP_PIN1_DISABLE,
83 IMC_SIM_CURR_SEC_OP_PIN2_ENABLE,
84 IMC_SIM_CURR_SEC_OP_PIN2_DISABLE, // 10
85 IMC_SIM_CURR_SEC_OP_SIM_ENABLE,
86 IMC_SIM_CURR_SEC_OP_SIM_DISABLE,
87 IMC_SIM_CURR_SEC_OP_NET_ENABLE,
88 IMC_SIM_CURR_SEC_OP_NET_DISABLE,
89 IMC_SIM_CURR_SEC_OP_NS_ENABLE,
90 IMC_SIM_CURR_SEC_OP_NS_DISABLE,
91 IMC_SIM_CURR_SEC_OP_SP_ENABLE,
92 IMC_SIM_CURR_SEC_OP_SP_DISABLE,
93 IMC_SIM_CURR_SEC_OP_CP_ENABLE,
94 IMC_SIM_CURR_SEC_OP_CP_DISABLE, // 20
95 IMC_SIM_CURR_SEC_OP_FDN_ENABLE,
96 IMC_SIM_CURR_SEC_OP_FDN_DISABLE,
97 IMC_SIM_CURR_SEC_OP_PIN1_STATUS,
98 IMC_SIM_CURR_SEC_OP_PIN2_STATUS,
99 IMC_SIM_CURR_SEC_OP_FDN_STATUS,
100 IMC_SIM_CURR_SEC_OP_NET_STATUS,
101 IMC_SIM_CURR_SEC_OP_NS_STATUS,
102 IMC_SIM_CURR_SEC_OP_SP_STATUS,
103 IMC_SIM_CURR_SEC_OP_CP_STATUS,
104 IMC_SIM_CURR_SEC_OP_SIM_STATUS,
105 IMC_SIM_CURR_SEC_OP_SIM_UNKNOWN = 0xff
109 guint smsp_count; /**< SMSP record count */
110 guint smsp_rec_len; /**< SMSP record length */
114 gboolean b_valid; /**< Valid or not */
115 guint rec_length; /**< Length of one record in file */
116 guint rec_count; /**< Number of records in file */
117 guint data_size; /**< File size */
118 guint current_index; /**< Current index to read */
119 ImcSimFileType file_type; /**< File type and structure */
120 ImcSimCurrSecOp sec_op; /**< Current index to read */
121 TelSimMailboxList mbi_list; /**< Mailbox List */
122 TelSimMailBoxNumber mb_list[TEL_SIM_MSP_CNT_MAX*5]; /**< Mailbox number */
123 TelSimFileId file_id; /**< Current file id */
124 TelSimResult file_result; /**< File access result */
125 TelSimFileResult files; /**< File read data */
126 TcoreCommand req_command; /**< Request command Id */
127 TelSimImsiInfo imsi; /**< Stored locally as of now,
128 Need to store in secure storage*/
131 /* Utility Function Declaration */
132 static TelSimResult __imc_sim_decode_status_word(unsigned short status_word1, unsigned short status_word2);
133 static void __imc_sim_update_sim_status(CoreObject *co, TelSimCardStatus sim_status);
134 static void __imc_sim_notify_sms_state(CoreObject *co, gboolean sms_ready);
135 static TelReturn __imc_sim_start_to_cache(CoreObject *co);
136 static gboolean __imc_sim_get_sim_type(CoreObject *co, TcoreObjectResponseCallback cb, void *cb_data);
137 static void __imc_sim_next_from_read_binary(CoreObject *co, ImcRespCbData *resp_cb_data, TelSimResult sim_result, gboolean decode_ret);
138 static void __imc_sim_next_from_get_response(CoreObject *co, ImcRespCbData *resp_cb_data, TelSimResult sim_result);
139 static TelReturn __imc_sim_update_file(CoreObject *co, ImcRespCbData *resp_cb_data, int cmd, TelSimFileId ef,
140 int p1, int p2, int p3, char *encoded_data);
141 static void __imc_sim_read_record(CoreObject *co, ImcRespCbData *resp_cb_data);
142 static void __imc_sim_read_binary(CoreObject *co, ImcRespCbData *resp_cb_data);
143 static TelReturn __imc_sim_get_response (CoreObject *co, ImcRespCbData *resp_cb_data);
144 static TelReturn __imc_sim_get_retry_count(CoreObject *co, ImcRespCbData *resp_cb_data);
145 static TelSimLockType __imc_sim_lock_type(int lock_type);
146 static char *__imc_sim_get_fac_from_lock_type(TelSimLockType lock_type, ImcSimCurrSecOp *sec_op, int flag);
147 static int __imc_sim_get_lock_type(ImcSimCurrSecOp sec_op);
149 /* Internal Response Functions*/
150 static void __on_response_imc_sim_get_sim_type_internal(CoreObject *co, gint result, const void *response, void *user_data);
151 static void __on_response_imc_sim_get_sim_type(TcorePending *p, guint data_len, const void *data, void *user_data);
152 static void __on_response_imc_sim_read_data(TcorePending *p, guint data_len, const void *data, void *user_data);
153 static void __on_response_imc_sim_get_response(TcorePending *p, guint data_len, const void *data, void *user_data);
154 static void __on_response_imc_sim_get_retry_count(TcorePending *p, guint data_len, const void *data, void *user_data);
155 static void __on_response_imc_sim_update_file(TcorePending *p, guint data_len, const void *data, void *user_data);
157 /* GET SMSP info for SMS module */
158 gboolean imc_sim_get_smsp_info(TcorePlugin *plugin, int *rec_count, int *rec_len)
160 CoreObject *co = NULL;
161 ImcSimPrivateInfo *priv_info = NULL;
165 co = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SIM);
166 priv_info = tcore_sim_ref_userdata(co);
170 *rec_count = priv_info->smsp_count;
171 *rec_len = priv_info->smsp_rec_len;
173 dbg("smsp_count:[%d], smsp_rec_len:[%d]", priv_info->smsp_count, priv_info->smsp_rec_len);
177 static void __imc_sim_set_identity(CoreObject *co, TelSimImsiInfo *imsi)
179 gchar new_imsi[15 + 1] = {0, };
182 memcpy(&new_imsi, imsi->mcc, strlen(imsi->mcc));
183 memcpy(&new_imsi[strlen(imsi->mcc)], imsi->mnc, strlen(imsi->mnc));
184 memcpy(&new_imsi[strlen(imsi->mcc) + strlen(imsi->mnc)], imsi->msin, strlen(imsi->msin));
186 /* TODO: This is temporary code, we should use secure storage instead of vconf */
187 old_imsi = vconf_get_str("db/telephony/imsi");
189 if (g_strcmp0(old_imsi, new_imsi) != 0) {
191 vconf_set_str("db/telephony/imsi", new_imsi);
192 tcore_sim_set_identification(co, TRUE);
195 tcore_sim_set_identification(co, FALSE);
198 dbg("Old IMSI value is NULL, set IMSI");
199 vconf_set_str("db/telephony/imsi", new_imsi);
200 tcore_sim_set_identification(co, TRUE);
204 /* Utility Functions */
205 static TelSimResult __imc_sim_decode_status_word(unsigned short status_word1, unsigned short status_word2)
207 TelSimResult rst = TEL_SIM_RESULT_FAILURE;
209 if (status_word1 == 0x93 && status_word2 == 0x00) {
210 /*Failed SIM request command*/
211 dbg("error - SIM application toolkit busy [%x][%x]", status_word1, status_word2);
212 } else if (status_word1 == 0x94 && status_word2 == 0x00) {
213 /*Failed SIM request command*/
214 dbg("error - No EF Selected [%x][%x]", status_word1, status_word2);
215 } else if (status_word1 == 0x94 && status_word2 == 0x02) {
216 /*Failed SIM request command*/
217 dbg("error - Out of Range - Invalid address or record number[%x][%x]",
218 status_word1, status_word2);
219 } else if (status_word1 == 0x94 && status_word2 == 0x04) {
220 /*Failed SIM request command*/
221 dbg("error - File ID not found [%x][%x]", status_word1, status_word2);
222 } else if (status_word1 == 0x94 && status_word2 == 0x08) {
223 /*Failed SIM request command*/
224 dbg("error - File is inconsistent with command - Modem not support or USE IPC [%x][%x]",
225 status_word1, status_word2);
226 } else if (status_word1 == 0x98 && status_word2 == 0x02) {
227 /*Failed SIM request command*/
228 dbg("error - CHV not initialized [%x][%x]", status_word1, status_word2);
229 } else if (status_word1 == 0x98 && status_word2 == 0x04) {
230 /*Failed SIM request command*/
231 dbg("error - Access condition not fullfilled [%x][%x]", status_word1, status_word2);
232 dbg("error -Unsuccessful CHV verification - at least one attempt left [%x][%x]",
233 status_word1, status_word2);
234 dbg("error - Unsuccessful Unblock CHV - at least one attempt left [%x][%x]",
235 status_word1, status_word2);
236 dbg("error - Authentication failure [%x][%x]", status_word1, status_word2);
237 } else if (status_word1 == 0x98 && status_word2 == 0x08) {
238 /*Failed SIM request command*/
239 dbg("error - Contradiction with CHV status [%x][%x]", status_word1, status_word2);
240 } else if (status_word1 == 0x98 && status_word2 == 0x10) {
241 /*Failed SIM request command*/
242 dbg("error - Contradiction with invalidation status [%x][%x]",
243 status_word1, status_word2);
244 } else if (status_word1 == 0x98 && status_word2 == 0x40) {
245 /*Failed SIM request command*/
246 dbg("error -Unsuccessful CHV verification - no attempt left [%x][%x]",
247 status_word1, status_word2);
248 dbg("error - Unsuccessful Unblock CHV - no attempt left [%x][%x]",
249 status_word1, status_word2);
250 dbg("error - CHV blocked [%x][%x]", status_word1, status_word2);
251 } else if (status_word1 == 0x67 && status_word2 == 0x00) {
252 dbg("error -Incorrect Parameter 3 [%x][%x]", status_word1, status_word2);
253 } else if (status_word1 == 0x6B && status_word2 == 0x00) {
254 dbg("error -Incorrect Parameter 1 or 2 [%x][%x]", status_word1, status_word2);
255 } else if (status_word1 == 0x6D && status_word2 == 0x00) {
256 dbg("error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
257 } else if (status_word1 == 0x6E && status_word2 == 0x00) {
258 dbg("error -Unknown instruction given as command [%x][%x]", status_word1, status_word2);
259 } else if (status_word1 == 0x69 && status_word2 == 0x82) {
260 dbg("error -Access denied [%x][%x]", status_word1, status_word2);
261 } else if (status_word1 == 0x6A && status_word2 == 0x87) {
262 dbg("error -Incorrect parameters [%x][%x]", status_word1, status_word2);
263 } else if (status_word1 == 0x6A && status_word2 == 0x82) {
264 dbg("error -File Not found [%x][%x]", status_word1, status_word2);
265 } else if (status_word1 == 0x6A && status_word2 == 0x83) {
266 dbg("error -Record Not found [%x][%x]", status_word1, status_word2);
268 rst = TEL_SIM_RESULT_CARD_ERROR;
269 dbg("error -Unknown state [%x][%x]", status_word1, status_word2);
274 static void __imc_sim_update_sim_status(CoreObject *co, TelSimCardStatus sim_status)
276 TelSimCardStatus curr_sim_status;
279 * Send SIM Init status, if not sent already
281 (void)tcore_sim_get_status(co, &curr_sim_status);
282 if (sim_status != curr_sim_status) {
283 TelSimCardStatusInfo sim_status_noti = {0, };
285 dbg("Change in SIM State - Old State: [0x%02x] --> New State: [0x%02x]",
286 curr_sim_status, sim_status);
288 /* Update SIM Status */
289 tcore_sim_set_status(co, sim_status);
290 sim_status_noti.status = sim_status;
291 tcore_sim_get_identification(co, &sim_status_noti.change_status);
293 /* Send notification: SIM Status */
294 tcore_object_send_notification(co,
295 TCORE_NOTIFICATION_SIM_STATUS,
296 sizeof(sim_status_noti), &sim_status_noti);
300 static void __imc_sim_notify_sms_state(CoreObject *co,
305 gboolean sms_status = FALSE;
309 plugin = tcore_object_ref_plugin(co);
310 co_sms = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SMS);
311 tcore_check_return_assert(co_sms != NULL);
313 (void)tcore_sms_get_ready_status(co_sms, &sms_status);
314 if (sms_status == sms_ready) {
315 dbg("No change in SMS Status: [%s]",
316 (sms_status ? "INITIALIZED" : "UNINITIALIZED"));
318 TelSimCardStatus sim_status;
320 /* Update SMS State */
321 tcore_sms_set_ready_status(co_sms, sms_ready);
323 dbg("SMS Status - Changed [%s] --> [%s]",
324 (sms_status ? "INITIALIZED" : "UNINITIALIZED"),
325 (sms_ready ? "INITIALIZED" : "UNINITIALIZED"));
328 * Send SMS device ready notification, if SIM is initialiazed.
330 (void)tcore_sim_get_status(co, &sim_status);
331 if (sim_status == TEL_SIM_STATUS_SIM_INIT_COMPLETED) {
332 /* Send notification: SMS Device ready */
333 tcore_object_send_notification(co_sms,
334 TCORE_NOTIFICATION_SMS_DEVICE_READY,
335 sizeof(sms_ready), &sms_ready);
340 TelReturn __imc_sim_start_to_cache(CoreObject *co)
343 IMC_SIM_READ_FILE(co, NULL, NULL, TEL_SIM_EF_IMSI, ret);
344 IMC_SIM_READ_FILE(co, NULL, NULL, TEL_SIM_EF_CPHS_CPHS_INFO, ret);
345 IMC_SIM_READ_FILE(co, NULL, NULL, TEL_SIM_EF_ICCID, ret);
346 IMC_SIM_READ_FILE(co, NULL, NULL, TEL_SIM_EF_SPN, ret);
347 IMC_SIM_READ_FILE(co, NULL, NULL, TEL_SIM_EF_SST, ret);
348 IMC_SIM_READ_FILE(co, NULL, NULL, TEL_SIM_EF_ECC, ret);
349 IMC_SIM_READ_FILE(co, NULL, NULL, TEL_SIM_EF_MSISDN, ret);
350 IMC_SIM_READ_FILE(co, NULL, NULL, TEL_SIM_EF_SMSP, ret);
355 static void __on_response_imc_sim_get_sim_type_internal(CoreObject *co,
356 gint result, const void *response, void *user_data)
358 dbg("SIM Response - SIM Type (internal): [+XUICC]");
360 if (result == TEL_SIM_RESULT_SUCCESS) {
361 TelSimCardType *sim_type = (TelSimCardType *)response;
362 dbg("SIM Type: [%d]", *sim_type);
364 /* Update SIM type */
365 tcore_sim_set_type(co, *sim_type);
366 if (*sim_type != TEL_SIM_CARD_TYPE_UNKNOWN) {
369 /* Start Caching SIM files */
370 ret = __imc_sim_start_to_cache(co);
372 /* Send SIM Type notification */
373 tcore_object_send_notification(co,
374 TCORE_NOTIFICATION_SIM_TYPE,
375 sizeof(TelSimCardType), sim_type);
380 static void __on_response_imc_sim_get_sim_type(TcorePending *p,
381 guint data_len, const void *data, void *user_data)
383 const TcoreAtResponse *at_resp = data;
384 CoreObject *co = tcore_pending_ref_core_object(p);
385 ImcRespCbData *resp_cb_data = user_data;
386 TelSimCardType sim_type = TEL_SIM_CARD_TYPE_UNKNOWN;
388 TelSimResult result = TEL_SIM_RESULT_FAILURE;
390 dbg("SIM Response - SIM Type: [+XUICC]");
392 tcore_check_return_assert(co != NULL);
393 tcore_check_return_assert(resp_cb_data != NULL);
395 if (at_resp && at_resp->success) {
396 if (at_resp->lines) {
400 line = (const gchar *)at_resp->lines->data;
407 tokens = tcore_at_tok_new(line);
410 if (g_slist_length(tokens) == 1) {
411 guint state = atoi(g_slist_nth_data(tokens, 0));
413 if (state == 0) /* 0 - 2G SIM */
414 sim_type = TEL_SIM_CARD_TYPE_GSM;
415 else if (state == 1) /* 1 - 3G SIM */
416 sim_type = TEL_SIM_CARD_TYPE_USIM;
418 result = TEL_SIM_RESULT_SUCCESS;
421 err("Invalid message");
424 tcore_at_tok_free(tokens);
428 /* Invoke callback */
429 if (resp_cb_data->cb)
430 resp_cb_data->cb(co, (gint)result, &sim_type, resp_cb_data->cb_data);
432 /* Free callback data */
433 imc_destroy_resp_cb_data(resp_cb_data);
437 * Operation - get_sim_type
440 * AT-Command: AT+XUICC?
442 * Response - sim_type (TelSimCardType)
443 * Success: (Single line) -
447 * +CME ERROR: <error>
449 gboolean __imc_sim_get_sim_type(CoreObject *co,
450 TcoreObjectResponseCallback cb, void *cb_data)
452 ImcRespCbData *resp_cb_data;
455 /* Response callback data */
456 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
459 /* Send Request to modem */
460 ret = tcore_at_prepare_and_send_request(co,
461 "AT+XUICC?", "+XUICC:",
462 TCORE_AT_COMMAND_TYPE_SINGLELINE,
463 TCORE_PENDING_PRIORITY_DEFAULT,
465 __on_response_imc_sim_get_sim_type, resp_cb_data,
466 on_send_imc_request, NULL,
468 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SIM Type");
473 static void __imc_sim_process_sim_status(CoreObject *co, guint sim_state)
475 TelSimCardStatus sim_card_status;
479 sim_card_status = TEL_SIM_STATUS_CARD_NOT_PRESENT;
484 sim_card_status = TEL_SIM_STATUS_SIM_PIN_REQUIRED;
489 sim_card_status = TEL_SIM_STATUS_SIM_INITIALIZING;
490 dbg("PIN DISABLED AT BOOT UP");
494 sim_card_status = TEL_SIM_STATUS_SIM_INITIALIZING;
499 sim_card_status = TEL_SIM_STATUS_SIM_PUK_REQUIRED;
504 sim_card_status = TEL_SIM_STATUS_SIM_PUK_REQUIRED;
505 dbg("CARD PERMANENTLY BLOCKED");
509 sim_card_status = TEL_SIM_STATUS_CARD_ERROR;
510 dbg("SIM CARD ERROR");
514 sim_card_status = TEL_SIM_STATUS_SIM_INIT_COMPLETED;
515 dbg("SIM INIT COMPLETED");
519 sim_card_status = TEL_SIM_STATUS_CARD_ERROR;
520 dbg("SIM CARD ERROR");
524 sim_card_status = TEL_SIM_STATUS_CARD_REMOVED;
529 dbg("SIM SMS Ready");
531 /* Notify SMS status */
532 return __imc_sim_notify_sms_state(co, TRUE);
535 sim_card_status = TEL_SIM_STATUS_UNKNOWN;
536 dbg("SIM STATE UNKNOWN");
540 err("Unknown/Unsupported SIM state: [%d]", sim_state);
544 switch (sim_card_status) {
545 case TEL_SIM_STATUS_SIM_INIT_COMPLETED: {
546 TelSimCardType sim_type;
548 dbg("SIM INIT COMPLETED");
550 (void)tcore_sim_get_type(co, &sim_type);
551 if (sim_type == TEL_SIM_CARD_TYPE_UNKNOWN) {
553 * SIM is initialized for first time, need to
556 (void)__imc_sim_get_sim_type(co,
557 __on_response_imc_sim_get_sim_type_internal, NULL);
564 case TEL_SIM_STATUS_CARD_REMOVED:
565 dbg("SIM CARD REMOVED");
566 tcore_sim_set_type(co, TEL_SIM_CARD_TYPE_UNKNOWN);
569 case TEL_SIM_STATUS_CARD_NOT_PRESENT:
570 dbg("SIM CARD NOT PRESENT");
571 tcore_sim_set_type(co, TEL_SIM_CARD_TYPE_UNKNOWN);
574 case TEL_SIM_STATUS_CARD_ERROR:
575 dbg("SIM CARD ERROR");
576 tcore_sim_set_type(co, TEL_SIM_CARD_TYPE_UNKNOWN);
580 err("SIM Status: [0x%02x]", sim_card_status);
584 /* Update SIM Status */
585 return __imc_sim_update_sim_status(co, sim_card_status);
588 static void __on_response_imc_sim_get_sim_status(TcorePending *p,
589 guint data_len, const void *data, void *user_data)
591 const TcoreAtResponse *at_resp = data;
592 CoreObject *co = tcore_pending_ref_core_object(p);
593 ImcRespCbData *resp_cb_data = (ImcRespCbData *)user_data;
596 dbg("SIM Response - SIM status: [+XSIMSTATE]");
598 tcore_check_return_assert(co != NULL);
599 tcore_check_return_assert(resp_cb_data != NULL);
601 if (at_resp && at_resp->success) {
602 if (at_resp->lines) {
603 const gchar *line = NULL;
605 /* Process +XSIMSTATE response */
606 line = (const gchar *) (at_resp->lines->data);
609 guint sim_state, sms_state;
614 * +XSIMSTATE: <mode>,<SIM state>,<PB Ready>,<SMS Ready>
616 tokens = tcore_at_tok_new(line);
618 if (g_slist_length(tokens) == 4) {
620 sim_state = atoi(g_slist_nth_data(tokens, 1));
622 /* Process SIM Status */
623 __imc_sim_process_sim_status(co, sim_state);
626 sms_state = atoi(g_slist_nth_data(tokens, 3));
628 /* Notify SMS status */
629 __imc_sim_notify_sms_state(co, (sms_state > 0));
632 err("Invalid message");
635 tcore_at_tok_free(tokens);
640 /* Free callback data */
641 imc_destroy_resp_cb_data(resp_cb_data);
645 * Operation - get_sim_status
648 * AT-Command: AT+XSIMSTATE?
650 * Response - sim_status
651 * Success: (Single line) -
652 * +XSIMSTATE: <mode>,<SIM state>,<PB Ready>,<SMS Ready>
655 * +CME ERROR: <error>
657 static gboolean __imc_sim_get_sim_status(CoreObject *co,
658 TcoreObjectResponseCallback cb, void *cb_data)
660 ImcRespCbData *resp_cb_data;
663 /* Response callback data */
664 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
667 /* Send Request to modem */
668 ret = tcore_at_prepare_and_send_request(co,
669 "AT+XSIMSTATE?", "+XSIMSTATE:",
670 TCORE_AT_COMMAND_TYPE_SINGLELINE,
671 TCORE_PENDING_PRIORITY_DEFAULT,
673 __on_response_imc_sim_get_sim_status, resp_cb_data,
674 on_send_imc_request, NULL,
676 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SIM Status");
681 static void __imc_sim_next_from_read_binary(CoreObject *co, ImcRespCbData *resp_cb_data, TelSimResult sim_result, gboolean decode_ret)
683 ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
684 TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
688 dbg("[SIM]EF[0x%x] read sim_result[%d] Decode rt[%d]", file_meta->file_id, sim_result, decode_ret);
689 switch (file_meta->file_id) {
691 case TEL_SIM_EF_USIM_PL:
693 case TEL_SIM_EF_USIM_LI:
694 if (decode_ret == TRUE) {
695 if (resp_cb_data->cb)
696 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
698 tcore_sim_get_type(co, &card_type);
700 /* The ME requests the Extended Language Preference. The ME only requests the Language Preference (EFLP) if at least one of the following conditions holds:
701 - EFELP is not available;
702 - EFELP does not contain an entry corresponding to a language specified in ISO 639[30];
703 - the ME does not support any of the languages in EFELP.
706 /* The ME only requests the Language Preference (EFPL) if at least one of the following conditions holds:
707 - if the EFLI has the value 'FFFF' in its highest priority position
708 - if the ME does not support any of the language codes indicated in EFLI , or if EFLI is not present
710 if (TEL_SIM_CARD_TYPE_GSM == card_type) {
711 if (file_meta->file_id == TEL_SIM_EF_LP) {
712 if (resp_cb_data->cb)
713 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
715 file_meta->file_id = TEL_SIM_EF_LP;
716 __imc_sim_get_response(co, resp_cb_data);
718 } else if (TEL_SIM_CARD_TYPE_USIM) {
719 if (file_meta->file_id == TEL_SIM_EF_LP || file_meta->file_id == TEL_SIM_EF_USIM_LI) {
720 file_meta->file_id = TEL_SIM_EF_ELP;
721 __imc_sim_get_response(co, resp_cb_data);
723 if (resp_cb_data->cb)
724 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
731 tcore_sim_get_type(co, &card_type);
732 if (TEL_SIM_CARD_TYPE_USIM == card_type) {
733 if (file_meta->current_index == file_meta->rec_count) {
734 if (resp_cb_data->cb)
735 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
737 file_meta->current_index++;
738 __imc_sim_read_record(co, resp_cb_data);
740 } else if (TEL_SIM_CARD_TYPE_GSM == card_type) {
741 if (resp_cb_data->cb)
742 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
744 dbg("[SIM DATA]Invalid CardType[%d] Unable to handle", card_type);
748 case TEL_SIM_EF_IMSI:
749 if (resp_cb_data->cb) {
750 resp_cb_data->cb(co, (gint)sim_result, &file_meta->imsi, resp_cb_data->cb_data);
752 file_meta->file_id = TEL_SIM_EF_CPHS_CPHS_INFO;
753 file_meta->file_result = TEL_SIM_RESULT_FAILURE;
754 __imc_sim_get_response(co, resp_cb_data);
756 /* Update SIM INIT status - INIT COMPLETE */
757 __imc_sim_update_sim_status(co, TEL_SIM_STATUS_SIM_INIT_COMPLETED);
760 case TEL_SIM_EF_MSISDN:
761 if (file_meta->current_index == file_meta->rec_count) {
763 dbg("rec_count [%d], msisdn_count[%d]", file_meta->rec_count,
764 file_meta->files.data.msisdn_list.count);
765 if (resp_cb_data->cb) {
766 resp_cb_data->cb(co, (gint)sim_result,
767 &file_meta->files.data.msisdn_list, resp_cb_data->cb_data);
771 for (i = 0; i < file_meta->files.data.msisdn_list.count; i++) {
772 tcore_free(file_meta->files.data.msisdn_list.list[i].alpha_id);
773 tcore_free(file_meta->files.data.msisdn_list.list[i].num);
775 tcore_free(file_meta->files.data.msisdn_list.list);
777 file_meta->current_index++;
778 __imc_sim_read_record(co, resp_cb_data);
783 if (file_meta->current_index == file_meta->rec_count) {
784 if (resp_cb_data->cb)
785 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
788 file_meta->current_index++;
789 __imc_sim_read_record(co, resp_cb_data);
794 if (file_meta->current_index == file_meta->rec_count) {
795 if (resp_cb_data->cb)
796 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
798 file_meta->current_index++;
799 __imc_sim_read_record(co, resp_cb_data);
803 case TEL_SIM_EF_USIM_CFIS:
804 case TEL_SIM_EF_USIM_MWIS:
805 case TEL_SIM_EF_USIM_MBI:
806 case TEL_SIM_EF_MBDN:
807 case TEL_SIM_EF_CPHS_MAILBOX_NUMBERS:
808 case TEL_SIM_EF_CPHS_INFORMATION_NUMBERS:
809 if (file_meta->current_index == file_meta->rec_count) {
810 if (resp_cb_data->cb)
811 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
813 file_meta->current_index++;
814 __imc_sim_read_record(co, resp_cb_data);
818 case TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING:
820 ImcSimMetaInfo *file_meta_new = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
822 file_meta->files.result = sim_result;
823 if (decode_ret == TRUE && sim_result == TEL_SIM_RESULT_SUCCESS) {
824 file_meta_new->files.data.cphs_net.full_name = file_meta->files.data.cphs_net.full_name;
825 dbg("file_meta_new->files.data.cphs_net.full_name[%s]", file_meta_new->files.data.cphs_net.full_name);
828 file_meta_new->file_id = TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING;
829 file_meta_new->file_result = TEL_SIM_RESULT_FAILURE;
831 __imc_sim_get_response(co, resp_cb_data);
835 case TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
836 if (resp_cb_data->cb)
837 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data.cphs_net, resp_cb_data->cb_data);
839 tcore_free(file_meta->files.data.cphs_net.full_name);
840 tcore_free(file_meta->files.data.cphs_net.short_name);
841 file_meta->files.data.cphs_net.full_name = NULL;
842 file_meta->files.data.cphs_net.short_name = NULL;
845 case TEL_SIM_EF_ICCID:
846 if (resp_cb_data->cb)
847 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data.iccid, resp_cb_data->cb_data);
850 case TEL_SIM_EF_SPDI: {
852 dbg("spdi count[%d]", file_meta->files.data.spdi.count);
854 if (resp_cb_data->cb)
855 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
858 for (i = 0; i < file_meta->files.data.spdi.count; i++)
859 tcore_free(file_meta->files.data.spdi.list[i].plmn);
861 tcore_free(file_meta->files.data.spdi.list);
867 case TEL_SIM_EF_OPLMN_ACT:
868 case TEL_SIM_EF_CPHS_CPHS_INFO:
869 case TEL_SIM_EF_CPHS_CALL_FORWARD_FLAGS:
870 case TEL_SIM_EF_CPHS_VOICE_MSG_WAITING:
871 case TEL_SIM_EF_CPHS_DYNAMICFLAGS:
872 case TEL_SIM_EF_CPHS_DYNAMIC2FLAG:
873 case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
874 case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
875 if (resp_cb_data->cb)
876 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
880 err("File id not handled [0x%x]", file_meta->file_id);
885 static void __imc_sim_next_from_get_response(CoreObject *co, ImcRespCbData *resp_cb_data, TelSimResult sim_result)
887 ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
888 TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
890 dbg("EF[0x%x] access Result[%d]", file_meta->file_id, sim_result);
892 file_meta->files.result = sim_result;
893 if (file_meta->file_id != TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING)
894 memset(&file_meta->files.data, 0x00, sizeof(file_meta->files.data));
896 if ((file_meta->file_id != TEL_SIM_EF_ELP && file_meta->file_id != TEL_SIM_EF_LP &&
897 file_meta->file_id != TEL_SIM_EF_USIM_PL && file_meta->file_id != TEL_SIM_EF_CPHS_CPHS_INFO)
898 && (sim_result != TEL_SIM_RESULT_SUCCESS)) {
899 if (resp_cb_data->cb)
900 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
904 switch (file_meta->file_id) {
906 if (sim_result == TEL_SIM_RESULT_SUCCESS) {
907 dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
908 __imc_sim_read_binary(co, resp_cb_data);
910 tcore_sim_get_type(co, &card_type);
911 if (TEL_SIM_CARD_TYPE_GSM == card_type) {
912 ImcSimMetaInfo file_meta_new = {0,};
914 dbg("[SIM DATA]SIM_EF_ELP(2F05) access fail. Request SIM_EF_LP(0x6F05) info");
915 /* The ME requests the Language Preference (EFLP) if EFELP is not available */
916 file_meta_new.file_id = TEL_SIM_EF_LP;
917 file_meta_new.file_result = TEL_SIM_RESULT_FAILURE;
918 file_meta_new.req_command = TCORE_COMMAND_SIM_GET_LANGUAGE;
920 memcpy(resp_cb_data->data, &file_meta_new, sizeof(ImcSimMetaInfo));
922 __imc_sim_get_response(co, resp_cb_data);
923 } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
924 dbg(" [SIM DATA]fail to get Language information in USIM(EF-LI(6F05),EF-PL(2F05))");
925 if (resp_cb_data->cb)
926 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
933 if (sim_result == TEL_SIM_RESULT_SUCCESS) {
934 dbg("[SIM DATA] exist EFLP/LI(0x6F05)");
935 __imc_sim_read_binary(co, resp_cb_data);
937 tcore_sim_get_type(co, &card_type);
938 dbg("[SIM DATA]SIM_EF_LP/LI(6F05) access fail. Current CardType[%d]", card_type);
939 if (TEL_SIM_CARD_TYPE_GSM == card_type) {
940 if (resp_cb_data->cb)
941 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
944 /* if EFLI is not present, then the language selection shall be as defined in EFPL at the MF level */
945 else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
946 ImcSimMetaInfo file_meta_new = {0,};
948 dbg("[SIM DATA] try USIM EFPL(0x2F05)");
949 file_meta_new.file_id = TEL_SIM_EF_ELP;
950 file_meta_new.file_result = TEL_SIM_RESULT_FAILURE;
951 file_meta_new.req_command = TCORE_COMMAND_SIM_GET_LANGUAGE;
953 memcpy(resp_cb_data->data, &file_meta_new, sizeof(ImcSimMetaInfo));
955 __imc_sim_get_response(co, resp_cb_data);
960 case TEL_SIM_EF_USIM_PL:
961 if (sim_result == TEL_SIM_RESULT_SUCCESS) {
962 dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
963 __imc_sim_read_binary(co, resp_cb_data);
965 /* EFELIand EFPL not present, so set language count as zero and select ECC */
967 " [SIM DATA]SIM_EF_USIM_PL(2A05) access fail. Request SIM_EF_ECC(0x6FB7) info");
968 if (resp_cb_data->cb)
969 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
975 tcore_sim_get_type(co, &card_type);
976 if (TEL_SIM_CARD_TYPE_GSM == card_type) {
977 __imc_sim_read_binary(co, resp_cb_data);
978 } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
979 if (file_meta->rec_count > TEL_SIM_ECC_LIST_MAX) {
980 file_meta->rec_count = TEL_SIM_ECC_LIST_MAX;
982 file_meta->current_index++;
983 __imc_sim_read_record(co, resp_cb_data);
987 case TEL_SIM_EF_ICCID:
988 case TEL_SIM_EF_IMSI:
991 case TEL_SIM_EF_SPDI:
992 case TEL_SIM_EF_CPHS_CALL_FORWARD_FLAGS:
993 case TEL_SIM_EF_CPHS_VOICE_MSG_WAITING:
994 case TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING:
995 case TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
996 case TEL_SIM_EF_CPHS_DYNAMICFLAGS:
997 case TEL_SIM_EF_CPHS_DYNAMIC2FLAG:
998 case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
999 case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
1000 __imc_sim_read_binary(co, resp_cb_data);
1003 case TEL_SIM_EF_CPHS_CPHS_INFO:
1004 if (sim_result == TEL_SIM_RESULT_SUCCESS) {
1005 tcore_sim_set_cphs_status(co, TRUE);
1006 __imc_sim_read_binary(co, resp_cb_data);
1008 tcore_sim_set_cphs_status(co, FALSE);
1009 if (resp_cb_data->cb)
1010 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
1015 case TEL_SIM_EF_USIM_CFIS:
1016 if (file_meta->rec_count > TEL_SIM_CALL_FORWARDING_TYPE_MAX) {
1017 file_meta->rec_count = TEL_SIM_CALL_FORWARDING_TYPE_MAX;
1019 file_meta->current_index++;
1020 __imc_sim_read_record(co, resp_cb_data);
1023 case TEL_SIM_EF_MSISDN:
1024 file_meta->files.data.msisdn_list.list =
1025 tcore_malloc0(sizeof(TelSimSubscriberInfo) * file_meta->rec_count);
1027 case TEL_SIM_EF_OPL:
1028 case TEL_SIM_EF_PNN:
1029 case TEL_SIM_EF_USIM_MWIS:
1030 case TEL_SIM_EF_USIM_MBI:
1031 case TEL_SIM_EF_MBDN:
1032 case TEL_SIM_EF_CPHS_MAILBOX_NUMBERS:
1033 case TEL_SIM_EF_CPHS_INFORMATION_NUMBERS:
1034 file_meta->current_index++;
1035 __imc_sim_read_record(co, resp_cb_data);
1038 case TEL_SIM_EF_SMSP:
1040 ImcSimPrivateInfo *priv_info = NULL;
1042 priv_info = tcore_sim_ref_userdata(co);
1044 dbg("SMSP info set to tcore : count:[%d], rec_len:[%d]",file_meta->rec_count, file_meta->rec_length);
1045 priv_info->smsp_count = file_meta->rec_count;
1046 priv_info->smsp_rec_len = file_meta->rec_length;
1051 dbg("error - File id for get file info [0x%x]", file_meta->file_id);
1057 static void __on_response_imc_sim_update_file(TcorePending *p, guint data_len, const void *data, void *user_data)
1059 const TcoreAtResponse *resp = data;
1060 CoreObject *co_sim = NULL;
1061 GSList *tokens = NULL;
1062 TelSimResult sim_result = TEL_SIM_RESULT_CARD_ERROR;
1064 ImcRespCbData *resp_cb_data = (ImcRespCbData *) user_data;
1065 ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1069 co_sim = tcore_pending_ref_core_object(p);
1071 dbg("file_id:[0x%x]", file_meta->file_id);
1073 if (resp->success > 0) {
1078 line = (const char *)resp->lines->data;
1079 tokens = tcore_at_tok_new(line);
1080 if (g_slist_length(tokens) != 2) {
1081 err("Invalid message");
1084 sw1 = atoi(g_slist_nth_data(tokens, 0));
1085 sw2 = atoi(g_slist_nth_data(tokens, 1));
1088 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1089 sim_result = TEL_SIM_RESULT_SUCCESS;
1091 sim_result = __imc_sim_decode_status_word(sw1, sw2);
1094 err("RESPONSE NOK");
1095 sim_result = TEL_SIM_RESULT_FAILURE;
1099 if (resp_cb_data->cb)
1100 resp_cb_data->cb(co_sim, (gint)sim_result, NULL, resp_cb_data->cb_data);
1102 tcore_at_tok_free(tokens);
1106 static void __on_response_imc_sim_read_data(TcorePending *p, guint data_len,
1107 const void *data, void *user_data)
1109 const TcoreAtResponse *resp = data;
1110 CoreObject *co = NULL;
1111 GSList *tokens = NULL;
1112 TelSimResult sim_result;
1113 gboolean dr = FALSE;
1114 const char *line = NULL;
1120 TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
1121 ImcRespCbData *resp_cb_data = (ImcRespCbData *) user_data;
1122 ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1126 co = tcore_pending_ref_core_object(p);
1128 if (resp->success > 0) {
1131 line = (const char *)resp->lines->data;
1132 tokens = tcore_at_tok_new(line);
1133 if (g_slist_length(tokens) != 3) {
1134 err("Invalid message");
1135 tcore_at_tok_free(tokens);
1139 sw1 = atoi(g_slist_nth_data(tokens, 0));
1140 sw2 = atoi(g_slist_nth_data(tokens, 1));
1141 res = g_slist_nth_data(tokens, 2);
1143 tmp = tcore_at_tok_extract(res);
1144 tcore_util_hexstring_to_bytes(tmp, &res, (guint *)&res_len);
1145 dbg("Response: [%s] Response length: [%d]", res, res_len);
1147 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1148 sim_result = TEL_SIM_RESULT_SUCCESS;
1149 file_meta->files.result = sim_result;
1151 dbg("File ID: [0x%x]", file_meta->file_id);
1152 switch (file_meta->file_id) {
1153 case TEL_SIM_EF_IMSI: {
1154 dbg("Data: [%s]", res);
1155 dr = tcore_sim_decode_imsi((unsigned char *)res, res_len, &file_meta->imsi);
1157 err("IMSI decoding failed");
1159 __imc_sim_set_identity(co, &file_meta->imsi);
1162 tcore_sim_set_imsi(co, &file_meta->imsi);
1167 case TEL_SIM_EF_ICCID: {
1168 dr = tcore_sim_decode_iccid((unsigned char *)res, res_len,
1169 file_meta->files.data.iccid);
1173 case TEL_SIM_EF_ELP: /* 2G EF - 2 bytes decoding */
1174 case TEL_SIM_EF_USIM_LI: /* 3G EF - 2 bytes decoding */
1175 case TEL_SIM_EF_USIM_PL: /* 3G EF - same as EFELP, so 2 byte decoding */
1176 case TEL_SIM_EF_LP: /* 1 byte encoding */
1178 tcore_sim_get_type(co, &card_type);
1179 if ((TEL_SIM_CARD_TYPE_GSM == card_type)
1180 && (file_meta->file_id == TEL_SIM_EF_LP)) {
1182 * 2G LP(0x6F05) has 1 byte for each language
1184 dr = tcore_sim_decode_lp((unsigned char *)res, res_len, &file_meta->files.data.language);
1187 * 3G LI(0x6F05)/PL(0x2F05),
1188 * 2G ELP(0x2F05) has 2 bytes for each language
1190 dr = tcore_sim_decode_li((unsigned char *)res, res_len,
1191 file_meta->file_id, &file_meta->files.data.language);
1196 case TEL_SIM_EF_SPN:
1197 dr = tcore_sim_decode_spn((unsigned char *)res, res_len, &file_meta->files.data.spn);
1200 case TEL_SIM_EF_SPDI:
1201 dr = tcore_sim_decode_spdi((unsigned char *)res, res_len, &file_meta->files.data.spdi);
1204 case TEL_SIM_EF_SST:
1206 TelSimServiceTable *svct = NULL;
1208 svct = g_try_new0(TelSimServiceTable, 1);
1209 tcore_sim_get_type(co, &card_type);
1210 svct->sim_type = card_type;
1211 if (TEL_SIM_CARD_TYPE_GSM == card_type) {
1212 dr = tcore_sim_decode_sst((unsigned char *)res, res_len, svct->table.sst_service);
1213 } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
1214 dr = tcore_sim_decode_ust((unsigned char *)res, res_len, svct->table.ust_service);
1216 err("Not handled card_type[%d]", card_type);
1220 err("SST/UST decoding failed");
1222 tcore_sim_set_service_table(co, svct);
1230 case TEL_SIM_EF_ECC:
1232 tcore_sim_get_type(co, &card_type);
1233 if (TEL_SIM_CARD_TYPE_GSM == card_type) {
1234 dr = tcore_sim_decode_ecc((unsigned char *)res, res_len, &file_meta->files.data.ecc);
1235 } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
1236 TelSimEcc *ecc = NULL;
1238 ecc = g_try_new0(TelSimEcc, 1);
1239 dbg("Index [%d]", file_meta->current_index);
1241 dr = tcore_sim_decode_uecc((unsigned char *)res, res_len, ecc);
1243 memcpy(&file_meta->files.data.ecc.list[file_meta->files.data.ecc.count], ecc, sizeof(TelSimEcc));
1244 file_meta->files.data.ecc.count++;
1250 dbg("Unknown/Unsupported SIM card Type: [%d]", card_type);
1255 case TEL_SIM_EF_MSISDN:
1257 TelSimSubscriberInfo *msisdn = NULL;
1259 dbg("Index [%d]", file_meta->current_index);
1260 msisdn = tcore_malloc0(sizeof(TelSimSubscriberInfo));
1261 dr = tcore_sim_decode_msisdn((unsigned char *)res, res_len, msisdn);
1263 memcpy(&file_meta->files.data.msisdn_list.list[file_meta->files.data.msisdn_list.count],
1264 msisdn, sizeof(TelSimSubscriberInfo));
1266 file_meta->files.data.msisdn_list.count++;
1270 dbg("Freeing resources");
1275 case TEL_SIM_EF_OPL:
1277 TelSimOpl *opl = NULL;
1279 dbg("decode w/ index [%d]", file_meta->current_index);
1280 opl = g_try_new0(TelSimOpl, 1);
1282 dr = tcore_sim_decode_opl((unsigned char *)res, res_len, opl);
1284 memcpy(&file_meta->files.data.opl.list[file_meta->files.data.opl.opl_count],
1285 opl, sizeof(TelSimOpl));
1287 file_meta->files.data.opl.opl_count++;
1295 case TEL_SIM_EF_PNN:
1297 TelSimPnn *pnn = NULL;
1299 dbg("decode w/ index [%d]", file_meta->current_index);
1300 pnn = g_try_new0(TelSimPnn, 1);
1302 dr = tcore_sim_decode_pnn((unsigned char *)res, res_len, pnn);
1304 memcpy(&file_meta->files.data.pnn.list[file_meta->files.data.pnn.pnn_count],
1305 pnn, sizeof(TelSimPnn));
1307 file_meta->files.data.pnn.pnn_count++;
1315 case TEL_SIM_EF_OPLMN_ACT:
1316 /*dr = tcore_sim_decode_oplmnwact(&file_meta->files.data.opwa,
1317 (unsigned char *)res, res_len);*/
1320 case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
1321 /*dr = tcore_sim_decode_csp(&po->p_cphs->csp,
1322 p_data->response, p_data->response_len);*/
1325 case TEL_SIM_EF_USIM_MBI: /* linear type */
1327 TelSimMbi *mbi = NULL;
1329 mbi = g_try_new0(TelSimMbi, 1);
1330 dr = tcore_sim_decode_mbi((unsigned char *)res, res_len, mbi);
1332 memcpy(&file_meta->mbi_list.list[file_meta->mbi_list.count],
1333 mbi, sizeof(TelSimMbi));
1334 file_meta->mbi_list.count++;
1336 dbg("mbi count[%d]", file_meta->mbi_list.count);
1344 case TEL_SIM_EF_CPHS_MAILBOX_NUMBERS: /* linear type */
1345 case TEL_SIM_EF_MBDN: /* linear type */
1346 dr = tcore_sim_decode_xdn((unsigned char *)res, res_len,
1347 file_meta->mb_list[file_meta->current_index-1].alpha_id,
1348 file_meta->mb_list[file_meta->current_index-1].number);
1349 file_meta->mb_list[file_meta->current_index-1].alpha_id_len = strlen(file_meta->mb_list[file_meta->current_index-1].alpha_id);
1350 file_meta->mb_list[file_meta->current_index-1].profile_id = file_meta->current_index;
1353 case TEL_SIM_EF_CPHS_VOICE_MSG_WAITING: /* transparent type */
1354 dr = tcore_sim_decode_vmwf((unsigned char *)res, res_len, file_meta->files.data.mw.mw);
1357 case TEL_SIM_EF_USIM_MWIS: { /* linear type */
1358 TelSimMwis *mw = NULL;
1360 mw = g_try_new0(TelSimMwis, 1);
1362 dr = tcore_sim_decode_mwis((unsigned char *)res, res_len, mw);
1364 guint count = file_meta->files.data.mw.profile_count;
1366 memcpy(&file_meta->files.data.mw.mw[count], mw, sizeof(TelSimMwis));
1369 * The Profile Identity shall be between 1 and 4 as defined
1370 * in TS 23.097 for MSP
1372 file_meta->files.data.mw.mw[count].profile_id = count+1;
1374 file_meta->files.data.mw.profile_count++;
1382 case TEL_SIM_EF_CPHS_CALL_FORWARD_FLAGS: /* transparent type */
1383 dr = tcore_sim_decode_cff((unsigned char *)res, res_len, file_meta->files.data.mw.mw);
1386 case TEL_SIM_EF_USIM_CFIS: /* linear type */
1388 TelSimCfis *cf = NULL;
1390 cf = g_try_new0(TelSimCfis, 1);
1391 dr = tcore_sim_decode_cfis((unsigned char *)res, res_len, cf);
1393 memcpy(&file_meta->files.data.cf.cf[file_meta->files.data.cf.profile_count],
1394 cf, sizeof(TelSimCfis));
1395 file_meta->files.data.cf.profile_count++;
1403 case TEL_SIM_EF_CPHS_SERVICE_STRING_TABLE:
1404 dbg("not handled - TEL_SIM_EF_CPHS_SERVICE_STRING_TABLE ");
1407 case TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING:
1408 file_meta->files.data.cphs_net.full_name = tcore_malloc0(TEL_SIM_CPHS_OPERATOR_NAME_LEN_MAX+1);
1409 dr = tcore_sim_decode_ons((unsigned char *)res, res_len,
1410 (unsigned char*)file_meta->files.data.cphs_net.full_name);
1411 dbg("file_meta->files.result[%d],file_meta->files.data.cphs_net.full_name[%s]",
1412 file_meta->files.result, file_meta->files.data.cphs_net.full_name);
1415 case TEL_SIM_EF_CPHS_DYNAMICFLAGS:
1416 /*dr = tcore_sim_decode_dynamic_flag(&po->p_cphs->dflagsinfo,
1417 p_data->response, p_data->response_len);*/
1420 case TEL_SIM_EF_CPHS_DYNAMIC2FLAG:
1421 /*dr = tcore_sim_decode_dynamic2_flag(&po->p_cphs->d2flagsinfo, p_data->response,
1422 p_data->response_len);*/
1425 case TEL_SIM_EF_CPHS_CPHS_INFO:
1426 /*dr = tcore_sim_decode_cphs_info(&file_meta->files.data.cphs,
1427 (unsigned char *)res, res_len);*/
1430 case TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
1431 file_meta->files.data.cphs_net.short_name = tcore_malloc0(TEL_SIM_CPHS_OPERATOR_NAME_SHORT_FORM_LEN_MAX+1);
1432 dr = tcore_sim_decode_short_ons((unsigned char *)res, res_len,
1433 (unsigned char*)file_meta->files.data.cphs_net.short_name);
1434 dbg("file_meta->files.result[%d],file_meta->files.data.cphs_net.short_name[%s]",
1435 file_meta->files.result, file_meta->files.data.cphs_net.short_name);
1438 case TEL_SIM_EF_CPHS_INFORMATION_NUMBERS:
1439 /*dr = tcore_sim_decode_information_number(&po->p_cphs->infn, p_data->response, p_data->response_len);*/
1443 dbg("File Decoding Failed - not handled File[0x%x]", file_meta->file_id);
1448 sim_result = __imc_sim_decode_status_word(sw1, sw2);
1449 file_meta->files.result = sim_result;
1457 tcore_at_tok_free(tokens);
1459 err("RESPONSE NOK");
1460 dbg("Error - File ID: [0x%x]", file_meta->file_id);
1461 sim_result = TEL_SIM_RESULT_FAILURE;
1465 __imc_sim_next_from_read_binary(tcore_pending_ref_core_object(p), resp_cb_data, sim_result, dr);
1470 static void __on_response_imc_sim_get_response(TcorePending *p,
1471 guint data_len, const void *data, void *user_data)
1473 const TcoreAtResponse *resp = data;
1474 CoreObject *co = NULL;
1475 TelSimResult sim_result;
1476 GSList *tokens = NULL;
1477 const char *line = NULL;
1480 ImcRespCbData *resp_cb_data = (ImcRespCbData *)user_data;
1481 ImcSimMetaInfo *file_meta =
1482 (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1484 dbg("SIM Response - SIM File info: [+CRSM]");
1486 co = tcore_pending_ref_core_object(p);
1488 if (resp->success > 0) {
1491 line = (const char *)resp->lines->data;
1492 tokens = tcore_at_tok_new(line);
1493 if (g_slist_length(tokens) < 2) {
1494 err("Invalid message");
1495 tcore_at_tok_free(tokens);
1499 sw1 = atoi(g_slist_nth_data(tokens, 0));
1500 sw2 = atoi(g_slist_nth_data(tokens, 1));
1502 /*1. SIM access success case*/
1503 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1504 unsigned char tag_len = 0;
1505 unsigned short record_len = 0;
1506 char num_of_records = 0;
1507 unsigned char file_id_len = 0;
1508 unsigned short file_id = 0;
1509 unsigned short file_size = 0;
1510 unsigned short file_type = 0;
1511 unsigned short arr_file_id = 0;
1512 int arr_file_id_rec_num = 0;
1513 TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
1515 /* handling only last 3 bits */
1516 unsigned char file_type_tag = 0x07;
1517 unsigned char *ptr_data;
1521 char *record_data = NULL;
1522 guint record_data_len;
1523 hexData = g_slist_nth_data(tokens, 2);
1524 dbg("hexData: %s", hexData);
1525 dbg("hexData: %s", hexData + 1);
1527 tmp = tcore_at_tok_extract(hexData);
1528 tcore_util_hexstring_to_bytes(tmp, &record_data, &record_data_len);
1529 tcore_util_hex_dump(" ", record_data_len, record_data);
1532 ptr_data = (unsigned char *)record_data;
1533 tcore_sim_get_type(co, &card_type);
1534 if (TEL_SIM_CARD_TYPE_USIM == card_type) {
1536 ETSI TS 102 221 v7.9.0
1538 '62' FCP template tag
1539 - Response for an EF
1540 '82' M File Descriptor
1541 '83' M File Identifier
1542 'A5' O Proprietary information
1543 '8A' M Life Cycle Status Integer
1544 '8B', '8C' or 'AB' C1 Security attributes
1546 '81' O Total file size
1547 '88' O Short File Identifier (SFI)
1550 /* rsim.res_len has complete data length received */
1552 /* FCP template tag - File Control Parameters tag*/
1553 if (*ptr_data == 0x62) {
1554 /* parse complete FCP tag*/
1555 /* increment to next byte */
1557 tag_len = *ptr_data++;
1558 dbg("tag_len: %02x", tag_len);
1559 /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
1560 if (*ptr_data == 0x82) {
1561 /* increment to next byte */
1565 /* consider only last 3 bits*/
1566 dbg("file_type_tag: %02x", file_type_tag);
1567 file_type_tag = file_type_tag & (*ptr_data);
1568 dbg("file_type_tag: %02x", file_type_tag);
1570 switch (file_type_tag) {
1571 /* increment to next byte */
1574 dbg("Getting FileType: [Transparent file type]");
1575 file_type = IMC_SIM_FILE_TYPE_TRANSPARENT;
1577 /* increment to next byte */
1579 /* increment to next byte */
1584 dbg("Getting FileType: [Linear fixed file type]");
1585 /* increment to next byte */
1587 /* data coding byte - value 21 */
1590 memcpy(&record_len, ptr_data, 2);
1592 IMC_SWAP_BYTES_16(record_len);
1593 ptr_data = ptr_data + 2;
1594 num_of_records = *ptr_data++;
1595 /* Data lossy conversation from enum (int) to unsigned char */
1596 file_type = IMC_SIM_FILE_TYPE_LINEAR_FIXED;
1600 dbg("Cyclic fixed file type");
1601 /* increment to next byte */
1603 /* data coding byte - value 21 */
1606 memcpy(&record_len, ptr_data, 2);
1608 IMC_SWAP_BYTES_16(record_len);
1609 ptr_data = ptr_data + 2;
1610 num_of_records = *ptr_data++;
1611 file_type = IMC_SIM_FILE_TYPE_CYCLIC;
1615 dbg("not handled file type [0x%x]", *ptr_data);
1619 dbg("INVALID FCP received - DEbug!");
1620 tcore_at_tok_free(tokens);
1621 g_free(record_data);
1625 /*File identifier - 0x84,0x85,0x86 etc are currently ignored and not handled */
1626 if (*ptr_data == 0x83) {
1627 /* increment to next byte */
1629 file_id_len = *ptr_data++;
1630 dbg("file_id_len: %02x", file_id_len);
1632 memcpy(&file_id, ptr_data, file_id_len);
1633 dbg("file_id: %x", file_id);
1636 IMC_SWAP_BYTES_16(file_id);
1637 dbg("file_id: %x", file_id);
1639 ptr_data = ptr_data + 2;
1640 dbg("Getting FileID=[0x%x]", file_id);
1642 dbg("INVALID FCP received - DEbug!");
1643 tcore_at_tok_free(tokens);
1644 g_free(record_data);
1648 /* proprietary information */
1649 if (*ptr_data == 0xA5) {
1650 unsigned short prop_len;
1651 /* increment to next byte */
1655 prop_len = *ptr_data;
1656 dbg("prop_len: %02x", prop_len);
1659 ptr_data = ptr_data + prop_len + 1;
1661 dbg("INVALID FCP received - DEbug!");
1664 /* life cycle status integer [8A][length:0x01][status]*/
1667 00000000 : No information given
1668 00000001 : creation state
1669 00000011 : initialization state
1670 000001-1 : operation state -activated
1671 000001-0 : operation state -deactivated
1672 000011-- : Termination state
1673 b8~b5 !=0, b4~b1=X : Proprietary
1674 Any other value : RFU
1676 if (*ptr_data == 0x8A) {
1677 /* increment to next byte */
1679 /* length - value 1 */
1682 switch (*ptr_data) {
1685 dbg("<RX> operation state -deactivated");
1691 dbg("<RX> operation state -activated");
1696 dbg("<RX> DEBUG! LIFE CYCLE STATUS =[0x%x]", *ptr_data);
1702 /* related to security attributes : currently not handled*/
1703 if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
1704 /* increment to next byte */
1706 /* if tag length is 3 */
1707 if (*ptr_data == 0x03) {
1708 /* increment to next byte */
1711 memcpy(&arr_file_id, ptr_data, 2);
1713 IMC_SWAP_BYTES_16(arr_file_id);
1714 ptr_data = ptr_data + 2;
1715 arr_file_id_rec_num = *ptr_data++;
1716 dbg("arr_file_id_rec_num:[%d]", arr_file_id_rec_num);
1718 /* if tag length is not 3 */
1719 /* ignoring bytes */
1720 // ptr_data = ptr_data + 4;
1721 dbg("Useless security attributes, so jump to next tag");
1722 ptr_data = ptr_data + (*ptr_data + 1);
1725 dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
1726 tcore_at_tok_free(tokens);
1727 g_free(record_data);
1731 dbg("Current ptr_data value is [%x]", *ptr_data);
1733 /* file size excluding structural info*/
1734 if (*ptr_data == 0x80) {
1735 /* for EF file size is body of file and for Linear or cyclic it is
1736 * number of recXsizeof(one record)
1738 /* increment to next byte */
1740 /* length is 1 byte - value is 2 bytes or more */
1742 memcpy(&file_size, ptr_data, 2);
1744 IMC_SWAP_BYTES_16(file_size);
1745 ptr_data = ptr_data + 2;
1747 dbg("INVALID FCP received - DEbug!");
1748 tcore_at_tok_free(tokens);
1749 g_free(record_data);
1753 /* total file size including structural info*/
1754 if (*ptr_data == 0x81) {
1756 /* increment to next byte */
1760 dbg("len:[%d]", len);
1762 ptr_data = ptr_data + 3;
1764 dbg("INVALID FCP received - DEbug!");
1765 /* 0x81 is optional tag?? check out! so do not return -1 from here! */
1767 /*short file identifier ignored*/
1768 if (*ptr_data == 0x88) {
1769 dbg("0x88: Do Nothing");
1773 dbg("INVALID FCP received - DEbug!");
1774 tcore_at_tok_free(tokens);
1775 g_free(record_data);
1778 } else if (TEL_SIM_CARD_TYPE_GSM == card_type) {
1779 unsigned char gsm_specific_file_data_len = 0;
1780 /* ignore RFU byte1 and byte2 */
1784 // file_size = p_info->response_len;
1785 memcpy(&file_size, ptr_data, 2);
1787 IMC_SWAP_BYTES_16(file_size);
1788 /* parsed file size */
1789 ptr_data = ptr_data + 2;
1791 memcpy(&file_id, ptr_data, 2);
1792 IMC_SWAP_BYTES_16(file_id);
1793 dbg("FILE id --> [%x]", file_id);
1794 ptr_data = ptr_data + 2;
1795 /* save file type - transparent, linear fixed or cyclic */
1796 file_type_tag = (*(ptr_data + 7));
1798 switch (*ptr_data) {
1801 dbg("RFU file type- not handled - Debug!");
1806 dbg("MF file type - not handled - Debug!");
1811 dbg("DF file type - not handled - Debug!");
1816 dbg("EF file type [%d] ", file_type_tag);
1817 /* increment to next byte */
1820 if (file_type_tag == 0x00 || file_type_tag == 0x01) {
1821 /* increament to next byte as this byte is RFU */
1824 (file_type_tag == 0x00) ? IMC_SIM_FILE_TYPE_TRANSPARENT : IMC_SIM_FILE_TYPE_LINEAR_FIXED;
1826 /* increment to next byte */
1828 /* For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
1829 /* the INCREASE command is allowed on the selected cyclic file. */
1830 file_type = IMC_SIM_FILE_TYPE_CYCLIC;
1832 /* bytes 9 to 11 give SIM file access conditions */
1834 /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
1836 /* byte 11 is invalidate and rehabilate nibbles */
1838 /* byte 12 - file status */
1840 /* byte 13 - GSM specific data */
1841 gsm_specific_file_data_len = *ptr_data;
1842 dbg("gsm_specific_file_data_len:[%d]", gsm_specific_file_data_len);
1844 /* byte 14 - structure of EF - transparent or linear or cyclic , already saved above */
1846 /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */
1847 record_len = *ptr_data;
1848 dbg("record length[%d], file size[%d]", record_len, file_size);
1849 if (record_len != 0)
1850 num_of_records = (file_size / record_len);
1852 dbg("Number of records [%d]", num_of_records);
1856 dbg("not handled file type");
1860 err("Unknown Card Type - [%d]", card_type);
1863 dbg("req ef[0x%x] resp ef[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]",
1864 file_meta->file_id, file_id, file_size, file_type, num_of_records, record_len);
1866 file_meta->file_type = file_type;
1867 file_meta->data_size = file_size;
1868 file_meta->rec_length = record_len;
1869 file_meta->rec_count = num_of_records;
1870 file_meta->current_index = 0; /* reset for new record type EF */
1871 sim_result = TEL_SIM_RESULT_SUCCESS;
1872 g_free(record_data);
1874 /*2. SIM access fail case*/
1875 err("Failed to get ef[0x%x] (file_meta->file_id) ", file_meta->file_id);
1876 sim_result = __imc_sim_decode_status_word(sw1, sw2);
1879 tcore_at_tok_free(tokens);
1881 err("RESPONSE NOK");
1882 err("Failed to get ef[0x%x] (file_meta->file_id) ", file_meta->file_id);
1883 sim_result = TEL_SIM_RESULT_FAILURE;
1886 dbg("Calling __imc_sim_next_from_get_response");
1887 __imc_sim_next_from_get_response(co, resp_cb_data, sim_result);
1891 static TelReturn __imc_sim_update_file(CoreObject *co,
1892 ImcRespCbData *resp_cb_data, int cmd, TelSimFileId ef,
1893 int p1, int p2, int p3, char *encoded_data)
1895 char *cmd_str = NULL;
1896 TelReturn ret = TEL_RETURN_FAILURE;
1897 ImcSimMetaInfo *file_meta =
1898 (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1900 dbg("Entry File-id:[0x%02x]", file_meta->file_id);
1902 cmd_str = g_strdup_printf("AT+CRSM=%d,%d,%d,%d,%d,\"%s\"",
1903 cmd, ef, p1, p2, p3, encoded_data);
1905 ret = tcore_at_prepare_and_send_request(co, cmd_str, "+CRSM:",
1906 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1907 TCORE_PENDING_PRIORITY_DEFAULT, NULL,
1908 __on_response_imc_sim_update_file, resp_cb_data,
1909 on_send_imc_request, NULL, 0, NULL, NULL);
1911 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Update SIM File");
1913 tcore_free(encoded_data);
1919 static void __imc_sim_read_record(CoreObject *co, ImcRespCbData *resp_cb_data)
1921 gchar *at_cmd = NULL;
1925 ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1926 TelReturn ret = TEL_RETURN_FAILURE;
1928 dbg("Entry File-id:[0x%02x]", file_meta->file_id);
1930 /* According to TS 102 221, values of p1, p2, p3 can be as below:
1931 * 11.1.5 READ RECORD
1933 * P2: Mode, see table 11.11
1936 * Le: Number of bytes to be read (P3)
1939 p1 = (unsigned char) file_meta->current_index;
1940 p2 = (unsigned char) 0x04; /* 0x4 for absolute mode */
1941 p3 = (unsigned char) file_meta->rec_length;
1943 at_cmd = g_strdup_printf("AT+CRSM=%d, %d, %d, %d, %d",
1944 IMC_SIM_ACCESS_READ_RECORD, file_meta->file_id, p1, p2, p3);
1946 ret = tcore_at_prepare_and_send_request(co, at_cmd, "+CRSM:",
1947 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1948 TCORE_PENDING_PRIORITY_DEFAULT, NULL,
1949 __on_response_imc_sim_read_data, resp_cb_data,
1950 on_send_imc_request, NULL, 0, NULL, NULL);
1952 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get File Record");
1954 dbg("ret:[%d]", ret);
1960 static void __imc_sim_read_binary(CoreObject *co, ImcRespCbData *resp_cb_data)
1962 gchar *at_cmd = NULL;
1967 ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1968 TelReturn ret = TEL_RETURN_FAILURE;
1970 dbg("Entry File-id:[0x%02x]", file_meta->file_id);
1972 /* According to TS 102 221, values of P1, P2, P3 can be as below:
1973 * 11.1.3 READ BINARY
1974 * P1: See table 11.10
1978 * Le: Number of bytes to be read (P3)
1981 p1 = (unsigned char) (offset & 0xFF00) >> 8;
1982 p2 = (unsigned char) offset & 0x00FF; /* offset low */
1983 p3 = (unsigned char) file_meta->data_size;
1985 at_cmd = g_strdup_printf("AT+CRSM=%d, %d, %d, %d, %d",
1986 IMC_SIM_ACCESS_READ_BINARY, file_meta->file_id, p1, p2, p3);
1988 ret = tcore_at_prepare_and_send_request(co, at_cmd, "+CRSM:",
1989 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1990 TCORE_PENDING_PRIORITY_DEFAULT, NULL,
1991 __on_response_imc_sim_read_data, resp_cb_data,
1992 on_send_imc_request, NULL, 0, NULL, NULL);
1994 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get File Data");
1996 dbg("ret:[%d]", ret);
2002 static TelReturn __imc_sim_get_response(CoreObject *co, ImcRespCbData *resp_cb_data)
2004 gchar *at_cmd = NULL;
2005 ImcSimMetaInfo *file_meta =
2006 (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2007 TelReturn ret = TEL_RETURN_FAILURE;
2009 dbg("Entry File-id:[0x%02x]", file_meta->file_id);
2011 at_cmd = g_strdup_printf("AT+CRSM=%d, %d",
2012 IMC_SIM_ACCESS_GET_RESPONSE, file_meta->file_id);
2014 ret = tcore_at_prepare_and_send_request(co,
2016 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2017 TCORE_PENDING_PRIORITY_DEFAULT, NULL,
2018 __on_response_imc_sim_get_response, resp_cb_data,
2019 on_send_imc_request, NULL,
2021 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get File Info");
2028 static void __on_response_imc_sim_get_retry_count(TcorePending *p, guint data_len,
2029 const void *data, void *user_data)
2031 TelSimResult result = TEL_SIM_RESULT_INCORRECT_PASSWORD;
2032 const TcoreAtResponse *at_resp = data;
2033 ImcRespCbData *resp_cb_data = user_data;
2034 CoreObject *co = tcore_pending_ref_core_object(p);
2035 ImcSimCurrSecOp *sec_op = NULL;
2036 GSList *tokens = NULL;
2037 const char *line = NULL;
2039 int attempts_left = 0;
2040 int time_penalty = 0;
2044 tcore_check_return_assert(co != NULL);
2045 tcore_check_return_assert(resp_cb_data != NULL);
2047 sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2049 if (at_resp && at_resp->success) {
2050 dbg("Sim Get Retry Count [OK]");
2052 if (at_resp->lines) {
2053 line = (const char *)at_resp->lines->data;
2054 tokens = tcore_at_tok_new(line);
2055 if (g_slist_length(tokens) < 3) {
2056 err("Invalid message");
2060 lock_type = atoi(g_slist_nth_data(tokens, 0));
2061 attempts_left = atoi(g_slist_nth_data(tokens, 1));
2062 time_penalty = atoi(g_slist_nth_data(tokens, 2));
2064 dbg("lock_type = %d, attempts_left = %d, time_penalty = %d",
2065 lock_type, attempts_left, time_penalty);
2068 case IMC_SIM_CURR_SEC_OP_PIN1_VERIFY:
2069 case IMC_SIM_CURR_SEC_OP_PIN2_VERIFY:
2071 TelSimSecPinResult verify_pin = {0, };
2073 if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN1_VERIFY)
2074 verify_pin.pin_type = TEL_SIM_PIN_TYPE_PIN1;
2075 else if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN2_VERIFY)
2076 verify_pin.pin_type = TEL_SIM_PIN_TYPE_PIN2;
2078 verify_pin.retry_count = attempts_left;
2080 if(resp_cb_data->cb)
2081 resp_cb_data->cb(co, (gint)result,
2082 &verify_pin, resp_cb_data->cb_data);
2085 case IMC_SIM_CURR_SEC_OP_PUK1_VERIFY:
2086 case IMC_SIM_CURR_SEC_OP_PUK2_VERIFY:
2088 TelSimSecPukResult verify_puk = {0, };
2090 if (*sec_op == IMC_SIM_CURR_SEC_OP_PUK1_VERIFY)
2091 verify_puk.puk_type = TEL_SIM_PUK_TYPE_PUK1;
2092 else if (*sec_op == IMC_SIM_CURR_SEC_OP_PUK2_VERIFY)
2093 verify_puk.puk_type = TEL_SIM_PUK_TYPE_PUK2;
2095 verify_puk.retry_count = attempts_left;
2097 if(resp_cb_data->cb)
2098 resp_cb_data->cb(co, (gint)result,
2099 &verify_puk, resp_cb_data->cb_data);
2102 case IMC_SIM_CURR_SEC_OP_PIN1_CHANGE:
2103 case IMC_SIM_CURR_SEC_OP_PIN2_CHANGE:
2105 TelSimSecPinResult change_pin = {0, };
2107 if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN1_CHANGE)
2108 change_pin.pin_type = TEL_SIM_PIN_TYPE_PIN1;
2109 else if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN2_CHANGE)
2110 change_pin.pin_type = TEL_SIM_PIN_TYPE_PIN2;
2112 change_pin.retry_count = attempts_left;
2114 if(resp_cb_data->cb)
2115 resp_cb_data->cb(co, (gint)result,
2116 &change_pin, resp_cb_data->cb_data);
2119 case IMC_SIM_CURR_SEC_OP_PIN1_DISABLE:
2120 case IMC_SIM_CURR_SEC_OP_PIN2_DISABLE:
2121 case IMC_SIM_CURR_SEC_OP_FDN_DISABLE:
2122 case IMC_SIM_CURR_SEC_OP_SIM_DISABLE:
2123 case IMC_SIM_CURR_SEC_OP_NET_DISABLE:
2124 case IMC_SIM_CURR_SEC_OP_NS_DISABLE:
2125 case IMC_SIM_CURR_SEC_OP_SP_DISABLE:
2126 case IMC_SIM_CURR_SEC_OP_CP_DISABLE:
2128 TelSimFacilityResult disable_facility = {0, };
2131 lock_type = __imc_sim_get_lock_type(*sec_op);
2132 if (lock_type == -1)
2135 disable_facility.type = lock_type;
2136 disable_facility.retry_count = attempts_left;
2138 if(resp_cb_data->cb)
2139 resp_cb_data->cb(co, (gint)result,
2140 &disable_facility, resp_cb_data->cb_data);
2143 case IMC_SIM_CURR_SEC_OP_PIN1_ENABLE:
2144 case IMC_SIM_CURR_SEC_OP_PIN2_ENABLE:
2145 case IMC_SIM_CURR_SEC_OP_FDN_ENABLE:
2146 case IMC_SIM_CURR_SEC_OP_SIM_ENABLE:
2147 case IMC_SIM_CURR_SEC_OP_NET_ENABLE:
2148 case IMC_SIM_CURR_SEC_OP_NS_ENABLE:
2149 case IMC_SIM_CURR_SEC_OP_SP_ENABLE:
2150 case IMC_SIM_CURR_SEC_OP_CP_ENABLE:
2152 TelSimFacilityResult enable_facility = {0, };
2155 lock_type = __imc_sim_get_lock_type(*sec_op);
2156 if (lock_type == -1)
2159 enable_facility.type = lock_type;
2160 enable_facility.retry_count = attempts_left;
2162 if(resp_cb_data->cb)
2163 resp_cb_data->cb(co, (gint)result,
2164 &enable_facility, resp_cb_data->cb_data);
2168 err("Unhandled sec op [%d]", *sec_op);
2172 tcore_at_tok_free(tokens);
2173 imc_destroy_resp_cb_data(resp_cb_data);
2176 err("Sim Get Retry Count [NOK]");
2178 /*TODO - send response for verify pin, puk etc.,
2179 * when get_retry_count fails
2181 tcore_at_tok_free(tokens);
2182 imc_destroy_resp_cb_data(resp_cb_data);
2185 static TelReturn __imc_sim_get_retry_count(CoreObject *co,
2186 ImcRespCbData *resp_cb_data)
2188 TelReturn ret = TEL_RETURN_FAILURE;
2189 ImcSimCurrSecOp *sec_op = (
2190 ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2192 gchar *cmd_str = NULL;
2197 case IMC_SIM_CURR_SEC_OP_PIN1_VERIFY:
2198 case IMC_SIM_CURR_SEC_OP_PIN1_CHANGE:
2199 case IMC_SIM_CURR_SEC_OP_PIN1_ENABLE:
2200 case IMC_SIM_CURR_SEC_OP_PIN1_DISABLE:
2203 case IMC_SIM_CURR_SEC_OP_PIN2_VERIFY:
2204 case IMC_SIM_CURR_SEC_OP_PIN2_CHANGE:
2205 case IMC_SIM_CURR_SEC_OP_PIN2_ENABLE:
2206 case IMC_SIM_CURR_SEC_OP_PIN2_DISABLE:
2207 case IMC_SIM_CURR_SEC_OP_FDN_ENABLE:
2208 case IMC_SIM_CURR_SEC_OP_FDN_DISABLE:
2211 case IMC_SIM_CURR_SEC_OP_PUK1_VERIFY:
2214 case IMC_SIM_CURR_SEC_OP_PUK2_VERIFY:
2217 case IMC_SIM_CURR_SEC_OP_NET_ENABLE:
2218 case IMC_SIM_CURR_SEC_OP_NET_DISABLE:
2221 case IMC_SIM_CURR_SEC_OP_NS_ENABLE:
2222 case IMC_SIM_CURR_SEC_OP_NS_DISABLE:
2225 case IMC_SIM_CURR_SEC_OP_SP_ENABLE:
2226 case IMC_SIM_CURR_SEC_OP_SP_DISABLE:
2229 case IMC_SIM_CURR_SEC_OP_CP_ENABLE:
2230 case IMC_SIM_CURR_SEC_OP_CP_DISABLE:
2233 case IMC_SIM_CURR_SEC_OP_ADM_VERIFY:
2239 cmd_str = g_strdup_printf("AT+XPINCNT=%d", lock_type);
2241 ret = tcore_at_prepare_and_send_request(co, cmd_str, NULL,
2242 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2243 TCORE_PENDING_PRIORITY_DEFAULT,
2245 __on_response_imc_sim_get_retry_count,
2247 on_send_imc_request,
2248 NULL, 0, NULL, NULL);
2250 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get Retry Count");
2255 static TelSimLockType __imc_sim_lock_type(int lock_type)
2259 return TEL_SIM_LOCK_SC;
2261 return TEL_SIM_LOCK_FD;
2263 return TEL_SIM_LOCK_PN;
2265 return TEL_SIM_LOCK_PU;
2267 return TEL_SIM_LOCK_PP;
2269 return TEL_SIM_LOCK_PC ;
2271 return TEL_SIM_LOCK_PS ;
2273 err("Invalid lock_type [%d]", lock_type);
2278 static char *__imc_sim_get_fac_from_lock_type(TelSimLockType lock_type,
2279 ImcSimCurrSecOp *sec_op, int flag)
2283 case TEL_SIM_LOCK_PS :
2285 if (flag == ENABLE_FLAG)
2286 *sec_op = IMC_SIM_CURR_SEC_OP_SIM_ENABLE;
2287 else if (flag == DISABLE_FLAG)
2288 *sec_op = IMC_SIM_CURR_SEC_OP_SIM_DISABLE;
2290 *sec_op = IMC_SIM_CURR_SEC_OP_SIM_STATUS;
2292 case TEL_SIM_LOCK_SC :
2294 if (flag == ENABLE_FLAG)
2295 *sec_op = IMC_SIM_CURR_SEC_OP_PIN1_ENABLE;
2296 else if (flag == DISABLE_FLAG)
2297 *sec_op = IMC_SIM_CURR_SEC_OP_PIN1_DISABLE;
2299 *sec_op = IMC_SIM_CURR_SEC_OP_PIN1_STATUS;
2301 case TEL_SIM_LOCK_FD :
2303 if (flag == ENABLE_FLAG)
2304 *sec_op = IMC_SIM_CURR_SEC_OP_FDN_ENABLE;
2305 else if (flag == DISABLE_FLAG)
2306 *sec_op = IMC_SIM_CURR_SEC_OP_FDN_DISABLE;
2308 *sec_op = IMC_SIM_CURR_SEC_OP_FDN_STATUS;
2310 case TEL_SIM_LOCK_PN :
2312 if (flag == ENABLE_FLAG)
2313 *sec_op = IMC_SIM_CURR_SEC_OP_NET_ENABLE;
2314 else if (flag == DISABLE_FLAG)
2315 *sec_op = IMC_SIM_CURR_SEC_OP_NET_DISABLE;
2317 *sec_op = IMC_SIM_CURR_SEC_OP_NET_STATUS;
2319 case TEL_SIM_LOCK_PU :
2321 if (flag == ENABLE_FLAG)
2322 *sec_op = IMC_SIM_CURR_SEC_OP_NS_ENABLE;
2323 else if (flag == DISABLE_FLAG)
2324 *sec_op = IMC_SIM_CURR_SEC_OP_NS_DISABLE;
2326 *sec_op = IMC_SIM_CURR_SEC_OP_NS_STATUS;
2328 case TEL_SIM_LOCK_PP :
2330 if (flag == ENABLE_FLAG)
2331 *sec_op = IMC_SIM_CURR_SEC_OP_SP_ENABLE;
2332 else if (flag == DISABLE_FLAG)
2333 *sec_op = IMC_SIM_CURR_SEC_OP_SP_DISABLE;
2335 *sec_op = IMC_SIM_CURR_SEC_OP_SP_STATUS;
2337 case TEL_SIM_LOCK_PC :
2339 if (flag == ENABLE_FLAG)
2340 *sec_op = IMC_SIM_CURR_SEC_OP_CP_ENABLE;
2341 else if (flag == DISABLE_FLAG)
2342 *sec_op = IMC_SIM_CURR_SEC_OP_CP_DISABLE;
2344 *sec_op = IMC_SIM_CURR_SEC_OP_CP_STATUS;
2347 err("Unhandled sim lock type [%d]", lock_type);
2352 static int __imc_sim_get_lock_type(ImcSimCurrSecOp sec_op)
2355 case IMC_SIM_CURR_SEC_OP_SIM_DISABLE :
2356 case IMC_SIM_CURR_SEC_OP_SIM_ENABLE :
2357 case IMC_SIM_CURR_SEC_OP_SIM_STATUS :
2358 return TEL_SIM_LOCK_PS;
2359 case IMC_SIM_CURR_SEC_OP_PIN1_DISABLE :
2360 case IMC_SIM_CURR_SEC_OP_PIN1_ENABLE :
2361 case IMC_SIM_CURR_SEC_OP_PIN1_STATUS :
2362 return TEL_SIM_LOCK_SC;
2363 case IMC_SIM_CURR_SEC_OP_FDN_DISABLE :
2364 case IMC_SIM_CURR_SEC_OP_FDN_ENABLE :
2365 case IMC_SIM_CURR_SEC_OP_FDN_STATUS :
2366 return TEL_SIM_LOCK_FD;
2367 case IMC_SIM_CURR_SEC_OP_NET_DISABLE :
2368 case IMC_SIM_CURR_SEC_OP_NET_ENABLE :
2369 case IMC_SIM_CURR_SEC_OP_NET_STATUS :
2370 return TEL_SIM_LOCK_PN;
2371 case IMC_SIM_CURR_SEC_OP_NS_DISABLE :
2372 case IMC_SIM_CURR_SEC_OP_NS_ENABLE :
2373 case IMC_SIM_CURR_SEC_OP_NS_STATUS :
2374 return TEL_SIM_LOCK_PU;
2375 case IMC_SIM_CURR_SEC_OP_SP_DISABLE :
2376 case IMC_SIM_CURR_SEC_OP_SP_ENABLE :
2377 case IMC_SIM_CURR_SEC_OP_SP_STATUS :
2378 return TEL_SIM_LOCK_PP;
2379 case IMC_SIM_CURR_SEC_OP_CP_DISABLE :
2380 case IMC_SIM_CURR_SEC_OP_CP_ENABLE :
2381 case IMC_SIM_CURR_SEC_OP_CP_STATUS :
2382 return TEL_SIM_LOCK_PC ;
2384 err("Invalid sec op [%d]", sec_op);
2391 * Notification: +XSIM: <SIM state>
2393 * Possible values of <SIM state> can be
2395 * 1 PIN verification needed
2396 * 2 PIN verification not needed - Ready
2397 * 3 PIN verified - Ready
2398 * 4 PUK verification needed
2399 * 5 SIM permanently blocked
2401 * 7 ready for attach (+COPS)
2402 * 8 SIM Technical Problem
2404 * 10 SIM Reactivating
2405 * 11 SIM Reactivated
2406 * 12 SIM SMS Caching Completed. (Sent only when SMS caching enabled)
2407 * 99 SIM State Unknown
2409 static gboolean on_notification_imc_sim_status(CoreObject *co,
2410 const void *event_info, void *user_data)
2412 GSList *lines = (GSList *)event_info;
2415 dbg("SIM notification - SIM status: [+XSIM]");
2417 if (g_slist_length(lines) != 1) {
2418 err("+XSIM unsolicited message expected to be "
2419 "Single line but received multiple lines");
2423 line = (const gchar *) (lines->data);
2431 * +XSIM: <SIM state>
2433 tokens = tcore_at_tok_new(line);
2434 if (g_slist_length(tokens) == 1) {
2436 sim_state = atoi(g_slist_nth_data(tokens, 0));
2438 /* Process SIM Status */
2439 __imc_sim_process_sim_status(co, sim_state);
2441 err("Invalid message");
2444 tcore_at_tok_free(tokens);
2451 static TcoreHookReturn on_hook_imc_modem_power(TcorePlugin *source,
2452 TcoreNotification command, guint data_len, void *data, void *user_data)
2454 CoreObject *co = (CoreObject *)user_data;
2456 tcore_check_return_value(co != NULL, TCORE_HOOK_RETURN_CONTINUE);
2458 dbg("Get SIM status");
2459 (void)__imc_sim_get_sim_status(co, NULL, NULL);
2461 return TCORE_HOOK_RETURN_CONTINUE;
2464 /* Response Functions */
2465 static void on_response_imc_sim_req_authentication(TcorePending *p, guint data_len,
2466 const void *data, void *user_data)
2468 const TcoreAtResponse *at_resp = data;
2469 GSList *tokens = NULL;
2470 CoreObject *co = tcore_pending_ref_core_object(p);
2471 TelSimAuthenticationResponse auth_resp = {0, };
2472 TelSimResult sim_result = TEL_SIM_RESULT_FAILURE;
2473 ImcRespCbData *resp_cb_data = user_data;
2474 TelSimAuthenticationType *auth_type = (TelSimAuthenticationType *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2478 if (NULL == at_resp) {
2479 err("at_resp is NULL");
2480 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2484 auth_resp.auth_type = *auth_type;
2486 if (at_resp->success == TRUE) {
2491 if (at_resp->lines != NULL) {
2492 line = at_resp->lines->data;
2493 dbg("Received data: [%s]", line);
2495 err("at_resp->lines is NULL");
2496 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2500 tokens = tcore_at_tok_new(line);
2501 if (tokens == NULL) {
2502 err("tokens is NULL");
2503 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2507 status = atoi(g_slist_nth_data(tokens, 0));
2510 dbg("Authentications successful");
2511 auth_resp.detailed_result = TEL_SIM_AUTH_NO_ERROR;
2514 err("Synchronize fail");
2515 auth_resp.detailed_result = TEL_SIM_AUTH_SYNCH_FAILURE;
2519 auth_resp.detailed_result = TEL_SIM_AUTH_MAK_CODE_FAILURE;
2522 err("Does not support security context");
2523 auth_resp.detailed_result = TEL_SIM_AUTH_UNSUPPORTED_CONTEXT;
2526 err("Other failure");
2527 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2531 if (auth_resp.auth_type == TEL_SIM_AUTH_GSM) {
2533 char *convert_kc, *convert_sres;
2535 kc = g_slist_nth_data(tokens, 1);
2537 guint convert_kc_len = 0;
2538 kc = tcore_at_tok_extract(kc);
2539 dbg("Kc: [%s]", kc);
2541 tcore_util_hexstring_to_bytes(kc, &convert_kc, &convert_kc_len);
2542 if (convert_kc_len && convert_kc_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
2543 auth_resp.authentication_key_length = convert_kc_len;
2544 memcpy(&auth_resp.authentication_key, convert_kc, convert_kc_len);
2547 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2553 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2557 sres = g_slist_nth_data(tokens, 2);
2559 guint convert_sres_len = 0;
2560 sres = tcore_at_tok_extract(sres);
2561 dbg("SRES: [%s]", sres);
2563 tcore_util_hexstring_to_bytes(sres, &convert_sres, &convert_sres_len);
2564 if (convert_sres_len && convert_sres_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
2565 auth_resp.resp_length = convert_sres_len;
2566 memcpy(&auth_resp.resp_data, convert_sres, convert_sres_len);
2568 err("Invalid SRES");
2569 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2572 g_free(convert_sres);
2574 err("Invalid SRES");
2575 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2578 } else if (auth_resp.auth_type == TEL_SIM_AUTH_3G_CTX) {
2579 char *res, *ck, *ik, *kc;
2580 char *convert_res, *convert_ck;
2581 char *convert_ik, *convert_kc;
2583 res = g_slist_nth_data(tokens, 1);
2585 guint convert_res_len = 0;
2586 res = tcore_at_tok_extract(res);
2587 dbg("RES/AUTS: [%s]", res);
2589 tcore_util_hexstring_to_bytes(res, &convert_res, &convert_res_len);
2590 if (convert_res_len && convert_res_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
2591 auth_resp.resp_length = convert_res_len;
2592 memcpy(auth_resp.resp_data, convert_res, convert_res_len);
2594 err("Invalid RES/AUTS");
2595 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2598 g_free(convert_res);
2600 err("Invalid RES/AUTS");
2601 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2605 ck = g_slist_nth_data(tokens, 2);
2607 guint convert_ck_len = 0;
2608 ck = tcore_at_tok_extract(ck);
2609 dbg("CK: [%s]", ck);
2611 tcore_util_hexstring_to_bytes(ck, &convert_ck, &convert_ck_len);
2612 if (convert_ck_len && convert_ck_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
2613 auth_resp.cipher_length = convert_ck_len;
2614 memcpy(&auth_resp.cipher_data, convert_ck, convert_ck_len);
2617 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2623 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2627 ik = g_slist_nth_data(tokens, 3);
2629 guint convert_ik_len = 0;
2630 ik = tcore_at_tok_extract(ik);
2631 dbg("IK: [%s]", ik);
2633 tcore_util_hexstring_to_bytes(ik, &convert_ik, &convert_ik_len);
2634 if (convert_ik_len && convert_ik_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
2635 auth_resp.integrity_length = convert_ik_len;
2636 memcpy(&auth_resp.integrity_data, convert_ik, convert_ik_len);
2639 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2645 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2649 kc = g_slist_nth_data(tokens, 4);
2651 guint convert_kc_len = 0;
2652 kc = tcore_at_tok_extract(kc);
2653 dbg("Kc: [%s]", kc);
2655 tcore_util_hexstring_to_bytes(kc, &convert_kc, &convert_kc_len);
2656 if (convert_kc_len && convert_kc_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
2657 auth_resp.authentication_key_length = convert_kc_len;
2658 memcpy(&auth_resp.authentication_key, convert_kc, convert_kc_len);
2661 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2667 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2671 err("Not supported");
2672 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2675 sim_result = TEL_SIM_RESULT_SUCCESS;
2677 err("RESPONSE NOK");
2678 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2682 if(resp_cb_data->cb)
2683 resp_cb_data->cb(co, (gint)sim_result, &auth_resp, resp_cb_data->cb_data);
2685 tcore_at_tok_free(tokens);
2688 static void on_response_imc_sim_verify_pins(TcorePending *p, guint data_len,
2689 const void *data, void *user_data)
2691 const TcoreAtResponse *at_resp = data;
2692 ImcRespCbData *resp_cb_data = user_data;
2693 CoreObject *co = tcore_pending_ref_core_object(p);
2694 TelSimResult result = TEL_SIM_RESULT_FAILURE;
2695 ImcSimCurrSecOp *sec_op = NULL;
2696 TelSimSecPinResult verify_pin_resp = {0, };
2700 tcore_check_return_assert(co != NULL);
2701 tcore_check_return_assert(resp_cb_data != NULL);
2703 sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2705 if (at_resp && at_resp->success) {
2706 dbg("Sim Verify Pin Response- [OK]");
2708 result = TEL_SIM_RESULT_SUCCESS;
2710 if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN1_VERIFY) {
2711 TelSimCardStatus status;
2713 verify_pin_resp.pin_type = TEL_SIM_PIN_TYPE_PIN1;
2715 tcore_sim_get_status(co, &status);
2716 if (status != TEL_SIM_STATUS_SIM_INIT_COMPLETED) {
2717 /*Update sim status*/
2718 __imc_sim_update_sim_status(co,
2719 TEL_SIM_STATUS_SIM_INITIALIZING);
2721 } else if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN2_VERIFY) {
2722 verify_pin_resp.pin_type = TEL_SIM_PIN_TYPE_PIN2;
2726 if(resp_cb_data->cb)
2727 resp_cb_data->cb(co, (gint)result,
2729 resp_cb_data->cb_data);
2730 imc_destroy_resp_cb_data(resp_cb_data);
2732 err("Sim Verify Pin Response- [NOK]");
2733 /* Get retry count */
2734 __imc_sim_get_retry_count(co, resp_cb_data);
2738 static void on_response_imc_sim_verify_puks(TcorePending *p, guint data_len,
2739 const void *data, void *user_data)
2741 const TcoreAtResponse *at_resp = data;
2742 ImcRespCbData *resp_cb_data = user_data;
2743 CoreObject *co = tcore_pending_ref_core_object(p);
2744 TelSimResult result = TEL_SIM_RESULT_FAILURE;
2745 ImcSimCurrSecOp *sec_op = NULL;
2746 TelSimSecPukResult verify_puk_resp = {0, };
2750 tcore_check_return_assert(co != NULL);
2751 tcore_check_return_assert(resp_cb_data != NULL);
2753 sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2755 if (at_resp && at_resp->success) {
2756 dbg("Sim Verify Puk Response- [OK]");
2758 result = TEL_SIM_RESULT_SUCCESS;
2760 if (*sec_op == IMC_SIM_CURR_SEC_OP_PUK1_VERIFY) {
2761 verify_puk_resp.puk_type = TEL_SIM_PUK_TYPE_PUK1;
2762 } else if (*sec_op == IMC_SIM_CURR_SEC_OP_PUK2_VERIFY) {
2763 verify_puk_resp.puk_type = TEL_SIM_PUK_TYPE_PUK2;
2766 if(resp_cb_data->cb)
2767 resp_cb_data->cb(co, (gint)result,
2769 resp_cb_data->cb_data);
2770 imc_destroy_resp_cb_data(resp_cb_data);
2772 err("Sim Verify Puk Response- [NOK]");
2773 /* Get retry count */
2774 __imc_sim_get_retry_count(co, resp_cb_data);
2778 static void on_response_imc_sim_change_pins(TcorePending *p, guint data_len,
2779 const void *data, void *user_data)
2781 const TcoreAtResponse *at_resp = data;
2782 ImcRespCbData *resp_cb_data = user_data;
2783 CoreObject *co = tcore_pending_ref_core_object(p);
2784 TelSimResult result = TEL_SIM_RESULT_FAILURE;
2785 ImcSimCurrSecOp *sec_op = NULL;
2786 TelSimSecPinResult change_pin_resp = {0, };
2790 tcore_check_return_assert(co != NULL);
2791 tcore_check_return_assert(resp_cb_data != NULL);
2793 sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2795 if (at_resp && at_resp->success) {
2796 dbg("Sim Change Pin Response- [OK]");
2798 result = TEL_SIM_RESULT_SUCCESS;
2800 if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN1_CHANGE) {
2801 change_pin_resp.pin_type = TEL_SIM_PIN_TYPE_PIN1;
2802 } else if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN2_CHANGE) {
2803 change_pin_resp.pin_type = TEL_SIM_PIN_TYPE_PIN2;
2806 if(resp_cb_data->cb)
2807 resp_cb_data->cb(co, (gint)result,
2809 resp_cb_data->cb_data);
2810 imc_destroy_resp_cb_data(resp_cb_data);
2812 err("Sim Change Pin Response- [NOK]");
2813 /* Get retry count */
2814 __imc_sim_get_retry_count(co, resp_cb_data);
2818 static void on_response_imc_sim_disable_facility(TcorePending *p, guint data_len,
2819 const void *data, void *user_data)
2821 const TcoreAtResponse *at_resp = data;
2822 ImcRespCbData *resp_cb_data = user_data;
2823 CoreObject *co = tcore_pending_ref_core_object(p);
2824 TelSimResult result = TEL_SIM_RESULT_FAILURE;
2825 ImcSimCurrSecOp *sec_op = NULL;
2826 TelSimFacilityResult disable_facility_resp = {0, };
2830 tcore_check_return_assert(co != NULL);
2831 tcore_check_return_assert(resp_cb_data != NULL);
2833 sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2835 if (at_resp && at_resp->success) {
2837 dbg("Sim Disable Facility Response- [OK]");
2839 lock_type = __imc_sim_get_lock_type(*sec_op);
2840 if (lock_type == -1) {
2841 result = TEL_SIM_RESULT_INVALID_PARAMETER;
2844 if(resp_cb_data->cb)
2845 resp_cb_data->cb(co, (gint)result,
2847 resp_cb_data->cb_data);
2848 imc_destroy_resp_cb_data(resp_cb_data);
2852 disable_facility_resp.type = lock_type;
2853 result = TEL_SIM_RESULT_SUCCESS;
2856 if(resp_cb_data->cb)
2857 resp_cb_data->cb(co, (gint)result,
2858 &disable_facility_resp,
2859 resp_cb_data->cb_data);
2860 imc_destroy_resp_cb_data(resp_cb_data);
2862 err("Sim Disable Facility Response- [NOK]");
2863 /* Get retry count */
2864 __imc_sim_get_retry_count(co, resp_cb_data);
2868 static void on_response_imc_sim_enable_facility(TcorePending *p, guint data_len,
2869 const void *data, void *user_data)
2871 const TcoreAtResponse *at_resp = data;
2872 ImcRespCbData *resp_cb_data = user_data;
2873 CoreObject *co = tcore_pending_ref_core_object(p);
2874 TelSimResult result = TEL_SIM_RESULT_FAILURE;
2875 ImcSimCurrSecOp *sec_op = NULL;
2876 TelSimFacilityResult enable_facility_resp = {0, };
2880 tcore_check_return_assert(co != NULL);
2881 tcore_check_return_assert(resp_cb_data != NULL);
2883 sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2885 if (at_resp && at_resp->success) {
2887 dbg("Sim Enable Facility Response- [OK]");
2889 lock_type = __imc_sim_get_lock_type(*sec_op);
2890 if (lock_type == -1) {
2891 result = TEL_SIM_RESULT_INVALID_PARAMETER;
2894 if(resp_cb_data->cb)
2895 resp_cb_data->cb(co, (gint)result,
2897 resp_cb_data->cb_data);
2898 imc_destroy_resp_cb_data(resp_cb_data);
2902 enable_facility_resp.type = lock_type;
2903 result = TEL_SIM_RESULT_SUCCESS;
2906 if(resp_cb_data->cb)
2907 resp_cb_data->cb(co, (gint)result,
2908 &enable_facility_resp,
2909 resp_cb_data->cb_data);
2910 imc_destroy_resp_cb_data(resp_cb_data);
2912 err("Sim Enable Facility Response- [NOK]");
2913 /* Get retry count */
2914 __imc_sim_get_retry_count(co, resp_cb_data);
2918 static void on_response_imc_sim_get_facility(TcorePending *p, guint data_len,
2919 const void *data, void *user_data)
2921 const TcoreAtResponse *at_resp = data;
2922 ImcRespCbData *resp_cb_data = user_data;
2923 CoreObject *co = tcore_pending_ref_core_object(p);
2924 TelSimResult result = TEL_SIM_RESULT_FAILURE;
2925 ImcSimCurrSecOp *sec_op = NULL;
2926 TelSimFacilityInfo get_facility_resp = {0, };
2930 tcore_check_return_assert(co != NULL);
2931 tcore_check_return_assert(resp_cb_data != NULL);
2933 sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2935 if (at_resp && at_resp->success) {
2936 GSList *tokens = NULL;
2940 dbg("Sim Get Facility Response- [OK]");
2942 lock_type = __imc_sim_get_lock_type(*sec_op);
2943 if (lock_type == -1) {
2944 result = TEL_SIM_RESULT_INVALID_PARAMETER;
2947 if (at_resp->lines) {
2948 line = (const char *)at_resp->lines->data;
2949 tokens = tcore_at_tok_new(line);
2950 if (g_slist_length(tokens) != 1) {
2951 err("Invalid message");
2952 tcore_at_tok_free(tokens);
2955 get_facility_resp.f_status = atoi(g_slist_nth_data(tokens, 0));
2956 get_facility_resp.type = lock_type;
2957 result = TEL_SIM_RESULT_SUCCESS;
2960 tcore_at_tok_free(tokens);
2962 err("Sim Get Facility Response- [NOK]");
2965 /* Invoke callback */
2966 if(resp_cb_data->cb)
2967 resp_cb_data->cb(co, (gint)result, &get_facility_resp, resp_cb_data->cb_data);
2968 imc_destroy_resp_cb_data(resp_cb_data);
2971 static void on_response_imc_sim_get_lock_info(TcorePending *p, guint data_len,
2972 const void *data, void *user_data)
2974 const TcoreAtResponse *at_resp = data;
2975 ImcRespCbData *resp_cb_data = user_data;
2976 CoreObject *co = tcore_pending_ref_core_object(p);
2977 TelSimResult result = TEL_SIM_RESULT_FAILURE;
2978 TelSimLockInfo get_lock_info_resp = {0, };
2982 tcore_check_return_assert(co != NULL);
2983 tcore_check_return_assert(resp_cb_data != NULL);
2985 if(at_resp && at_resp->success) {
2986 GSList *tokens = NULL;
2989 int attempts_left = 0;
2990 int time_penalty = 0;
2992 dbg("Sim Get Lock Info Response- [OK]");
2994 if (at_resp->lines) {
2995 line = (const char *)at_resp->lines->data;
2996 tokens = tcore_at_tok_new(line);
2997 if (g_slist_length(tokens) < 3) {
2998 err("Invalid message");
2999 tcore_at_tok_free(tokens);
3003 lock_type = atoi(g_slist_nth_data(tokens, 0));
3004 attempts_left = atoi(g_slist_nth_data(tokens, 1));
3005 time_penalty = atoi(g_slist_nth_data(tokens, 2));
3007 dbg("lock_type = %d, attempts_left = %d, time_penalty = %d",
3008 lock_type, attempts_left, time_penalty);
3010 get_lock_info_resp.lock_type = __imc_sim_lock_type(lock_type);
3011 get_lock_info_resp.retry_count = attempts_left;
3012 result = TEL_SIM_RESULT_SUCCESS;
3014 tcore_at_tok_free(tokens);
3016 err("Sim Get Lock Info Response- [NOK]");
3019 /* Invoke callback */
3020 if(resp_cb_data->cb)
3021 resp_cb_data->cb(co, (gint)result, &get_lock_info_resp, resp_cb_data->cb_data);
3022 imc_destroy_resp_cb_data(resp_cb_data);
3025 static void on_response_imc_sim_req_apdu (TcorePending *p, guint data_len, const void *data, void *user_data)
3027 const TcoreAtResponse *resp = data;
3028 CoreObject *co = NULL;
3029 TelSimApduResp apdu_resp = {0,};
3030 TelSimResult sim_result = TEL_SIM_RESULT_FAILURE;
3031 GSList *tokens = NULL;
3033 ImcRespCbData *resp_cb_data = (ImcRespCbData *) user_data;
3037 co = tcore_pending_ref_core_object(p);
3039 if (resp->success > 0) {
3043 char *decoded_data = NULL;
3044 guint decoded_data_len = 0;
3045 line = (const char *)resp->lines->data;
3046 tokens = tcore_at_tok_new(line);
3047 if (g_slist_length(tokens) != 2) {
3048 err("Invalid message");
3052 tmp = tcore_at_tok_extract(g_slist_nth_data(tokens, 1));
3053 tcore_util_hexstring_to_bytes(tmp, &decoded_data, &decoded_data_len);
3055 apdu_resp.apdu_resp_len = decoded_data_len;
3056 memcpy((char *)apdu_resp.apdu_resp, decoded_data, decoded_data_len);
3058 g_free(decoded_data);
3059 sim_result = TEL_SIM_RESULT_SUCCESS;
3062 err("RESPONSE NOK");
3067 if (resp_cb_data->cb)
3068 resp_cb_data->cb(co, (gint)sim_result, &apdu_resp, resp_cb_data->cb_data);
3069 tcore_at_tok_free(tokens);
3073 static void on_response_imc_sim_req_atr(TcorePending *p, guint data_len, const void *data, void *user_data)
3075 const TcoreAtResponse *resp = data;
3076 CoreObject *co = NULL;
3077 TelSimAtr atr_res = {0,};
3078 TelSimResult sim_result = TEL_SIM_RESULT_FAILURE;
3079 GSList *tokens = NULL;
3081 ImcRespCbData *resp_cb_data = (ImcRespCbData *) user_data;
3085 co = tcore_pending_ref_core_object(p);
3087 if (resp->success > 0) {
3091 char *decoded_data = NULL;
3092 guint decoded_data_len = 0;
3093 line = (const char *)resp->lines->data;
3094 tokens = tcore_at_tok_new(line);
3095 if (g_slist_length(tokens) < 1) {
3096 err("Invalid message");
3100 tmp = tcore_at_tok_extract(g_slist_nth_data(tokens, 0));
3101 tcore_util_hexstring_to_bytes(tmp, &decoded_data, &decoded_data_len);
3103 atr_res.atr_len = decoded_data_len;
3104 memcpy((char *)atr_res.atr, decoded_data, decoded_data_len);
3106 g_free(decoded_data);
3107 sim_result = TEL_SIM_RESULT_SUCCESS;
3110 err("RESPONSE NOK");
3115 if (resp_cb_data->cb)
3116 resp_cb_data->cb(co, (gint)sim_result, &atr_res, resp_cb_data->cb_data);
3117 tcore_at_tok_free(tokens);
3121 /* SIM Operations */
3123 * Operation - get_imsi
3126 * AT-Command: AT+CRSM= <command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
3137 * 28423 meaning IMSI file (6F07)
3138 * 28473 meaning ACM file (6F39)
3139 * 28481 meaning PUKT file (6F41)
3140 * 28482 meaning SMS file (6F42)
3143 * Integer type defining the request.
3144 * These parameters are mandatory for every command, except GET RESPONSE and STATUS.
3147 * Information which shall be written to the SIM
3150 * String type, contains the path of an elementary file on the SIM/USIM in hexadecimal format
3158 * +CRSM: <sw1>,<sw2>[,<response>]
3161 * Integer type containing the SIM information
3164 * Response of successful completion of the command previously issued
3167 * +CME ERROR: <error>
3169 static TelReturn imc_sim_get_imsi (CoreObject *co,
3170 TcoreObjectResponseCallback cb, void *cb_data)
3175 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_IMSI, ret);
3180 static TelReturn imc_sim_get_ecc (CoreObject *co,
3181 TcoreObjectResponseCallback cb, void *cb_data)
3186 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_ECC, ret);
3191 static TelReturn imc_sim_get_iccid (CoreObject *co,
3192 TcoreObjectResponseCallback cb, void *cb_data)
3197 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_ICCID, ret);
3202 static TelReturn imc_sim_get_language (CoreObject *co,
3203 TcoreObjectResponseCallback cb, void *cb_data)
3208 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_LP, ret);
3213 static TelReturn imc_sim_set_language (CoreObject *co,
3214 TelSimLanguagePreferenceCode language,
3215 TcoreObjectResponseCallback cb, void *cb_data)
3217 ImcSimMetaInfo file_meta = {0, };
3218 TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
3219 ImcRespCbData *resp_cb_data = NULL;
3222 char *encoded_data = NULL;
3223 int encoded_data_len = 0;
3230 file_meta.file_id = TEL_SIM_EF_LP;
3231 file_meta.file_result = TEL_SIM_RESULT_FAILURE;
3233 tcore_sim_get_type(co, &card_type);
3235 dbg("language[%d], card_type[%d]", language, card_type);
3237 if (TEL_SIM_CARD_TYPE_GSM == card_type) {
3240 tcore_sim_encode_lp(language, &encoded_data, &encoded_data_len);
3241 } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
3245 if (tcore_sim_encode_li(language, &tmp, &encoded_data_len)) {
3246 encoded_data = g_strdup_printf("%02x%02x", tmp[0], tmp[1]);
3250 err("Failed to encode Language [%d]", language);
3251 return TEL_RETURN_FAILURE;
3254 err("Invalid card_type:[%d]", card_type);
3255 return TEL_RETURN_OPERATION_NOT_SUPPORTED;
3258 if (!encoded_data_len) {
3259 err("Failed to encode Language [%d]", language);
3260 return TEL_RETURN_FAILURE;
3262 dbg("Encoded Language [%s] len[%d]", encoded_data, encoded_data_len);
3266 p3 = encoded_data_len;
3268 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3269 &file_meta, sizeof(ImcSimMetaInfo));
3271 return __imc_sim_update_file(co, resp_cb_data,
3272 IMC_SIM_ACCESS_UPDATE_BINARY, TEL_SIM_EF_LP,
3273 p1, p2, p3, encoded_data);
3276 static TelReturn imc_sim_get_callforwarding_info (CoreObject *co,
3277 TcoreObjectResponseCallback cb, void *cb_data)
3282 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_USIM_CFIS, ret);
3287 static TelReturn imc_sim_get_messagewaiting_info (CoreObject *co,
3288 TcoreObjectResponseCallback cb, void *cb_data)
3293 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_USIM_MWIS, ret);
3298 static TelReturn imc_sim_set_messagewaiting_info (CoreObject *co,
3299 const TelSimMwis *request, TcoreObjectResponseCallback cb, void *cb_data)
3301 ImcSimMetaInfo file_meta = {0, };
3302 ImcRespCbData *resp_cb_data = NULL;
3303 gchar *encoded_mwis;
3304 guint encoded_mwis_len = 0;
3305 gchar *encoded_data = NULL;
3306 guint encoded_data_len = 0;
3314 * Videomail is not supported.
3316 if (!tcore_sim_encode_mwis(request, TEL_SIM_MAILBOX_TYPE_MAX,
3317 &encoded_mwis, &encoded_mwis_len)) {
3318 err("Failed to encode mwis");
3319 return TEL_RETURN_FAILURE;
3322 encoded_data_len = 2 * encoded_mwis_len;
3323 encoded_data = (char *)tcore_malloc0(encoded_data_len + 1);
3324 tcore_util_byte_to_hex(encoded_mwis, encoded_data, encoded_mwis_len);
3325 tcore_free(encoded_mwis);
3326 dbg("Encoded data: [%s] Encoded data length: [%d]", encoded_data, encoded_data_len);
3330 p3 = TEL_SIM_MAILBOX_TYPE_MAX; /* Indicator Status | Voicemail | Fax | Electronic Mail | Others */
3331 dbg("p1: [%d] p2: [%d] p3: [%d]", p1, p2, p3);
3333 file_meta.file_id = TEL_SIM_EF_USIM_MWIS;
3334 file_meta.file_result = TEL_SIM_RESULT_FAILURE;
3336 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, &file_meta, sizeof(ImcSimMetaInfo));
3338 return __imc_sim_update_file(co, resp_cb_data, IMC_SIM_ACCESS_UPDATE_RECORD,
3339 TEL_SIM_EF_USIM_MWIS, p1, p2, p3, encoded_data);
3342 static TelReturn imc_sim_get_mailbox_info (CoreObject *co,
3343 TcoreObjectResponseCallback cb, void *cb_data)
3348 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_USIM_MBI, ret);
3353 static TelReturn imc_sim_set_mailbox_info (CoreObject *co,
3354 const TelSimMailBoxNumber *request, TcoreObjectResponseCallback cb, void *cb_data)
3356 ImcSimMetaInfo file_meta = {0, };
3357 ImcRespCbData *resp_cb_data = NULL;
3360 char *encoded_data = NULL;
3361 int encoded_data_len = 0;
3368 file_meta.file_id = TEL_SIM_EF_USIM_MBI;
3369 file_meta.file_result = TEL_SIM_RESULT_FAILURE;
3371 /* TBD - Do Encoding.
3372 if (!tcore_sim_encode_mbi(request, sizeof(request), tmp, &tmp_len)) {
3373 err("Failed to encode mwis");
3374 return TEL_RETURN_FAILURE;
3377 encoded_data_len = tmp_len * 2;
3378 encoded_data = (char *)tcore_malloc0(encoded_data_len + 1);
3379 tcore_util_byte_to_hex(tmp, encoded_data, tmp_len);
3380 if (!encoded_data) {
3381 err("Failed to convert byte to hex");
3382 tcore_free(encoded_data);
3383 return TEL_RETURN_FAILURE;
3388 p3 = encoded_data_len;
3389 dbg("encoded_data - [%s], encoded_data_len - %d", encoded_data, encoded_data_len);
3391 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, &file_meta, sizeof(ImcSimMetaInfo));
3393 return __imc_sim_update_file(co, resp_cb_data, IMC_SIM_ACCESS_UPDATE_RECORD,
3394 TEL_SIM_EF_USIM_MBI, p1, p2, p3, encoded_data);
3397 static TelReturn imc_sim_get_msisdn (CoreObject *co,
3398 TcoreObjectResponseCallback cb, void *cb_data)
3403 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_MSISDN, ret);
3408 static TelReturn imc_sim_get_spn (CoreObject *co,
3409 TcoreObjectResponseCallback cb, void *cb_data)
3414 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_SPN, ret);
3419 static TelReturn imc_sim_get_cphs_netname (CoreObject *co,
3420 TcoreObjectResponseCallback cb, void *cb_data)
3425 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING, ret);
3430 static TelReturn imc_sim_get_sp_display_info (CoreObject *co,
3431 TcoreObjectResponseCallback cb, void *cb_data)
3436 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_SPDI, ret);
3441 static TelReturn imc_sim_req_authentication (CoreObject *co,
3442 const TelSimAuthenticationData *request,
3443 TcoreObjectResponseCallback cb, void *cb_data)
3445 gchar *cmd_str = NULL;
3446 ImcRespCbData *resp_cb_data = NULL;
3447 TelReturn ret = TEL_RETURN_FAILURE;
3448 TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
3449 char *convert_rand = NULL;
3450 char *convert_autn = NULL;
3456 tcore_sim_get_type(co, &card_type);
3457 if (TEL_SIM_CARD_TYPE_GSM == card_type || TEL_SIM_CARD_TYPE_USIM == card_type) {
3460 err("Not Supported SIM type:[%d]", card_type);
3461 return TEL_SIM_RESULT_OPERATION_NOT_SUPPORTED;
3464 if (request->rand_data != NULL) {
3465 convert_rand = tcore_malloc0(request->rand_length*2 + 1);
3466 tcore_util_byte_to_hex(request->rand_data, convert_rand, request->rand_length);
3467 dbg("Convert RAND hex to string: [%s]", convert_rand);
3469 err("rand_data is NULL");
3473 switch (request->auth_type) {
3474 case TEL_SIM_AUTH_GSM:
3476 cmd_str = g_strdup_printf("AT+XAUTH=%d,%d,\"%s\"",
3477 session_id, context_type, convert_rand);
3479 case TEL_SIM_AUTH_3G_CTX:
3481 if (request->autn_data != NULL) {
3482 convert_autn = tcore_malloc0(request->autn_length*2 + 1);
3483 tcore_util_byte_to_hex(request->autn_data, convert_autn, request->autn_length);
3484 dbg("Convert AUTN hex to string: [%s]", convert_autn);
3486 err("autn_data is NULL");
3489 cmd_str = g_strdup_printf("AT+XAUTH=%d,%d,\"%s\",\"%s\"",
3490 session_id, context_type, convert_rand, convert_autn);
3493 err("Not supported Authentication type:[%d]", request->auth_type);
3494 ret = TEL_SIM_RESULT_OPERATION_NOT_SUPPORTED;
3498 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, (void *)&request->auth_type, sizeof(TelSimAuthenticationType));
3500 ret = tcore_at_prepare_and_send_request(co, cmd_str, "+XAUTH:",
3501 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3502 TCORE_PENDING_PRIORITY_DEFAULT, NULL,
3503 on_response_imc_sim_req_authentication, resp_cb_data,
3504 on_send_imc_request, NULL, 0, NULL, NULL);
3506 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim request authentication");
3509 tcore_free(convert_rand);
3510 tcore_free(convert_autn);
3516 * Operation - verify_pins/verify_puks
3520 * AT-Command: AT+CPIN= <pin> [, <newpin>]
3523 * String type values
3526 * AT-Command: AT+CPIN2= <puk2/oldpin2> [, <newpin2>]andAT+CPIN2=<oldpin2>
3528 * <puk2/pin2>, <newpin2>
3529 * String type values
3535 * +CME ERROR: <error>
3537 static TelReturn imc_sim_verify_pins(CoreObject *co, const TelSimSecPinPw *request,
3538 TcoreObjectResponseCallback cb, void *cb_data)
3540 TelReturn ret = TEL_RETURN_FAILURE;
3541 ImcRespCbData *resp_cb_data = NULL;
3542 ImcSimCurrSecOp sec_op;
3543 gchar *cmd_str = NULL;
3547 if (request->pin_type == TEL_SIM_PIN_TYPE_PIN1) {
3548 sec_op = IMC_SIM_CURR_SEC_OP_PIN1_VERIFY;
3549 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", request->pw);
3550 } else if (request->pin_type == TEL_SIM_PIN_TYPE_PIN2) {
3551 sec_op = IMC_SIM_CURR_SEC_OP_PIN2_VERIFY;
3552 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\"", request->pw);
3554 err("Invalid pin type [%d]", request->pin_type);
3555 return TEL_RETURN_INVALID_PARAMETER;
3558 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3559 &sec_op, sizeof(sec_op));
3561 ret = tcore_at_prepare_and_send_request(co, cmd_str, NULL,
3562 TCORE_AT_COMMAND_TYPE_NO_RESULT,
3563 TCORE_PENDING_PRIORITY_DEFAULT,
3565 on_response_imc_sim_verify_pins,
3567 on_send_imc_request,
3568 NULL, 0, NULL, NULL);
3570 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Verify Pins");
3575 static TelReturn imc_sim_verify_puks(CoreObject *co, const TelSimSecPukPw *request,
3576 TcoreObjectResponseCallback cb, void *cb_data)
3578 TelReturn ret = TEL_RETURN_FAILURE;
3579 ImcRespCbData *resp_cb_data = NULL;
3580 ImcSimCurrSecOp sec_op;
3581 gchar *cmd_str = NULL;
3585 if (request->puk_type == TEL_SIM_PUK_TYPE_PUK1) {
3586 sec_op = IMC_SIM_CURR_SEC_OP_PUK1_VERIFY;
3587 cmd_str = g_strdup_printf("AT+CPIN=\"%s\", \"%s\"",
3588 request->puk_pw, request->new_pin_pw);
3589 } else if (request->puk_type == TEL_SIM_PUK_TYPE_PUK2) {
3590 sec_op = IMC_SIM_CURR_SEC_OP_PUK2_VERIFY;
3591 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\", \"%s\"",
3592 request->puk_pw, request->new_pin_pw);
3594 err("Invalid puk type [%d]", request->puk_type);
3595 return TEL_RETURN_INVALID_PARAMETER;
3598 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3599 &sec_op, sizeof(sec_op));
3601 ret = tcore_at_prepare_and_send_request(co, cmd_str, NULL,
3602 TCORE_AT_COMMAND_TYPE_NO_RESULT,
3603 TCORE_PENDING_PRIORITY_DEFAULT,
3605 on_response_imc_sim_verify_puks,
3607 on_send_imc_request,
3608 NULL, 0, NULL, NULL);
3610 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Verify Puks");
3616 * Operation - change_pins
3619 * AT-Command: AT+CPWD= <fac>,<oldpwd>,<newpwd>
3634 * +CME ERROR: <error>
3636 static TelReturn imc_sim_change_pins(CoreObject *co, const TelSimSecChangePinPw *request,
3637 TcoreObjectResponseCallback cb, void *cb_data)
3639 TelReturn ret = TEL_RETURN_FAILURE;
3640 ImcRespCbData *resp_cb_data = NULL;
3641 ImcSimCurrSecOp sec_op;
3642 gchar *cmd_str = NULL;
3643 char *pin1_fac = "SC";
3644 char *pin2_fac = "P2";
3648 if (request->pin_type == TEL_SIM_PIN_TYPE_PIN1) {
3649 sec_op = IMC_SIM_CURR_SEC_OP_PIN1_CHANGE;
3650 cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"",
3651 pin1_fac, request->old_pw, request->new_pw);
3652 } else if (request->pin_type == TEL_SIM_PIN_TYPE_PIN2) {
3653 sec_op = IMC_SIM_CURR_SEC_OP_PIN2_CHANGE;
3654 cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"",
3655 pin2_fac, request->old_pw, request->new_pw);
3657 err("Invalid pin type [%d]", request->pin_type);
3658 return TEL_RETURN_INVALID_PARAMETER;
3661 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3662 &sec_op, sizeof(sec_op));
3664 ret = tcore_at_prepare_and_send_request(co, cmd_str, NULL,
3665 TCORE_AT_COMMAND_TYPE_NO_RESULT,
3666 TCORE_PENDING_PRIORITY_DEFAULT,
3668 on_response_imc_sim_change_pins,
3670 on_send_imc_request,
3671 NULL, 0, NULL, NULL);
3673 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Change Pins");
3679 * Operation - disable_facility/enable_facility/get_facility
3682 * AT-Command: AT+CLCK = <fac>, <mode> [, <passwd> [, <class>]]
3699 * Success: when <mode>=2:
3701 * +CLCK: <status>[,<class1> [<CR><LF>
3702 * +CLCK: <status>,<class2> [...]]
3706 static TelReturn imc_sim_disable_facility(CoreObject *co, const TelSimFacilityPw *request,
3707 TcoreObjectResponseCallback cb, void *cb_data)
3709 TelReturn ret = TEL_RETURN_FAILURE;
3710 ImcRespCbData *resp_cb_data = NULL;
3711 ImcSimCurrSecOp sec_op;
3712 gchar *cmd_str = NULL;
3714 int mode = 0; /*mode = 0 for disable lock*/
3718 fac = __imc_sim_get_fac_from_lock_type(request->lock_type,
3719 &sec_op, DISABLE_FLAG);
3721 return TEL_RETURN_INVALID_PARAMETER;
3723 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"",
3724 fac, mode, request->pw);
3726 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3727 &sec_op, sizeof(sec_op));
3729 ret = tcore_at_prepare_and_send_request(co, cmd_str, "+CLCK:",
3730 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3731 TCORE_PENDING_PRIORITY_DEFAULT,
3733 on_response_imc_sim_disable_facility,
3735 on_send_imc_request,
3736 NULL, 0, NULL, NULL);
3738 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Disable Facility");
3743 static TelReturn imc_sim_enable_facility(CoreObject *co, const TelSimFacilityPw *request,
3744 TcoreObjectResponseCallback cb, void *cb_data)
3746 TelReturn ret = TEL_RETURN_FAILURE;
3747 ImcRespCbData *resp_cb_data = NULL;
3748 ImcSimCurrSecOp sec_op;
3749 gchar *cmd_str = NULL;
3751 int mode = 1; /*mode = 1 for enable lock*/
3755 fac = __imc_sim_get_fac_from_lock_type(request->lock_type,
3756 &sec_op, ENABLE_FLAG);
3758 return TEL_RETURN_INVALID_PARAMETER;
3760 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"",
3761 fac, mode, request->pw);
3763 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3764 &sec_op, sizeof(sec_op));
3766 ret = tcore_at_prepare_and_send_request(co, cmd_str, "+CLCK:",
3767 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3768 TCORE_PENDING_PRIORITY_DEFAULT,
3770 on_response_imc_sim_enable_facility,
3772 on_send_imc_request,
3773 NULL, 0, NULL, NULL);
3775 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Disable Facility");
3780 static TelReturn imc_sim_get_facility(CoreObject *co, TelSimLockType lock_type,
3781 TcoreObjectResponseCallback cb, void *cb_data)
3783 TelReturn ret = TEL_RETURN_FAILURE;
3784 ImcRespCbData *resp_cb_data = NULL;
3785 ImcSimCurrSecOp sec_op;
3786 gchar *cmd_str = NULL;
3788 int mode = 2; /*mode = 2 for Get Facility*/
3792 fac = __imc_sim_get_fac_from_lock_type(lock_type,
3795 return TEL_RETURN_INVALID_PARAMETER;
3797 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d", fac, mode);
3799 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3800 &sec_op, sizeof(sec_op));
3802 ret = tcore_at_prepare_and_send_request(co, cmd_str, "+CLCK:",
3803 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3804 TCORE_PENDING_PRIORITY_DEFAULT,
3806 on_response_imc_sim_get_facility,
3808 on_send_imc_request,
3809 NULL, 0, NULL, NULL);
3811 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Get Facility");
3816 static TelReturn imc_sim_get_lock_info(CoreObject *co, TelSimLockType lock_type,
3817 TcoreObjectResponseCallback cb, void *cb_data)
3819 TelReturn ret = TEL_RETURN_FAILURE;
3820 ImcRespCbData *resp_cb_data = NULL;
3821 gchar *cmd_str = NULL;
3826 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
3828 switch (lock_type) {
3829 case TEL_SIM_LOCK_PS:
3833 case TEL_SIM_LOCK_SC:
3837 case TEL_SIM_LOCK_FD:
3841 case TEL_SIM_LOCK_PN:
3845 case TEL_SIM_LOCK_PU:
3849 case TEL_SIM_LOCK_PP:
3853 case TEL_SIM_LOCK_PC:
3861 cmd_str = g_strdup_printf("AT+XPINCNT=%d", lockType);
3863 ret = tcore_at_prepare_and_send_request(co, cmd_str, "+XPINCNT:",
3864 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3865 TCORE_PENDING_PRIORITY_DEFAULT,
3867 on_response_imc_sim_get_lock_info,
3869 on_send_imc_request,
3870 NULL, 0, NULL, NULL);
3872 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Get Lock Info");
3877 static TelReturn imc_sim_req_apdu (CoreObject *co, const TelSimApdu *request, TcoreObjectResponseCallback cb, void *cb_data)
3879 gchar *cmd_str = NULL;
3881 ImcRespCbData *resp_cb_data = NULL;
3882 TelReturn ret = TEL_RETURN_FAILURE;
3886 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
3888 apdu = (char *)tcore_malloc0((2 * request->apdu_len) + 1);
3889 tcore_util_byte_to_hex((char *)request->apdu, apdu, request->apdu_len);
3891 cmd_str = g_strdup_printf("AT+CSIM=%d,\"%s\"", strlen((const char *)apdu), apdu);
3893 ret = tcore_at_prepare_and_send_request(co, cmd_str, "+CSIM:",
3894 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3895 TCORE_PENDING_PRIORITY_DEFAULT, NULL,
3896 on_response_imc_sim_req_apdu, resp_cb_data,
3897 on_send_imc_request, NULL, 0, NULL, NULL);
3899 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Request APDU");
3908 static TelReturn imc_sim_req_atr (CoreObject *co, TcoreObjectResponseCallback cb, void *cb_data)
3910 gchar *cmd_str = NULL;
3911 ImcRespCbData *resp_cb_data = NULL;
3912 TelReturn ret = TEL_RETURN_FAILURE;
3916 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
3918 cmd_str = g_strdup_printf("AT+XGATR");
3920 ret = tcore_at_prepare_and_send_request(co, cmd_str, "+XGATR:",
3921 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3922 TCORE_PENDING_PRIORITY_DEFAULT, NULL,
3923 on_response_imc_sim_req_atr, resp_cb_data,
3924 on_send_imc_request, NULL, 0, NULL, NULL);
3926 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Request ATR");
3934 /* SIM Operations */
3935 static TcoreSimOps imc_sim_ops = {
3936 .get_imsi = imc_sim_get_imsi,
3937 .get_ecc = imc_sim_get_ecc,
3938 .get_iccid = imc_sim_get_iccid,
3939 .get_language = imc_sim_get_language,
3940 .set_language = imc_sim_set_language,
3941 .get_callforwarding_info = imc_sim_get_callforwarding_info,
3942 .get_messagewaiting_info = imc_sim_get_messagewaiting_info,
3943 .set_messagewaiting_info = imc_sim_set_messagewaiting_info,
3944 .get_mailbox_info = imc_sim_get_mailbox_info,
3945 .set_mailbox_info = imc_sim_set_mailbox_info,
3946 .get_msisdn = imc_sim_get_msisdn,
3947 .get_spn = imc_sim_get_spn,
3948 .get_cphs_netname = imc_sim_get_cphs_netname,
3949 .get_sp_display_info = imc_sim_get_sp_display_info,
3950 .req_authentication = imc_sim_req_authentication,
3951 .verify_pins = imc_sim_verify_pins,
3952 .verify_puks = imc_sim_verify_puks,
3953 .change_pins = imc_sim_change_pins,
3954 .disable_facility = imc_sim_disable_facility,
3955 .enable_facility = imc_sim_enable_facility,
3956 .get_facility = imc_sim_get_facility,
3957 .get_lock_info = imc_sim_get_lock_info,
3958 .req_apdu = imc_sim_req_apdu,
3959 .req_atr = imc_sim_req_atr
3962 gboolean imc_sim_init(TcorePlugin *p, CoreObject *co)
3964 ImcSimPrivateInfo *priv_info = NULL;
3968 priv_info = g_try_new0(ImcSimPrivateInfo, 1);
3969 if (priv_info == NULL)
3972 tcore_sim_link_userdata(co, priv_info);
3974 /* Set operations */
3975 tcore_sim_set_ops(co, &imc_sim_ops);
3978 tcore_object_add_callback(co, "+XSIM:",
3979 on_notification_imc_sim_status, NULL);
3982 tcore_plugin_add_notification_hook(p,
3983 TCORE_NOTIFICATION_MODEM_POWER,
3984 on_hook_imc_modem_power, co);
3990 void imc_sim_exit(TcorePlugin *plugin, CoreObject *co)
3992 ImcSimPrivateInfo *priv_info = NULL;
3996 priv_info = tcore_sim_ref_userdata(co);