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 guint mb_count; /**< Current mbdn read index */
120 int mb_index[TEL_SIM_MSP_CNT_MAX * TEL_SIM_MAILBOX_TYPE_MAX]; /**< List of mbdn index to read */
121 ImcSimFileType file_type; /**< File type and structure */
122 ImcSimCurrSecOp sec_op; /**< Current index to read */
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);
371 dbg("ret:[%d]", ret);
373 /* Send SIM Type notification */
374 tcore_object_send_notification(co,
375 TCORE_NOTIFICATION_SIM_TYPE,
376 sizeof(TelSimCardType), sim_type);
381 static void __on_response_imc_sim_get_sim_type(TcorePending *p,
382 guint data_len, const void *data, void *user_data)
384 const TcoreAtResponse *at_resp = data;
385 CoreObject *co = tcore_pending_ref_core_object(p);
386 ImcRespCbData *resp_cb_data = user_data;
387 TelSimCardType sim_type = TEL_SIM_CARD_TYPE_UNKNOWN;
389 TelSimResult result = TEL_SIM_RESULT_FAILURE;
391 dbg("SIM Response - SIM Type: [+XUICC]");
393 tcore_check_return_assert(co != NULL);
394 tcore_check_return_assert(resp_cb_data != NULL);
396 if (at_resp && at_resp->success) {
397 if (at_resp->lines) {
401 line = (const gchar *)at_resp->lines->data;
408 tokens = tcore_at_tok_new(line);
411 if (g_slist_length(tokens) == 1) {
412 guint state = atoi(g_slist_nth_data(tokens, 0));
414 if (state == 0) /* 0 - 2G SIM */
415 sim_type = TEL_SIM_CARD_TYPE_GSM;
416 else if (state == 1) /* 1 - 3G SIM */
417 sim_type = TEL_SIM_CARD_TYPE_USIM;
419 result = TEL_SIM_RESULT_SUCCESS;
422 err("Invalid message");
425 tcore_at_tok_free(tokens);
429 /* Invoke callback */
430 if (resp_cb_data->cb)
431 resp_cb_data->cb(co, (gint)result, &sim_type, resp_cb_data->cb_data);
433 /* Free callback data */
434 imc_destroy_resp_cb_data(resp_cb_data);
438 * Operation - get_sim_type
441 * AT-Command: AT+XUICC?
443 * Response - sim_type (TelSimCardType)
444 * Success: (Single line) -
448 * +CME ERROR: <error>
450 gboolean __imc_sim_get_sim_type(CoreObject *co,
451 TcoreObjectResponseCallback cb, void *cb_data)
453 ImcRespCbData *resp_cb_data;
456 /* Response callback data */
457 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
460 /* Send Request to modem */
461 ret = tcore_at_prepare_and_send_request(co,
462 "AT+XUICC?", "+XUICC:",
463 TCORE_AT_COMMAND_TYPE_SINGLELINE,
465 __on_response_imc_sim_get_sim_type, resp_cb_data,
466 on_send_imc_request, NULL);
467 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SIM Type");
472 static void __imc_sim_process_sim_status(CoreObject *co, guint sim_state)
474 TelSimCardStatus sim_card_status;
478 sim_card_status = TEL_SIM_STATUS_CARD_NOT_PRESENT;
483 sim_card_status = TEL_SIM_STATUS_SIM_PIN_REQUIRED;
488 sim_card_status = TEL_SIM_STATUS_SIM_INITIALIZING;
489 dbg("PIN DISABLED AT BOOT UP");
493 sim_card_status = TEL_SIM_STATUS_SIM_INITIALIZING;
498 sim_card_status = TEL_SIM_STATUS_SIM_PUK_REQUIRED;
503 sim_card_status = TEL_SIM_STATUS_SIM_PUK_REQUIRED;
504 dbg("CARD PERMANENTLY BLOCKED");
508 sim_card_status = TEL_SIM_STATUS_CARD_ERROR;
509 dbg("SIM CARD ERROR");
513 sim_card_status = TEL_SIM_STATUS_SIM_INIT_COMPLETED;
514 dbg("SIM INIT COMPLETED");
518 sim_card_status = TEL_SIM_STATUS_CARD_ERROR;
519 dbg("SIM CARD ERROR");
523 sim_card_status = TEL_SIM_STATUS_CARD_REMOVED;
528 dbg("SIM SMS Ready");
530 /* Notify SMS status */
531 return __imc_sim_notify_sms_state(co, TRUE);
534 sim_card_status = TEL_SIM_STATUS_UNKNOWN;
535 dbg("SIM STATE UNKNOWN");
539 err("Unknown/Unsupported SIM state: [%d]", sim_state);
543 switch (sim_card_status) {
544 case TEL_SIM_STATUS_SIM_INIT_COMPLETED: {
545 TelSimCardType sim_type;
547 dbg("SIM INIT COMPLETED");
549 (void)tcore_sim_get_type(co, &sim_type);
550 if (sim_type == TEL_SIM_CARD_TYPE_UNKNOWN) {
552 * SIM is initialized for first time, need to
555 (void)__imc_sim_get_sim_type(co,
556 __on_response_imc_sim_get_sim_type_internal, NULL);
563 case TEL_SIM_STATUS_CARD_REMOVED:
564 dbg("SIM CARD REMOVED");
565 tcore_sim_set_type(co, TEL_SIM_CARD_TYPE_UNKNOWN);
568 case TEL_SIM_STATUS_CARD_NOT_PRESENT:
569 dbg("SIM CARD NOT PRESENT");
570 tcore_sim_set_type(co, TEL_SIM_CARD_TYPE_UNKNOWN);
573 case TEL_SIM_STATUS_CARD_ERROR:
574 dbg("SIM CARD ERROR");
575 tcore_sim_set_type(co, TEL_SIM_CARD_TYPE_UNKNOWN);
579 err("SIM Status: [0x%02x]", sim_card_status);
583 /* Update SIM Status */
584 return __imc_sim_update_sim_status(co, sim_card_status);
587 static void __on_response_imc_sim_get_sim_status(TcorePending *p,
588 guint data_len, const void *data, void *user_data)
590 const TcoreAtResponse *at_resp = data;
591 CoreObject *co = tcore_pending_ref_core_object(p);
592 ImcRespCbData *resp_cb_data = (ImcRespCbData *)user_data;
595 dbg("SIM Response - SIM status: [+XSIMSTATE]");
597 tcore_check_return_assert(co != NULL);
598 tcore_check_return_assert(resp_cb_data != NULL);
600 if (at_resp && at_resp->success) {
601 if (at_resp->lines) {
602 const gchar *line = NULL;
604 /* Process +XSIMSTATE response */
605 line = (const gchar *) (at_resp->lines->data);
608 guint sim_state, sms_state;
613 * +XSIMSTATE: <mode>,<SIM state>,<PB Ready>,<SMS Ready>
615 tokens = tcore_at_tok_new(line);
617 if (g_slist_length(tokens) == 4) {
619 sim_state = atoi(g_slist_nth_data(tokens, 1));
621 /* Process SIM Status */
622 __imc_sim_process_sim_status(co, sim_state);
625 sms_state = atoi(g_slist_nth_data(tokens, 3));
627 /* Notify SMS status */
628 __imc_sim_notify_sms_state(co, (sms_state > 0));
631 err("Invalid message");
634 tcore_at_tok_free(tokens);
639 /* Free callback data */
640 imc_destroy_resp_cb_data(resp_cb_data);
644 * Operation - get_sim_status
647 * AT-Command: AT+XSIMSTATE?
649 * Response - sim_status
650 * Success: (Single line) -
651 * +XSIMSTATE: <mode>,<SIM state>,<PB Ready>,<SMS Ready>
654 * +CME ERROR: <error>
656 static gboolean __imc_sim_get_sim_status(CoreObject *co,
657 TcoreObjectResponseCallback cb, void *cb_data)
659 ImcRespCbData *resp_cb_data;
662 /* Response callback data */
663 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
666 /* Send Request to modem */
667 ret = tcore_at_prepare_and_send_request(co,
668 "AT+XSIMSTATE?", "+XSIMSTATE:",
669 TCORE_AT_COMMAND_TYPE_SINGLELINE,
671 __on_response_imc_sim_get_sim_status, resp_cb_data,
672 on_send_imc_request, NULL);
673 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get SIM Status");
678 static void __imc_sim_next_from_read_binary(CoreObject *co, ImcRespCbData *resp_cb_data, TelSimResult sim_result, gboolean decode_ret)
680 ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
681 TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
685 dbg("[SIM]EF[0x%x] read sim_result[%d] Decode rt[%d]", file_meta->file_id, sim_result, decode_ret);
686 switch (file_meta->file_id) {
688 case TEL_SIM_EF_USIM_PL:
690 case TEL_SIM_EF_USIM_LI:
691 if (decode_ret == TRUE) {
692 if (resp_cb_data->cb)
693 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
695 tcore_sim_get_type(co, &card_type);
697 /* The ME requests the Extended Language Preference. The ME only requests the Language Preference (EFLP) if at least one of the following conditions holds:
698 - EFELP is not available;
699 - EFELP does not contain an entry corresponding to a language specified in ISO 639[30];
700 - the ME does not support any of the languages in EFELP.
703 /* The ME only requests the Language Preference (EFPL) if at least one of the following conditions holds:
704 - if the EFLI has the value 'FFFF' in its highest priority position
705 - if the ME does not support any of the language codes indicated in EFLI , or if EFLI is not present
707 if (TEL_SIM_CARD_TYPE_GSM == card_type) {
708 if (file_meta->file_id == TEL_SIM_EF_LP) {
709 if (resp_cb_data->cb)
710 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
712 file_meta->file_id = TEL_SIM_EF_LP;
713 __imc_sim_get_response(co, resp_cb_data);
716 } else if (TEL_SIM_CARD_TYPE_USIM) {
717 if (file_meta->file_id == TEL_SIM_EF_LP || file_meta->file_id == TEL_SIM_EF_USIM_LI) {
718 file_meta->file_id = TEL_SIM_EF_ELP;
719 __imc_sim_get_response(co, resp_cb_data);
722 if (resp_cb_data->cb)
723 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
730 tcore_sim_get_type(co, &card_type);
731 if (TEL_SIM_CARD_TYPE_USIM == card_type) {
732 if (file_meta->current_index == file_meta->rec_count) {
733 if (resp_cb_data->cb)
734 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
736 file_meta->current_index++;
737 __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 /* Update SIM INIT status - INIT COMPLETE */
750 __imc_sim_update_sim_status(co, TEL_SIM_STATUS_SIM_INIT_COMPLETED);
752 if (resp_cb_data->cb) {
753 resp_cb_data->cb(co, (gint)sim_result, &file_meta->imsi, resp_cb_data->cb_data);
755 file_meta->file_id = TEL_SIM_EF_CPHS_CPHS_INFO;
756 file_meta->file_result = TEL_SIM_RESULT_FAILURE;
757 __imc_sim_get_response(co, resp_cb_data);
762 case TEL_SIM_EF_MSISDN:
763 if (file_meta->current_index == file_meta->rec_count) {
765 dbg("rec_count [%d], msisdn_count[%d]", file_meta->rec_count,
766 file_meta->files.data.msisdn_list.count);
767 if (resp_cb_data->cb) {
768 resp_cb_data->cb(co, (gint)sim_result,
769 &file_meta->files.data.msisdn_list, resp_cb_data->cb_data);
773 for (i = 0; i < file_meta->files.data.msisdn_list.count; i++) {
774 tcore_free(file_meta->files.data.msisdn_list.list[i].alpha_id);
775 tcore_free(file_meta->files.data.msisdn_list.list[i].num);
777 tcore_free(file_meta->files.data.msisdn_list.list);
779 file_meta->current_index++;
780 __imc_sim_read_record(co, resp_cb_data);
786 if (file_meta->current_index == file_meta->rec_count) {
787 if (resp_cb_data->cb)
788 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
791 file_meta->current_index++;
792 __imc_sim_read_record(co, resp_cb_data);
798 if (file_meta->current_index == file_meta->rec_count) {
799 if (resp_cb_data->cb)
800 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
802 file_meta->current_index++;
803 __imc_sim_read_record(co, resp_cb_data);
808 case TEL_SIM_EF_USIM_MBI:
809 if (file_meta->current_index == file_meta->rec_count) {
810 /* Init file_meta to read next EF file */
811 file_meta->rec_count = 0;
812 file_meta->current_index = 0;
813 file_meta->file_id = TEL_SIM_EF_MBDN;
814 /* Read MBDN record*/
815 dbg("Read MBDN record");
816 __imc_sim_get_response(co, resp_cb_data);
820 file_meta->current_index++;
821 __imc_sim_read_record(co, resp_cb_data);
826 case TEL_SIM_EF_MBDN:
827 case TEL_SIM_EF_CPHS_MAILBOX_NUMBERS:
828 if (file_meta->mb_count == file_meta->files.data.mb.count) {
829 if (resp_cb_data->cb)
830 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
832 file_meta->current_index = file_meta->mb_index[file_meta->mb_count];
833 __imc_sim_read_record(co, resp_cb_data);
838 case TEL_SIM_EF_USIM_CFIS:
839 case TEL_SIM_EF_USIM_MWIS:
840 case TEL_SIM_EF_CPHS_INFORMATION_NUMBERS:
841 if (file_meta->current_index == file_meta->rec_count) {
842 if (resp_cb_data->cb)
843 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
845 file_meta->current_index++;
846 __imc_sim_read_record(co, resp_cb_data);
851 case TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING:
853 ImcSimMetaInfo *file_meta_new = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
855 file_meta->files.result = sim_result;
856 if (decode_ret == TRUE && sim_result == TEL_SIM_RESULT_SUCCESS) {
857 file_meta_new->files.data.cphs_net.full_name = file_meta->files.data.cphs_net.full_name;
858 dbg("file_meta_new->files.data.cphs_net.full_name[%s]", file_meta_new->files.data.cphs_net.full_name);
861 file_meta_new->file_id = TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING;
862 file_meta_new->file_result = TEL_SIM_RESULT_FAILURE;
864 __imc_sim_get_response(co, resp_cb_data);
869 case TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
870 if (resp_cb_data->cb)
871 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data.cphs_net, resp_cb_data->cb_data);
873 tcore_free(file_meta->files.data.cphs_net.full_name);
874 tcore_free(file_meta->files.data.cphs_net.short_name);
875 file_meta->files.data.cphs_net.full_name = NULL;
876 file_meta->files.data.cphs_net.short_name = NULL;
879 case TEL_SIM_EF_ICCID:
880 if (resp_cb_data->cb)
881 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data.iccid, resp_cb_data->cb_data);
884 case TEL_SIM_EF_SPDI: {
886 dbg("spdi count[%d]", file_meta->files.data.spdi.count);
888 if (resp_cb_data->cb)
889 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
892 for (i = 0; i < file_meta->files.data.spdi.count; i++)
893 tcore_free(file_meta->files.data.spdi.list[i].plmn);
895 tcore_free(file_meta->files.data.spdi.list);
901 case TEL_SIM_EF_OPLMN_ACT:
902 case TEL_SIM_EF_CPHS_CPHS_INFO:
903 case TEL_SIM_EF_CPHS_CALL_FORWARD_FLAGS:
904 case TEL_SIM_EF_CPHS_VOICE_MSG_WAITING:
905 case TEL_SIM_EF_CPHS_DYNAMICFLAGS:
906 case TEL_SIM_EF_CPHS_DYNAMIC2FLAG:
907 case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
908 case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
909 if (resp_cb_data->cb)
910 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
914 err("File id not handled [0x%x]", file_meta->file_id);
918 /* free resp_cb_data */
919 imc_destroy_resp_cb_data(resp_cb_data);
922 static void __imc_sim_next_from_get_response(CoreObject *co, ImcRespCbData *resp_cb_data, TelSimResult sim_result)
924 ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
925 TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
927 dbg("EF[0x%x] access Result[%d]", file_meta->file_id, sim_result);
929 file_meta->files.result = sim_result;
930 if (file_meta->file_id != TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING &&
931 file_meta->file_id != TEL_SIM_EF_USIM_MBI &&
932 file_meta->file_id != TEL_SIM_EF_MBDN)
933 memset(&file_meta->files.data, 0x00, sizeof(file_meta->files.data));
935 if ((file_meta->file_id != TEL_SIM_EF_ELP && file_meta->file_id != TEL_SIM_EF_LP &&
936 file_meta->file_id != TEL_SIM_EF_USIM_PL && file_meta->file_id != TEL_SIM_EF_CPHS_CPHS_INFO)
937 && (sim_result != TEL_SIM_RESULT_SUCCESS)) {
938 if (resp_cb_data->cb)
939 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
943 switch (file_meta->file_id) {
945 if (sim_result == TEL_SIM_RESULT_SUCCESS) {
946 dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
947 __imc_sim_read_binary(co, resp_cb_data);
949 tcore_sim_get_type(co, &card_type);
950 if (TEL_SIM_CARD_TYPE_GSM == card_type) {
951 ImcSimMetaInfo file_meta_new = {0,};
953 dbg("[SIM DATA]SIM_EF_ELP(2F05) access fail. Request SIM_EF_LP(0x6F05) info");
954 /* The ME requests the Language Preference (EFLP) if EFELP is not available */
955 file_meta_new.file_id = TEL_SIM_EF_LP;
956 file_meta_new.file_result = TEL_SIM_RESULT_FAILURE;
957 file_meta_new.req_command = TCORE_COMMAND_SIM_GET_LANGUAGE;
959 memcpy(resp_cb_data->data, &file_meta_new, sizeof(ImcSimMetaInfo));
961 __imc_sim_get_response(co, resp_cb_data);
962 } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
963 dbg(" [SIM DATA]fail to get Language information in USIM(EF-LI(6F05),EF-PL(2F05))");
964 if (resp_cb_data->cb)
965 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
972 case TEL_SIM_EF_USIM_LI:
973 if (sim_result == TEL_SIM_RESULT_SUCCESS) {
974 dbg("[SIM DATA] exist EFLP/LI(0x6F05)");
975 __imc_sim_read_binary(co, resp_cb_data);
977 tcore_sim_get_type(co, &card_type);
978 dbg("[SIM DATA]SIM_EF_LP/LI(6F05) access fail. Current CardType[%d]", card_type);
979 if (TEL_SIM_CARD_TYPE_GSM == card_type) {
980 if (resp_cb_data->cb)
981 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
984 /* if EFLI is not present, then the language selection shall be as defined in EFPL at the MF level */
985 else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
986 ImcSimMetaInfo file_meta_new = {0,};
988 dbg("[SIM DATA] try USIM EFPL(0x2F05)");
989 file_meta_new.file_id = TEL_SIM_EF_ELP;
990 file_meta_new.file_result = TEL_SIM_RESULT_FAILURE;
991 file_meta_new.req_command = TCORE_COMMAND_SIM_GET_LANGUAGE;
993 memcpy(resp_cb_data->data, &file_meta_new, sizeof(ImcSimMetaInfo));
995 __imc_sim_get_response(co, resp_cb_data);
1000 case TEL_SIM_EF_USIM_PL:
1001 if (sim_result == TEL_SIM_RESULT_SUCCESS) {
1002 dbg("[SIM DATA] exist EFELP/PL(0x2F05)");
1003 __imc_sim_read_binary(co, resp_cb_data);
1005 /* EFELIand EFPL not present, so set language count as zero and select ECC */
1007 " [SIM DATA]SIM_EF_USIM_PL(2A05) access fail. Request SIM_EF_ECC(0x6FB7) info");
1008 if (resp_cb_data->cb)
1009 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
1014 case TEL_SIM_EF_ECC:
1015 tcore_sim_get_type(co, &card_type);
1016 if (TEL_SIM_CARD_TYPE_GSM == card_type) {
1017 __imc_sim_read_binary(co, resp_cb_data);
1018 } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
1019 if (file_meta->rec_count > TEL_SIM_ECC_LIST_MAX) {
1020 file_meta->rec_count = TEL_SIM_ECC_LIST_MAX;
1022 file_meta->current_index++;
1023 __imc_sim_read_record(co, resp_cb_data);
1027 case TEL_SIM_EF_ICCID:
1028 case TEL_SIM_EF_IMSI:
1029 case TEL_SIM_EF_SST:
1030 case TEL_SIM_EF_SPN:
1031 case TEL_SIM_EF_SPDI:
1032 case TEL_SIM_EF_CPHS_CALL_FORWARD_FLAGS:
1033 case TEL_SIM_EF_CPHS_VOICE_MSG_WAITING:
1034 case TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING:
1035 case TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
1036 case TEL_SIM_EF_CPHS_DYNAMICFLAGS:
1037 case TEL_SIM_EF_CPHS_DYNAMIC2FLAG:
1038 case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
1039 case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE_LINE2:
1040 __imc_sim_read_binary(co, resp_cb_data);
1043 case TEL_SIM_EF_CPHS_CPHS_INFO:
1044 if (sim_result == TEL_SIM_RESULT_SUCCESS) {
1045 tcore_sim_set_cphs_status(co, TRUE);
1046 __imc_sim_read_binary(co, resp_cb_data);
1048 tcore_sim_set_cphs_status(co, FALSE);
1049 if (resp_cb_data->cb)
1050 resp_cb_data->cb(co, (gint)sim_result, &file_meta->files.data, resp_cb_data->cb_data);
1055 case TEL_SIM_EF_USIM_CFIS:
1056 if (file_meta->rec_count > TEL_SIM_CALL_FORWARDING_TYPE_MAX) {
1057 file_meta->rec_count = TEL_SIM_CALL_FORWARDING_TYPE_MAX;
1059 file_meta->current_index++;
1060 __imc_sim_read_record(co, resp_cb_data);
1063 case TEL_SIM_EF_MSISDN:
1064 file_meta->files.data.msisdn_list.list =
1065 tcore_malloc0(sizeof(TelSimSubscriberInfo) * file_meta->rec_count);
1066 file_meta->current_index++;
1067 __imc_sim_read_record(co, resp_cb_data);
1070 case TEL_SIM_EF_MBDN:
1071 file_meta->mb_count = 0;
1072 file_meta->current_index = file_meta->mb_index[file_meta->mb_count];
1073 __imc_sim_read_record(co, resp_cb_data);
1076 case TEL_SIM_EF_OPL:
1077 case TEL_SIM_EF_PNN:
1078 case TEL_SIM_EF_USIM_MWIS:
1079 case TEL_SIM_EF_USIM_MBI:
1080 case TEL_SIM_EF_CPHS_MAILBOX_NUMBERS:
1081 case TEL_SIM_EF_CPHS_INFORMATION_NUMBERS:
1082 file_meta->current_index++;
1083 __imc_sim_read_record(co, resp_cb_data);
1086 case TEL_SIM_EF_SMSP:
1088 ImcSimPrivateInfo *priv_info = NULL;
1090 priv_info = tcore_sim_ref_userdata(co);
1092 dbg("SMSP info set to tcore : count:[%d], rec_len:[%d]",file_meta->rec_count, file_meta->rec_length);
1093 priv_info->smsp_count = file_meta->rec_count;
1094 priv_info->smsp_rec_len = file_meta->rec_length;
1099 dbg("error - File id for get file info [0x%x]", file_meta->file_id);
1105 static void __on_response_imc_sim_update_file(TcorePending *p, guint data_len, const void *data, void *user_data)
1107 const TcoreAtResponse *resp = data;
1108 CoreObject *co_sim = NULL;
1109 GSList *tokens = NULL;
1110 TelSimResult sim_result = TEL_SIM_RESULT_CARD_ERROR;
1112 ImcRespCbData *resp_cb_data = (ImcRespCbData *) user_data;
1113 ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1117 co_sim = tcore_pending_ref_core_object(p);
1119 dbg("file_id:[0x%x]", file_meta->file_id);
1121 if (resp->success > 0) {
1126 line = (const char *)resp->lines->data;
1127 tokens = tcore_at_tok_new(line);
1128 if (g_slist_length(tokens) != 2) {
1129 err("Invalid message");
1132 sw1 = atoi(g_slist_nth_data(tokens, 0));
1133 sw2 = atoi(g_slist_nth_data(tokens, 1));
1136 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1137 sim_result = TEL_SIM_RESULT_SUCCESS;
1139 sim_result = __imc_sim_decode_status_word(sw1, sw2);
1142 err("RESPONSE NOK");
1143 sim_result = TEL_SIM_RESULT_FAILURE;
1147 if (resp_cb_data->cb)
1148 resp_cb_data->cb(co_sim, (gint)sim_result, NULL, resp_cb_data->cb_data);
1150 tcore_at_tok_free(tokens);
1154 static void __on_response_imc_sim_read_data(TcorePending *p, guint data_len,
1155 const void *data, void *user_data)
1157 const TcoreAtResponse *resp = data;
1158 CoreObject *co = NULL;
1159 GSList *tokens = NULL;
1160 TelSimResult sim_result;
1161 gboolean dr = FALSE;
1162 const char *line = NULL;
1168 TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
1169 ImcRespCbData *resp_cb_data = (ImcRespCbData *) user_data;
1170 ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1174 co = tcore_pending_ref_core_object(p);
1176 if (resp->success > 0) {
1179 line = (const char *)resp->lines->data;
1180 tokens = tcore_at_tok_new(line);
1181 if (g_slist_length(tokens) < 2) {
1182 err("Invalid message");
1183 tcore_at_tok_free(tokens);
1187 sw1 = atoi(g_slist_nth_data(tokens, 0));
1188 sw2 = atoi(g_slist_nth_data(tokens, 1));
1190 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1191 res = g_slist_nth_data(tokens, 2);
1193 tmp = tcore_at_tok_extract(res);
1194 tcore_util_hexstring_to_bytes(tmp, &res, (guint *)&res_len);
1195 dbg("Response: [%s] Response length: [%d]", res, res_len);
1197 sim_result = TEL_SIM_RESULT_SUCCESS;
1198 file_meta->files.result = sim_result;
1200 dbg("File ID: [0x%x]", file_meta->file_id);
1201 switch (file_meta->file_id) {
1202 case TEL_SIM_EF_IMSI: {
1203 dbg("Data: [%s]", res);
1204 dr = tcore_sim_decode_imsi((unsigned char *)res, res_len, &file_meta->imsi);
1206 err("IMSI decoding failed");
1208 __imc_sim_set_identity(co, &file_meta->imsi);
1211 tcore_sim_set_imsi(co, &file_meta->imsi);
1216 case TEL_SIM_EF_ICCID: {
1217 dr = tcore_sim_decode_iccid((unsigned char *)res, res_len,
1218 file_meta->files.data.iccid);
1222 case TEL_SIM_EF_ELP: /* 2G EF - 2 bytes decoding */
1223 case TEL_SIM_EF_USIM_LI: /* 3G EF - 2 bytes decoding */
1224 case TEL_SIM_EF_USIM_PL: /* 3G EF - same as EFELP, so 2 byte decoding */
1225 case TEL_SIM_EF_LP: /* 1 byte encoding */
1227 tcore_sim_get_type(co, &card_type);
1228 if ((TEL_SIM_CARD_TYPE_GSM == card_type)
1229 && (file_meta->file_id == TEL_SIM_EF_LP)) {
1231 * 2G LP(0x6F05) has 1 byte for each language
1233 dr = tcore_sim_decode_lp((unsigned char *)res, res_len, &file_meta->files.data.language);
1236 * 3G LI(0x6F05)/PL(0x2F05),
1237 * 2G ELP(0x2F05) has 2 bytes for each language
1239 dr = tcore_sim_decode_li((unsigned char *)res, res_len,
1240 file_meta->file_id, &file_meta->files.data.language);
1245 case TEL_SIM_EF_SPN:
1246 dr = tcore_sim_decode_spn((unsigned char *)res, res_len, &file_meta->files.data.spn);
1249 case TEL_SIM_EF_SPDI:
1250 dr = tcore_sim_decode_spdi((unsigned char *)res, res_len, &file_meta->files.data.spdi);
1253 case TEL_SIM_EF_SST:
1255 TelSimServiceTable *svct = NULL;
1257 svct = g_try_new0(TelSimServiceTable, 1);
1258 tcore_sim_get_type(co, &card_type);
1259 svct->sim_type = card_type;
1260 if (TEL_SIM_CARD_TYPE_GSM == card_type) {
1261 dr = tcore_sim_decode_sst((unsigned char *)res, res_len, svct->table.sst_service);
1262 } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
1263 dr = tcore_sim_decode_ust((unsigned char *)res, res_len, svct->table.ust_service);
1265 err("Not handled card_type[%d]", card_type);
1269 err("SST/UST decoding failed");
1271 tcore_sim_set_service_table(co, svct);
1279 case TEL_SIM_EF_ECC:
1281 tcore_sim_get_type(co, &card_type);
1282 if (TEL_SIM_CARD_TYPE_GSM == card_type) {
1283 dr = tcore_sim_decode_ecc((unsigned char *)res, res_len, &file_meta->files.data.ecc);
1284 } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
1285 TelSimEcc *ecc = NULL;
1287 ecc = g_try_new0(TelSimEcc, 1);
1288 dbg("Index [%d]", file_meta->current_index);
1290 dr = tcore_sim_decode_uecc((unsigned char *)res, res_len, ecc);
1292 memcpy(&file_meta->files.data.ecc.list[file_meta->files.data.ecc.count], ecc, sizeof(TelSimEcc));
1293 file_meta->files.data.ecc.count++;
1299 dbg("Unknown/Unsupported SIM card Type: [%d]", card_type);
1304 case TEL_SIM_EF_MSISDN:
1306 TelSimSubscriberInfo *msisdn = NULL;
1308 dbg("Index [%d]", file_meta->current_index);
1309 msisdn = tcore_malloc0(sizeof(TelSimSubscriberInfo));
1310 dr = tcore_sim_decode_msisdn((unsigned char *)res, res_len, msisdn);
1312 memcpy(&file_meta->files.data.msisdn_list.list[file_meta->files.data.msisdn_list.count],
1313 msisdn, sizeof(TelSimSubscriberInfo));
1315 file_meta->files.data.msisdn_list.count++;
1319 dbg("Freeing resources");
1324 case TEL_SIM_EF_OPL:
1326 TelSimOpl *opl = NULL;
1328 dbg("decode w/ index [%d]", file_meta->current_index);
1329 opl = g_try_new0(TelSimOpl, 1);
1331 dr = tcore_sim_decode_opl((unsigned char *)res, res_len, opl);
1333 memcpy(&file_meta->files.data.opl.list[file_meta->files.data.opl.opl_count],
1334 opl, sizeof(TelSimOpl));
1336 file_meta->files.data.opl.opl_count++;
1344 case TEL_SIM_EF_PNN:
1346 TelSimPnn *pnn = NULL;
1348 dbg("decode w/ index [%d]", file_meta->current_index);
1349 pnn = g_try_new0(TelSimPnn, 1);
1351 dr = tcore_sim_decode_pnn((unsigned char *)res, res_len, pnn);
1353 memcpy(&file_meta->files.data.pnn.list[file_meta->files.data.pnn.pnn_count],
1354 pnn, sizeof(TelSimPnn));
1356 file_meta->files.data.pnn.pnn_count++;
1364 case TEL_SIM_EF_OPLMN_ACT:
1365 /*dr = tcore_sim_decode_oplmnwact(&file_meta->files.data.opwa,
1366 (unsigned char *)res, res_len);*/
1369 case TEL_SIM_EF_CPHS_CUSTOMER_SERVICE_PROFILE:
1370 /*dr = tcore_sim_decode_csp(&po->p_cphs->csp,
1371 p_data->response, p_data->response_len);*/
1374 case TEL_SIM_EF_USIM_MBI: /* linear type */
1376 TelSimMbi *mbi = NULL;
1379 mbi = g_try_new0(TelSimMbi, 1);
1380 dr = tcore_sim_decode_mbi((unsigned char *)res, res_len, mbi);
1382 dbg("voice_index [0x%2x],fax_index[0x%2x], email_index[0x%2x]," \
1383 "other_index[0x%2x], video_index [0x%2x] ", mbi->voice_index,
1384 mbi->fax_index, mbi->email_index, mbi->other_index, mbi->video_index);
1387 count = file_meta->files.data.mb.count;
1389 if(mbi->voice_index) {
1390 file_meta->files.data.mb.list[count].mb_type = TEL_SIM_MAILBOX_VOICE;
1391 file_meta->mb_index[count] = mbi->voice_index;
1394 if(mbi->fax_index) {
1395 file_meta->files.data.mb.list[count].mb_type = TEL_SIM_MAILBOX_FAX;
1396 file_meta->mb_index[count] = mbi->fax_index;
1399 if(mbi->email_index) {
1400 file_meta->files.data.mb.list[count].mb_type = TEL_SIM_MAILBOX_EMAIL;
1401 file_meta->mb_index[count] = mbi->email_index;
1404 if(mbi->other_index) {
1405 file_meta->files.data.mb.list[count].mb_type = TEL_SIM_MAILBOX_OTHER;
1406 file_meta->mb_index[count] = mbi->other_index;
1409 if(mbi->video_index) {
1410 file_meta->files.data.mb.list[count].mb_type = TEL_SIM_MAILBOX_VIDEO;
1411 file_meta->mb_index[count] = mbi->video_index;
1415 file_meta->files.data.mb.count = count;
1420 dbg("index [%d] mb_type[%d]", count, file_meta->files.data.mb.list[count].mb_type);
1424 case TEL_SIM_EF_CPHS_MAILBOX_NUMBERS: /* linear type */
1425 case TEL_SIM_EF_MBDN: /* linear type */
1427 dr = tcore_sim_decode_xdn((unsigned char *)res, res_len,
1428 file_meta->files.data.mb.list[file_meta->mb_count].alpha_id,
1429 &file_meta->files.data.mb.list[file_meta->mb_count].alpha_id_len,
1430 file_meta->files.data.mb.list[file_meta->mb_count].number);
1431 file_meta->files.data.mb.list[file_meta->mb_count].profile_id = file_meta->mb_count+1;
1432 file_meta->mb_count++;
1436 case TEL_SIM_EF_CPHS_VOICE_MSG_WAITING: /* transparent type */
1437 dr = tcore_sim_decode_vmwf((unsigned char *)res, res_len, file_meta->files.data.mw.mw);
1440 case TEL_SIM_EF_USIM_MWIS: { /* linear type */
1441 TelSimMwis *mw = NULL;
1443 mw = g_try_new0(TelSimMwis, 1);
1445 dr = tcore_sim_decode_mwis((unsigned char *)res, res_len, mw);
1447 guint count = file_meta->files.data.mw.profile_count;
1449 memcpy(&file_meta->files.data.mw.mw[count], mw, sizeof(TelSimMwis));
1452 * The Profile Identity shall be between 1 and 4 as defined
1453 * in TS 23.097 for MSP
1455 file_meta->files.data.mw.mw[count].profile_id = count+1;
1457 file_meta->files.data.mw.profile_count++;
1465 case TEL_SIM_EF_CPHS_CALL_FORWARD_FLAGS: /* transparent type */
1466 dr = tcore_sim_decode_cff((unsigned char *)res, res_len, file_meta->files.data.mw.mw);
1469 case TEL_SIM_EF_USIM_CFIS: /* linear type */
1471 TelSimCfis *cf = NULL;
1473 cf = g_try_new0(TelSimCfis, 1);
1474 dr = tcore_sim_decode_cfis((unsigned char *)res, res_len, cf);
1476 memcpy(&file_meta->files.data.cf.cf[file_meta->files.data.cf.profile_count],
1477 cf, sizeof(TelSimCfis));
1478 file_meta->files.data.cf.profile_count++;
1486 case TEL_SIM_EF_CPHS_SERVICE_STRING_TABLE:
1487 dbg("not handled - TEL_SIM_EF_CPHS_SERVICE_STRING_TABLE ");
1490 case TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING:
1491 file_meta->files.data.cphs_net.full_name = tcore_malloc0(TEL_SIM_CPHS_OPERATOR_NAME_LEN_MAX+1);
1492 dr = tcore_sim_decode_ons((unsigned char *)res, res_len,
1493 (unsigned char*)file_meta->files.data.cphs_net.full_name);
1494 dbg("file_meta->files.result[%d],file_meta->files.data.cphs_net.full_name[%s]",
1495 file_meta->files.result, file_meta->files.data.cphs_net.full_name);
1498 case TEL_SIM_EF_CPHS_DYNAMICFLAGS:
1499 /*dr = tcore_sim_decode_dynamic_flag(&po->p_cphs->dflagsinfo,
1500 p_data->response, p_data->response_len);*/
1503 case TEL_SIM_EF_CPHS_DYNAMIC2FLAG:
1504 /*dr = tcore_sim_decode_dynamic2_flag(&po->p_cphs->d2flagsinfo, p_data->response,
1505 p_data->response_len);*/
1508 case TEL_SIM_EF_CPHS_CPHS_INFO:
1509 /*dr = tcore_sim_decode_cphs_info(&file_meta->files.data.cphs,
1510 (unsigned char *)res, res_len);*/
1513 case TEL_SIM_EF_CPHS_OPERATOR_NAME_SHORT_FORM_STRING:
1514 file_meta->files.data.cphs_net.short_name = tcore_malloc0(TEL_SIM_CPHS_OPERATOR_NAME_SHORT_FORM_LEN_MAX+1);
1515 dr = tcore_sim_decode_short_ons((unsigned char *)res, res_len,
1516 (unsigned char*)file_meta->files.data.cphs_net.short_name);
1517 dbg("file_meta->files.result[%d],file_meta->files.data.cphs_net.short_name[%s]",
1518 file_meta->files.result, file_meta->files.data.cphs_net.short_name);
1521 case TEL_SIM_EF_CPHS_INFORMATION_NUMBERS:
1522 /*dr = tcore_sim_decode_information_number(&po->p_cphs->infn, p_data->response, p_data->response_len);*/
1526 dbg("File Decoding Failed - not handled File[0x%x]", file_meta->file_id);
1531 sim_result = __imc_sim_decode_status_word(sw1, sw2);
1532 file_meta->files.result = sim_result;
1540 tcore_at_tok_free(tokens);
1542 err("RESPONSE NOK");
1543 dbg("Error - File ID: [0x%x]", file_meta->file_id);
1544 sim_result = TEL_SIM_RESULT_FAILURE;
1548 __imc_sim_next_from_read_binary(tcore_pending_ref_core_object(p), resp_cb_data, sim_result, dr);
1553 static void __on_response_imc_sim_get_response(TcorePending *p,
1554 guint data_len, const void *data, void *user_data)
1556 const TcoreAtResponse *resp = data;
1557 CoreObject *co = NULL;
1558 TelSimResult sim_result;
1559 GSList *tokens = NULL;
1560 const char *line = NULL;
1563 ImcRespCbData *resp_cb_data = (ImcRespCbData *)user_data;
1564 ImcSimMetaInfo *file_meta =
1565 (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1567 dbg("SIM Response - SIM File info: [+CRSM]");
1569 co = tcore_pending_ref_core_object(p);
1571 if (resp->success > 0) {
1574 line = (const char *)resp->lines->data;
1575 tokens = tcore_at_tok_new(line);
1576 if (g_slist_length(tokens) < 2) {
1577 err("Invalid message");
1578 tcore_at_tok_free(tokens);
1582 sw1 = atoi(g_slist_nth_data(tokens, 0));
1583 sw2 = atoi(g_slist_nth_data(tokens, 1));
1585 /*1. SIM access success case*/
1586 if ((sw1 == 0x90 && sw2 == 0x00) || sw1 == 0x91) {
1587 unsigned char tag_len = 0;
1588 unsigned short record_len = 0;
1589 char num_of_records = 0;
1590 unsigned char file_id_len = 0;
1591 unsigned short file_id = 0;
1592 unsigned short file_size = 0;
1593 unsigned short file_type = 0;
1594 unsigned short arr_file_id = 0;
1595 int arr_file_id_rec_num = 0;
1596 TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
1598 /* handling only last 3 bits */
1599 unsigned char file_type_tag = 0x07;
1600 unsigned char *ptr_data;
1604 char *record_data = NULL;
1605 guint record_data_len;
1606 hexData = g_slist_nth_data(tokens, 2);
1607 dbg("hexData: %s", hexData);
1608 dbg("hexData: %s", hexData + 1);
1610 tmp = tcore_at_tok_extract(hexData);
1611 tcore_util_hexstring_to_bytes(tmp, &record_data, &record_data_len);
1612 tcore_util_hex_dump(" ", record_data_len, record_data);
1615 ptr_data = (unsigned char *)record_data;
1616 tcore_sim_get_type(co, &card_type);
1617 if (TEL_SIM_CARD_TYPE_USIM == card_type) {
1619 ETSI TS 102 221 v7.9.0
1621 '62' FCP template tag
1622 - Response for an EF
1623 '82' M File Descriptor
1624 '83' M File Identifier
1625 'A5' O Proprietary information
1626 '8A' M Life Cycle Status Integer
1627 '8B', '8C' or 'AB' C1 Security attributes
1629 '81' O Total file size
1630 '88' O Short File Identifier (SFI)
1633 /* rsim.res_len has complete data length received */
1635 /* FCP template tag - File Control Parameters tag*/
1636 if (*ptr_data == 0x62) {
1637 /* parse complete FCP tag*/
1638 /* increment to next byte */
1640 tag_len = *ptr_data++;
1641 dbg("tag_len: %02x", tag_len);
1642 /* FCP file descriptor - file type, accessibility, DF, ADF etc*/
1643 if (*ptr_data == 0x82) {
1644 /* increment to next byte */
1648 /* consider only last 3 bits*/
1649 dbg("file_type_tag: %02x", file_type_tag);
1650 file_type_tag = file_type_tag & (*ptr_data);
1651 dbg("file_type_tag: %02x", file_type_tag);
1653 switch (file_type_tag) {
1654 /* increment to next byte */
1657 dbg("Getting FileType: [Transparent file type]");
1658 file_type = IMC_SIM_FILE_TYPE_TRANSPARENT;
1660 /* increment to next byte */
1662 /* increment to next byte */
1667 dbg("Getting FileType: [Linear fixed file type]");
1668 /* increment to next byte */
1670 /* data coding byte - value 21 */
1673 memcpy(&record_len, ptr_data, 2);
1675 IMC_SWAP_BYTES_16(record_len);
1676 ptr_data = ptr_data + 2;
1677 num_of_records = *ptr_data++;
1678 /* Data lossy conversation from enum (int) to unsigned char */
1679 file_type = IMC_SIM_FILE_TYPE_LINEAR_FIXED;
1683 dbg("Cyclic fixed file type");
1684 /* increment to next byte */
1686 /* data coding byte - value 21 */
1689 memcpy(&record_len, ptr_data, 2);
1691 IMC_SWAP_BYTES_16(record_len);
1692 ptr_data = ptr_data + 2;
1693 num_of_records = *ptr_data++;
1694 file_type = IMC_SIM_FILE_TYPE_CYCLIC;
1698 dbg("not handled file type [0x%x]", *ptr_data);
1702 dbg("INVALID FCP received - DEbug!");
1703 tcore_at_tok_free(tokens);
1704 g_free(record_data);
1708 /*File identifier - 0x84,0x85,0x86 etc are currently ignored and not handled */
1709 if (*ptr_data == 0x83) {
1710 /* increment to next byte */
1712 file_id_len = *ptr_data++;
1713 dbg("file_id_len: %02x", file_id_len);
1715 memcpy(&file_id, ptr_data, file_id_len);
1716 dbg("file_id: %x", file_id);
1719 IMC_SWAP_BYTES_16(file_id);
1720 dbg("file_id: %x", file_id);
1722 ptr_data = ptr_data + 2;
1723 dbg("Getting FileID=[0x%x]", file_id);
1725 dbg("INVALID FCP received - DEbug!");
1726 tcore_at_tok_free(tokens);
1727 g_free(record_data);
1731 /* proprietary information */
1732 if (*ptr_data == 0xA5) {
1733 unsigned short prop_len;
1734 /* increment to next byte */
1738 prop_len = *ptr_data;
1739 dbg("prop_len: %02x", prop_len);
1742 ptr_data = ptr_data + prop_len + 1;
1744 dbg("INVALID FCP received - DEbug!");
1747 /* life cycle status integer [8A][length:0x01][status]*/
1750 00000000 : No information given
1751 00000001 : creation state
1752 00000011 : initialization state
1753 000001-1 : operation state -activated
1754 000001-0 : operation state -deactivated
1755 000011-- : Termination state
1756 b8~b5 !=0, b4~b1=X : Proprietary
1757 Any other value : RFU
1759 if (*ptr_data == 0x8A) {
1760 /* increment to next byte */
1762 /* length - value 1 */
1765 switch (*ptr_data) {
1768 dbg("<RX> operation state -deactivated");
1774 dbg("<RX> operation state -activated");
1779 dbg("<RX> DEBUG! LIFE CYCLE STATUS =[0x%x]", *ptr_data);
1785 /* related to security attributes : currently not handled*/
1786 if (*ptr_data == 0x86 || *ptr_data == 0x8B || *ptr_data == 0x8C || *ptr_data == 0xAB) {
1787 /* increment to next byte */
1789 /* if tag length is 3 */
1790 if (*ptr_data == 0x03) {
1791 /* increment to next byte */
1794 memcpy(&arr_file_id, ptr_data, 2);
1796 IMC_SWAP_BYTES_16(arr_file_id);
1797 ptr_data = ptr_data + 2;
1798 arr_file_id_rec_num = *ptr_data++;
1799 dbg("arr_file_id_rec_num:[%d]", arr_file_id_rec_num);
1801 /* if tag length is not 3 */
1802 /* ignoring bytes */
1803 // ptr_data = ptr_data + 4;
1804 dbg("Useless security attributes, so jump to next tag");
1805 ptr_data = ptr_data + (*ptr_data + 1);
1808 dbg("INVALID FCP received[0x%x] - DEbug!", *ptr_data);
1809 tcore_at_tok_free(tokens);
1810 g_free(record_data);
1814 dbg("Current ptr_data value is [%x]", *ptr_data);
1816 /* file size excluding structural info*/
1817 if (*ptr_data == 0x80) {
1818 /* for EF file size is body of file and for Linear or cyclic it is
1819 * number of recXsizeof(one record)
1821 /* increment to next byte */
1823 /* length is 1 byte - value is 2 bytes or more */
1825 memcpy(&file_size, ptr_data, 2);
1827 IMC_SWAP_BYTES_16(file_size);
1828 ptr_data = ptr_data + 2;
1830 dbg("INVALID FCP received - DEbug!");
1831 tcore_at_tok_free(tokens);
1832 g_free(record_data);
1836 /* total file size including structural info*/
1837 if (*ptr_data == 0x81) {
1839 /* increment to next byte */
1843 dbg("len:[%d]", len);
1845 ptr_data = ptr_data + 3;
1847 dbg("INVALID FCP received - DEbug!");
1848 /* 0x81 is optional tag?? check out! so do not return -1 from here! */
1850 /*short file identifier ignored*/
1851 if (*ptr_data == 0x88) {
1852 dbg("0x88: Do Nothing");
1856 dbg("INVALID FCP received - DEbug!");
1857 tcore_at_tok_free(tokens);
1858 g_free(record_data);
1861 } else if (TEL_SIM_CARD_TYPE_GSM == card_type) {
1862 unsigned char gsm_specific_file_data_len = 0;
1863 /* ignore RFU byte1 and byte2 */
1867 // file_size = p_info->response_len;
1868 memcpy(&file_size, ptr_data, 2);
1870 IMC_SWAP_BYTES_16(file_size);
1871 /* parsed file size */
1872 ptr_data = ptr_data + 2;
1874 memcpy(&file_id, ptr_data, 2);
1875 IMC_SWAP_BYTES_16(file_id);
1876 dbg("FILE id --> [%x]", file_id);
1877 ptr_data = ptr_data + 2;
1878 /* save file type - transparent, linear fixed or cyclic */
1879 file_type_tag = (*(ptr_data + 7));
1881 switch (*ptr_data) {
1884 dbg("RFU file type- not handled - Debug!");
1889 dbg("MF file type - not handled - Debug!");
1894 dbg("DF file type - not handled - Debug!");
1899 dbg("EF file type [%d] ", file_type_tag);
1900 /* increment to next byte */
1903 if (file_type_tag == 0x00 || file_type_tag == 0x01) {
1904 /* increament to next byte as this byte is RFU */
1907 (file_type_tag == 0x00) ? IMC_SIM_FILE_TYPE_TRANSPARENT : IMC_SIM_FILE_TYPE_LINEAR_FIXED;
1909 /* increment to next byte */
1911 /* For a cyclic EF all bits except bit 7 are RFU; b7=1 indicates that */
1912 /* the INCREASE command is allowed on the selected cyclic file. */
1913 file_type = IMC_SIM_FILE_TYPE_CYCLIC;
1915 /* bytes 9 to 11 give SIM file access conditions */
1917 /* byte 10 has one nibble that is RF U and another for INCREASE which is not used currently */
1919 /* byte 11 is invalidate and rehabilate nibbles */
1921 /* byte 12 - file status */
1923 /* byte 13 - GSM specific data */
1924 gsm_specific_file_data_len = *ptr_data;
1925 dbg("gsm_specific_file_data_len:[%d]", gsm_specific_file_data_len);
1927 /* byte 14 - structure of EF - transparent or linear or cyclic , already saved above */
1929 /* byte 15 - length of record for linear and cyclic , for transparent it is set to 0x00. */
1930 record_len = *ptr_data;
1931 dbg("record length[%d], file size[%d]", record_len, file_size);
1932 if (record_len != 0)
1933 num_of_records = (file_size / record_len);
1935 dbg("Number of records [%d]", num_of_records);
1939 dbg("not handled file type");
1943 err("Unknown Card Type - [%d]", card_type);
1946 dbg("req ef[0x%x] resp ef[0x%x] size[%ld] Type[0x%x] NumOfRecords[%ld] RecordLen[%ld]",
1947 file_meta->file_id, file_id, file_size, file_type, num_of_records, record_len);
1949 file_meta->file_type = file_type;
1950 file_meta->data_size = file_size;
1951 file_meta->rec_length = record_len;
1952 file_meta->rec_count = num_of_records;
1953 file_meta->current_index = 0; /* reset for new record type EF */
1954 sim_result = TEL_SIM_RESULT_SUCCESS;
1955 g_free(record_data);
1957 /*2. SIM access fail case*/
1958 err("Failed to get ef[0x%x] (file_meta->file_id) ", file_meta->file_id);
1959 sim_result = __imc_sim_decode_status_word(sw1, sw2);
1962 tcore_at_tok_free(tokens);
1964 err("RESPONSE NOK");
1965 err("Failed to get ef[0x%x] (file_meta->file_id) ", file_meta->file_id);
1966 sim_result = TEL_SIM_RESULT_FAILURE;
1969 dbg("Calling __imc_sim_next_from_get_response");
1970 __imc_sim_next_from_get_response(co, resp_cb_data, sim_result);
1974 static TelReturn __imc_sim_update_file(CoreObject *co,
1975 ImcRespCbData *resp_cb_data, int cmd, TelSimFileId ef,
1976 int p1, int p2, int p3, char *encoded_data)
1978 char *cmd_str = NULL;
1979 TelReturn ret = TEL_RETURN_FAILURE;
1980 ImcSimMetaInfo *file_meta =
1981 (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
1983 dbg("Entry File-id:[0x%02x]", file_meta->file_id);
1985 cmd_str = g_strdup_printf("AT+CRSM=%d,%d,%d,%d,%d,\"%s\"",
1986 cmd, ef, p1, p2, p3, encoded_data);
1988 ret = tcore_at_prepare_and_send_request(co,
1990 TCORE_AT_COMMAND_TYPE_SINGLELINE,
1992 __on_response_imc_sim_update_file, resp_cb_data,
1993 on_send_imc_request, NULL);
1994 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Update SIM File");
1996 tcore_free(encoded_data);
2002 static void __imc_sim_read_record(CoreObject *co, ImcRespCbData *resp_cb_data)
2004 gchar *at_cmd = NULL;
2008 ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2009 TelReturn ret = TEL_RETURN_FAILURE;
2011 dbg("Entry File-id:[0x%02x]", file_meta->file_id);
2013 /* According to TS 102 221, values of p1, p2, p3 can be as below:
2014 * 11.1.5 READ RECORD
2016 * P2: Mode, see table 11.11
2019 * Le: Number of bytes to be read (P3)
2022 p1 = (unsigned char) file_meta->current_index;
2023 p2 = (unsigned char) 0x04; /* 0x4 for absolute mode */
2024 p3 = (unsigned char) file_meta->rec_length;
2026 at_cmd = g_strdup_printf("AT+CRSM=%d, %d, %d, %d, %d",
2027 IMC_SIM_ACCESS_READ_RECORD, file_meta->file_id, p1, p2, p3);
2029 ret = tcore_at_prepare_and_send_request(co,
2031 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2033 __on_response_imc_sim_read_data, resp_cb_data,
2034 on_send_imc_request, NULL);
2035 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get File Record");
2037 dbg("ret:[%d]", ret);
2043 static void __imc_sim_read_binary(CoreObject *co, ImcRespCbData *resp_cb_data)
2045 gchar *at_cmd = NULL;
2050 ImcSimMetaInfo *file_meta = (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2051 TelReturn ret = TEL_RETURN_FAILURE;
2053 dbg("Entry File-id:[0x%02x]", file_meta->file_id);
2055 /* According to TS 102 221, values of P1, P2, P3 can be as below:
2056 * 11.1.3 READ BINARY
2057 * P1: See table 11.10
2061 * Le: Number of bytes to be read (P3)
2064 p1 = (unsigned char) (offset & 0xFF00) >> 8;
2065 p2 = (unsigned char) offset & 0x00FF; /* offset low */
2066 p3 = (unsigned char) file_meta->data_size;
2068 at_cmd = g_strdup_printf("AT+CRSM=%d, %d, %d, %d, %d",
2069 IMC_SIM_ACCESS_READ_BINARY, file_meta->file_id, p1, p2, p3);
2071 ret = tcore_at_prepare_and_send_request(co,
2073 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2075 __on_response_imc_sim_read_data, resp_cb_data,
2076 on_send_imc_request, NULL);
2077 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get File Data");
2079 dbg("ret:[%d]", ret);
2085 static TelReturn __imc_sim_get_response(CoreObject *co, ImcRespCbData *resp_cb_data)
2087 gchar *at_cmd = NULL;
2088 ImcSimMetaInfo *file_meta =
2089 (ImcSimMetaInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2090 TelReturn ret = TEL_RETURN_FAILURE;
2092 dbg("Entry File-id:[0x%02x]", file_meta->file_id);
2094 at_cmd = g_strdup_printf("AT+CRSM=%d, %d",
2095 IMC_SIM_ACCESS_GET_RESPONSE, file_meta->file_id);
2097 ret = tcore_at_prepare_and_send_request(co,
2099 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2101 __on_response_imc_sim_get_response, resp_cb_data,
2102 on_send_imc_request, NULL);
2103 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get File Info");
2110 static void __on_response_imc_sim_get_retry_count(TcorePending *p, guint data_len,
2111 const void *data, void *user_data)
2113 TelSimResult result = TEL_SIM_RESULT_INCORRECT_PASSWORD;
2114 const TcoreAtResponse *at_resp = data;
2115 ImcRespCbData *resp_cb_data = user_data;
2116 CoreObject *co = tcore_pending_ref_core_object(p);
2117 ImcSimCurrSecOp *sec_op = NULL;
2118 GSList *tokens = NULL;
2119 const char *line = NULL;
2121 int attempts_left = 0;
2122 int time_penalty = 0;
2126 tcore_check_return_assert(co != NULL);
2127 tcore_check_return_assert(resp_cb_data != NULL);
2129 sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2131 if (at_resp && at_resp->success) {
2132 dbg("Sim Get Retry Count [OK]");
2134 if (at_resp->lines) {
2135 line = (const char *)at_resp->lines->data;
2136 tokens = tcore_at_tok_new(line);
2137 if (g_slist_length(tokens) < 3) {
2138 err("Invalid message");
2142 lock_type = atoi(g_slist_nth_data(tokens, 0));
2143 attempts_left = atoi(g_slist_nth_data(tokens, 1));
2144 time_penalty = atoi(g_slist_nth_data(tokens, 2));
2146 dbg("lock_type = %d, attempts_left = %d, time_penalty = %d",
2147 lock_type, attempts_left, time_penalty);
2150 case IMC_SIM_CURR_SEC_OP_PIN1_VERIFY:
2151 case IMC_SIM_CURR_SEC_OP_PIN2_VERIFY:
2153 TelSimSecPinResult verify_pin = {0, };
2155 if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN1_VERIFY)
2156 verify_pin.pin_type = TEL_SIM_PIN_TYPE_PIN1;
2157 else if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN2_VERIFY)
2158 verify_pin.pin_type = TEL_SIM_PIN_TYPE_PIN2;
2160 verify_pin.retry_count = attempts_left;
2162 if(resp_cb_data->cb)
2163 resp_cb_data->cb(co, (gint)result,
2164 &verify_pin, resp_cb_data->cb_data);
2167 case IMC_SIM_CURR_SEC_OP_PUK1_VERIFY:
2168 case IMC_SIM_CURR_SEC_OP_PUK2_VERIFY:
2170 TelSimSecPukResult verify_puk = {0, };
2172 if (*sec_op == IMC_SIM_CURR_SEC_OP_PUK1_VERIFY)
2173 verify_puk.puk_type = TEL_SIM_PUK_TYPE_PUK1;
2174 else if (*sec_op == IMC_SIM_CURR_SEC_OP_PUK2_VERIFY)
2175 verify_puk.puk_type = TEL_SIM_PUK_TYPE_PUK2;
2177 verify_puk.retry_count = attempts_left;
2179 if(resp_cb_data->cb)
2180 resp_cb_data->cb(co, (gint)result,
2181 &verify_puk, resp_cb_data->cb_data);
2184 case IMC_SIM_CURR_SEC_OP_PIN1_CHANGE:
2185 case IMC_SIM_CURR_SEC_OP_PIN2_CHANGE:
2187 TelSimSecPinResult change_pin = {0, };
2189 if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN1_CHANGE)
2190 change_pin.pin_type = TEL_SIM_PIN_TYPE_PIN1;
2191 else if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN2_CHANGE)
2192 change_pin.pin_type = TEL_SIM_PIN_TYPE_PIN2;
2194 change_pin.retry_count = attempts_left;
2196 if(resp_cb_data->cb)
2197 resp_cb_data->cb(co, (gint)result,
2198 &change_pin, resp_cb_data->cb_data);
2201 case IMC_SIM_CURR_SEC_OP_PIN1_DISABLE:
2202 case IMC_SIM_CURR_SEC_OP_PIN2_DISABLE:
2203 case IMC_SIM_CURR_SEC_OP_FDN_DISABLE:
2204 case IMC_SIM_CURR_SEC_OP_SIM_DISABLE:
2205 case IMC_SIM_CURR_SEC_OP_NET_DISABLE:
2206 case IMC_SIM_CURR_SEC_OP_NS_DISABLE:
2207 case IMC_SIM_CURR_SEC_OP_SP_DISABLE:
2208 case IMC_SIM_CURR_SEC_OP_CP_DISABLE:
2210 TelSimFacilityResult disable_facility = {0, };
2213 lock_type = __imc_sim_get_lock_type(*sec_op);
2214 if (lock_type == -1)
2217 disable_facility.type = lock_type;
2218 disable_facility.retry_count = attempts_left;
2220 if(resp_cb_data->cb)
2221 resp_cb_data->cb(co, (gint)result,
2222 &disable_facility, resp_cb_data->cb_data);
2225 case IMC_SIM_CURR_SEC_OP_PIN1_ENABLE:
2226 case IMC_SIM_CURR_SEC_OP_PIN2_ENABLE:
2227 case IMC_SIM_CURR_SEC_OP_FDN_ENABLE:
2228 case IMC_SIM_CURR_SEC_OP_SIM_ENABLE:
2229 case IMC_SIM_CURR_SEC_OP_NET_ENABLE:
2230 case IMC_SIM_CURR_SEC_OP_NS_ENABLE:
2231 case IMC_SIM_CURR_SEC_OP_SP_ENABLE:
2232 case IMC_SIM_CURR_SEC_OP_CP_ENABLE:
2234 TelSimFacilityResult enable_facility = {0, };
2237 lock_type = __imc_sim_get_lock_type(*sec_op);
2238 if (lock_type == -1)
2241 enable_facility.type = lock_type;
2242 enable_facility.retry_count = attempts_left;
2244 if(resp_cb_data->cb)
2245 resp_cb_data->cb(co, (gint)result,
2246 &enable_facility, resp_cb_data->cb_data);
2250 err("Unhandled sec op [%d]", *sec_op);
2254 tcore_at_tok_free(tokens);
2255 imc_destroy_resp_cb_data(resp_cb_data);
2258 err("Sim Get Retry Count [NOK]");
2260 /*TODO - send response for verify pin, puk etc.,
2261 * when get_retry_count fails
2263 tcore_at_tok_free(tokens);
2264 imc_destroy_resp_cb_data(resp_cb_data);
2267 static TelReturn __imc_sim_get_retry_count(CoreObject *co,
2268 ImcRespCbData *resp_cb_data)
2270 TelReturn ret = TEL_RETURN_FAILURE;
2271 ImcSimCurrSecOp *sec_op = (
2272 ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2274 gchar *cmd_str = NULL;
2279 case IMC_SIM_CURR_SEC_OP_PIN1_VERIFY:
2280 case IMC_SIM_CURR_SEC_OP_PIN1_CHANGE:
2281 case IMC_SIM_CURR_SEC_OP_PIN1_ENABLE:
2282 case IMC_SIM_CURR_SEC_OP_PIN1_DISABLE:
2285 case IMC_SIM_CURR_SEC_OP_PIN2_VERIFY:
2286 case IMC_SIM_CURR_SEC_OP_PIN2_CHANGE:
2287 case IMC_SIM_CURR_SEC_OP_PIN2_ENABLE:
2288 case IMC_SIM_CURR_SEC_OP_PIN2_DISABLE:
2289 case IMC_SIM_CURR_SEC_OP_FDN_ENABLE:
2290 case IMC_SIM_CURR_SEC_OP_FDN_DISABLE:
2293 case IMC_SIM_CURR_SEC_OP_PUK1_VERIFY:
2296 case IMC_SIM_CURR_SEC_OP_PUK2_VERIFY:
2299 case IMC_SIM_CURR_SEC_OP_NET_ENABLE:
2300 case IMC_SIM_CURR_SEC_OP_NET_DISABLE:
2303 case IMC_SIM_CURR_SEC_OP_NS_ENABLE:
2304 case IMC_SIM_CURR_SEC_OP_NS_DISABLE:
2307 case IMC_SIM_CURR_SEC_OP_SP_ENABLE:
2308 case IMC_SIM_CURR_SEC_OP_SP_DISABLE:
2311 case IMC_SIM_CURR_SEC_OP_CP_ENABLE:
2312 case IMC_SIM_CURR_SEC_OP_CP_DISABLE:
2315 case IMC_SIM_CURR_SEC_OP_ADM_VERIFY:
2321 cmd_str = g_strdup_printf("AT+XPINCNT=%d", lock_type);
2323 ret = tcore_at_prepare_and_send_request(co,
2325 TCORE_AT_COMMAND_TYPE_SINGLELINE,
2327 __on_response_imc_sim_get_retry_count, resp_cb_data,
2328 on_send_imc_request, NULL);
2329 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get Retry Count");
2335 static TelSimLockType __imc_sim_lock_type(int lock_type)
2339 return TEL_SIM_LOCK_SC;
2341 return TEL_SIM_LOCK_FD;
2343 return TEL_SIM_LOCK_PN;
2345 return TEL_SIM_LOCK_PU;
2347 return TEL_SIM_LOCK_PP;
2349 return TEL_SIM_LOCK_PC ;
2351 return TEL_SIM_LOCK_PS ;
2353 err("Invalid lock_type [%d]", lock_type);
2358 static char *__imc_sim_get_fac_from_lock_type(TelSimLockType lock_type,
2359 ImcSimCurrSecOp *sec_op, int flag)
2363 case TEL_SIM_LOCK_PS :
2365 if (flag == ENABLE_FLAG)
2366 *sec_op = IMC_SIM_CURR_SEC_OP_SIM_ENABLE;
2367 else if (flag == DISABLE_FLAG)
2368 *sec_op = IMC_SIM_CURR_SEC_OP_SIM_DISABLE;
2370 *sec_op = IMC_SIM_CURR_SEC_OP_SIM_STATUS;
2372 case TEL_SIM_LOCK_SC :
2374 if (flag == ENABLE_FLAG)
2375 *sec_op = IMC_SIM_CURR_SEC_OP_PIN1_ENABLE;
2376 else if (flag == DISABLE_FLAG)
2377 *sec_op = IMC_SIM_CURR_SEC_OP_PIN1_DISABLE;
2379 *sec_op = IMC_SIM_CURR_SEC_OP_PIN1_STATUS;
2381 case TEL_SIM_LOCK_FD :
2383 if (flag == ENABLE_FLAG)
2384 *sec_op = IMC_SIM_CURR_SEC_OP_FDN_ENABLE;
2385 else if (flag == DISABLE_FLAG)
2386 *sec_op = IMC_SIM_CURR_SEC_OP_FDN_DISABLE;
2388 *sec_op = IMC_SIM_CURR_SEC_OP_FDN_STATUS;
2390 case TEL_SIM_LOCK_PN :
2392 if (flag == ENABLE_FLAG)
2393 *sec_op = IMC_SIM_CURR_SEC_OP_NET_ENABLE;
2394 else if (flag == DISABLE_FLAG)
2395 *sec_op = IMC_SIM_CURR_SEC_OP_NET_DISABLE;
2397 *sec_op = IMC_SIM_CURR_SEC_OP_NET_STATUS;
2399 case TEL_SIM_LOCK_PU :
2401 if (flag == ENABLE_FLAG)
2402 *sec_op = IMC_SIM_CURR_SEC_OP_NS_ENABLE;
2403 else if (flag == DISABLE_FLAG)
2404 *sec_op = IMC_SIM_CURR_SEC_OP_NS_DISABLE;
2406 *sec_op = IMC_SIM_CURR_SEC_OP_NS_STATUS;
2408 case TEL_SIM_LOCK_PP :
2410 if (flag == ENABLE_FLAG)
2411 *sec_op = IMC_SIM_CURR_SEC_OP_SP_ENABLE;
2412 else if (flag == DISABLE_FLAG)
2413 *sec_op = IMC_SIM_CURR_SEC_OP_SP_DISABLE;
2415 *sec_op = IMC_SIM_CURR_SEC_OP_SP_STATUS;
2417 case TEL_SIM_LOCK_PC :
2419 if (flag == ENABLE_FLAG)
2420 *sec_op = IMC_SIM_CURR_SEC_OP_CP_ENABLE;
2421 else if (flag == DISABLE_FLAG)
2422 *sec_op = IMC_SIM_CURR_SEC_OP_CP_DISABLE;
2424 *sec_op = IMC_SIM_CURR_SEC_OP_CP_STATUS;
2427 err("Unhandled sim lock type [%d]", lock_type);
2432 static int __imc_sim_get_lock_type(ImcSimCurrSecOp sec_op)
2435 case IMC_SIM_CURR_SEC_OP_SIM_DISABLE :
2436 case IMC_SIM_CURR_SEC_OP_SIM_ENABLE :
2437 case IMC_SIM_CURR_SEC_OP_SIM_STATUS :
2438 return TEL_SIM_LOCK_PS;
2439 case IMC_SIM_CURR_SEC_OP_PIN1_DISABLE :
2440 case IMC_SIM_CURR_SEC_OP_PIN1_ENABLE :
2441 case IMC_SIM_CURR_SEC_OP_PIN1_STATUS :
2442 return TEL_SIM_LOCK_SC;
2443 case IMC_SIM_CURR_SEC_OP_FDN_DISABLE :
2444 case IMC_SIM_CURR_SEC_OP_FDN_ENABLE :
2445 case IMC_SIM_CURR_SEC_OP_FDN_STATUS :
2446 return TEL_SIM_LOCK_FD;
2447 case IMC_SIM_CURR_SEC_OP_NET_DISABLE :
2448 case IMC_SIM_CURR_SEC_OP_NET_ENABLE :
2449 case IMC_SIM_CURR_SEC_OP_NET_STATUS :
2450 return TEL_SIM_LOCK_PN;
2451 case IMC_SIM_CURR_SEC_OP_NS_DISABLE :
2452 case IMC_SIM_CURR_SEC_OP_NS_ENABLE :
2453 case IMC_SIM_CURR_SEC_OP_NS_STATUS :
2454 return TEL_SIM_LOCK_PU;
2455 case IMC_SIM_CURR_SEC_OP_SP_DISABLE :
2456 case IMC_SIM_CURR_SEC_OP_SP_ENABLE :
2457 case IMC_SIM_CURR_SEC_OP_SP_STATUS :
2458 return TEL_SIM_LOCK_PP;
2459 case IMC_SIM_CURR_SEC_OP_CP_DISABLE :
2460 case IMC_SIM_CURR_SEC_OP_CP_ENABLE :
2461 case IMC_SIM_CURR_SEC_OP_CP_STATUS :
2462 return TEL_SIM_LOCK_PC ;
2464 err("Invalid sec op [%d]", sec_op);
2471 * Notification: +XSIM: <SIM state>
2473 * Possible values of <SIM state> can be
2475 * 1 PIN verification needed
2476 * 2 PIN verification not needed - Ready
2477 * 3 PIN verified - Ready
2478 * 4 PUK verification needed
2479 * 5 SIM permanently blocked
2481 * 7 ready for attach (+COPS)
2482 * 8 SIM Technical Problem
2484 * 10 SIM Reactivating
2485 * 11 SIM Reactivated
2486 * 12 SIM SMS Caching Completed. (Sent only when SMS caching enabled)
2487 * 99 SIM State Unknown
2489 static gboolean on_notification_imc_sim_status(CoreObject *co,
2490 const void *event_info, void *user_data)
2492 GSList *lines = (GSList *)event_info;
2495 dbg("SIM notification - SIM status: [+XSIM]");
2497 if (g_slist_length(lines) != 1) {
2498 err("+XSIM unsolicited message expected to be "
2499 "Single line but received multiple lines");
2503 line = (const gchar *) (lines->data);
2511 * +XSIM: <SIM state>
2513 tokens = tcore_at_tok_new(line);
2514 if (g_slist_length(tokens) == 1) {
2516 sim_state = atoi(g_slist_nth_data(tokens, 0));
2518 /* Process SIM Status */
2519 __imc_sim_process_sim_status(co, sim_state);
2521 err("Invalid message");
2524 tcore_at_tok_free(tokens);
2531 static TcoreHookReturn on_hook_imc_modem_power(TcorePlugin *source,
2532 TcoreNotification command, guint data_len, void *data, void *user_data)
2534 CoreObject *co = (CoreObject *)user_data;
2536 tcore_check_return_value(co != NULL, TCORE_HOOK_RETURN_CONTINUE);
2538 dbg("Get SIM status");
2539 (void)__imc_sim_get_sim_status(co, NULL, NULL);
2541 return TCORE_HOOK_RETURN_CONTINUE;
2544 /* Response Functions */
2545 static void on_response_imc_sim_req_authentication(TcorePending *p, guint data_len,
2546 const void *data, void *user_data)
2548 const TcoreAtResponse *at_resp = data;
2549 GSList *tokens = NULL;
2550 CoreObject *co = tcore_pending_ref_core_object(p);
2551 TelSimAuthenticationResponse auth_resp = {0, };
2552 TelSimResult sim_result = TEL_SIM_RESULT_FAILURE;
2553 ImcRespCbData *resp_cb_data = user_data;
2554 TelSimAuthenticationType *auth_type = (TelSimAuthenticationType *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2558 if (NULL == at_resp) {
2559 err("at_resp is NULL");
2560 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2564 auth_resp.auth_type = *auth_type;
2566 if (at_resp->success == TRUE) {
2571 if (at_resp->lines != NULL) {
2572 line = at_resp->lines->data;
2573 dbg("Received data: [%s]", line);
2575 err("at_resp->lines is NULL");
2576 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2580 tokens = tcore_at_tok_new(line);
2581 if (tokens == NULL) {
2582 err("tokens is NULL");
2583 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2587 status = atoi(g_slist_nth_data(tokens, 0));
2590 dbg("Authentications successful");
2591 auth_resp.detailed_result = TEL_SIM_AUTH_NO_ERROR;
2594 err("Synchronize fail");
2595 auth_resp.detailed_result = TEL_SIM_AUTH_SYNCH_FAILURE;
2599 auth_resp.detailed_result = TEL_SIM_AUTH_MAK_CODE_FAILURE;
2602 err("Does not support security context");
2603 auth_resp.detailed_result = TEL_SIM_AUTH_UNSUPPORTED_CONTEXT;
2606 err("Other failure");
2607 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2611 if (auth_resp.auth_type == TEL_SIM_AUTH_GSM) {
2613 char *convert_kc, *convert_sres;
2615 kc = g_slist_nth_data(tokens, 1);
2617 guint convert_kc_len = 0;
2618 kc = tcore_at_tok_extract(kc);
2619 dbg("Kc: [%s]", kc);
2621 tcore_util_hexstring_to_bytes(kc, &convert_kc, &convert_kc_len);
2622 if (convert_kc_len && convert_kc_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
2623 auth_resp.authentication_key_length = convert_kc_len;
2624 memcpy(&auth_resp.authentication_key, convert_kc, convert_kc_len);
2627 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2633 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2637 sres = g_slist_nth_data(tokens, 2);
2639 guint convert_sres_len = 0;
2640 sres = tcore_at_tok_extract(sres);
2641 dbg("SRES: [%s]", sres);
2643 tcore_util_hexstring_to_bytes(sres, &convert_sres, &convert_sres_len);
2644 if (convert_sres_len && convert_sres_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
2645 auth_resp.resp_length = convert_sres_len;
2646 memcpy(&auth_resp.resp_data, convert_sres, convert_sres_len);
2648 err("Invalid SRES");
2649 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2652 g_free(convert_sres);
2654 err("Invalid SRES");
2655 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2658 } else if (auth_resp.auth_type == TEL_SIM_AUTH_3G_CTX) {
2659 char *res, *ck, *ik, *kc;
2660 char *convert_res, *convert_ck;
2661 char *convert_ik, *convert_kc;
2663 res = g_slist_nth_data(tokens, 1);
2665 guint convert_res_len = 0;
2666 res = tcore_at_tok_extract(res);
2667 dbg("RES/AUTS: [%s]", res);
2669 tcore_util_hexstring_to_bytes(res, &convert_res, &convert_res_len);
2670 if (convert_res_len && convert_res_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
2671 auth_resp.resp_length = convert_res_len;
2672 memcpy(auth_resp.resp_data, convert_res, convert_res_len);
2674 err("Invalid RES/AUTS");
2675 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2678 g_free(convert_res);
2680 err("Invalid RES/AUTS");
2681 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2685 ck = g_slist_nth_data(tokens, 2);
2687 guint convert_ck_len = 0;
2688 ck = tcore_at_tok_extract(ck);
2689 dbg("CK: [%s]", ck);
2691 tcore_util_hexstring_to_bytes(ck, &convert_ck, &convert_ck_len);
2692 if (convert_ck_len && convert_ck_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
2693 auth_resp.cipher_length = convert_ck_len;
2694 memcpy(&auth_resp.cipher_data, convert_ck, convert_ck_len);
2697 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2703 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2707 ik = g_slist_nth_data(tokens, 3);
2709 guint convert_ik_len = 0;
2710 ik = tcore_at_tok_extract(ik);
2711 dbg("IK: [%s]", ik);
2713 tcore_util_hexstring_to_bytes(ik, &convert_ik, &convert_ik_len);
2714 if (convert_ik_len && convert_ik_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
2715 auth_resp.integrity_length = convert_ik_len;
2716 memcpy(&auth_resp.integrity_data, convert_ik, convert_ik_len);
2719 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2725 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2729 kc = g_slist_nth_data(tokens, 4);
2731 guint convert_kc_len = 0;
2732 kc = tcore_at_tok_extract(kc);
2733 dbg("Kc: [%s]", kc);
2735 tcore_util_hexstring_to_bytes(kc, &convert_kc, &convert_kc_len);
2736 if (convert_kc_len && convert_kc_len <= TEL_SIM_AUTH_MAX_RESP_DATA_LEN) {
2737 auth_resp.authentication_key_length = convert_kc_len;
2738 memcpy(&auth_resp.authentication_key, convert_kc, convert_kc_len);
2741 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2747 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2751 err("Not supported");
2752 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2755 sim_result = TEL_SIM_RESULT_SUCCESS;
2757 err("RESPONSE NOK");
2758 auth_resp.detailed_result = TEL_SIM_AUTH_CANNOT_PERFORM;
2762 if(resp_cb_data->cb)
2763 resp_cb_data->cb(co, (gint)sim_result, &auth_resp, resp_cb_data->cb_data);
2765 tcore_at_tok_free(tokens);
2768 static void on_response_imc_sim_verify_pins(TcorePending *p, guint data_len,
2769 const void *data, void *user_data)
2771 const TcoreAtResponse *at_resp = data;
2772 ImcRespCbData *resp_cb_data = user_data;
2773 CoreObject *co = tcore_pending_ref_core_object(p);
2774 TelSimResult result = TEL_SIM_RESULT_FAILURE;
2775 ImcSimCurrSecOp *sec_op = NULL;
2776 TelSimSecPinResult verify_pin_resp = {0, };
2780 tcore_check_return_assert(co != NULL);
2781 tcore_check_return_assert(resp_cb_data != NULL);
2783 sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2785 if (at_resp && at_resp->success) {
2786 dbg("Sim Verify Pin Response- [OK]");
2788 result = TEL_SIM_RESULT_SUCCESS;
2790 if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN1_VERIFY) {
2791 TelSimCardStatus status;
2793 verify_pin_resp.pin_type = TEL_SIM_PIN_TYPE_PIN1;
2795 tcore_sim_get_status(co, &status);
2796 if (status != TEL_SIM_STATUS_SIM_INIT_COMPLETED) {
2797 /*Update sim status*/
2798 __imc_sim_update_sim_status(co,
2799 TEL_SIM_STATUS_SIM_INITIALIZING);
2801 } else if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN2_VERIFY) {
2802 verify_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 Verify Pin Response- [NOK]");
2813 /* Get retry count */
2814 __imc_sim_get_retry_count(co, resp_cb_data);
2818 static void on_response_imc_sim_verify_puks(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 TelSimSecPukResult verify_puk_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) {
2836 dbg("Sim Verify Puk Response- [OK]");
2838 result = TEL_SIM_RESULT_SUCCESS;
2840 if (*sec_op == IMC_SIM_CURR_SEC_OP_PUK1_VERIFY) {
2841 verify_puk_resp.puk_type = TEL_SIM_PUK_TYPE_PUK1;
2842 } else if (*sec_op == IMC_SIM_CURR_SEC_OP_PUK2_VERIFY) {
2843 verify_puk_resp.puk_type = TEL_SIM_PUK_TYPE_PUK2;
2846 if(resp_cb_data->cb)
2847 resp_cb_data->cb(co, (gint)result,
2849 resp_cb_data->cb_data);
2850 imc_destroy_resp_cb_data(resp_cb_data);
2852 err("Sim Verify Puk Response- [NOK]");
2853 /* Get retry count */
2854 __imc_sim_get_retry_count(co, resp_cb_data);
2858 static void on_response_imc_sim_change_pins(TcorePending *p, guint data_len,
2859 const void *data, void *user_data)
2861 const TcoreAtResponse *at_resp = data;
2862 ImcRespCbData *resp_cb_data = user_data;
2863 CoreObject *co = tcore_pending_ref_core_object(p);
2864 TelSimResult result = TEL_SIM_RESULT_FAILURE;
2865 ImcSimCurrSecOp *sec_op = NULL;
2866 TelSimSecPinResult change_pin_resp = {0, };
2870 tcore_check_return_assert(co != NULL);
2871 tcore_check_return_assert(resp_cb_data != NULL);
2873 sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2875 if (at_resp && at_resp->success) {
2876 dbg("Sim Change Pin Response- [OK]");
2878 result = TEL_SIM_RESULT_SUCCESS;
2880 if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN1_CHANGE) {
2881 change_pin_resp.pin_type = TEL_SIM_PIN_TYPE_PIN1;
2882 } else if (*sec_op == IMC_SIM_CURR_SEC_OP_PIN2_CHANGE) {
2883 change_pin_resp.pin_type = TEL_SIM_PIN_TYPE_PIN2;
2886 if(resp_cb_data->cb)
2887 resp_cb_data->cb(co, (gint)result,
2889 resp_cb_data->cb_data);
2890 imc_destroy_resp_cb_data(resp_cb_data);
2892 err("Sim Change Pin Response- [NOK]");
2893 /* Get retry count */
2894 __imc_sim_get_retry_count(co, resp_cb_data);
2898 static void on_response_imc_sim_disable_facility(TcorePending *p, guint data_len,
2899 const void *data, void *user_data)
2901 const TcoreAtResponse *at_resp = data;
2902 ImcRespCbData *resp_cb_data = user_data;
2903 CoreObject *co = tcore_pending_ref_core_object(p);
2904 TelSimResult result = TEL_SIM_RESULT_FAILURE;
2905 ImcSimCurrSecOp *sec_op = NULL;
2906 TelSimFacilityResult disable_facility_resp = {0, };
2910 tcore_check_return_assert(co != NULL);
2911 tcore_check_return_assert(resp_cb_data != NULL);
2913 sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2915 if (at_resp && at_resp->success) {
2917 dbg("Sim Disable Facility Response- [OK]");
2919 lock_type = __imc_sim_get_lock_type(*sec_op);
2920 if (lock_type == -1) {
2921 result = TEL_SIM_RESULT_INVALID_PARAMETER;
2924 if(resp_cb_data->cb)
2925 resp_cb_data->cb(co, (gint)result,
2927 resp_cb_data->cb_data);
2928 imc_destroy_resp_cb_data(resp_cb_data);
2932 disable_facility_resp.type = lock_type;
2933 result = TEL_SIM_RESULT_SUCCESS;
2936 if(resp_cb_data->cb)
2937 resp_cb_data->cb(co, (gint)result,
2938 &disable_facility_resp,
2939 resp_cb_data->cb_data);
2940 imc_destroy_resp_cb_data(resp_cb_data);
2942 err("Sim Disable Facility Response- [NOK]");
2943 /* Get retry count */
2944 __imc_sim_get_retry_count(co, resp_cb_data);
2948 static void on_response_imc_sim_enable_facility(TcorePending *p, guint data_len,
2949 const void *data, void *user_data)
2951 const TcoreAtResponse *at_resp = data;
2952 ImcRespCbData *resp_cb_data = user_data;
2953 CoreObject *co = tcore_pending_ref_core_object(p);
2954 TelSimResult result = TEL_SIM_RESULT_FAILURE;
2955 ImcSimCurrSecOp *sec_op = NULL;
2956 TelSimFacilityResult enable_facility_resp = {0, };
2960 tcore_check_return_assert(co != NULL);
2961 tcore_check_return_assert(resp_cb_data != NULL);
2963 sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
2965 if (at_resp && at_resp->success) {
2967 dbg("Sim Enable Facility Response- [OK]");
2969 lock_type = __imc_sim_get_lock_type(*sec_op);
2970 if (lock_type == -1) {
2971 result = TEL_SIM_RESULT_INVALID_PARAMETER;
2974 if(resp_cb_data->cb)
2975 resp_cb_data->cb(co, (gint)result,
2977 resp_cb_data->cb_data);
2978 imc_destroy_resp_cb_data(resp_cb_data);
2982 enable_facility_resp.type = lock_type;
2983 result = TEL_SIM_RESULT_SUCCESS;
2986 if(resp_cb_data->cb)
2987 resp_cb_data->cb(co, (gint)result,
2988 &enable_facility_resp,
2989 resp_cb_data->cb_data);
2990 imc_destroy_resp_cb_data(resp_cb_data);
2992 err("Sim Enable Facility Response- [NOK]");
2993 /* Get retry count */
2994 __imc_sim_get_retry_count(co, resp_cb_data);
2998 static void on_response_imc_sim_get_facility(TcorePending *p, guint data_len,
2999 const void *data, void *user_data)
3001 const TcoreAtResponse *at_resp = data;
3002 ImcRespCbData *resp_cb_data = user_data;
3003 CoreObject *co = tcore_pending_ref_core_object(p);
3004 TelSimResult result = TEL_SIM_RESULT_FAILURE;
3005 ImcSimCurrSecOp *sec_op = NULL;
3006 TelSimFacilityInfo get_facility_resp = {0, };
3010 tcore_check_return_assert(co != NULL);
3011 tcore_check_return_assert(resp_cb_data != NULL);
3013 sec_op = (ImcSimCurrSecOp *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
3015 if (at_resp && at_resp->success) {
3016 GSList *tokens = NULL;
3020 dbg("Sim Get Facility Response- [OK]");
3022 lock_type = __imc_sim_get_lock_type(*sec_op);
3023 if (lock_type == -1) {
3024 result = TEL_SIM_RESULT_INVALID_PARAMETER;
3027 if (at_resp->lines) {
3028 line = (const char *)at_resp->lines->data;
3029 tokens = tcore_at_tok_new(line);
3030 if (g_slist_length(tokens) != 1) {
3031 err("Invalid message");
3032 tcore_at_tok_free(tokens);
3035 get_facility_resp.f_status = atoi(g_slist_nth_data(tokens, 0));
3036 get_facility_resp.type = lock_type;
3037 result = TEL_SIM_RESULT_SUCCESS;
3040 tcore_at_tok_free(tokens);
3042 err("Sim Get Facility Response- [NOK]");
3045 /* Invoke callback */
3046 if(resp_cb_data->cb)
3047 resp_cb_data->cb(co, (gint)result, &get_facility_resp, resp_cb_data->cb_data);
3048 imc_destroy_resp_cb_data(resp_cb_data);
3051 static void on_response_imc_sim_get_lock_info(TcorePending *p, guint data_len,
3052 const void *data, void *user_data)
3054 const TcoreAtResponse *at_resp = data;
3055 ImcRespCbData *resp_cb_data = user_data;
3056 CoreObject *co = tcore_pending_ref_core_object(p);
3057 TelSimResult result = TEL_SIM_RESULT_FAILURE;
3058 TelSimLockInfo get_lock_info_resp = {0, };
3062 tcore_check_return_assert(co != NULL);
3063 tcore_check_return_assert(resp_cb_data != NULL);
3065 if(at_resp && at_resp->success) {
3066 GSList *tokens = NULL;
3069 int attempts_left = 0;
3070 int time_penalty = 0;
3072 dbg("Sim Get Lock Info Response- [OK]");
3074 if (at_resp->lines) {
3075 line = (const char *)at_resp->lines->data;
3076 tokens = tcore_at_tok_new(line);
3077 if (g_slist_length(tokens) < 3) {
3078 err("Invalid message");
3079 tcore_at_tok_free(tokens);
3083 lock_type = atoi(g_slist_nth_data(tokens, 0));
3084 attempts_left = atoi(g_slist_nth_data(tokens, 1));
3085 time_penalty = atoi(g_slist_nth_data(tokens, 2));
3087 dbg("lock_type = %d, attempts_left = %d, time_penalty = %d",
3088 lock_type, attempts_left, time_penalty);
3090 get_lock_info_resp.lock_type = __imc_sim_lock_type(lock_type);
3091 get_lock_info_resp.retry_count = attempts_left;
3092 result = TEL_SIM_RESULT_SUCCESS;
3094 tcore_at_tok_free(tokens);
3096 err("Sim Get Lock Info Response- [NOK]");
3099 /* Invoke callback */
3100 if(resp_cb_data->cb)
3101 resp_cb_data->cb(co, (gint)result, &get_lock_info_resp, resp_cb_data->cb_data);
3102 imc_destroy_resp_cb_data(resp_cb_data);
3105 static void on_response_imc_sim_req_apdu (TcorePending *p, guint data_len, const void *data, void *user_data)
3107 const TcoreAtResponse *resp = data;
3108 CoreObject *co = NULL;
3109 TelSimApduResp apdu_resp = {0,};
3110 TelSimResult sim_result = TEL_SIM_RESULT_FAILURE;
3111 GSList *tokens = NULL;
3113 ImcRespCbData *resp_cb_data = (ImcRespCbData *) user_data;
3117 co = tcore_pending_ref_core_object(p);
3119 if (resp->success > 0) {
3123 char *decoded_data = NULL;
3124 guint decoded_data_len = 0;
3125 line = (const char *)resp->lines->data;
3126 tokens = tcore_at_tok_new(line);
3127 if (g_slist_length(tokens) != 2) {
3128 err("Invalid message");
3132 tmp = tcore_at_tok_extract(g_slist_nth_data(tokens, 1));
3133 tcore_util_hexstring_to_bytes(tmp, &decoded_data, &decoded_data_len);
3135 apdu_resp.apdu_resp_len = decoded_data_len;
3136 memcpy((char *)apdu_resp.apdu_resp, decoded_data, decoded_data_len);
3138 g_free(decoded_data);
3139 sim_result = TEL_SIM_RESULT_SUCCESS;
3142 err("RESPONSE NOK");
3147 if (resp_cb_data->cb)
3148 resp_cb_data->cb(co, (gint)sim_result, &apdu_resp, resp_cb_data->cb_data);
3149 tcore_at_tok_free(tokens);
3153 static void on_response_imc_sim_req_atr(TcorePending *p, guint data_len, const void *data, void *user_data)
3155 const TcoreAtResponse *resp = data;
3156 CoreObject *co = NULL;
3157 TelSimAtr atr_res = {0,};
3158 TelSimResult sim_result = TEL_SIM_RESULT_FAILURE;
3159 GSList *tokens = NULL;
3161 ImcRespCbData *resp_cb_data = (ImcRespCbData *) user_data;
3165 co = tcore_pending_ref_core_object(p);
3167 if (resp->success > 0) {
3171 char *decoded_data = NULL;
3172 guint decoded_data_len = 0;
3173 line = (const char *)resp->lines->data;
3174 tokens = tcore_at_tok_new(line);
3175 if (g_slist_length(tokens) < 1) {
3176 err("Invalid message");
3180 tmp = tcore_at_tok_extract(g_slist_nth_data(tokens, 0));
3181 tcore_util_hexstring_to_bytes(tmp, &decoded_data, &decoded_data_len);
3183 atr_res.atr_len = decoded_data_len;
3184 memcpy((char *)atr_res.atr, decoded_data, decoded_data_len);
3186 g_free(decoded_data);
3187 sim_result = TEL_SIM_RESULT_SUCCESS;
3190 err("RESPONSE NOK");
3195 if (resp_cb_data->cb)
3196 resp_cb_data->cb(co, (gint)sim_result, &atr_res, resp_cb_data->cb_data);
3197 tcore_at_tok_free(tokens);
3201 /* SIM Operations */
3203 * Operation - get_imsi
3206 * AT-Command: AT+CRSM= <command>[,<fileid>[,<P1>,<P2>,<P3>[,<data>[,<pathid>]]]]
3217 * 28423 meaning IMSI file (6F07)
3218 * 28473 meaning ACM file (6F39)
3219 * 28481 meaning PUKT file (6F41)
3220 * 28482 meaning SMS file (6F42)
3223 * Integer type defining the request.
3224 * These parameters are mandatory for every command, except GET RESPONSE and STATUS.
3227 * Information which shall be written to the SIM
3230 * String type, contains the path of an elementary file on the SIM/USIM in hexadecimal format
3238 * +CRSM: <sw1>,<sw2>[,<response>]
3241 * Integer type containing the SIM information
3244 * Response of successful completion of the command previously issued
3247 * +CME ERROR: <error>
3249 static TelReturn imc_sim_get_imsi (CoreObject *co,
3250 TcoreObjectResponseCallback cb, void *cb_data)
3255 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_IMSI, ret);
3260 static TelReturn imc_sim_get_ecc (CoreObject *co,
3261 TcoreObjectResponseCallback cb, void *cb_data)
3266 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_ECC, ret);
3271 static TelReturn imc_sim_get_iccid (CoreObject *co,
3272 TcoreObjectResponseCallback cb, void *cb_data)
3277 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_ICCID, ret);
3282 static TelReturn imc_sim_get_language (CoreObject *co,
3283 TcoreObjectResponseCallback cb, void *cb_data)
3288 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_LP, ret);
3292 static TelReturn imc_sim_set_language (CoreObject *co,
3293 TelSimLanguagePreferenceCode language,
3294 TcoreObjectResponseCallback cb, void *cb_data)
3296 ImcSimMetaInfo file_meta = {0, };
3297 TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
3298 ImcRespCbData *resp_cb_data = NULL;
3299 char *encoded_data = NULL;
3300 int encoded_data_len = 0;
3307 file_meta.file_id = TEL_SIM_EF_LP;
3308 file_meta.file_result = TEL_SIM_RESULT_FAILURE;
3310 tcore_sim_get_type(co, &card_type);
3312 dbg("language[%d], card_type[%d]", language, card_type);
3314 if (TEL_SIM_CARD_TYPE_GSM == card_type) {
3317 tcore_sim_encode_lp(language, &encoded_data, &encoded_data_len);
3318 } else if (TEL_SIM_CARD_TYPE_USIM == card_type) {
3322 if (tcore_sim_encode_li(language, &tmp, &encoded_data_len)) {
3323 encoded_data = g_strdup_printf("%02x%02x", tmp[0], tmp[1]);
3327 err("Failed to encode Language [%d]", language);
3328 return TEL_RETURN_FAILURE;
3331 err("Invalid card_type:[%d]", card_type);
3332 return TEL_RETURN_OPERATION_NOT_SUPPORTED;
3335 if (!encoded_data_len) {
3336 err("Failed to encode Language [%d]", language);
3337 return TEL_RETURN_FAILURE;
3339 dbg("Encoded Language [%s] len[%d]", encoded_data, encoded_data_len);
3343 p3 = encoded_data_len;
3345 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3346 &file_meta, sizeof(ImcSimMetaInfo));
3348 return __imc_sim_update_file(co, resp_cb_data,
3349 IMC_SIM_ACCESS_UPDATE_BINARY, TEL_SIM_EF_LP,
3350 p1, p2, p3, encoded_data);
3353 static TelReturn imc_sim_get_callforwarding_info (CoreObject *co,
3354 TcoreObjectResponseCallback cb, void *cb_data)
3359 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_USIM_CFIS, ret);
3364 static TelReturn imc_sim_get_messagewaiting_info (CoreObject *co,
3365 TcoreObjectResponseCallback cb, void *cb_data)
3370 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_USIM_MWIS, ret);
3375 static TelReturn imc_sim_set_messagewaiting_info (CoreObject *co,
3376 const TelSimMwis *request, TcoreObjectResponseCallback cb, void *cb_data)
3378 ImcSimMetaInfo file_meta = {0, };
3379 ImcRespCbData *resp_cb_data = NULL;
3380 gchar *encoded_mwis;
3381 guint encoded_mwis_len = 0;
3382 gchar *encoded_data = NULL;
3383 guint encoded_data_len = 0;
3391 * Videomail is not supported.
3393 if (!tcore_sim_encode_mwis(request, TEL_SIM_MAILBOX_TYPE_MAX,
3394 &encoded_mwis, &encoded_mwis_len)) {
3395 err("Failed to encode mwis");
3396 return TEL_RETURN_FAILURE;
3399 encoded_data_len = 2 * encoded_mwis_len;
3400 encoded_data = (char *)tcore_malloc0(encoded_data_len + 1);
3401 tcore_util_byte_to_hex(encoded_mwis, encoded_data, encoded_mwis_len);
3402 tcore_free(encoded_mwis);
3403 dbg("Encoded data: [%s] Encoded data length: [%d]", encoded_data, encoded_data_len);
3407 p3 = TEL_SIM_MAILBOX_TYPE_MAX; /* Indicator Status | Voicemail | Fax | Electronic Mail | Others */
3408 dbg("p1: [%d] p2: [%d] p3: [%d]", p1, p2, p3);
3410 file_meta.file_id = TEL_SIM_EF_USIM_MWIS;
3411 file_meta.file_result = TEL_SIM_RESULT_FAILURE;
3413 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, &file_meta, sizeof(ImcSimMetaInfo));
3415 return __imc_sim_update_file(co, resp_cb_data, IMC_SIM_ACCESS_UPDATE_RECORD,
3416 TEL_SIM_EF_USIM_MWIS, p1, p2, p3, encoded_data);
3419 static TelReturn imc_sim_get_mailbox_info (CoreObject *co,
3420 TcoreObjectResponseCallback cb, void *cb_data)
3425 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_USIM_MBI, ret);
3429 static TelReturn imc_sim_set_mailbox_info (CoreObject *co,
3430 const TelSimMailBoxNumber *request, TcoreObjectResponseCallback cb, void *cb_data)
3432 ImcSimMetaInfo file_meta = {0, };
3433 ImcRespCbData *resp_cb_data = NULL;
3436 char *encoded_data = NULL;
3437 int encoded_data_len = 0;
3444 file_meta.file_id = TEL_SIM_EF_USIM_MBI;
3445 file_meta.file_result = TEL_SIM_RESULT_FAILURE;
3447 /* TBD - Do Encoding.
3448 if (!tcore_sim_encode_mbi(request, sizeof(request), tmp, &tmp_len)) {
3449 err("Failed to encode mwis");
3450 return TEL_RETURN_FAILURE;
3453 encoded_data_len = tmp_len * 2;
3454 encoded_data = (char *)tcore_malloc0(encoded_data_len + 1);
3455 tcore_util_byte_to_hex(tmp, encoded_data, tmp_len);
3456 if (!encoded_data) {
3457 err("Failed to convert byte to hex");
3458 tcore_free(encoded_data);
3459 return TEL_RETURN_FAILURE;
3464 p3 = encoded_data_len;
3465 dbg("encoded_data - [%s], encoded_data_len - %d", encoded_data, encoded_data_len);
3467 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, &file_meta, sizeof(ImcSimMetaInfo));
3469 return __imc_sim_update_file(co, resp_cb_data, IMC_SIM_ACCESS_UPDATE_RECORD,
3470 TEL_SIM_EF_USIM_MBI, p1, p2, p3, encoded_data);
3473 static TelReturn imc_sim_get_msisdn (CoreObject *co,
3474 TcoreObjectResponseCallback cb, void *cb_data)
3479 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_MSISDN, ret);
3484 static TelReturn imc_sim_get_spn (CoreObject *co,
3485 TcoreObjectResponseCallback cb, void *cb_data)
3490 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_SPN, ret);
3495 static TelReturn imc_sim_get_cphs_netname (CoreObject *co,
3496 TcoreObjectResponseCallback cb, void *cb_data)
3501 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_CPHS_OPERATOR_NAME_STRING, ret);
3506 static TelReturn imc_sim_get_sp_display_info (CoreObject *co,
3507 TcoreObjectResponseCallback cb, void *cb_data)
3512 IMC_SIM_READ_FILE(co, cb, cb_data, TEL_SIM_EF_SPDI, ret);
3517 static TelReturn imc_sim_req_authentication (CoreObject *co,
3518 const TelSimAuthenticationData *request,
3519 TcoreObjectResponseCallback cb, void *cb_data)
3521 gchar *cmd_str = NULL;
3522 ImcRespCbData *resp_cb_data = NULL;
3523 TelReturn ret = TEL_RETURN_FAILURE;
3524 TelSimCardType card_type = TEL_SIM_CARD_TYPE_UNKNOWN;
3525 char *convert_rand = NULL;
3526 char *convert_autn = NULL;
3532 tcore_sim_get_type(co, &card_type);
3533 if (TEL_SIM_CARD_TYPE_GSM == card_type || TEL_SIM_CARD_TYPE_USIM == card_type) {
3536 err("Not Supported SIM type:[%d]", card_type);
3537 return TEL_SIM_RESULT_OPERATION_NOT_SUPPORTED;
3540 if (request->rand_data != NULL) {
3541 convert_rand = tcore_malloc0(request->rand_length*2 + 1);
3542 tcore_util_byte_to_hex(request->rand_data, convert_rand, request->rand_length);
3543 dbg("Convert RAND hex to string: [%s]", convert_rand);
3545 err("rand_data is NULL");
3549 switch (request->auth_type) {
3550 case TEL_SIM_AUTH_GSM:
3552 cmd_str = g_strdup_printf("AT+XAUTH=%d,%d,\"%s\"",
3553 session_id, context_type, convert_rand);
3555 case TEL_SIM_AUTH_3G_CTX:
3557 if (request->autn_data != NULL) {
3558 convert_autn = tcore_malloc0(request->autn_length*2 + 1);
3559 tcore_util_byte_to_hex(request->autn_data, convert_autn, request->autn_length);
3560 dbg("Convert AUTN hex to string: [%s]", convert_autn);
3562 err("autn_data is NULL");
3565 cmd_str = g_strdup_printf("AT+XAUTH=%d,%d,\"%s\",\"%s\"",
3566 session_id, context_type, convert_rand, convert_autn);
3569 err("Not supported Authentication type:[%d]", request->auth_type);
3570 ret = TEL_SIM_RESULT_OPERATION_NOT_SUPPORTED;
3574 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, (void *)&request->auth_type, sizeof(TelSimAuthenticationType));
3576 ret = tcore_at_prepare_and_send_request(co,
3578 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3580 on_response_imc_sim_req_authentication, resp_cb_data,
3581 on_send_imc_request, NULL);
3582 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim request authentication");
3586 tcore_free(convert_rand);
3587 tcore_free(convert_autn);
3593 * Operation - verify_pins/verify_puks
3597 * AT-Command: AT+CPIN= <pin> [, <newpin>]
3600 * String type values
3603 * AT-Command: AT+CPIN2= <puk2/oldpin2> [, <newpin2>]andAT+CPIN2=<oldpin2>
3605 * <puk2/pin2>, <newpin2>
3606 * String type values
3612 * +CME ERROR: <error>
3614 static TelReturn imc_sim_verify_pins(CoreObject *co, const TelSimSecPinPw *request,
3615 TcoreObjectResponseCallback cb, void *cb_data)
3617 TelReturn ret = TEL_RETURN_FAILURE;
3618 ImcRespCbData *resp_cb_data = NULL;
3619 ImcSimCurrSecOp sec_op;
3620 gchar *cmd_str = NULL;
3624 if (request->pin_type == TEL_SIM_PIN_TYPE_PIN1) {
3625 sec_op = IMC_SIM_CURR_SEC_OP_PIN1_VERIFY;
3626 cmd_str = g_strdup_printf("AT+CPIN=\"%s\"", request->pw);
3627 } else if (request->pin_type == TEL_SIM_PIN_TYPE_PIN2) {
3628 sec_op = IMC_SIM_CURR_SEC_OP_PIN2_VERIFY;
3629 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\"", request->pw);
3631 err("Invalid pin type [%d]", request->pin_type);
3632 return TEL_RETURN_INVALID_PARAMETER;
3635 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3636 &sec_op, sizeof(sec_op));
3638 ret = tcore_at_prepare_and_send_request(co,
3640 TCORE_AT_COMMAND_TYPE_NO_RESULT,
3642 on_response_imc_sim_verify_pins, resp_cb_data,
3643 on_send_imc_request, NULL);
3644 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Verify Pins");
3650 static TelReturn imc_sim_verify_puks(CoreObject *co, const TelSimSecPukPw *request,
3651 TcoreObjectResponseCallback cb, void *cb_data)
3653 TelReturn ret = TEL_RETURN_FAILURE;
3654 ImcRespCbData *resp_cb_data = NULL;
3655 ImcSimCurrSecOp sec_op;
3656 gchar *cmd_str = NULL;
3660 if (request->puk_type == TEL_SIM_PUK_TYPE_PUK1) {
3661 sec_op = IMC_SIM_CURR_SEC_OP_PUK1_VERIFY;
3662 cmd_str = g_strdup_printf("AT+CPIN=\"%s\", \"%s\"",
3663 request->puk_pw, request->new_pin_pw);
3664 } else if (request->puk_type == TEL_SIM_PUK_TYPE_PUK2) {
3665 sec_op = IMC_SIM_CURR_SEC_OP_PUK2_VERIFY;
3666 cmd_str = g_strdup_printf("AT+CPIN2=\"%s\", \"%s\"",
3667 request->puk_pw, request->new_pin_pw);
3669 err("Invalid puk type [%d]", request->puk_type);
3670 return TEL_RETURN_INVALID_PARAMETER;
3673 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3674 &sec_op, sizeof(sec_op));
3676 ret = tcore_at_prepare_and_send_request(co,
3678 TCORE_AT_COMMAND_TYPE_NO_RESULT,
3680 on_response_imc_sim_verify_puks, resp_cb_data,
3681 on_send_imc_request, NULL);
3682 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Verify Puks");
3689 * Operation - change_pins
3692 * AT-Command: AT+CPWD= <fac>,<oldpwd>,<newpwd>
3707 * +CME ERROR: <error>
3709 static TelReturn imc_sim_change_pins(CoreObject *co, const TelSimSecChangePinPw *request,
3710 TcoreObjectResponseCallback cb, void *cb_data)
3712 TelReturn ret = TEL_RETURN_FAILURE;
3713 ImcRespCbData *resp_cb_data = NULL;
3714 ImcSimCurrSecOp sec_op;
3715 gchar *cmd_str = NULL;
3716 char *pin1_fac = "SC";
3717 char *pin2_fac = "P2";
3721 if (request->pin_type == TEL_SIM_PIN_TYPE_PIN1) {
3722 sec_op = IMC_SIM_CURR_SEC_OP_PIN1_CHANGE;
3723 cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"",
3724 pin1_fac, request->old_pw, request->new_pw);
3725 } else if (request->pin_type == TEL_SIM_PIN_TYPE_PIN2) {
3726 sec_op = IMC_SIM_CURR_SEC_OP_PIN2_CHANGE;
3727 cmd_str = g_strdup_printf("AT+CPWD=\"%s\",\"%s\",\"%s\"",
3728 pin2_fac, request->old_pw, request->new_pw);
3730 err("Invalid pin type [%d]", request->pin_type);
3731 return TEL_RETURN_INVALID_PARAMETER;
3734 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3735 &sec_op, sizeof(sec_op));
3737 ret = tcore_at_prepare_and_send_request(co,
3739 TCORE_AT_COMMAND_TYPE_NO_RESULT,
3741 on_response_imc_sim_change_pins, resp_cb_data,
3742 on_send_imc_request, NULL);
3743 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Change Pins");
3750 * Operation - disable_facility/enable_facility/get_facility
3753 * AT-Command: AT+CLCK = <fac>, <mode> [, <passwd> [, <class>]]
3770 * Success: when <mode>=2:
3772 * +CLCK: <status>[,<class1> [<CR><LF>
3773 * +CLCK: <status>,<class2> [...]]
3777 static TelReturn imc_sim_disable_facility(CoreObject *co, const TelSimFacilityPw *request,
3778 TcoreObjectResponseCallback cb, void *cb_data)
3780 TelReturn ret = TEL_RETURN_FAILURE;
3781 ImcRespCbData *resp_cb_data = NULL;
3782 ImcSimCurrSecOp sec_op;
3783 gchar *cmd_str = NULL;
3785 int mode = 0; /*mode = 0 for disable lock*/
3789 fac = __imc_sim_get_fac_from_lock_type(request->lock_type,
3790 &sec_op, DISABLE_FLAG);
3792 return TEL_RETURN_INVALID_PARAMETER;
3794 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"",
3795 fac, mode, request->pw);
3797 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3798 &sec_op, sizeof(sec_op));
3800 ret = tcore_at_prepare_and_send_request(co,
3802 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3804 on_response_imc_sim_disable_facility, resp_cb_data,
3805 on_send_imc_request, NULL);
3806 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Disable Facility");
3812 static TelReturn imc_sim_enable_facility(CoreObject *co, const TelSimFacilityPw *request,
3813 TcoreObjectResponseCallback cb, void *cb_data)
3815 TelReturn ret = TEL_RETURN_FAILURE;
3816 ImcRespCbData *resp_cb_data = NULL;
3817 ImcSimCurrSecOp sec_op;
3818 gchar *cmd_str = NULL;
3820 int mode = 1; /*mode = 1 for enable lock*/
3824 fac = __imc_sim_get_fac_from_lock_type(request->lock_type,
3825 &sec_op, ENABLE_FLAG);
3827 return TEL_RETURN_INVALID_PARAMETER;
3829 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d, \"%s\"",
3830 fac, mode, request->pw);
3832 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3833 &sec_op, sizeof(sec_op));
3835 ret = tcore_at_prepare_and_send_request(co,
3837 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3839 on_response_imc_sim_enable_facility, resp_cb_data,
3840 on_send_imc_request, NULL);
3841 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Disable Facility");
3847 static TelReturn imc_sim_get_facility(CoreObject *co, TelSimLockType lock_type,
3848 TcoreObjectResponseCallback cb, void *cb_data)
3850 TelReturn ret = TEL_RETURN_FAILURE;
3851 ImcRespCbData *resp_cb_data = NULL;
3852 ImcSimCurrSecOp sec_op;
3853 gchar *cmd_str = NULL;
3855 int mode = 2; /*mode = 2 for Get Facility*/
3859 fac = __imc_sim_get_fac_from_lock_type(lock_type,
3862 return TEL_RETURN_INVALID_PARAMETER;
3864 cmd_str = g_strdup_printf("AT+CLCK=\"%s\", %d", fac, mode);
3866 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
3867 &sec_op, sizeof(sec_op));
3869 ret = tcore_at_prepare_and_send_request(co,
3871 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3873 on_response_imc_sim_get_facility, resp_cb_data,
3874 on_send_imc_request, NULL);
3875 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Get Facility");
3881 static TelReturn imc_sim_get_lock_info(CoreObject *co, TelSimLockType lock_type,
3882 TcoreObjectResponseCallback cb, void *cb_data)
3884 TelReturn ret = TEL_RETURN_FAILURE;
3885 ImcRespCbData *resp_cb_data = NULL;
3886 gchar *cmd_str = NULL;
3891 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
3893 switch (lock_type) {
3894 case TEL_SIM_LOCK_PS:
3898 case TEL_SIM_LOCK_SC:
3902 case TEL_SIM_LOCK_FD:
3906 case TEL_SIM_LOCK_PN:
3910 case TEL_SIM_LOCK_PU:
3914 case TEL_SIM_LOCK_PP:
3918 case TEL_SIM_LOCK_PC:
3926 cmd_str = g_strdup_printf("AT+XPINCNT=%d", lockType);
3928 ret = tcore_at_prepare_and_send_request(co,
3929 cmd_str, "+XPINCNT:",
3930 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3932 on_response_imc_sim_get_lock_info, resp_cb_data,
3933 on_send_imc_request, NULL);
3934 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Get Lock Info");
3940 static TelReturn imc_sim_req_apdu (CoreObject *co, const TelSimApdu *request, TcoreObjectResponseCallback cb, void *cb_data)
3942 gchar *cmd_str = NULL;
3944 ImcRespCbData *resp_cb_data = NULL;
3945 TelReturn ret = TEL_RETURN_FAILURE;
3949 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
3951 apdu = (char *)tcore_malloc0((2 * request->apdu_len) + 1);
3952 tcore_util_byte_to_hex((char *)request->apdu, apdu, request->apdu_len);
3954 cmd_str = g_strdup_printf("AT+CSIM=%d,\"%s\"", strlen((const char *)apdu), apdu);
3956 ret = tcore_at_prepare_and_send_request(co,
3958 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3960 on_response_imc_sim_req_apdu, resp_cb_data,
3961 on_send_imc_request, NULL);
3962 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Request APDU");
3971 static TelReturn imc_sim_req_atr (CoreObject *co, TcoreObjectResponseCallback cb, void *cb_data)
3973 gchar *cmd_str = NULL;
3974 ImcRespCbData *resp_cb_data = NULL;
3975 TelReturn ret = TEL_RETURN_FAILURE;
3979 resp_cb_data = imc_create_resp_cb_data(cb, cb_data, NULL, 0);
3981 cmd_str = g_strdup_printf("AT+XGATR");
3983 ret = tcore_at_prepare_and_send_request(co,
3985 TCORE_AT_COMMAND_TYPE_SINGLELINE,
3987 on_response_imc_sim_req_atr, resp_cb_data,
3988 on_send_imc_request, NULL);
3989 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Sim Request ATR");
3997 /* SIM Operations */
3998 static TcoreSimOps imc_sim_ops = {
3999 .get_imsi = imc_sim_get_imsi,
4000 .get_ecc = imc_sim_get_ecc,
4001 .get_iccid = imc_sim_get_iccid,
4002 .get_language = imc_sim_get_language,
4003 .set_language = imc_sim_set_language,
4004 .get_callforwarding_info = imc_sim_get_callforwarding_info,
4005 .get_messagewaiting_info = imc_sim_get_messagewaiting_info,
4006 .set_messagewaiting_info = imc_sim_set_messagewaiting_info,
4007 .get_mailbox_info = imc_sim_get_mailbox_info,
4008 .set_mailbox_info = imc_sim_set_mailbox_info,
4009 .get_msisdn = imc_sim_get_msisdn,
4010 .get_spn = imc_sim_get_spn,
4011 .get_cphs_netname = imc_sim_get_cphs_netname,
4012 .get_sp_display_info = imc_sim_get_sp_display_info,
4013 .req_authentication = imc_sim_req_authentication,
4014 .verify_pins = imc_sim_verify_pins,
4015 .verify_puks = imc_sim_verify_puks,
4016 .change_pins = imc_sim_change_pins,
4017 .disable_facility = imc_sim_disable_facility,
4018 .enable_facility = imc_sim_enable_facility,
4019 .get_facility = imc_sim_get_facility,
4020 .get_lock_info = imc_sim_get_lock_info,
4021 .req_apdu = imc_sim_req_apdu,
4022 .req_atr = imc_sim_req_atr
4025 gboolean imc_sim_init(TcorePlugin *p, CoreObject *co)
4027 ImcSimPrivateInfo *priv_info = NULL;
4031 priv_info = g_try_new0(ImcSimPrivateInfo, 1);
4032 if (priv_info == NULL)
4035 tcore_sim_link_userdata(co, priv_info);
4037 /* Set operations */
4038 tcore_sim_set_ops(co, &imc_sim_ops);
4041 tcore_object_add_callback(co, "+XSIM:",
4042 on_notification_imc_sim_status, NULL);
4045 tcore_plugin_add_notification_hook(p,
4046 TCORE_NOTIFICATION_MODEM_POWER,
4047 on_hook_imc_modem_power, co);
4053 void imc_sim_exit(TcorePlugin *plugin, CoreObject *co)
4055 ImcSimPrivateInfo *priv_info = NULL;
4059 priv_info = tcore_sim_ref_userdata(co);