23ce7507348b6a27ea63f7f3ef854e27f95fa2a1
[platform/core/telephony/tel-plugin-imc.git] / src / s_phonebook.c
1 /**
2  * tel-plugin-imc
3  *
4  * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved
5  *
6  * Contact: Ankit Jogi <ankit.jogi@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <glib.h>
25 #include <tcore.h>
26 #include <hal.h>
27 #include <core_object.h>
28 #include <plugin.h>
29 #include <queue.h>
30 #include <co_phonebook.h>
31 #include <co_sim.h>
32 #include <user_request.h>
33 #include <server.h>
34 #include <at.h>
35
36 #include "s_common.h"
37 #include "s_phonebook.h"
38
39 /* Constants */
40 #define VAL_ZERO        0
41 #define VAL_ONE         1
42 #define VAL_TWO         2
43 #define VAL_THREE       3
44 #define VAL_FOUR        4
45 #define VAL_FIVE        5
46 #define VAL_SIX         6
47 #define VAL_SEVEN       7
48 #define VAL_NINE        9
49
50 /* Type Of Number and Number Plan */
51 #define TON_INTERNATIONAL               145
52 #define TON_UNKNOWN                             129
53 #define NUM_PLAN_INTERNATIONAL  0x0070
54 #define NUM_PLAN_UNKNOWN                0x0060
55
56 enum pb_usim_file_type {
57         PB_USIM_NAME = 0x01,            /**< Name */
58         PB_USIM_NUMBER,                         /**< Number */
59         PB_USIM_ANR,                            /**< Another number */
60         PB_USIM_EMAIL,                          /**< Email */
61         PB_USIM_SNE,                            /**< Second name entry */
62         PB_USIM_GRP,                            /**< Group file */
63         PB_USIM_PBC,                            /** <1 byte control info and 1 byte hidden info*/
64         PB_USIM_ANRA,                           /**< Another number a*/
65         PB_USIM_ANRB,                           /**< Another number b*/
66         PB_USIM_ANRC,                           /**< Another number c*/
67         PB_USIM_EMAILA,                         /**< email a*/
68         PB_USIM_EMAILB,                         /**< email b*/
69         PB_USIM_EMAILC,                         /**< email c*/
70 };
71
72 static TReturn _get_support_list(CoreObject *o);
73 static TReturn s_get_count(CoreObject *o, UserRequest *ur);
74 static TReturn s_get_info(CoreObject *o, UserRequest *ur);
75 static TReturn s_get_usim_info(CoreObject *o, UserRequest *ur);
76 static TReturn s_read_record(CoreObject *o, UserRequest *ur);
77 static TReturn s_update_record(CoreObject *o, UserRequest *ur);
78 static TReturn s_delete_record(CoreObject *o, UserRequest *ur);
79
80 static enum tcore_response_command _find_resp_command(UserRequest *ur)
81 {
82         switch(tcore_user_request_get_command(ur))
83         {
84                 case TREQ_PHONEBOOK_GETCOUNT:
85                         return TRESP_PHONEBOOK_GETCOUNT;
86                 case TREQ_PHONEBOOK_GETMETAINFO:
87                         return TRESP_PHONEBOOK_GETMETAINFO;
88                 case TREQ_PHONEBOOK_GETUSIMINFO:
89                         return TRESP_PHONEBOOK_GETUSIMINFO;
90                 case TREQ_PHONEBOOK_READRECORD:
91                         return TRESP_PHONEBOOK_READRECORD;
92                 case TREQ_PHONEBOOK_UPDATERECORD:
93                         return TRESP_PHONEBOOK_UPDATERECORD;
94                 case TREQ_PHONEBOOK_DELETERECORD:
95                         return TRESP_PHONEBOOK_DELETERECORD;
96                 default:
97                         return TRESP_UNKNOWN;
98         }
99 }
100
101 static enum tel_phonebook_ton _find_num_plan(int number_plan)
102 {
103         enum tel_phonebook_ton result;
104         dbg("number_plan : 0x%04x", number_plan);
105
106         if(number_plan & NUM_PLAN_INTERNATIONAL) {
107                 result = PB_TON_INTERNATIONAL;
108         }
109         else {
110                 result = PB_TON_UNKNOWN;
111         }
112         dbg("result : %d", result);
113         return result;
114 }
115
116 static void on_confirmation_phonebook_message_send(TcorePending *p, gboolean result, void *user_data)
117 {
118         dbg("msg out from queue");
119
120         if (result == FALSE) {          /* Fail */
121                 dbg("SEND FAIL");
122         }
123         else {
124                 dbg("SEND OK");
125         }
126 }
127
128 static char* _get_phonebook_type(enum tel_phonebook_type pb_type)
129 {
130         char *phonebook_type = NULL;
131         dbg(" Function entry ");
132         dbg("pb_type = %d", pb_type);
133
134         phonebook_type = (char*)calloc(sizeof(char), VAL_FIVE);
135         if(NULL == phonebook_type) {
136                 err("Memory allcoation failed");
137                 return phonebook_type;
138         }
139         
140         switch(pb_type)
141         {
142                 case PB_TYPE_FDN:
143                         phonebook_type = "FD";
144                         break;
145                 case PB_TYPE_ADN:
146                 case PB_TYPE_AAS:
147                 case PB_TYPE_GAS:
148                         phonebook_type = "SM";
149                         break;
150                 case PB_TYPE_SDN:
151                         phonebook_type = "SN";
152                         break;
153                 case PB_TYPE_USIM:
154                         phonebook_type = "AP";
155                         break;
156                 default:
157                         dbg("Invalid pb_type [%02x]", pb_type);
158                         free(phonebook_type);
159                         phonebook_type = NULL;
160                         break;
161         }
162         dbg(" Function exit");
163         return phonebook_type;
164 }
165
166 static enum tel_phonebook_type _get_phonebook_enum(const char* pb_type)
167 {
168         enum tel_phonebook_type phonebook_type = PB_TYPE_UNKNOWNN;
169         dbg(" Function entry ");
170         dbg("pb_type = %s", pb_type);
171         
172         if(strcmp("FD", pb_type) == VAL_ZERO) {
173                 phonebook_type = PB_TYPE_FDN;
174         }
175         else if(strcmp("SM", pb_type) == VAL_ZERO) {
176                 phonebook_type = PB_TYPE_ADN;
177         }
178         else if(strcmp("SN", pb_type) == VAL_ZERO) {
179                 phonebook_type = PB_TYPE_SDN;
180         }
181         else if(strcmp("AP", pb_type) == VAL_ZERO) {
182                 phonebook_type = PB_TYPE_USIM;
183         }
184         
185         dbg(" Function exit");
186         return phonebook_type;
187 }
188
189 static gboolean on_event_phonebook_status(CoreObject *o, const void *event_info, void *user_data)
190 {
191         dbg("Phonebook init received from modem");
192         
193         _get_support_list(o);
194         
195         return TRUE;
196 }
197
198 static void _on_response_select(TcorePending *p, int data_len, const void *data, void *user_data)
199 {
200         const TcoreATResponse *resp = data;
201         UserRequest *ur = NULL;
202         CoreObject *o = NULL;
203         enum tcore_request_command req_cmd = TREQ_UNKNOWN;
204         int *selected_pb = user_data;
205         GQueue *queue = NULL;
206         dbg(" Function entry ");
207
208         o = tcore_pending_ref_core_object(p);
209         ur = tcore_pending_ref_user_request(p);
210         if (!ur){
211                 dbg("error - current ur is NULL");
212                 return;
213         }
214
215         queue = tcore_object_ref_user_data(o);
216         if(queue) {
217                 ur = tcore_user_request_ref(ur);
218         }
219         
220         req_cmd = tcore_user_request_get_command(ur);
221         dbg("origin treq command [%x]", req_cmd);
222
223         if(resp->success > VAL_ZERO) {
224                 dbg("RESPONSE OK");
225                 tcore_phonebook_set_selected_type(o, *selected_pb);
226                 switch (req_cmd)
227                 {
228                         case TREQ_PHONEBOOK_GETCOUNT:
229                                 s_get_count(o, ur);
230                                 break;
231                         case TREQ_PHONEBOOK_GETMETAINFO:
232                                 s_get_info(o, ur);
233                                 break;
234                         case TREQ_PHONEBOOK_GETUSIMINFO:
235                                 s_get_usim_info(o, ur);
236                                 break;
237                         case TREQ_PHONEBOOK_READRECORD:
238                                 s_read_record(o, ur);
239                                 break;
240                         case TREQ_PHONEBOOK_UPDATERECORD:
241                                 s_update_record(o, ur);
242                                 break;
243                         case TREQ_PHONEBOOK_DELETERECORD:
244                                 s_delete_record(o, ur);
245                                 break;
246                         default:
247                                 dbg("not handled treq cmd[%d]", req_cmd);
248                                 break;
249                 }
250         }
251         else
252         {
253                 dbg("RESPONSE NOK");
254                 switch (req_cmd)
255                 {
256                         case TREQ_PHONEBOOK_GETCOUNT:
257                         {
258                                 struct tresp_phonebook_get_count resp_getcount;
259                                 dbg("error TREQ_PHONEBOOK_GETCOUNT");
260                                 memset(&resp_getcount, 0x00, sizeof(struct tresp_phonebook_get_count));
261                                 resp_getcount.result = PB_FAIL;
262                                 tcore_user_request_send_response(ur, TRESP_PHONEBOOK_GETCOUNT, sizeof(struct tresp_phonebook_get_count), &resp_getcount);
263                         }
264                         break;
265                         case TREQ_PHONEBOOK_GETMETAINFO:
266                         {
267                                 dbg("error TREQ_PHONEBOOK_GETMETAINFO");
268                         }
269                         break;
270                         case TREQ_PHONEBOOK_GETUSIMINFO:
271                         {
272                                 dbg("error TREQ_PHONEBOOK_GETUSIMINFO");
273                         }
274                         break;
275                         case TREQ_PHONEBOOK_READRECORD:
276                         {
277                                 struct tresp_phonebook_read_record resp_readrecord;
278                                 dbg("error TREQ_PHONEBOOK_READRECORD");
279                                 memset(&resp_readrecord, 0x00, sizeof(struct tresp_phonebook_read_record));
280                                 resp_readrecord.result = PB_FAIL;
281                                 resp_readrecord.phonebook_type = *selected_pb;
282                                 tcore_user_request_send_response(ur, TRESP_PHONEBOOK_READRECORD, sizeof(struct tresp_phonebook_read_record), &resp_readrecord);
283                         }
284                         break;
285                         case TREQ_PHONEBOOK_UPDATERECORD:
286                         {
287                                 struct tresp_phonebook_update_record resp_updaterecord;
288                                 dbg("error TREQ_PHONEBOOK_UPDATERECORD");
289                                 memset(&resp_updaterecord, 0x00, sizeof(struct tresp_phonebook_update_record));
290                                 resp_updaterecord.result = PB_FAIL;
291                                 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_phonebook_update_record), &resp_updaterecord);
292                         }
293                         break;
294                         case TREQ_PHONEBOOK_DELETERECORD:
295                         {
296                                 struct tresp_phonebook_delete_record resp_deleterecord;
297                                 dbg("error TREQ_PHONEBOOK_DELETERECORD");
298                                 memset(&resp_deleterecord, 0x00, sizeof(struct tresp_phonebook_delete_record));
299                                 resp_deleterecord.result = PB_FAIL;
300                                 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_phonebook_delete_record), &resp_deleterecord);
301                         }
302                         break;
303                         default:
304                                 dbg("not handled treq cmd[%d]", req_cmd);
305                         break;
306                 }
307
308         }
309         
310         free(selected_pb);
311         selected_pb = NULL;
312         dbg(" Function exit");
313 }
314
315 static void on_response_get_count(TcorePending *p, int data_len, const void *data, void *user_data)
316 {
317         const TcoreATResponse *resp = data;
318         UserRequest *ur = NULL;
319         GSList *tokens=NULL;
320         const char *temp = NULL;
321         struct tresp_phonebook_get_count res;
322         char *pbtype = NULL;
323         dbg(" Function entry ");
324
325         ur = tcore_pending_ref_user_request(p);
326         if (!ur){
327                 dbg("error - current ur is NULL");
328                 return;
329         }
330
331         memset(&res, 0x00, sizeof(struct tresp_phonebook_get_count));
332         if(resp->success > VAL_ZERO) {
333                 dbg("RESPONSE OK");
334                 if(resp->lines) {
335                         temp = (const char*)resp->lines->data;
336                         tokens = tcore_at_tok_new(temp);
337                         if (g_slist_length(tokens) < VAL_ONE) {
338                                 msg("invalid message");
339                                 tcore_at_tok_free(tokens);
340                                 return;
341                         }
342                 }
343                 res.result = PB_SUCCESS;
344                 
345                 temp = (const char*)g_slist_nth_data(tokens, VAL_ZERO);
346                 pbtype =  util_removeQuotes((void*)temp);
347                 res.type = _get_phonebook_enum(pbtype);
348                 
349                 if(NULL != g_slist_nth_data(tokens, VAL_ONE)){
350                         res.used_count = atoi(g_slist_nth_data(tokens, VAL_ONE));
351                 }
352                 
353                 if(NULL != g_slist_nth_data(tokens, VAL_TWO)){
354                         res.total_count = atoi(g_slist_nth_data(tokens, VAL_TWO));
355                 }
356                 dbg("used count = %d,  total count= %d", res.used_count, res.total_count);
357                 free(pbtype);
358                 pbtype = NULL;
359         }
360         else{
361                 dbg("RESPONSE NOK");
362                 res.result = PB_FAIL;
363         }
364
365         tcore_user_request_send_response(ur, TRESP_PHONEBOOK_GETCOUNT, sizeof(struct tresp_phonebook_get_count), &res);
366         
367         tcore_at_tok_free(tokens);
368         dbg(" Function exit");
369 }
370
371 static void on_response_get_info(TcorePending *p, int data_len, const void *data, void *user_data)
372 {
373         struct tresp_phonebook_get_info res = {0,};
374         const TcoreATResponse *resp = data;
375         UserRequest *ur = NULL;
376         GSList *tokens=NULL;
377         const char *line;
378         int *selected_pb = (int*)user_data;
379
380         dbg(" Function entry ");
381         
382         ur = tcore_pending_ref_user_request(p);
383         if (!ur){
384                 dbg("error - current ur is NULL");
385                 return;
386         }
387
388         memset(&res, 0x00, sizeof(struct tresp_phonebook_get_info));
389         res.type = *selected_pb;
390         if(resp->success > VAL_ZERO) {
391                 dbg("RESPONSE OK");
392                 if(resp->lines) {
393                         line = (const char*)resp->lines->data;
394                         tokens = tcore_at_tok_new(line);
395                         if (g_slist_length(tokens) < VAL_ONE) {
396                                 msg("invalid message");
397                                 tcore_at_tok_free(tokens);
398                                 return;
399                         }
400                 }
401                 res.result = PB_SUCCESS;
402                 
403                 res.number_length_max = atoi(g_slist_nth_data(tokens, VAL_ZERO));
404                 res.text_length_max = atoi(g_slist_nth_data(tokens, VAL_ONE));
405                 dbg("number_length_max %d text_length_max %d",res.number_length_max,res.text_length_max);
406         }
407         else{
408                 dbg("RESPONSE NOK");
409                 res.result = PB_FAIL;
410         }
411
412         tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_phonebook_get_info), &res);
413         
414         tcore_at_tok_free(tokens);
415         free(selected_pb);
416         selected_pb = NULL;
417         dbg(" Function exit");
418 }
419
420 static void on_response_read_record(TcorePending *p, int data_len, const void *data, void *user_data)
421 {
422         const TcoreATResponse *resp = data;
423         UserRequest *ur = NULL;
424         GSList *tokens=NULL;
425         const char *line;
426         struct tresp_phonebook_read_record res;
427         int num_len = VAL_ZERO;
428         int name_len = VAL_ZERO;
429         int num_plan = VAL_ZERO;
430         char *member = NULL;
431         char *temp = NULL;
432         int *selected_pb = (int*)user_data;
433
434         dbg(" Function entry ");
435         
436         ur = tcore_pending_ref_user_request(p);
437         if (!ur){
438                 dbg("error - current ur is NULL");
439                 return;
440         }
441
442         memset(&res, 0x00, sizeof(struct tresp_phonebook_read_record));
443         res.phonebook_type = *selected_pb;
444         
445         if(resp->success > VAL_ZERO) {
446                 dbg("RESPONSE OK");
447                 if(resp->lines) {
448                         line = (const char*)resp->lines->data;
449                         tokens = tcore_at_tok_new(line);
450                         if (g_slist_length(tokens) < VAL_ONE) {
451                                 msg("invalid message");
452                                 tcore_at_tok_free(tokens);
453                                 return;
454                         }
455                 }
456                 res.result = PB_SUCCESS;
457                 
458                 res.index = atoi(g_slist_nth_data(tokens, VAL_ZERO));
459                 res.next_index = (res.index + VAL_ONE);
460                 num_plan = atoi(g_slist_nth_data(tokens, VAL_TWO));
461                 res.ton = _find_num_plan(num_plan);
462
463                 temp = g_slist_nth_data(tokens, VAL_ONE);
464                 member =  util_removeQuotes((void*)temp);
465                 dbg("number %s - %d", member, (num_len-VAL_TWO));
466                 memcpy(res.number, member, strlen(member));
467                 free(member);
468                 member = NULL;
469
470                 temp = g_slist_nth_data(tokens, VAL_THREE);
471                 member =  util_removeQuotes((void*)temp);
472                 dbg("name %s - %d", member, strlen(member));
473                 memcpy(res.name, member, strlen(member));
474                 free(member);
475                 member = NULL;
476
477                 if(NULL != g_slist_nth_data(tokens, VAL_FOUR)) {
478                         if(atoi(g_slist_nth_data(tokens, VAL_FOUR)) == VAL_ZERO) {
479                                 dbg("phonebook entry not hidden");
480                         }
481                         else{
482                                 dbg("phonebook entry hidden");
483                         }
484                 }
485
486                 if(NULL != g_slist_nth_data(tokens, VAL_SIX)){
487                         num_len =  strlen(g_slist_nth_data(tokens, VAL_SIX));
488                         snprintf((char *)res.anr1, num_len+1, "%s", (char*)g_slist_nth_data(tokens, VAL_SIX));
489                 }
490                 
491                 if(NULL != g_slist_nth_data(tokens, VAL_SEVEN)){
492                         num_plan = atoi(g_slist_nth_data(tokens, VAL_SEVEN));
493                         res.anr1_ton = _find_num_plan(num_plan);
494                 }
495                 
496                 if(NULL != g_slist_nth_data(tokens, VAL_NINE)){
497                         name_len = strlen(g_slist_nth_data(tokens, VAL_NINE));
498                         memcpy(res.email1, g_slist_nth_data(tokens, VAL_NINE), name_len);
499                 }
500         }
501         else{
502                 dbg("RESPONSE NOK");
503                 res.result = PB_FAIL;
504         }
505         
506         tcore_user_request_send_response(ur, TRESP_PHONEBOOK_READRECORD, sizeof(struct tresp_phonebook_read_record), &res);
507         
508         tcore_at_tok_free(tokens);
509         free(selected_pb);
510         selected_pb = NULL;
511         dbg(" Function exit");
512 }
513
514 static void on_response_update_record(TcorePending *p, int data_len, const void *data, void *user_data)
515 {
516         const TcoreATResponse *resp = data;
517         UserRequest *ur = NULL;
518         struct tresp_phonebook_update_record res;
519         dbg(" Function entry ");
520
521         if(resp->success > VAL_ZERO) {
522                 dbg("RESPONSE OK");
523                 res.result = PB_SUCCESS;
524         }
525         else{
526                 dbg("RESPONSE NOK");
527                 res.result = PB_FAIL;
528         }
529
530         ur = tcore_pending_ref_user_request(p);
531         if (ur){
532                 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_phonebook_update_record),
533                                 &res);
534         }
535         else{
536                 dbg("error - current ur is NULL");
537         }
538
539 }
540
541 static void on_response_delete_record(TcorePending *p, int data_len, const void *data, void *user_data)
542 {
543         const TcoreATResponse *resp = data;
544         UserRequest *ur = NULL;
545         struct tresp_phonebook_delete_record res;
546
547         if(resp->success > VAL_ZERO) {
548                 dbg("RESPONSE OK");
549                 res.result = PB_SUCCESS;
550         }
551         else{
552                 dbg("RESPONSE NOK");
553                 res.result = PB_FAIL;
554         }
555
556         ur = tcore_pending_ref_user_request(p);
557         if (ur){
558                 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_phonebook_delete_record), &res);
559         }
560         else{
561                 dbg("error - current ur is NULL");
562         }
563 }
564
565 static void _response_get_support_list(TcorePending *p, int data_len, const void *data, void *user_data)
566 {
567         const TcoreATResponse *resp = data;
568         CoreObject*o = NULL;
569         GSList *tokens=NULL;
570         const char *line;
571         char *temp = NULL;
572         char *pbtype = NULL;
573         struct tnoti_phonebook_status noti_data = {0,};
574
575         dbg(" Function entry ");
576
577         o = tcore_pending_ref_core_object(p);
578         if(!o){
579                 dbg("error -  core object is null");
580                 return;
581         }
582
583         if(resp->success > VAL_ZERO) {
584                 dbg("RESPONSE OK");
585                 if(resp->lines) {
586                         line = (const char*)resp->lines->data;
587                         tokens = tcore_at_tok_new(line);
588                         if (g_slist_length(tokens) < VAL_ONE) {
589                                 msg("invalid message");
590                                 tcore_at_tok_free(tokens);
591                                 return;
592                         }
593                 }
594
595                 temp = (char*)g_slist_nth_data(tokens, VAL_ZERO);
596                 pbtype = strtok(temp, "(,)");
597                 while(pbtype != NULL) {
598                         temp =  util_removeQuotes((void*)pbtype);
599                         dbg("pbtype %s", temp);
600                         if (VAL_ZERO == strcmp(temp, "FD")) {
601                                 dbg("SIM fixed-dialing phonebook");
602                                 noti_data.support_list.b_fdn = VAL_ONE;
603                         }
604                         else if (VAL_ZERO == strcmp(temp, "SN")) {
605                                 dbg("Service Dialing Number");
606                                 noti_data.support_list.b_sdn = VAL_ONE;
607                         }
608                         else if (VAL_ZERO == strcmp(temp, "SM")) {
609                                 dbg("2G SIM ADN phonebook");
610                                 noti_data.support_list.b_adn = VAL_ONE;
611                         }
612                         else if (VAL_ZERO == strcmp(temp, "LD")) {
613                                 dbg("SIM/UICC last-dialling-phonebook");
614                         }
615                         else if (VAL_ZERO == strcmp(temp, "ON")) {
616                                 dbg("SIM (or MT) own numbers (MSISDNs) list");
617                         }
618                         else if (VAL_ZERO == strcmp(temp, "BL")) {
619                                 dbg("Blacklist phonebook");
620                         }
621                         else if (VAL_ZERO == strcmp(temp, "EC")) {
622                                 dbg("SIM emergency-call-codes phonebook");
623                         }
624                         else if (VAL_ZERO == strcmp(temp, "AP")) {
625                                 dbg("Selected application phonebook");
626                         }
627                         else if (VAL_ZERO == strcmp(temp, "BN")) {
628                                 dbg("SIM barred-dialling-number");
629                         }
630                         pbtype = strtok (NULL, "(,)");
631                         g_free(temp);
632                 }
633                 
634                 noti_data.b_init = TRUE;
635                 tcore_phonebook_set_support_list(o, &noti_data.support_list);
636                 tcore_phonebook_set_status(o, noti_data.b_init);
637                 tcore_at_tok_free(tokens);
638         }
639         else{
640                 dbg("RESPONSE NOK");
641                 noti_data.b_init = FALSE;
642                 tcore_phonebook_set_status(o, noti_data.b_init);
643         }
644
645         tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_PHONEBOOK_STATUS,
646                         sizeof(struct tnoti_phonebook_status), &noti_data);
647 }
648
649 static  TReturn _get_support_list(CoreObject *o)
650 {
651         TcoreHal *hal = NULL;
652         TcoreATRequest *req = NULL;
653         TcorePending *pending = NULL;
654         char *cmd_str = NULL;
655
656         dbg(" Function entry ");
657
658         if (!o){
659                 return TCORE_RETURN_EINVAL;
660         }
661
662         hal = tcore_object_get_hal(o);
663         pending = tcore_pending_new(o, VAL_ZERO);
664
665         cmd_str = g_strdup_printf("AT+CPBS=?");
666         req = tcore_at_request_new(cmd_str, "+CPBS:", TCORE_AT_SINGLELINE);
667         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
668
669         tcore_pending_set_request_data(pending, VAL_ZERO, req);
670         tcore_pending_set_response_callback(pending, _response_get_support_list, NULL);
671         tcore_pending_set_send_callback(pending, on_confirmation_phonebook_message_send, NULL);
672         
673         tcore_hal_send_request(hal, pending);
674
675         g_free(cmd_str);
676         dbg(" Function exit");
677         return TCORE_RETURN_SUCCESS;
678 }
679
680 static  TReturn _select(CoreObject *o, UserRequest *ur, enum tel_phonebook_type pbt)
681 {
682         TcoreHal *hal = NULL;
683         TcoreATRequest *req = NULL;
684         TcorePending *pending = NULL;
685         char *cmd_str = NULL;
686         const struct treq_phonebook_get_count *req_data;
687         int *pb_type = NULL;
688         char *phonebook_type = NULL;
689
690         dbg(" Function entry ");
691
692         if (!o || !ur)
693                 return TCORE_RETURN_EINVAL;
694         
695         req_data = tcore_user_request_ref_data(ur, NULL);
696
697         phonebook_type = (char*)_get_phonebook_type(req_data->phonebook_type);
698         if(NULL == phonebook_type){
699                 err("phonebook_type is NULL");
700                 return TCORE_RETURN_FAILURE;
701         }
702         
703         pb_type = calloc(sizeof(enum tel_phonebook_type),VAL_ONE);
704         if(pb_type == NULL) {
705                 err("Failed to allocate memory");
706                 return TCORE_RETURN_FAILURE;
707         }
708         *pb_type = pbt;
709
710         cmd_str = g_strdup_printf("AT+CPBS=\"%s\"", phonebook_type);
711         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
712         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
713
714         hal = tcore_object_get_hal(o);
715         pending = tcore_pending_new(o, VAL_ZERO);
716         tcore_pending_set_request_data(pending, VAL_ZERO, req);
717         tcore_pending_set_response_callback(pending, _on_response_select, (void*)pb_type);
718         tcore_pending_link_user_request(pending, ur);
719         tcore_pending_set_send_callback(pending, on_confirmation_phonebook_message_send, NULL);
720         
721         tcore_hal_send_request(hal, pending);
722
723         free(phonebook_type);
724         g_free(cmd_str);
725         dbg(" Function exit");
726         return TCORE_RETURN_SUCCESS;
727 }
728
729 static  TReturn s_get_count(CoreObject *o, UserRequest *ur)
730 {
731         TcoreHal *hal = NULL;
732         TcoreATRequest *req = NULL;
733         TcorePending *pending = NULL;
734         char *cmd_str = NULL;
735         const struct treq_phonebook_get_count *req_data = NULL;
736         enum tel_phonebook_type pbt = PB_TYPE_UNKNOWNN;
737
738         dbg("Function Entry");
739         if (!o || !ur)
740                 return TCORE_RETURN_EINVAL;
741
742         req_data = tcore_user_request_ref_data(ur, NULL);
743         pbt = tcore_phonebook_get_selected_type(o);
744         if (req_data->phonebook_type != pbt) {
745                 dbg("req pb[%d] is different with tcore pb[%d]", req_data->phonebook_type, pbt);
746                 _select(o, ur, req_data->phonebook_type);
747                 return TCORE_RETURN_SUCCESS;
748         }
749
750         cmd_str = g_strdup_printf("AT+CPBS?");
751         req = tcore_at_request_new(cmd_str, "+CPBS:", TCORE_AT_SINGLELINE);
752         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
753
754         hal = tcore_object_get_hal(o);
755         pending = tcore_pending_new(o, VAL_ZERO);
756         
757         tcore_pending_set_request_data(pending, VAL_ZERO, req);
758         tcore_pending_set_response_callback(pending, on_response_get_count, hal);
759         tcore_pending_link_user_request(pending, ur);
760         tcore_pending_set_send_callback(pending, on_confirmation_phonebook_message_send, NULL);
761         
762         tcore_hal_send_request(hal, pending);
763
764         g_free(cmd_str);
765         dbg("Function exit");
766         return TCORE_RETURN_SUCCESS;
767 }
768
769 static  TReturn s_get_info(CoreObject *o, UserRequest *ur)
770 {
771         TcoreHal *hal = NULL;
772         TcoreATRequest *req = NULL;
773         TcorePending *pending = NULL;
774         char *cmd_str = NULL;
775         const struct treq_phonebook_get_info *req_data = NULL;
776         enum tel_phonebook_type pbt = PB_TYPE_UNKNOWNN;
777         int *pb_type = NULL;
778
779         dbg(" Function entry ");
780
781         if (!o || !ur)
782                 return TCORE_RETURN_EINVAL;
783
784         req_data = tcore_user_request_ref_data(ur, NULL);
785         pbt = tcore_phonebook_get_selected_type(o);
786         if (req_data->phonebook_type != pbt) {
787                 dbg("req pb[%d] is different with tcore pb[%d]", req_data->phonebook_type, pbt);
788                 _select(o, ur, req_data->phonebook_type);
789                 return TCORE_RETURN_SUCCESS;
790         }
791
792         pb_type = calloc(sizeof(enum tel_phonebook_type),VAL_ONE);
793         if(pb_type == NULL) {
794                 err("Failed to allocate memory");
795                 return TCORE_RETURN_FAILURE;
796         }
797         *pb_type = pbt;
798         dbg("pb_type %d", *pb_type);
799
800         cmd_str = g_strdup_printf("AT+CPBF=?");
801         req = tcore_at_request_new(cmd_str, "+CPBF:", TCORE_AT_SINGLELINE);
802         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
803
804         hal = tcore_object_get_hal(o);
805         pending = tcore_pending_new(o, VAL_ZERO);
806
807         tcore_pending_set_request_data(pending, VAL_ZERO, req);
808         tcore_pending_set_response_callback(pending, on_response_get_info, (void*)pb_type);
809         tcore_pending_link_user_request(pending, ur);
810         tcore_pending_set_send_callback(pending, on_confirmation_phonebook_message_send, NULL);
811
812         tcore_hal_send_request(hal, pending);
813
814         g_free(cmd_str);
815         dbg(" Function exit");
816         return TCORE_RETURN_SUCCESS;
817
818 }
819
820 static TReturn s_get_usim_info(CoreObject *o, UserRequest *ur)
821 {
822         dbg("NOT IMPLEMENTED");
823
824         return TCORE_RETURN_SUCCESS;
825 }
826
827 static TReturn s_read_record(CoreObject *o, UserRequest *ur)
828 {
829         TcoreHal*hal = NULL;
830         TcoreATRequest *req = NULL;
831         TcorePending *pending = NULL;
832         char *cmd_str = NULL;
833         const struct treq_phonebook_read_record *req_data = NULL;
834         enum tel_phonebook_type pbt = PB_TYPE_UNKNOWNN;
835         int *pb_type = NULL;
836
837         dbg(" Function entry ");
838
839         if (!o || !ur)
840                 return TCORE_RETURN_EINVAL;
841
842         req_data = tcore_user_request_ref_data(ur, NULL);
843         pbt = tcore_phonebook_get_selected_type(o);
844         if (req_data->phonebook_type != pbt) {
845                 dbg("req pb[%d] is different with tcore pb[%d]", req_data->phonebook_type, pbt);
846                 _select(o, ur, req_data->phonebook_type);
847                 return TCORE_RETURN_SUCCESS;
848         }
849
850         pb_type = calloc(sizeof(enum tel_phonebook_type),VAL_ONE);
851         if(pb_type == NULL) {
852                 err("Failed to allocate memory");
853                 return TCORE_RETURN_FAILURE;
854         }
855         *pb_type = pbt;
856         dbg("pb_type %d", *pb_type);
857
858         cmd_str = g_strdup_printf("AT+CPBR=%d,%d", req_data->index, req_data->index);
859         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
860         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
861
862         hal = tcore_object_get_hal(o);
863         pending = tcore_pending_new(o, VAL_ZERO);
864
865         tcore_pending_set_request_data(pending, VAL_ZERO, req);
866         tcore_pending_set_response_callback(pending, on_response_read_record, (void*)pb_type);
867         tcore_pending_link_user_request(pending, ur);
868         tcore_pending_set_send_callback(pending, on_confirmation_phonebook_message_send, NULL);
869
870         tcore_hal_send_request(hal, pending);
871
872         g_free(cmd_str);
873         dbg(" Function exit");
874         return TCORE_RETURN_SUCCESS;
875 }
876
877 static  TReturn s_update_record(CoreObject *o, UserRequest *ur)
878 {
879         TcoreHal *hal = NULL;
880         TcoreATRequest *req = NULL;
881         TcorePending *pending = NULL;
882         char *cmd_str = NULL;
883         const struct treq_phonebook_update_record *req_data = NULL;
884         enum tel_phonebook_type pbt = PB_TYPE_UNKNOWNN;
885
886         dbg(" Function entry ");
887
888         if (!o || !ur)
889                 return TCORE_RETURN_EINVAL;
890
891         req_data = tcore_user_request_ref_data(ur, NULL);
892         pbt = tcore_phonebook_get_selected_type(o);
893         if (req_data->phonebook_type != pbt) {
894                 dbg("req pb[%d] is different with tcore pb[%d]", req_data->phonebook_type, pbt);
895                 _select(o, ur, req_data->phonebook_type);
896                 return TCORE_RETURN_SUCCESS;
897         }
898
899         cmd_str = g_strdup_printf("AT+CPBW=,\"%s\",%d,\"%s\"", req_data->number, ((PB_TON_INTERNATIONAL == req_data->ton) ? TON_INTERNATIONAL: TON_UNKNOWN), req_data->name);
900         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
901         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
902
903         hal = tcore_object_get_hal(o);
904         pending = tcore_pending_new(o, VAL_ZERO);
905         
906         tcore_pending_set_request_data(pending, VAL_ZERO, req);
907         tcore_pending_set_response_callback(pending, on_response_update_record, hal);
908         tcore_pending_link_user_request(pending, ur);
909         tcore_pending_set_send_callback(pending, on_confirmation_phonebook_message_send, NULL);
910
911         tcore_hal_send_request(hal, pending);
912
913         g_free(cmd_str);
914         dbg(" Function exit");
915         return TCORE_RETURN_SUCCESS;
916 }
917
918 static  TReturn s_delete_record(CoreObject *o, UserRequest *ur)
919 {
920         TcoreHal *hal = NULL;
921         TcoreATRequest *req = NULL;
922         TcorePending *pending = NULL;
923         char *cmd_str = NULL;
924         const struct treq_phonebook_delete_record *req_data;
925         enum tel_phonebook_type pbt = PB_TYPE_UNKNOWNN;
926
927         dbg(" Function entry ");
928
929         if (!o || !ur)
930                 return TCORE_RETURN_EINVAL;
931
932         req_data = tcore_user_request_ref_data(ur, NULL);
933         pbt = tcore_phonebook_get_selected_type(o);
934         if (req_data->phonebook_type != pbt) {
935                 dbg("req pb[%d] is different with tcore pb[%d]", req_data->phonebook_type, pbt);
936                 _select(o, ur, req_data->phonebook_type);
937                 return TCORE_RETURN_SUCCESS;
938         }
939
940         cmd_str = g_strdup_printf("AT+CPBW=%d", req_data->index);
941         req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
942         dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
943
944         hal = tcore_object_get_hal(o);
945         pending = tcore_pending_new(o, VAL_ZERO);
946
947         tcore_pending_set_request_data(pending, VAL_ZERO, req);
948         tcore_pending_set_response_callback(pending, on_response_delete_record, hal);
949         tcore_pending_link_user_request(pending, ur);
950         tcore_pending_set_send_callback(pending, on_confirmation_phonebook_message_send, NULL);
951
952         tcore_hal_send_request(hal, pending);
953
954         g_free(cmd_str);
955         dbg(" Function exit");
956         return TCORE_RETURN_SUCCESS;
957 }
958
959 static struct tcore_phonebook_operations phonebook_ops = {
960         .get_count = s_get_count,
961         .get_info = s_get_info,
962         .get_usim_info = s_get_usim_info,
963         .read_record = s_read_record,
964         .update_record = s_update_record,
965         .delete_record = s_delete_record,
966 };
967
968 gboolean s_phonebook_init(TcorePlugin *p, TcoreHal *h)
969 {
970         CoreObject *o = NULL;
971
972         dbg("Entry");
973         o = tcore_phonebook_new(p, "phonebook", &phonebook_ops, h);
974         if (!o)
975                 return FALSE;
976
977         tcore_object_add_callback(o, "+PBREADY", on_event_phonebook_status, NULL);
978         dbg("Exit");
979         return TRUE;
980 }
981
982 void s_phonebook_exit(TcorePlugin *p)
983 {
984         CoreObject *o = NULL;
985         o = tcore_plugin_ref_core_object(p, "phonebook");
986         if (!o)
987                 return;
988
989         tcore_phonebook_free(o);
990 }