tizen 2.3.1 release
[framework/api/telephony.git] / src / telephony_sim.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include <string.h>
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <glib.h>
21 #include <gio/gio.h>
22 #include <dlog.h>
23
24 #include <tapi_common.h>
25 #include <TapiUtility.h>
26 #include <ITapiSim.h>
27 #include "telephony_sim.h"
28 #include "telephony_private.h"
29
30 #ifdef LOG_TAG
31 #undef LOG_TAG
32 #endif
33 #define LOG_TAG "CAPI_TELEPHONY"
34
35 #define DBUS_SIM_STATUS_ERROR "SIM STATUS ERROR"
36 #define DBUS_SIM_NOT_FOUND "SIM NOT FOUND"
37 #define DBUS_SIM_PERM_BLOCKED "SIM PERM BLOCKED"
38 #define DBUS_SIM_CARD_ERROR "SIM CARD ERROR"
39 #define DBUS_SIM_NOT_INITIALIZED "SIM NOT INITIALIZED"
40 #define DBUS_SIM_INIT_COMPLETED "SIM INIT COMPLETED"
41 #define DBUS_SIM_LOCKED "SIM LOCKED"
42 #define DBUS_SIM_NOT_READY "SIM NOT READY"
43 #define DBUS_SIM_RESPONSE_DATA_ERROR "SIM RESPONSE DATA ERROR"
44 #define DBUS_SIM_ACCESS_DENIED "No access rights"
45
46 #define CHECK_INPUT_PARAMETER(arg) \
47         if (arg == NULL) { \
48                 LOGE("INVALID_PARAMETER"); \
49                 return TELEPHONY_ERROR_INVALID_PARAMETER; \
50         }
51
52 #define GET_SIM_STATUS(tapi_h, sim_card_state) { \
53         int card_changed = 0; \
54         int ret = tel_get_sim_init_info(tapi_h, &sim_card_state, &card_changed); \
55         if (ret == TAPI_API_ACCESS_DENIED) { \
56                 LOGE("PERMISSION_DENIED"); \
57                 return TELEPHONY_ERROR_PERMISSION_DENIED; \
58         } else if (ret != TAPI_API_SUCCESS) { \
59                 LOGE("OPERATION_FAILED"); \
60                 return TELEPHONY_ERROR_OPERATION_FAILED; \
61         } \
62 }
63
64 static telephony_error_e _convert_dbus_errmsg_to_sim_error(gchar *err_msg)
65 {
66         telephony_error_e ret = TELEPHONY_ERROR_OPERATION_FAILED;
67         if (err_msg == NULL)
68                 return ret;
69
70         if (strstr(err_msg, DBUS_SIM_NOT_FOUND)) {
71                 ret = TELEPHONY_ERROR_SIM_NOT_AVAILABLE;
72         } else if (strstr(err_msg, DBUS_SIM_PERM_BLOCKED)) {
73                 ret = TELEPHONY_ERROR_SIM_NOT_AVAILABLE;
74         } else if (strstr(err_msg, DBUS_SIM_CARD_ERROR)) {
75                 ret = TELEPHONY_ERROR_OPERATION_FAILED;
76         } else if (strstr(err_msg, DBUS_SIM_NOT_INITIALIZED)) {
77                 ret = TELEPHONY_ERROR_SIM_NOT_AVAILABLE;
78         } else if (strstr(err_msg, DBUS_SIM_INIT_COMPLETED)) {
79                 ret = TELEPHONY_ERROR_NONE;
80         } else if (strstr(err_msg, DBUS_SIM_LOCKED)) {
81                 ret = TELEPHONY_ERROR_SIM_NOT_AVAILABLE;
82         } else if (strstr(err_msg, DBUS_SIM_NOT_READY)) {
83                 ret = TELEPHONY_ERROR_SIM_NOT_AVAILABLE;
84         } else if (strstr(err_msg, DBUS_SIM_RESPONSE_DATA_ERROR)) {
85                 ret = TELEPHONY_ERROR_OPERATION_FAILED;
86         } else if (strstr(err_msg, DBUS_SIM_ACCESS_DENIED)) {
87                 LOGE("PERMISSION_DENIED");
88                 ret = TELEPHONY_ERROR_PERMISSION_DENIED;
89         } else {
90                 ret = TELEPHONY_ERROR_OPERATION_FAILED;
91         }
92
93         return ret;
94 }
95
96 int telephony_sim_get_icc_id(telephony_h handle, char **icc_id)
97 {
98         int error_code = TELEPHONY_ERROR_NONE;
99         TelSimCardStatus_t sim_card_state = TAPI_SIM_STATUS_UNKNOWN;
100         TapiHandle *tapi_h;
101
102         CHECK_TELEPHONY_SUPPORTED(TELEPHONY_FEATURE);
103         CHECK_INPUT_PARAMETER(handle);
104         tapi_h = ((telephony_data *)handle)->tapi_h;
105         CHECK_INPUT_PARAMETER(tapi_h);
106         CHECK_INPUT_PARAMETER(icc_id);
107         GET_SIM_STATUS(tapi_h, sim_card_state);
108
109         *icc_id = NULL;
110         if (sim_card_state == TAPI_SIM_STATUS_CARD_ERROR
111                         || sim_card_state == TAPI_SIM_STATUS_CARD_BLOCKED
112                         || sim_card_state == TAPI_SIM_STATUS_CARD_NOT_PRESENT
113                         || sim_card_state == TAPI_SIM_STATUS_CARD_REMOVED
114                         || sim_card_state == TAPI_SIM_STATUS_UNKNOWN) {
115                 error_code = TELEPHONY_ERROR_SIM_NOT_AVAILABLE;
116         } else {
117                 GError *gerr = NULL;
118                 GVariant *sync_gv = NULL;
119                 gchar *iccid = NULL;
120                 TelSimAccessResult_t result = TAPI_SIM_ACCESS_SUCCESS;
121
122                 sync_gv = g_dbus_connection_call_sync(tapi_h->dbus_connection,
123                         DBUS_TELEPHONY_SERVICE, tapi_h->path, DBUS_TELEPHONY_SIM_INTERFACE,
124                         "GetICCID", NULL, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &gerr);
125
126                 if (sync_gv) {
127                         g_variant_get(sync_gv, "(is)", &result, &iccid);
128                         if (result == TAPI_SIM_ACCESS_SUCCESS) {
129                                 if (iccid != NULL && strlen(iccid) != 0) {
130                                         *icc_id = g_strdup_printf("%s", iccid);
131                                 } else {
132                                         *icc_id = g_strdup_printf("%s", "");
133                                 }
134                         } else {
135                                 error_code = TELEPHONY_ERROR_OPERATION_FAILED;
136                         }
137                         g_free(iccid);
138                 } else {
139                         LOGE("g_dbus_conn failed. error (%s)", gerr->message);
140                         error_code = _convert_dbus_errmsg_to_sim_error(gerr->message);
141                         g_error_free(gerr);
142                 }
143         }
144
145         return error_code;
146 }
147
148 int telephony_sim_get_operator(telephony_h handle, char **sim_operator)
149 {
150         int error_code = TELEPHONY_ERROR_NONE;
151         TelSimCardStatus_t sim_card_state = TAPI_SIM_STATUS_UNKNOWN;
152         TapiHandle *tapi_h;
153
154         CHECK_TELEPHONY_SUPPORTED(TELEPHONY_FEATURE);
155         CHECK_INPUT_PARAMETER(handle);
156         tapi_h = ((telephony_data *)handle)->tapi_h;
157         CHECK_INPUT_PARAMETER(tapi_h);
158         CHECK_INPUT_PARAMETER(sim_operator);
159         GET_SIM_STATUS(tapi_h, sim_card_state);
160
161         *sim_operator = NULL;
162         if (sim_card_state != TAPI_SIM_STATUS_SIM_INIT_COMPLETED) {
163                 error_code = TELEPHONY_ERROR_SIM_NOT_AVAILABLE;
164         } else {
165                 TelSimImsiInfo_t sim_imsi_info;
166                 int ret = tel_get_sim_imsi(tapi_h, &sim_imsi_info);
167                 if (ret == TAPI_API_SUCCESS) {
168                         *sim_operator = g_strdup_printf("%s%s", sim_imsi_info.szMcc, sim_imsi_info.szMnc);
169                         LOGI("SIM operator: [%s]", *sim_operator);
170                 } else if (ret == TAPI_API_ACCESS_DENIED) {
171                         LOGE("PERMISSION_DENIED");
172                         error_code = TELEPHONY_ERROR_PERMISSION_DENIED;
173                 } else {
174                         LOGE("OPERATION_FAILED");
175                         error_code = TELEPHONY_ERROR_OPERATION_FAILED;
176                 }
177         }
178
179         return error_code;
180 }
181
182 int telephony_sim_get_msin(telephony_h handle, char **msin)
183 {
184         int error_code = TELEPHONY_ERROR_NONE;
185         TelSimCardStatus_t sim_card_state = TAPI_SIM_STATUS_UNKNOWN;
186         TapiHandle *tapi_h;
187
188         CHECK_TELEPHONY_SUPPORTED(TELEPHONY_FEATURE);
189         CHECK_INPUT_PARAMETER(handle);
190         tapi_h = ((telephony_data *)handle)->tapi_h;
191         CHECK_INPUT_PARAMETER(tapi_h);
192         CHECK_INPUT_PARAMETER(msin);
193         GET_SIM_STATUS(tapi_h, sim_card_state);
194
195         *msin = NULL;
196         if (sim_card_state != TAPI_SIM_STATUS_SIM_INIT_COMPLETED) {
197                 error_code = TELEPHONY_ERROR_SIM_NOT_AVAILABLE;
198         } else {
199                 TelSimImsiInfo_t sim_imsi_info;
200                 int ret = tel_get_sim_imsi(tapi_h, &sim_imsi_info);
201                 if (ret == TAPI_API_SUCCESS) {
202                         *msin = g_strdup_printf("%s", sim_imsi_info.szMsin);
203                 } else if (ret == TAPI_API_ACCESS_DENIED) {
204                         LOGE("PERMISSION_DENIED");
205                         error_code = TELEPHONY_ERROR_PERMISSION_DENIED;
206                 } else {
207                         LOGE("OPERATION_FAILED");
208                         error_code = TELEPHONY_ERROR_OPERATION_FAILED;
209                 }
210         }
211
212         return error_code;
213 }
214
215 int telephony_sim_get_spn(telephony_h handle, char **spn)
216 {
217         int error_code = TELEPHONY_ERROR_NONE;
218         TelSimCardStatus_t sim_card_state = TAPI_SIM_STATUS_UNKNOWN;
219         TapiHandle *tapi_h;
220
221         CHECK_TELEPHONY_SUPPORTED(TELEPHONY_FEATURE);
222         CHECK_INPUT_PARAMETER(handle);
223         tapi_h = ((telephony_data *)handle)->tapi_h;
224         CHECK_INPUT_PARAMETER(tapi_h);
225         CHECK_INPUT_PARAMETER(spn);
226         GET_SIM_STATUS(tapi_h, sim_card_state);
227
228         *spn = NULL;
229         if (sim_card_state == TAPI_SIM_STATUS_CARD_ERROR
230                         || sim_card_state == TAPI_SIM_STATUS_CARD_BLOCKED
231                         || sim_card_state == TAPI_SIM_STATUS_CARD_NOT_PRESENT
232                         || sim_card_state == TAPI_SIM_STATUS_CARD_REMOVED
233                         || sim_card_state == TAPI_SIM_STATUS_UNKNOWN) {
234                 error_code = TELEPHONY_ERROR_SIM_NOT_AVAILABLE;
235         } else {
236                 GError *gerr = NULL;
237                 GVariant *sync_gv = NULL;
238                 TelSimAccessResult_t result = TAPI_SIM_ACCESS_SUCCESS;
239                 gchar *spn_str = NULL;
240                 guchar dc = 0;
241
242                 sync_gv = g_dbus_connection_call_sync(tapi_h->dbus_connection,
243                         DBUS_TELEPHONY_SERVICE, tapi_h->path, DBUS_TELEPHONY_SIM_INTERFACE,
244                         "GetSpn", NULL, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &gerr);
245
246                 if (sync_gv) {
247                         g_variant_get(sync_gv, "(iys)", &result, &dc, &spn_str);
248                         if (result == TAPI_SIM_ACCESS_SUCCESS) {
249                                 if (spn_str != NULL && strlen(spn_str) != 0) {
250                                         *spn = g_strdup_printf("%s", spn_str);
251                                         LOGI("SPN: [%s]", *spn);
252                                 } else {
253                                         *spn = g_strdup_printf("%s", "");
254                                         LOGI("SPN: [%s]", *spn);
255                                 }
256                         } else {
257                                 error_code = TELEPHONY_ERROR_OPERATION_FAILED;
258                         }
259                         g_free(spn_str);
260                 } else {
261                         LOGE("g_dbus_conn failed. error (%s)", gerr->message);
262                         error_code = _convert_dbus_errmsg_to_sim_error(gerr->message);
263                         g_error_free(gerr);
264                 }
265         }
266
267         return error_code;
268 }
269
270 int telephony_sim_is_changed(telephony_h handle, bool *is_changed)
271 {
272         int card_changed = 0;
273         TelSimCardStatus_t sim_card_state = 0x00;
274         int error_code = TELEPHONY_ERROR_NONE;
275         int ret;
276         TapiHandle *tapi_h;
277
278         CHECK_TELEPHONY_SUPPORTED(TELEPHONY_FEATURE);
279         CHECK_INPUT_PARAMETER(handle);
280         tapi_h = ((telephony_data *)handle)->tapi_h;
281         CHECK_INPUT_PARAMETER(tapi_h);
282         CHECK_INPUT_PARAMETER(is_changed);
283
284         ret = tel_get_sim_init_info(tapi_h, &sim_card_state, &card_changed);
285         if (ret == TAPI_API_SUCCESS) {
286                 if (sim_card_state == TAPI_SIM_STATUS_SIM_INIT_COMPLETED) {
287                         *is_changed = card_changed;
288                 } else {
289                         LOGE("NOT_AVAILABLE");
290                         error_code = TELEPHONY_ERROR_SIM_NOT_AVAILABLE;
291                 }
292         } else if (ret == TAPI_API_ACCESS_DENIED) {
293                 LOGE("PERMISSION_DENIED");
294                 error_code = TELEPHONY_ERROR_PERMISSION_DENIED;
295         } else {
296                 LOGE("OPERATION_FAILED");
297                 error_code = TELEPHONY_ERROR_OPERATION_FAILED;
298         }
299
300         return error_code;
301 }
302
303 int telephony_sim_get_state(telephony_h handle, telephony_sim_state_e *sim_state)
304 {
305         TelSimCardStatus_t sim_card_state = TAPI_SIM_STATUS_UNKNOWN;
306         int error_code = TELEPHONY_ERROR_NONE;
307         TapiHandle *tapi_h;
308
309         CHECK_TELEPHONY_SUPPORTED(TELEPHONY_FEATURE);
310         CHECK_INPUT_PARAMETER(handle);
311         tapi_h = ((telephony_data *)handle)->tapi_h;
312         CHECK_INPUT_PARAMETER(tapi_h);
313         CHECK_INPUT_PARAMETER(sim_state);
314         GET_SIM_STATUS(tapi_h, sim_card_state);
315
316         switch (sim_card_state) {
317         case TAPI_SIM_STATUS_CARD_ERROR:
318         case TAPI_SIM_STATUS_CARD_NOT_PRESENT:
319         case TAPI_SIM_STATUS_CARD_BLOCKED:
320         case TAPI_SIM_STATUS_CARD_REMOVED:
321         case TAPI_SIM_STATUS_CARD_CRASHED:
322                 *sim_state = TELEPHONY_SIM_STATE_UNAVAILABLE;
323                 break;
324         case TAPI_SIM_STATUS_SIM_PIN_REQUIRED:
325         case TAPI_SIM_STATUS_SIM_PUK_REQUIRED:
326         case TAPI_SIM_STATUS_SIM_NCK_REQUIRED:
327         case TAPI_SIM_STATUS_SIM_NSCK_REQUIRED:
328         case TAPI_SIM_STATUS_SIM_SPCK_REQUIRED:
329         case TAPI_SIM_STATUS_SIM_CCK_REQUIRED:
330         case TAPI_SIM_STATUS_SIM_LOCK_REQUIRED:
331                 *sim_state = TELEPHONY_SIM_STATE_LOCKED;
332                 break;
333         case TAPI_SIM_STATUS_SIM_INIT_COMPLETED:
334                 *sim_state = TELEPHONY_SIM_STATE_AVAILABLE;
335                 break;
336         case TAPI_SIM_STATUS_UNKNOWN:
337         case TAPI_SIM_STATUS_SIM_INITIALIZING:
338         default:
339                 *sim_state = TELEPHONY_SIM_STATE_UNKNOWN;
340                 break;
341         }
342
343         return error_code;
344 }
345
346 int telephony_sim_get_subscriber_number(telephony_h handle, char **subscriber_number)
347 {
348         int error_code = TELEPHONY_ERROR_NONE;
349         GError *gerr = NULL;
350         GVariant *sync_gv = NULL;
351         TelSimAccessResult_t result = TAPI_SIM_ACCESS_SUCCESS;
352         TapiHandle *tapi_h;
353
354         CHECK_TELEPHONY_SUPPORTED(TELEPHONY_FEATURE);
355         CHECK_INPUT_PARAMETER(handle);
356         tapi_h = ((telephony_data *)handle)->tapi_h;
357         CHECK_INPUT_PARAMETER(tapi_h);
358         CHECK_INPUT_PARAMETER(subscriber_number);
359
360         *subscriber_number = NULL;
361         sync_gv = g_dbus_connection_call_sync(tapi_h->dbus_connection,
362                 DBUS_TELEPHONY_SERVICE, tapi_h->path, DBUS_TELEPHONY_SIM_INTERFACE,
363                 "GetMSISDN", NULL, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &gerr);
364         if (sync_gv) {
365                 GVariantIter *iter = NULL;
366                 g_variant_get(sync_gv, "(iaa{sv})", &result, &iter);
367                 if (result == TAPI_SIM_ACCESS_SUCCESS) {
368                         gchar *key = NULL;
369                         GVariant *value = NULL;
370                         const gchar *str_value = NULL;
371                         GVariantIter *iter_row = NULL;
372
373                         while (g_variant_iter_next(iter, "a{sv}", &iter_row)) {
374                                 while (g_variant_iter_loop(iter_row, "{sv}", &key, &value)) {
375                                         if (!g_strcmp0(key, "number")) {
376                                                 str_value = g_variant_get_string(value, NULL);
377                                                 if (str_value != NULL && strlen(str_value) != 0) {
378                                                         *subscriber_number = g_strdup_printf("%s", str_value);
379                                                 }
380                                         }
381                                 }
382                                 g_variant_iter_free(iter_row);
383                                 /* Acquire only 1 subscriber number */
384                                 break;
385                         }
386                         if (!*subscriber_number)
387                                 *subscriber_number = g_strdup_printf("%s", "");
388                         g_variant_iter_free(iter);
389                 } else {
390                         error_code = TELEPHONY_ERROR_OPERATION_FAILED;
391                 }
392         } else {
393                 LOGE("g_dbus_conn failed. error (%s)", gerr->message);
394                 error_code = _convert_dbus_errmsg_to_sim_error(gerr->message);
395                 g_error_free(gerr);
396         }
397
398         return error_code;
399 }