802d4ab3f4766fc9af0bed018cfe0f0e8baa104e
[platform/core/pim/contacts-service.git] / server / ctsvc_server_sim.c
1 /*
2  * Contacts Service
3  *
4  * Copyright (c) 2010 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
5  *
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
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  *
18  */
19
20 #include <glib-object.h>
21 #include <string.h>
22 #include <tapi_common.h>
23 #include <ITapiSim.h>
24 #include <ITapiPhonebook.h>
25 #include <TapiUtility.h>
26 #include <vconf.h>
27 #include <vconf-internal-telephony-keys.h>
28
29 #include "contacts.h"
30
31 #include "ctsvc_internal.h"
32 #include "ctsvc_struct.h"
33 #include "ctsvc_db_schema.h"
34 #include "ctsvc_db_sqlite.h"
35 #include "ctsvc_server_socket.h"
36 #include "ctsvc_server_sqlite.h"
37 #include "ctsvc_server_utils.h"
38 #include "ctsvc_server_sim.h"
39 #include "ctsvc_db_utils.h"
40 #include "ctsvc_list.h"
41 #include "ctsvc_db_access_control.h"
42 #include "ctsvc_db_query.h"
43
44 /* #define CTSVC_SIM_FIELD_FULL_SUPPORT// support ANR,EMAIL2,3,NICK NAME */
45 #define DEFAULT_ADDRESS_BOOK_ID 0
46
47 #define CTSVC_TAPI_SIM_PB_MAX 0xFFFF
48
49 #define TAPI_PB_MAX_FILE_CNT TAPI_PB_3G_PBC+1
50
51 #define CTSVC_2GSIM_NAME TAPI_PB_3G_NAME
52 #define CTSVC_2GSIM_NUMBER TAPI_PB_3G_NUMBER
53
54 typedef struct {
55         bool support;
56         unsigned int index_max;
57         unsigned int text_max;
58         unsigned int used_count;
59 } sim_file_s;
60
61 typedef struct {
62         /* SIM slot number */
63         int sim_slot_no;
64
65         /*
66          * SIM info table id
67          * it is used when inserting/seaching phonelog
68          */
69         int sim_info_id;
70
71         /* SIM slot id */
72         char *cp_name;
73
74         /* Tapi handle to control each SIM slot */
75         TapiHandle *handle;
76
77         /* SIM type */
78         TelSimPbType_t sim_type;
79
80         /* Each sim file info (max index, max text length, used count) */
81         sim_file_s file_record[TAPI_PB_MAX_FILE_CNT];
82
83         /* To bulk insert SIM contact, Free after insert them */
84         GSList *import_contacts;
85
86         /*
87          * Set true after read SIM meta info
88          * in case of private : set true after reading all SIM contact and save to DB
89          */
90         bool initialized;
91
92         /*
93          * unique info of SIM : iccid
94          * It should be save to phone log table
95          * in order to find which SIM is used to the call/message log
96          */
97         char *sim_unique_id;
98
99 } ctsvc_sim_info_s;
100
101
102 static GSList *__ctsvc_sim_info = NULL;
103 static void *greturn_data = NULL;
104 static bool __ctsvc_tapi_cb = false;
105 static bool __ctsvc_sim_cb = false;
106
107 static void __ctsvc_server_sim_get_meta_info_cb(TapiHandle *handle, int result, void *data, void *user_data);
108 static int __ctsvc_server_sim_init_info(ctsvc_sim_info_s *info);
109
110 static TapiHandle* __ctsvc_server_sim_get_tapi_handle(ctsvc_sim_info_s *info)
111 {
112         if (NULL == info->handle) {
113                 int bReady = 0;
114                 vconf_get_bool(VCONFKEY_TELEPHONY_READY, &bReady);
115
116                 if (0 == bReady) {
117                         ERR("telephony is not ready ");
118                         return NULL;
119                 } else {
120                         info->handle = tel_init(info->cp_name);
121                         RETVM_IF(NULL == info->handle, NULL, "tel_init() Fail");
122                 }
123         }
124
125         return info->handle;
126 }
127
128 static inline void __ctsvc_server_sim_set_return_data(void *data)
129 {
130         greturn_data = data;
131 }
132
133 static inline void* __ctsvc_server_sim_get_return_data(void)
134 {
135         RETV_IF(NULL == greturn_data, NULL);
136
137         return greturn_data;
138 }
139
140 static void __ctsvc_server_sim_record_destroy(sim_contact_s *record)
141 {
142         RET_IF(NULL == record);
143
144         free(record->name);
145         free(record->number);
146         free(record->anr1);
147         free(record->anr2);
148         free(record->anr3);
149         free(record->email1);
150         free(record->email2);
151         free(record->email3);
152         free(record->email4);
153         free(record);
154
155         return;
156 }
157
158 static sim_contact_s * __ctsvc_server_sim_record_clone(TelSimPbRecord_t *sim_record)
159 {
160         sim_contact_s *record = calloc(1, sizeof(sim_contact_s));
161         if (NULL == record) {
162                 ERR("calloc() Fail");
163                 return NULL;
164         }
165
166         record->sim_index = sim_record->index;
167         record->name = SAFE_STRDUP((char*)sim_record->name);
168         record->nickname = SAFE_STRDUP((char*)sim_record->sne);
169         record->number = SAFE_STRDUP((char*)sim_record->number);
170         record->anr1 = SAFE_STRDUP((char*)sim_record->anr1);
171         record->anr2 = SAFE_STRDUP((char*)sim_record->anr2);
172         record->anr3 = SAFE_STRDUP((char*)sim_record->anr3);
173         record->email1 = SAFE_STRDUP((char*)sim_record->email1);
174         record->email2 = SAFE_STRDUP((char*)sim_record->email2);
175         record->email3 = SAFE_STRDUP((char*)sim_record->email3);
176         record->email4 = SAFE_STRDUP((char*)sim_record->email4);
177
178         return record;
179 }
180
181 static inline int __ctsvc_server_sim_record_add_num(contacts_record_h *record, char *number)
182 {
183         int ret;
184
185         RETVM_IF(NULL == number, CONTACTS_ERROR_INVALID_PARAMETER, "invalid number");
186
187         ret = contacts_record_create(_contacts_number._uri, record);
188         RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create() Fail(%d)", ret);
189         ret = contacts_record_set_str(*record, _contacts_number.number, number);
190         RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_set_str() Fail(%d)", ret);
191         ret = contacts_record_set_int(*record, _contacts_number.type, CONTACTS_NUMBER_TYPE_OTHER);
192         RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_set_int() Fail(%d)", ret);
193
194         return ret;
195 }
196
197 static inline int __ctsvc_server_sim_record_add_email(contacts_record_h *record, char *email)
198 {
199         int ret;
200
201         RETVM_IF(NULL == email, CONTACTS_ERROR_INVALID_PARAMETER, "invalid email");
202
203         ret = contacts_record_create(_contacts_email._uri, record);
204         RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create() Fail(%d)", ret);
205         ret = contacts_record_set_str(*record, _contacts_email.email, email);
206         RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_set_str() Fail(%d)", ret);
207         ret = contacts_record_set_int(*record, _contacts_email.type, CONTACTS_EMAIL_TYPE_OTHER);
208         RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_set_int() Fail(%d)", ret);
209
210         return ret;
211 }
212
213 static int __ctsvc_server_sim_ctsvc_record_clone(sim_contact_s *record,
214                 int addressbook_id, contacts_record_h *contact)
215 {
216         CTS_FN_CALL;
217         int ret;
218         char sim_id[20] = {0};
219         contacts_record_h name = NULL;
220         contacts_record_h number = NULL;
221         contacts_record_h email = NULL;
222
223         RETV_IF(NULL == contact, CONTACTS_ERROR_INVALID_PARAMETER);
224         *contact = NULL;
225         RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
226         RETVM_IF(record->sim_index <= 0, CONTACTS_ERROR_INVALID_PARAMETER, "The index(%d) is invalid", record->sim_index);
227
228         DBG("insert record->sim_index %d", record->sim_index);
229
230         ret = contacts_record_create(_contacts_contact._uri, contact);
231         RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "contacts_record_create Fail(%d)", ret);
232         snprintf(sim_id, sizeof(sim_id), "%d", record->sim_index);
233         contacts_record_set_str(*contact, _contacts_contact.uid, sim_id);
234
235         if (record->name) {
236                 contacts_record_create(_contacts_name._uri, &name);
237                 if (name) {
238                         contacts_record_set_str(name, _contacts_name.first, (char *)record->name);
239                         contacts_record_add_child_record(*contact, _contacts_contact.name, name);
240                 }
241         }
242
243 #ifdef CTSVC_SIM_FIELD_FULL_SUPPORT
244         contacts_record_h nick = NULL;
245         if (record->nickname) {
246                 contacts_record_create(_contacts_nickname._uri, &nick);
247                 if (nick) {
248                         contacts_record_set_str(nick, _contacts_nickname.name, (char *)record->nickname);
249                         contacts_record_add_child_record(*contact, _contacts_contact.nickname, nick);
250                 }
251         }
252 #endif /* CTSVC_SIM_FIELD_FULL_SUPPORT */
253
254         ret = __ctsvc_server_sim_record_add_num(&number, (char *)record->number);
255         if (CONTACTS_ERROR_NONE == ret)
256                 contacts_record_add_child_record(*contact, _contacts_contact.number, number);
257
258 #ifdef CTSVC_SIM_FIELD_FULL_SUPPORT
259         ret = __ctsvc_server_sim_record_add_num(&number, (char *)record->anr1);
260         if (CONTACTS_ERROR_NONE == ret)
261                 contacts_record_add_child_record(*contact, _contacts_contact.number, number);
262
263         ret = __ctsvc_server_sim_record_add_num(&number, (char *)record->anr2);
264         if (CONTACTS_ERROR_NONE == ret)
265                 contacts_record_add_child_record(*contact, _contacts_contact.number, number);
266
267         ret = __ctsvc_server_sim_record_add_num(&number, (char *)record->anr3);
268         if (CONTACTS_ERROR_NONE == ret)
269                 contacts_record_add_child_record(*contact, _contacts_contact.number, number);
270 #endif /* CTSVC_SIM_FIELD_FULL_SUPPORT */
271
272         ret = __ctsvc_server_sim_record_add_email(&email, (char *)record->email1);
273         if (CONTACTS_ERROR_NONE == ret)
274                 contacts_record_add_child_record(*contact, _contacts_contact.email, email);
275
276 #ifdef CTSVC_SIM_FIELD_FULL_SUPPORT
277         ret = __ctsvc_server_sim_record_add_email(&email, (char *)record->email2);
278         if (CONTACTS_ERROR_NONE == ret)
279                 contacts_record_add_child_record(*contact, _contacts_contact.email, email);
280
281         ret = __ctsvc_server_sim_record_add_email(&email, (char *)record->email3);
282         if (CONTACTS_ERROR_NONE == ret)
283                 contacts_record_add_child_record(*contact, _contacts_contact.email, email);
284
285         ret = __ctsvc_server_sim_record_add_email(&email, (char *)record->email4);
286         if (CONTACTS_ERROR_NONE == ret)
287                 contacts_record_add_child_record(*contact, _contacts_contact.email, email);
288 #endif /* CTSVC_SIM_FIELD_FULL_SUPPORT */
289
290         contacts_record_set_int(*contact, _contacts_contact.address_book_id, addressbook_id);
291
292         return ret;
293 }
294
295 static ctsvc_sim_info_s* __ctsvc_server_sim_get_handle_by_tapi_handle(TapiHandle *handle)
296 {
297         GSList *cursor = NULL;
298         for (cursor = __ctsvc_sim_info; cursor; cursor = cursor->next) {
299                 ctsvc_sim_info_s *info = cursor->data;
300                 if (info->handle == handle)
301                         return info;
302         }
303         return NULL;
304 }
305
306 static ctsvc_sim_info_s* __ctsvc_server_sim_get_handle_by_sim_slot_no(int slot_no)
307 {
308         GSList *cursor = NULL;
309
310         if (slot_no < 0)
311                 return NULL;
312
313         for (cursor = __ctsvc_sim_info; cursor; cursor = cursor->next) {
314                 ctsvc_sim_info_s *info = cursor->data;
315                 if (info->sim_slot_no == slot_no) {
316                         if (NULL == __ctsvc_server_sim_get_tapi_handle(info))
317                                 return NULL;
318                         return info;
319                 }
320         }
321         return NULL;
322 }
323
324 int ctsvc_server_sim_get_info_id_by_sim_slot_no(int slot_no)
325 {
326         GSList *cursor = NULL;
327
328         if (slot_no < 0)
329                 return -1;
330
331         for (cursor = __ctsvc_sim_info; cursor; cursor = cursor->next) {
332                 ctsvc_sim_info_s *info = cursor->data;
333                 if (info->sim_slot_no == slot_no) {
334                         if (NULL == __ctsvc_server_sim_get_tapi_handle(info))
335                                 return -1;
336                         return info->sim_info_id;
337                 }
338         }
339         return -1;
340 }
341
342 int ctsvc_server_sim_get_sim_slot_no_by_info_id(int sim_info_id)
343 {
344         GSList *cursor = NULL;
345         for (cursor = __ctsvc_sim_info; cursor; cursor = cursor->next) {
346                 ctsvc_sim_info_s *info = cursor->data;
347                 if (info->sim_info_id == sim_info_id) {
348                         if (NULL == __ctsvc_server_sim_get_tapi_handle(info))
349                                 return -1;
350                         return info->sim_slot_no;
351                 }
352         }
353         return -1;
354 }
355
356 static void __ctsvc_server_sim_destroy_records(gpointer data)
357 {
358         sim_contact_s *record = data;
359         __ctsvc_server_sim_record_destroy(record);
360 }
361
362 static void __ctsvc_server_sim_destroy_import_contacts(ctsvc_sim_info_s *info)
363 {
364         RET_IF(NULL == info);
365         RET_IF(NULL == info->import_contacts);
366
367         g_slist_free_full(info->import_contacts, __ctsvc_server_sim_destroy_records);
368         info->import_contacts = NULL;
369 }
370
371 static int __ctsvc_server_sim_insert_records_to_db(ctsvc_sim_info_s *info)
372 {
373         CTS_FN_CALL;
374         int i;
375         int ret = 0;
376         int count = 0;
377         sim_contact_s *record = NULL;
378         contacts_record_h contact = NULL;
379         contacts_list_h list = NULL;
380         GSList *cursor = NULL;
381
382         /* insert contacts to DB */
383         ret = contacts_list_create(&list);
384         if (CONTACTS_ERROR_NONE != ret) {
385                 ERR("contacts_list_create() Fail(%d)", ret);
386                 return CONTACTS_ERROR_INTERNAL;
387         }
388
389         for (cursor = info->import_contacts, i = 0; cursor; i++) {
390                 record = cursor->data;
391                 ret = __ctsvc_server_sim_ctsvc_record_clone(record, DEFAULT_ADDRESS_BOOK_ID, &contact);
392                 if (CONTACTS_ERROR_NONE != ret) {
393                         ERR("__ctsvc_server_sim_ctsvc_record_clone() Fail(%d)", ret);
394                         contacts_list_destroy(list, true);
395                         return CONTACTS_ERROR_INTERNAL;
396                 }
397                 ret = contacts_list_add(list, contact);
398                 if (CONTACTS_ERROR_NONE != ret) {
399                         ERR("contacts_list_add() Fail(%d)", ret);
400                         contacts_list_destroy(list, true);
401                         return CONTACTS_ERROR_INTERNAL;
402                 }
403                 cursor = cursor->next;
404         }
405
406         contacts_list_get_count(list, &count);
407         DBG("records count:%d", count);
408         if (0 < count) {
409                 ret = ctsvc_db_insert_records(list, NULL, NULL);
410                 if (CONTACTS_ERROR_NONE != ret) {
411                         ERR("ctsvc_db_insert_records() Fail(%d)", ret);
412                         contacts_list_destroy(list, true);
413                         return ret;
414                 }
415         }
416
417         contacts_list_destroy(list, true);
418         return CONTACTS_ERROR_NONE;
419 }
420
421 static void __ctsvc_server_sim_import_contact_cb(TapiHandle *handle, int result, void *data, void *user_data)
422 {
423         CTS_FN_CALL;
424         int ret = 0;
425         TelSimPbAccessResult_t access_rt = result;
426         TelSimPbRecord_t *sim_info = data;
427         sim_contact_s *record = NULL;
428         ctsvc_sim_info_s *info;
429
430         if (NULL == sim_info) {
431                 ERR("sim_info is NULL, result = %d", access_rt);
432                 ret = ctsvc_server_socket_return(__ctsvc_server_sim_get_return_data(), CONTACTS_ERROR_SYSTEM, 0, NULL);
433                 WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_server_socket_return() Fail(%d)", ret);
434                 __ctsvc_server_sim_set_return_data(NULL);
435                 return;
436         }
437
438         info = __ctsvc_server_sim_get_handle_by_tapi_handle(handle);
439         if (NULL == info) {
440                 ERR("__ctsvc_server_sim_get_handle_by_tapi_handle() Fail");
441                 ret = ctsvc_server_socket_return(__ctsvc_server_sim_get_return_data(), CONTACTS_ERROR_INTERNAL, 0, NULL);
442                 WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_server_socket_return() Fail(%d)", ret);
443                 __ctsvc_server_sim_set_return_data(NULL);
444                 return;
445         }
446
447         if (TAPI_SIM_PB_INVALID_INDEX == access_rt) {
448                 int start_index = 0;
449                 if (user_data)
450                         start_index = (int)user_data;
451                 DBG("TAPI_SIM_PB_INVALID_INDEX : start_index = %d", start_index);
452                 start_index++;
453                 if (info->file_record[TAPI_PB_3G_NAME].index_max < start_index) {
454                         ERR("start_index is invalid start_index = %d, total = %d", start_index,
455                                         info->file_record[TAPI_PB_3G_NAME].index_max);
456                         ret = ctsvc_server_socket_return(__ctsvc_server_sim_get_return_data(), CONTACTS_ERROR_INTERNAL, 0, NULL);
457                         WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_server_socket_return() Fail(%d)", ret);
458                         __ctsvc_server_sim_destroy_import_contacts(info);
459                         __ctsvc_server_sim_set_return_data(NULL);
460                         return;
461                 }
462                 ret = tel_read_sim_pb_record(handle, info->sim_type, start_index,
463                                 __ctsvc_server_sim_import_contact_cb, (void*)start_index);
464                 if (TAPI_API_SUCCESS != ret) {
465                         ERR("SIM phonebook access Fail(%d) start_indext(%d)", access_rt, start_index);
466                         ret = ctsvc_server_socket_return(__ctsvc_server_sim_get_return_data(), CONTACTS_ERROR_SYSTEM, 0, NULL);
467                         WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_server_socket_return() Fail(%d)", ret);
468                         __ctsvc_server_sim_destroy_import_contacts(info);
469                         __ctsvc_server_sim_set_return_data(NULL);
470                         return;
471                 }
472                 return;
473         }
474
475         if (TAPI_SIM_PB_SUCCESS != access_rt) {
476                 ERR("SIM phonebook access Fail(%d)", access_rt);
477                 ret = ctsvc_server_socket_return(__ctsvc_server_sim_get_return_data(), CONTACTS_ERROR_SYSTEM, 0, NULL);
478                 WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_server_socket_return() Fail(%d)", ret);
479                 __ctsvc_server_sim_destroy_import_contacts(info);
480                 __ctsvc_server_sim_set_return_data(NULL);
481                 return;
482         }
483
484         switch (sim_info->phonebook_type) {
485         case TAPI_SIM_PB_ADN:
486         case TAPI_SIM_PB_3GSIM:
487                 record = __ctsvc_server_sim_record_clone(sim_info);
488                 info->import_contacts = g_slist_append(info->import_contacts, (void*)record);
489                 break;
490         case TAPI_SIM_PB_FDN:
491         case TAPI_SIM_PB_SDN:
492         default:
493                 ERR("Unknown storage type(%d)", sim_info->phonebook_type);
494                 ret = ctsvc_server_socket_return(__ctsvc_server_sim_get_return_data(), CONTACTS_ERROR_SYSTEM, 0, NULL);
495                 WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_server_socket_return() Fail(%d)", ret);
496                 __ctsvc_server_sim_destroy_import_contacts(info);
497                 __ctsvc_server_sim_set_return_data(NULL);
498                 return;
499         }
500
501         if (sim_info->next_index && CTSVC_TAPI_SIM_PB_MAX != sim_info->next_index) {
502                 DBG("NextIndex = %d", sim_info->next_index);
503                 ret = tel_read_sim_pb_record(__ctsvc_server_sim_get_tapi_handle(info), sim_info->phonebook_type,
504                                 sim_info->next_index, __ctsvc_server_sim_import_contact_cb, NULL);
505
506                 if (TAPI_API_SUCCESS != ret) {
507                         ERR("tel_read_sim_pb_record() Fail(%d)", ret);
508                         ret = ctsvc_server_socket_return(__ctsvc_server_sim_get_return_data(), CONTACTS_ERROR_SYSTEM, 0, NULL);
509                         WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_server_socket_return() Fail(%d)", ret);
510                         __ctsvc_server_sim_destroy_import_contacts(info);
511                         __ctsvc_server_sim_set_return_data(NULL);
512                         return;
513                 }
514         } else {
515                 /* insert imported contact to DB */
516                 ret = __ctsvc_server_sim_insert_records_to_db(info);
517                 ret = ctsvc_server_socket_return(__ctsvc_server_sim_get_return_data(), ret, 0, NULL);
518                 WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_server_socket_return() Fail(%d)", ret);
519                 __ctsvc_server_sim_destroy_import_contacts(info);
520                 __ctsvc_server_sim_set_return_data(NULL);
521         }
522 }
523
524 int ctsvc_server_sim_import_contact(void *data, int sim_slot_no)
525 {
526         CTS_FN_CALL;
527         int ret;
528         ctsvc_sim_info_s *info;
529
530         info = __ctsvc_server_sim_get_handle_by_sim_slot_no(sim_slot_no);
531         RETV_IF(NULL == info, CONTACTS_ERROR_SYSTEM);
532         RETV_IF(false == info->initialized, CONTACTS_ERROR_SYSTEM);
533         RETVM_IF(__ctsvc_server_sim_get_return_data(), CONTACTS_ERROR_INTERNAL,
534                         "Server is already processing with sim");
535
536         __ctsvc_server_sim_set_return_data(data);
537
538         if (0 == info->file_record[TAPI_PB_3G_NAME].used_count) {
539                 ret = ctsvc_server_socket_return(__ctsvc_server_sim_get_return_data(), CONTACTS_ERROR_NO_DATA, 0, NULL);
540                 WARN_IF(CONTACTS_ERROR_NONE != ret, "helper_socket_return() Fail(%d)", ret);
541                 __ctsvc_server_sim_set_return_data(NULL);
542                 return ret;
543         }
544
545         ret = tel_read_sim_pb_record(__ctsvc_server_sim_get_tapi_handle(info), info->sim_type, 1,
546                         __ctsvc_server_sim_import_contact_cb, NULL);
547         if (TAPI_API_SUCCESS != ret) {
548                 ERR("tel_read_sim_pb_record = %d", ret);
549                 __ctsvc_server_sim_set_return_data(NULL);
550                 return CONTACTS_ERROR_SYSTEM;
551         }
552
553         return CONTACTS_ERROR_NONE;
554 }
555
556 int ctsvc_server_socket_get_sim_init_status(void *data, int sim_slot_no)
557 {
558         CTS_FN_CALL;
559         ctsvc_sim_info_s *info;
560
561         info = __ctsvc_server_sim_get_handle_by_sim_slot_no(sim_slot_no);
562         RETVM_IF(NULL == info, CONTACTS_ERROR_SYSTEM, "sim init is not completed");
563         return ctsvc_server_socket_return_sim_int(data, (int)(info->initialized));
564 }
565
566 static void __ctsvc_server_sim_sdn_read_cb(TapiHandle *handle, int result, void *data, void *user_data)
567 {
568         CTS_FN_CALL;
569         int ret = 0;
570         TelSimPbAccessResult_t access_rt = result;
571         TelSimPbRecord_t *sim_info = data;
572         ctsvc_sim_info_s *info = (ctsvc_sim_info_s*)user_data;
573
574         RET_IF(NULL == sim_info);
575
576         if (TAPI_SIM_PB_SUCCESS != access_rt) {
577                 if (TAPI_SIM_PB_SDN == sim_info->phonebook_type &&
578                                 TAPI_SIM_PB_INVALID_INDEX == access_rt) {
579                         DBG("Index = %d", sim_info->index);
580                         ret = tel_read_sim_pb_record(handle, sim_info->phonebook_type, sim_info->index+1,
581                                         __ctsvc_server_sim_sdn_read_cb, info);
582                         RETM_IF(TAPI_API_SUCCESS != ret,  "tel_read_sim_pb_record() Fail(%d)", ret);
583                 }
584                 ERR("SIM phonebook access Fail(%d)", access_rt);
585                 ctsvc_server_trim_memory();
586                 return;
587         }
588
589         switch (sim_info->phonebook_type) {
590         case TAPI_SIM_PB_SDN:
591                 ret = ctsvc_server_insert_sdn_contact((char *)sim_info->name, (char *)sim_info->number, info->sim_slot_no);
592                 WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_server_insert_sdn_contact() Fail(%d)", ret);
593                 break;
594         case TAPI_SIM_PB_ADN:
595         case TAPI_SIM_PB_3GSIM:
596         case TAPI_SIM_PB_FDN:
597         default:
598                 ERR("Not SDN type(%d)", sim_info->phonebook_type);
599                 ctsvc_server_trim_memory();
600                 return;
601         }
602
603         if (sim_info->next_index && CTSVC_TAPI_SIM_PB_MAX != sim_info->next_index) {
604                 DBG("NextIndex = %d", sim_info->next_index);
605                 ret = tel_read_sim_pb_record(handle, sim_info->phonebook_type, sim_info->next_index,
606                                 __ctsvc_server_sim_sdn_read_cb, info);
607                 if (TAPI_API_SUCCESS != ret) {
608                         ERR("tel_read_sim_pb_record() Fail(%d)", ret);
609                         ctsvc_server_trim_memory();
610                         return;
611                 }
612         } else {
613                 ctsvc_server_trim_memory();
614         }
615 }
616
617 static void __ctsvc_server_sim_sdn_count_cb(TapiHandle *handle, int result, void *data, void *user_data)
618 {
619         CTS_FN_CALL;
620         int ret = 0;
621         TelSimPbAccessResult_t access_rt = result;
622         TelSimPbStorageInfo_t *ps = data;
623         ctsvc_sim_info_s *info = (ctsvc_sim_info_s*)user_data;
624
625         RETM_IF(TAPI_SIM_PB_SUCCESS != access_rt, "TelSimPbAccessResult:%d", access_rt);
626         RETM_IF(NULL == ps, "ps is NULL. TelSimPbAccessResult:%d", access_rt);
627
628         if (0 < ps->UsedRecordCount) {
629                 ret = tel_read_sim_pb_record(info->handle, TAPI_SIM_PB_SDN, 1, __ctsvc_server_sim_sdn_read_cb, info);
630                 if (TAPI_API_SUCCESS != ret) {
631                         ERR("tel_read_sim_pb_record() Fail(%d)", ret);
632                         ctsvc_server_trim_memory();
633                         return;
634                 }
635         } else {
636                 ERR("ps->UsedRecordCount:0. No SDN!!!!");
637         }
638         ctsvc_server_trim_memory();
639 }
640
641 static int __ctsvc_server_sim_sdn_read(ctsvc_sim_info_s *info)
642 {
643         CTS_FN_CALL;
644         int ret;
645         int card_changed = 0;
646         TelSimCardStatus_t sim_status;
647
648         RETVM_IF(__ctsvc_server_sim_get_return_data(), CONTACTS_ERROR_INTERNAL,
649                         "Server is already processing with sim");
650
651         ret = tel_get_sim_init_info(info->handle, &sim_status, &card_changed);
652         if (TAPI_API_SUCCESS != ret) {
653                 ERR("tel_get_sim_init_info() Fail(%d)", ret);
654                 DBG("sim_status = %d, card_changed = %d", sim_status, card_changed);
655                 ctsvc_server_trim_memory();
656                 return CONTACTS_ERROR_SYSTEM;
657         }
658
659         if (TAPI_SIM_STATUS_CARD_NOT_PRESENT == sim_status ||
660                         TAPI_SIM_STATUS_CARD_REMOVED == sim_status) {
661                 ret = ctsvc_server_delete_sdn_contact(info->sim_slot_no);
662                 if (CONTACTS_ERROR_NONE != ret) {
663                         ERR("ctsvc_server_delete_sdn_contact() Fail(%d)", ret);
664                         ctsvc_server_trim_memory();
665                         return ret;
666                 }
667         } else if (TAPI_SIM_STATUS_SIM_INIT_COMPLETED == sim_status) {
668                 ret = ctsvc_server_delete_sdn_contact(info->sim_slot_no);
669                 if (CONTACTS_ERROR_NONE != ret) {
670                         ERR("ctsvc_server_delete_sdn_contact() Fail(%d)", ret);
671                         ctsvc_server_trim_memory();
672                         return ret;
673                 }
674
675                 ret = tel_get_sim_pb_count(info->handle, TAPI_SIM_PB_SDN, __ctsvc_server_sim_sdn_count_cb, info);
676                 if (TAPI_API_SUCCESS != ret) {
677                         ERR("tel_get_sim_pb_meta_info() Fail(%d)", ret);
678                         ctsvc_server_trim_memory();
679                         return CONTACTS_ERROR_SYSTEM;
680                 }
681         } else {
682                 ERR("sim_status Fail(%d)", sim_status);
683                 return CONTACTS_ERROR_SYSTEM;
684         }
685
686         return CONTACTS_ERROR_NONE;
687 }
688
689 static void __ctsvc_server_sim_get_meta_info_cb(TapiHandle *handle, int result, void *data, void *user_data)
690 {
691         CTS_FN_CALL;
692         int ret = 0;
693         int i = 0;
694         int type = TAPI_PB_3G_NAME;
695         TelSimPbAccessResult_t access_rt = result;
696         ctsvc_sim_info_s *info = (ctsvc_sim_info_s*)user_data;
697
698         DBG("sim slot id :%d, sim_type = %d", info->sim_slot_no, info->sim_type);
699         if (TAPI_SIM_PB_3GSIM == info->sim_type) {
700                 TelSimPbCapabilityInfo_t *capa = data;
701                 RETM_IF(NULL == capa, "capa is NULL result =%d", access_rt);
702
703                 for (i = 0; i < capa->FileTypeCount; i++) {
704                         type = capa->FileTypeInfo[i].field_type;
705
706                         info->file_record[type].support = true;
707                         info->file_record[type].index_max = capa->FileTypeInfo[i].index_max;
708                         info->file_record[type].text_max = capa->FileTypeInfo[i].text_max;
709                         info->file_record[type].used_count = capa->FileTypeInfo[i].used_count;
710
711                         INFO(" field_type[%d] : index_max(%d), text_max(%d), used_count(%d)", type,
712                                         info->file_record[type].index_max,
713                                         info->file_record[type].text_max,
714                                         info->file_record[type].used_count);
715                 }
716         } else if (TAPI_SIM_PB_ADN == info->sim_type) {
717                 TelSimPbEntryInfo_t *pe = data;
718                 RETM_IF(NULL == pe, "pe is NULL result =%d", access_rt);
719
720                 info->file_record[CTSVC_2GSIM_NAME].support = true;
721                 info->file_record[CTSVC_2GSIM_NAME].index_max = pe->PbIndexMax;
722                 info->file_record[CTSVC_2GSIM_NAME].text_max = pe->PbTextLenMax;
723                 info->file_record[CTSVC_2GSIM_NAME].used_count = pe->PbUsedCount;
724                 DBG(" CTSVC_2GSIM_NAME : index_max(%d), text_max(%d), used_count(%d)",
725                                 pe->PbIndexMax, pe->PbTextLenMax, pe->PbUsedCount);
726
727                 info->file_record[CTSVC_2GSIM_NUMBER].support = true;
728                 info->file_record[CTSVC_2GSIM_NUMBER].index_max = pe->PbIndexMax;
729                 info->file_record[CTSVC_2GSIM_NUMBER].text_max = pe->PbNumLenMax;
730                 info->file_record[CTSVC_2GSIM_NUMBER].used_count = pe->PbUsedCount;
731                 DBG(" CTSVC_2GSIM_NUMBER : index_max(%d), text_max(%d), used_count(%d)",
732                                 pe->PbIndexMax, pe->PbNumLenMax, pe->PbUsedCount);
733
734                 INFO(" field_type[%d] : index_max(%d), text_max(%d), used_count(%d)", CTSVC_2GSIM_NAME,
735                                 info->file_record[CTSVC_2GSIM_NAME].index_max,
736                                 info->file_record[CTSVC_2GSIM_NAME].text_max,
737                                 info->file_record[CTSVC_2GSIM_NAME].used_count);
738         } else {
739                 ERR("sim_type [%d]error ", info->sim_type);
740                 return;
741         }
742
743         if (false == info->initialized) {
744                 info->initialized = true;
745                 ret = __ctsvc_server_sim_sdn_read(info);
746                 WARN_IF(CONTACTS_ERROR_NONE != ret, "__ctsvc_server_sim_sdn_read() Fail(%d)", ret);
747         }
748 }
749
750 static void __ctsvc_server_sim_get_iccid_cb(TapiHandle *handle, int result, void *data,
751                 void *user_data)
752 {
753         TelSimAccessResult_t access_rt = result;
754         TelSimIccIdInfo_t *iccid = data;
755         ctsvc_sim_info_s *info = user_data;
756         int ret;
757         int id;
758
759         RETM_IF(TAPI_SIM_ACCESS_SUCCESS != access_rt, "tel_get_sim_iccid Fail(%d)", access_rt);
760
761         DBG("%d, %s", iccid->icc_length, iccid->icc_num);
762
763         info->sim_unique_id = strdup(iccid->icc_num);
764
765         ret = ctsvc_server_get_sim_id(info->sim_unique_id, &id);
766         if (CONTACTS_ERROR_NONE == ret)
767                 info->sim_info_id = id;
768 }
769
770 static int __ctsvc_server_sim_init_meta_info(ctsvc_sim_info_s *info)
771 {
772         int ret = TAPI_API_SUCCESS;
773         int err = CONTACTS_ERROR_NONE;
774
775         if (TAPI_SIM_PB_UNKNOWNN == info->sim_type) {
776                 err = __ctsvc_server_sim_init_info(info);
777                 WARN_IF(CONTACTS_ERROR_NONE != err, "__ctsvc_server_sim_init_info() Fail(%d)", err);
778         }
779
780         if (TAPI_SIM_PB_3GSIM == info->sim_type) {
781                 ret = tel_get_sim_pb_usim_meta_info(info->handle, __ctsvc_server_sim_get_meta_info_cb, info);
782         } else if (TAPI_SIM_PB_ADN == info->sim_type) {
783                 ret = tel_get_sim_pb_meta_info(info->handle, info->sim_type, __ctsvc_server_sim_get_meta_info_cb, info);
784         } else {
785                 ERR("info->sim_type is invalid(%d) stop sim init !!!", info->sim_type);
786                 return CONTACTS_ERROR_SYSTEM;
787         }
788
789         RETVM_IF(TAPI_API_SUCCESS != ret, CONTACTS_ERROR_SYSTEM,
790                         "tel_get_sim_(usim)_meta_info(type:%d) Fail(%d)", info->sim_type, ret);
791
792         return CONTACTS_ERROR_NONE;
793 }
794
795 static int __ctsvc_server_sim_init_info(ctsvc_sim_info_s *info)
796 {
797         CTS_FN_CALL;
798         int ret;
799         TelSimCardType_t cardtype = TAPI_SIM_PB_UNKNOWNN;
800
801         /* get sim_type */
802         ret = tel_get_sim_type(info->handle, &cardtype);
803         RETVM_IF(TAPI_API_SUCCESS != ret, CONTACTS_ERROR_SYSTEM, "tel_get_sim_type Fail(%d)slot no(%d)", ret, info->sim_slot_no);
804         if (TAPI_SIM_CARD_TYPE_USIM == cardtype) {
805                 info->sim_type = TAPI_SIM_PB_3GSIM;
806         } else if (TAPI_SIM_CARD_TYPE_GSM == cardtype) {
807                 info->sim_type = TAPI_SIM_PB_ADN;
808         } else {
809                 ERR("cardtype(%d)is invalid!!!", cardtype);
810                 return CONTACTS_ERROR_SYSTEM;
811         }
812
813         /* set iccid : unique info of SIM */
814         ret = tel_get_sim_iccid(info->handle, __ctsvc_server_sim_get_iccid_cb, info);
815         RETVM_IF(TAPI_API_SUCCESS != ret, CONTACTS_ERROR_SYSTEM, "tel_get_sim_iccid Fail(%d)", ret);
816
817         return CONTACTS_ERROR_NONE;
818 }
819
820 static void __ctsvc_server_sim_noti_pb_status(TapiHandle *handle, const char *noti_id, void *data, void *user_data)
821 {
822         CTS_FN_CALL;
823         int ret = 0;
824         ctsvc_sim_info_s *info = (ctsvc_sim_info_s*)user_data;
825         TelSimPbStatus_t *pb_status = (TelSimPbStatus_t *)data;
826         RET_IF(NULL == pb_status);
827         INFO("received pb status noti : b_3g[%d], b_adn[%d], b_fdn[%d]", pb_status->pb_list.b_3g, pb_status->pb_list.b_adn, pb_status->pb_list.b_fdn);
828
829         if ((1 == pb_status->pb_list.b_3g) || (1 == pb_status->pb_list.b_adn)) {
830                 if (info->initialized)
831                         return;
832                 ret = __ctsvc_server_sim_init_meta_info(info);
833                 WARN_IF(CONTACTS_ERROR_NONE != ret, "__ctsvc_server_sim_init_meta_info() Fail(%d)", ret);
834         } else if ((1 == pb_status->pb_list.b_fdn) && (0 == pb_status->pb_list.b_adn)
835                         && (TAPI_SIM_PB_ADN == info->sim_type)) {
836                 /* FDN on : can not import sim contacts */
837                 INFO("This is sim card is 2G and FDN on status. sim phonebook will be block");
838                 info->initialized = false;
839                 __ctsvc_server_sim_destroy_import_contacts(info);
840         } else {
841                 ERR("This noti did not control !!!");
842         }
843 }
844
845 static void __ctsvc_server_sim_noti_sim_refreshed(TapiHandle *handle, const char *noti_id, void *data, void *user_data)
846 {
847         CTS_FN_CALL;
848         ctsvc_sim_info_s *info = (ctsvc_sim_info_s*)user_data;
849
850         INFO("Recieved SIM Refresh event");
851         info->initialized = false;
852         __ctsvc_server_sim_destroy_import_contacts(info);
853 }
854
855 static int __ctsvc_server_sim_info_init()
856 {
857         int ret;
858         int sim_stat = -1;
859         TelSimPbList_t pb_list = {0,};
860         char **cp_name = NULL;
861         int i;
862         unsigned int cp_index = 0;
863
864 #if !GLIB_CHECK_VERSION(2, 35, 0)
865         g_type_init();
866 #endif
867         cp_name = tel_get_cp_name_list();
868         RETVM_IF(NULL == cp_name, CONTACTS_ERROR_SYSTEM, "tel_get_cp_name_list() Fail");
869
870         ret = ctsvc_server_delete_sdn_contact(-1);
871         WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_server_delete_sdn_contact() Fail(%d)", ret);
872
873         while (cp_name[cp_index])
874                 cp_index++;
875
876         cp_index = 0;
877         while (cp_name[cp_index]) {
878                 TapiHandle *handle;
879                 ctsvc_sim_info_s *info = calloc(1, sizeof(ctsvc_sim_info_s));
880                 if (NULL == info) {
881                         ERR("calloc() Fail");
882                         g_strfreev(cp_name);
883                         return CONTACTS_ERROR_OUT_OF_MEMORY;
884                 }
885                 info->cp_name = strdup(cp_name[cp_index]);
886                 INFO("SIM cp_name[%d] : %s", cp_index, info->cp_name);
887                 info->sim_slot_no = cp_index;
888                 info->sim_info_id = -1;
889                 info->sim_type = TAPI_SIM_PB_UNKNOWNN;
890                 info->initialized = false;
891                 info->import_contacts = NULL;
892                 info->sim_unique_id = NULL;
893
894                 /* initialize file_record meta info */
895                 for (i = 0; i < TAPI_PB_MAX_FILE_CNT; i++) {
896                         info->file_record[i].support = false;
897                         info->file_record[i].index_max = 0;
898                         info->file_record[i].text_max = 0;
899                         info->file_record[i].used_count = 0;
900                 }
901
902                 handle = __ctsvc_server_sim_get_tapi_handle(info);
903                 if (handle) {
904                         ret = __ctsvc_server_sim_init_info(info);
905                         WARN_IF(CONTACTS_ERROR_NONE != ret, "__ctsvc_server_sim_init_info() Fail(%d)", ret);
906                         ret = tel_get_sim_pb_init_info(handle, &sim_stat, &pb_list);
907                         if (TAPI_API_SUCCESS == ret && ((1 == pb_list.b_3g) || (1 == pb_list.b_adn))) {
908                                 ret = __ctsvc_server_sim_init_meta_info(info);
909                                 WARN_IF(CONTACTS_ERROR_NONE != ret, "__ctsvc_server_sim_init_meta_info() Fail(%d)", ret);
910                         }
911
912                         ret = tel_register_noti_event(handle, TAPI_NOTI_PB_STATUS, __ctsvc_server_sim_noti_pb_status, info);
913                         WARN_IF(TAPI_API_SUCCESS != ret, "tel_register_noti_event() Fail(%d)", ret);
914
915                         ret = tel_register_noti_event(handle, TAPI_NOTI_SIM_REFRESHED, __ctsvc_server_sim_noti_sim_refreshed, info);
916                         WARN_IF(TAPI_API_SUCCESS != ret, "tel_register_noti_event() Fail(%d)", ret);
917                 } else {
918                         ERR("tel_init() Fail");
919                 }
920
921                 __ctsvc_sim_info = g_slist_append(__ctsvc_sim_info, (void*)info);
922                 cp_index++;
923         }
924
925         g_strfreev(cp_name);
926
927         return CONTACTS_ERROR_NONE;
928 }
929
930 static void __ctsvc_server_sim_ready_cb(keynode_t *key, void *data)
931 {
932         int status = 0;
933         vconf_get_int(VCONFKEY_TELEPHONY_SIM_STATUS, &status);
934
935         if (VCONFKEY_TELEPHONY_SIM_STATUS_INIT_COMPLETED != status) {
936                 ERR("sim is not ready (%d)", status);
937                 return;
938         }
939         INFO("sim is Ready");
940         __ctsvc_sim_cb = false;
941         vconf_ignore_key_changed(VCONFKEY_TELEPHONY_SIM_STATUS, __ctsvc_server_sim_ready_cb);
942
943         ctsvc_server_stop_timeout();
944         __ctsvc_server_sim_info_init();
945         ctsvc_server_start_timeout();
946 }
947
948 static void __ctsvc_server_telephony_ready_cb(keynode_t *key, void *data)
949 {
950         int bReady = 0;
951         vconf_get_bool(VCONFKEY_TELEPHONY_READY, &bReady);
952
953         if (0 == bReady) {
954                 ERR("telephony is not ready ");
955                 return;
956         }
957         INFO("telephony is Ready");
958
959         vconf_ignore_key_changed(VCONFKEY_TELEPHONY_READY, __ctsvc_server_telephony_ready_cb);
960         __ctsvc_tapi_cb = false;
961
962         int status = 0;
963         vconf_get_int(VCONFKEY_TELEPHONY_SIM_STATUS, &status);
964         if (VCONFKEY_TELEPHONY_SIM_STATUS_INIT_COMPLETED != status) {
965                 ERR("sim is not ready (%d)", status);
966                 vconf_notify_key_changed(VCONFKEY_TELEPHONY_SIM_STATUS, __ctsvc_server_sim_ready_cb, NULL);
967                 __ctsvc_sim_cb = true;
968                 return;
969         }
970
971         ctsvc_server_stop_timeout();
972         __ctsvc_server_sim_info_init();
973         ctsvc_server_start_timeout();
974 }
975
976
977 int ctsvc_server_sim_init()
978 {
979         int bReady = 0;
980         vconf_get_bool(VCONFKEY_TELEPHONY_READY, &bReady);
981
982         if (0 == bReady) {
983                 ERR("telephony is not ready ");
984                 vconf_notify_key_changed(VCONFKEY_TELEPHONY_READY, __ctsvc_server_telephony_ready_cb, NULL);
985                 __ctsvc_tapi_cb = true;
986                 return CONTACTS_ERROR_NONE;
987         }
988
989         int status = 0;
990         vconf_get_int(VCONFKEY_TELEPHONY_SIM_STATUS, &status);
991         if (VCONFKEY_TELEPHONY_SIM_STATUS_INIT_COMPLETED != status) {
992                 ERR("sim is not ready (%d)", status);
993                 vconf_notify_key_changed(VCONFKEY_TELEPHONY_SIM_STATUS, __ctsvc_server_sim_ready_cb, NULL);
994                 __ctsvc_sim_cb = true;
995                 return CONTACTS_ERROR_NONE;
996         }
997
998         return __ctsvc_server_sim_info_init();
999 }
1000
1001 int ctsvc_server_sim_final(void)
1002 {
1003         CTS_FN_CALL;
1004         GSList *info_cursor = NULL;
1005         int ret = 0;
1006
1007         if (__ctsvc_tapi_cb)
1008                 vconf_ignore_key_changed(VCONFKEY_TELEPHONY_READY, __ctsvc_server_telephony_ready_cb);
1009         if (__ctsvc_sim_cb)
1010                 vconf_ignore_key_changed(VCONFKEY_TELEPHONY_SIM_STATUS, __ctsvc_server_sim_ready_cb);
1011
1012         for (info_cursor = __ctsvc_sim_info; info_cursor; info_cursor = info_cursor->next) {
1013                 ctsvc_sim_info_s *info = info_cursor->data;
1014                 free(info->cp_name);
1015                 free(info->sim_unique_id);
1016
1017                 if (info->handle) {
1018                         ret = tel_deinit(info->handle);
1019                         WARN_IF(TAPI_API_SUCCESS != ret, "tel_deinit() Fail(%d)", ret);
1020                 }
1021
1022                 __ctsvc_server_sim_destroy_import_contacts(info);
1023
1024                 free(info);
1025         }
1026
1027         return CONTACTS_ERROR_NONE;
1028 }
1029