2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
25 #include <glib-object.h>
31 #include <tapi_events.h>
36 #define LOG_TAG "CAPI_TELEPHONY_SIM"
39 sim_state_e previous_state;
45 static TelHandle *handle = NULL;
46 static sim_cb_data *ccb = NULL;
49 #define SIM_CHECK_INPUT_PARAMETER(arg) \
51 LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, SIM_ERROR_INVALID_PARAMETER); \
52 return SIM_ERROR_INVALID_PARAMETER; \
55 #define SIM_INIT(th) \
56 th = tapi_init(NULL); \
58 LOGE("[%s] OPERATION_FAILED(0x%08x)", __FUNCTION__, SIM_ERROR_OPERATION_FAILED); \
59 return SIM_ERROR_OPERATION_FAILED; \
62 #define SIM_DEINIT(th) tapi_deinit(th)
64 static sim_error_e _convert_access_rt_to_sim_error(TelSimResult access_rt)
66 sim_error_e error = SIM_ERROR_NONE;
69 case TEL_SIM_RESULT_SUCCESS:
70 error = SIM_ERROR_NONE;
72 case TEL_SIM_RESULT_ACCESS_CONDITION_NOT_SATISFIED:
73 case TEL_SIM_RESULT_CARD_ERROR:
74 error = SIM_ERROR_NOT_AVAILABLE;
76 case TEL_SIM_RESULT_FAILURE:
78 error = SIM_ERROR_OPERATION_FAILED;
85 static int __sim_check_init_status(TelHandle *handle)
87 TelSimCardStatusInfo sim_status_info = {0,};
88 int error_code = SIM_ERROR_NONE;
90 if (tapi_sim_get_init_info(handle, &sim_status_info) != TEL_RETURN_SUCCESS
91 || sim_status_info.status != TEL_SIM_STATUS_SIM_INIT_COMPLETED) {
92 error_code = SIM_ERROR_NOT_AVAILABLE;
93 LOGE("[%s] NOT_AVAILABLE(0x%08x)", __FUNCTION__, error_code);
99 static GVariant *__sim_get_info(const char *method)
101 GVariant *sync_gv = NULL;
102 char **cp_list = NULL;
103 GDBusConnection *dbus_connection;
104 GError *error = NULL;
106 tapi_get_cp_name_list(&cp_list);
107 if (cp_list == NULL) {
108 LOGE("CP List is NULL");
112 dbus_connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
114 LOGE("Error Creating DBus Connection: [%s]", error->message);
117 sync_gv = g_dbus_connection_call_sync(dbus_connection,
118 TELEPHONY_SERVICE, cp_list[0],
119 TELEPHONY_SIM_INTERFACE, method,
120 NULL, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
123 LOGE("g_dbus_conn failed. error (%s)", error->message);
129 g_object_unref(dbus_connection);
134 int sim_get_icc_id(char **icc_id)
136 TelHandle *handle = NULL;
138 GVariant *sync_gv = NULL;
140 SIM_CHECK_INPUT_PARAMETER(icc_id);
144 error_code = __sim_check_init_status(handle);
145 if (error_code != SIM_ERROR_NONE) {
146 LOGE("[%s] SIM NOT Initialized (0x%08x)", __FUNCTION__, error_code);
150 sync_gv = __sim_get_info("GetIccid");
155 g_variant_get(sync_gv, "(is)", &result, &iccid);
156 if (result == TEL_SIM_RESULT_SUCCESS) {
158 *icc_id = g_strdup(iccid);
160 LOGI("ICCID: [%s]", *icc_id);
162 LOGE("ICCID is NULL");
165 error_code = _convert_access_rt_to_sim_error(result);
166 LOGE("[%s] Operation Failed!!! (0x%08x)", __FUNCTION__, error_code);
168 g_variant_unref(sync_gv);
170 error_code = SIM_ERROR_OPERATION_FAILED;
171 LOGE("[%s] Operation Failed!!! (0x%08x)", __FUNCTION__, error_code);
178 static int __sim_get_imsi(TelHandle *handle, TelSimImsiInfo *sim_imsi_info)
180 int error_code = SIM_ERROR_NONE;
182 error_code = __sim_check_init_status(handle);
183 if (error_code != SIM_ERROR_NONE) {
184 LOGE("[%s] SIM NOT Initialized (0x%08x)", __FUNCTION__, error_code);
188 error_code = tapi_sim_get_imsi(handle, sim_imsi_info);
192 int sim_get_mcc(char **mcc)
194 TelHandle *handle = NULL;
195 TelSimImsiInfo sim_imsi_info = {"",};
198 SIM_CHECK_INPUT_PARAMETER(mcc);
201 error_code = __sim_get_imsi(handle, &sim_imsi_info);
202 if (error_code != TEL_RETURN_SUCCESS) {
203 LOGE("[%s] OPERATION_FAILED(0x%08x)", __FUNCTION__, error_code);
206 *mcc = g_strdup(sim_imsi_info.mcc);
207 LOGI("MCC: [%s]", *mcc);
214 int sim_get_mnc(char **mnc)
216 TelHandle *handle = NULL;
217 TelSimImsiInfo sim_imsi_info = {"",};
220 SIM_CHECK_INPUT_PARAMETER(mnc);
223 error_code = __sim_get_imsi(handle, &sim_imsi_info);
224 if (error_code != TEL_RETURN_SUCCESS) {
225 LOGE("[%s] OPERATION_FAILED(0x%08x)", __FUNCTION__, error_code);
228 *mnc = g_strdup(sim_imsi_info.mnc);
229 LOGI("MNC: [%s]", *mnc);
236 int sim_get_msin(char **msin)
238 TelHandle *handle = NULL;
239 TelSimImsiInfo sim_imsi_info = {"",};
242 SIM_CHECK_INPUT_PARAMETER(msin);
245 error_code = __sim_get_imsi(handle, &sim_imsi_info);
246 if (error_code != TEL_RETURN_SUCCESS) {
247 LOGE("[%s] OPERATION_FAILED(0x%08x)", __FUNCTION__, error_code);
250 *msin = g_strdup(sim_imsi_info.msin);
251 LOGI("MSIN: [%s]", *msin);
258 int sim_get_spn(char **spn)
260 TelHandle *handle = NULL;
262 GVariant *sync_gv = NULL;
264 SIM_CHECK_INPUT_PARAMETER(spn);
268 error_code = __sim_check_init_status(handle);
269 if (error_code != SIM_ERROR_NONE) {
270 LOGE("[%s] SIM NOT initialized (0x%08x)", __FUNCTION__, error_code);
274 sync_gv = __sim_get_info("GetSpn");
277 gint display_condition;
278 gchar *spn_str = NULL;
280 g_variant_get(sync_gv, "(iis)", &result, &display_condition, &spn_str);
281 if (result == TEL_SIM_RESULT_SUCCESS) {
282 if (spn_str != NULL) {
283 *spn = g_strdup(spn_str);
285 LOGI("SPN: [%s]", *spn);
290 error_code = _convert_access_rt_to_sim_error(result);
291 LOGE("[%s] Operation Failed!!! (0x%08x)", __FUNCTION__, error_code);
293 g_variant_unref(sync_gv);
295 error_code = SIM_ERROR_OPERATION_FAILED;
296 LOGE("[%s] Operation Failed!!! (0x%08x)", __FUNCTION__, error_code);
303 int sim_get_cphs_operator_name(char **full_name, char **short_name)
305 TelHandle *handle = NULL;
307 GVariant *sync_gv = NULL;
309 SIM_CHECK_INPUT_PARAMETER(full_name);
310 SIM_CHECK_INPUT_PARAMETER(short_name);
315 error_code = __sim_check_init_status(handle);
316 if (error_code != SIM_ERROR_NONE) {
317 LOGE("[%s] SIM NOT initialized (0x%08x)", __FUNCTION__, error_code);
321 sync_gv = __sim_get_info("GetCphsNetName");
324 gchar *full_str = NULL;
325 gchar *short_str = NULL;
327 g_variant_get(sync_gv, "(iss)", &result, &full_str, &short_str);
328 if (result == TEL_SIM_RESULT_SUCCESS) {
329 if (full_str != NULL) {
330 *full_name = g_strdup(full_str);
332 LOGI("Full name: [%s]", *full_name);
334 LOGE("full_name is NULL");
337 if (short_str != NULL) {
338 *short_name = g_strdup(short_str);
340 LOGI("Short name: [%s]", *short_name);
342 LOGE("short_name is NULL");
345 error_code = _convert_access_rt_to_sim_error(result);
346 LOGE("[%s] Operation Failed!!! (0x%08x)", __FUNCTION__, error_code);
348 g_variant_unref(sync_gv);
350 error_code = SIM_ERROR_OPERATION_FAILED;
351 LOGE("[%s] Operation Failed!!! (0x%08x)", __FUNCTION__, error_code);
358 int sim_get_state(sim_state_e *sim_state)
360 TelSimCardStatusInfo sim_status_info = {0,};
361 int error_code = SIM_ERROR_NONE;
362 TelHandle *handle = NULL;
364 SIM_CHECK_INPUT_PARAMETER(sim_state);
367 if (tapi_sim_get_init_info(handle, &sim_status_info) != TEL_RETURN_SUCCESS) {
368 LOGE("[%s] OPERATION_FAILED(0x%08x)", __FUNCTION__, SIM_ERROR_OPERATION_FAILED);
369 *sim_state = SIM_STATE_UNKNOWN;
371 return SIM_ERROR_OPERATION_FAILED;
374 switch (sim_status_info.status) {
375 case TEL_SIM_STATUS_CARD_ERROR:
376 case TEL_SIM_STATUS_SIM_CARD_POWEROFF:
377 case TEL_SIM_STATUS_CARD_NOT_PRESENT:
378 case TEL_SIM_STATUS_CARD_BLOCKED:
379 case TEL_SIM_STATUS_CARD_REMOVED:
380 *sim_state = SIM_STATE_UNAVAILABLE;
382 case TEL_SIM_STATUS_UNKNOWN:
383 case TEL_SIM_STATUS_SIM_INITIALIZING:
384 *sim_state = SIM_STATE_UNKNOWN;
386 case TEL_SIM_STATUS_SIM_INIT_COMPLETED:
387 *sim_state = SIM_STATE_AVAILABLE;
389 case TEL_SIM_STATUS_SIM_PIN_REQUIRED:
390 case TEL_SIM_STATUS_SIM_PUK_REQUIRED:
391 case TEL_SIM_STATUS_SIM_NCK_REQUIRED:
392 case TEL_SIM_STATUS_SIM_NSCK_REQUIRED:
393 case TEL_SIM_STATUS_SIM_SPCK_REQUIRED:
394 case TEL_SIM_STATUS_SIM_CCK_REQUIRED:
395 case TEL_SIM_STATUS_SIM_LOCK_REQUIRED:
396 *sim_state = SIM_STATE_LOCKED;
400 LOGI("SIM state: [%d]", *sim_state);
406 int sim_get_subscriber_number(char **subscriber_number)
408 TelHandle *handle = NULL;
410 GVariant *sync_gv = NULL;
412 SIM_CHECK_INPUT_PARAMETER(subscriber_number);
413 *subscriber_number = NULL;
416 error_code = __sim_check_init_status(handle);
417 if (error_code != SIM_ERROR_NONE) {
418 LOGE("[%s] SIM NOT initialized (0x%08x)", __FUNCTION__, error_code);
422 sync_gv = __sim_get_info("GetMsisdn");
425 GVariant *var = NULL;
426 TelSimMsisdnList msisdn_list = {0,};
428 g_variant_get(sync_gv, "(iu@aa{sv})", &result, &msisdn_list.count, &var);
429 if (result == TEL_SIM_RESULT_SUCCESS && msisdn_list.count) {
431 GVariantIter *iter = NULL;
432 GVariantIter *iter_row = NULL;
434 LOGI("MSISDN list count: [%d]", msisdn_list.count);
435 msisdn_list.list = g_malloc0(msisdn_list.count * sizeof(TelSimMsisdnList));
436 g_variant_get(var, "aa{sv}", &iter);
437 while (g_variant_iter_next(iter, "a{sv}", &iter_row)) {
440 while (g_variant_iter_loop(iter_row, "{sv}", &key, &key_value)) {
441 if (g_strcmp0(key, "alpha_id") == 0) {
442 msisdn_list.list[i].alpha_id =
443 g_strdup(g_variant_get_string(key_value, NULL));
446 if (g_strcmp0(key, "num") == 0) {
447 msisdn_list.list[i].num =
448 g_strdup(g_variant_get_string(key_value, NULL));
452 g_variant_iter_free(iter_row);
454 g_variant_iter_free(iter);
456 /* Only set first number */
457 if (msisdn_list.count) {
458 *subscriber_number = g_strdup(msisdn_list.list[0].num);
459 LOGI("Subscribe Number: [%s]", *subscriber_number);
463 for (i = 0; i < msisdn_list.count; i++) {
464 g_free(msisdn_list.list[i].alpha_id);
465 g_free(msisdn_list.list[i].num);
467 g_free(msisdn_list.list);
469 error_code = _convert_access_rt_to_sim_error(result);
470 LOGE("[%s] Operation Failed!!! (0x%08x)", __FUNCTION__, error_code);
472 g_variant_unref(sync_gv);
474 error_code = SIM_ERROR_OPERATION_FAILED;
475 LOGE("[%s] Operation Failed!!! (0x%08x)", __FUNCTION__, error_code);
482 static void on_noti_sim_status(TelHandle *handle, const char *noti_id,
483 void *data, void *user_data)
485 TelSimCardStatus *status = data;
486 sim_state_e state = SIM_STATE_UNKNOWN;
487 sim_state_changed_cb cb;
489 LOGE("event(%s) receive with status[%d]", TEL_NOTI_SIM_STATUS, *status);
492 case TEL_SIM_STATUS_CARD_ERROR:
493 case TEL_SIM_STATUS_SIM_CARD_POWEROFF:
494 case TEL_SIM_STATUS_CARD_NOT_PRESENT:
495 case TEL_SIM_STATUS_CARD_BLOCKED:
496 case TEL_SIM_STATUS_CARD_REMOVED:
497 state = SIM_STATE_UNAVAILABLE;
499 case TEL_SIM_STATUS_UNKNOWN:
500 case TEL_SIM_STATUS_SIM_INITIALIZING:
501 state = SIM_STATE_UNKNOWN;
503 case TEL_SIM_STATUS_SIM_INIT_COMPLETED:
504 state = SIM_STATE_AVAILABLE;
506 case TEL_SIM_STATUS_SIM_PIN_REQUIRED:
507 case TEL_SIM_STATUS_SIM_PUK_REQUIRED:
508 case TEL_SIM_STATUS_SIM_NCK_REQUIRED:
509 case TEL_SIM_STATUS_SIM_NSCK_REQUIRED:
510 case TEL_SIM_STATUS_SIM_SPCK_REQUIRED:
511 case TEL_SIM_STATUS_SIM_CCK_REQUIRED:
512 case TEL_SIM_STATUS_SIM_LOCK_REQUIRED:
513 state = SIM_STATE_LOCKED;
518 LOGE("[%s] callback is null", __FUNCTION__);
523 cb(state, ccb->user_data);
526 int sim_set_state_changed_cb(sim_state_changed_cb sim_cb, void *user_data)
528 int error_code = SIM_ERROR_NONE;
530 SIM_CHECK_INPUT_PARAMETER(sim_cb);
536 ccb = g_malloc0(sizeof(sim_cb_data));
539 ccb->cb = (void *)sim_cb;
540 ccb->user_data = user_data;
542 error_code = tapi_register_event_id(handle, TEL_NOTI_SIM_STATUS, on_noti_sim_status, NULL);
543 if (error_code != TEL_RETURN_SUCCESS) {
544 error_code = SIM_ERROR_OPERATION_FAILED;
554 int sim_unset_state_changed_cb()
556 int error_code = SIM_ERROR_NONE;
559 return SIM_ERROR_NONE;
561 error_code = tapi_deregister_event_id(handle, TEL_NOTI_SIM_STATUS);
562 if (error_code != TEL_RETURN_SUCCESS)
563 error_code = SIM_ERROR_OPERATION_FAILED;