4 * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved
6 * Contact: Ankit Jogi <ankit.jogi@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
27 #include <core_object.h>
30 #include <co_phonebook.h>
32 #include <user_request.h>
37 #include "s_phonebook.h"
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
56 struct valid_pb_index{
59 int indexlist_populated;
63 static struct valid_pb_index __pbindex;
65 enum pb_usim_file_type {
66 PB_USIM_NAME = 0x01, /**< Name */
67 PB_USIM_NUMBER, /**< Number */
68 PB_USIM_ANR, /**< Another number */
69 PB_USIM_EMAIL, /**< Email */
70 PB_USIM_SNE, /**< Second name entry */
71 PB_USIM_GRP, /**< Group file */
72 PB_USIM_PBC, /** <1 byte control info and 1 byte hidden info*/
73 PB_USIM_ANRA, /**< Another number a*/
74 PB_USIM_ANRB, /**< Another number b*/
75 PB_USIM_ANRC, /**< Another number c*/
76 PB_USIM_EMAILA, /**< email a*/
77 PB_USIM_EMAILB, /**< email b*/
78 PB_USIM_EMAILC, /**< email c*/
81 static TReturn _get_support_list(CoreObject *o);
82 static TReturn s_get_count(CoreObject *o, UserRequest *ur);
83 static TReturn s_get_info(CoreObject *o, UserRequest *ur);
84 static TReturn s_get_usim_info(CoreObject *o, UserRequest *ur);
85 static TReturn s_read_record(CoreObject *o, UserRequest *ur);
86 static TReturn s_update_record(CoreObject *o, UserRequest *ur);
87 static TReturn s_delete_record(CoreObject *o, UserRequest *ur);
90 static void pbindex_reset()
92 if(__pbindex.indexlist){
93 free(__pbindex.indexlist);
95 memset(&__pbindex, 0x00, sizeof(struct valid_pb_index));
98 static enum tcore_response_command _find_resp_command(UserRequest *ur)
100 switch(tcore_user_request_get_command(ur))
102 case TREQ_PHONEBOOK_GETCOUNT:
103 return TRESP_PHONEBOOK_GETCOUNT;
104 case TREQ_PHONEBOOK_GETMETAINFO:
105 return TRESP_PHONEBOOK_GETMETAINFO;
106 case TREQ_PHONEBOOK_GETUSIMINFO:
107 return TRESP_PHONEBOOK_GETUSIMINFO;
108 case TREQ_PHONEBOOK_READRECORD:
109 return TRESP_PHONEBOOK_READRECORD;
110 case TREQ_PHONEBOOK_UPDATERECORD:
111 return TRESP_PHONEBOOK_UPDATERECORD;
112 case TREQ_PHONEBOOK_DELETERECORD:
113 return TRESP_PHONEBOOK_DELETERECORD;
115 return TRESP_UNKNOWN;
119 static enum tel_phonebook_ton _find_num_plan(int number_plan)
121 enum tel_phonebook_ton result;
122 dbg("number_plan : 0x%04x", number_plan);
124 if(number_plan & NUM_PLAN_INTERNATIONAL) {
125 result = PB_TON_INTERNATIONAL;
128 result = PB_TON_UNKNOWN;
130 dbg("result : %d", result);
134 static char* _get_phonebook_type(enum tel_phonebook_type pb_type)
136 char *phonebook_type = NULL;
137 dbg(" Function entry ");
138 dbg("pb_type = %d", pb_type);
140 phonebook_type = (char*)calloc(sizeof(char), VAL_FIVE);
141 if(NULL == phonebook_type) {
142 err("Memory allcoation failed");
143 return phonebook_type;
149 phonebook_type = "FD";
154 phonebook_type = "SM";
157 phonebook_type = "SN";
160 phonebook_type = "AP";
163 dbg("Invalid pb_type [%02x]", pb_type);
164 free(phonebook_type);
165 phonebook_type = NULL;
168 dbg(" Function exit");
169 return phonebook_type;
172 static enum tel_phonebook_type _get_phonebook_enum(const char* pb_type)
174 enum tel_phonebook_type phonebook_type = PB_TYPE_UNKNOWNN;
175 dbg(" Function entry ");
176 dbg("pb_type = %s", pb_type);
178 if(strcmp("FD", pb_type) == VAL_ZERO) {
179 phonebook_type = PB_TYPE_FDN;
181 else if(strcmp("SM", pb_type) == VAL_ZERO) {
182 phonebook_type = PB_TYPE_ADN;
184 else if(strcmp("SN", pb_type) == VAL_ZERO) {
185 phonebook_type = PB_TYPE_SDN;
187 else if(strcmp("AP", pb_type) == VAL_ZERO) {
188 phonebook_type = PB_TYPE_USIM;
191 dbg(" Function exit");
192 return phonebook_type;
195 static gboolean on_event_phonebook_status(CoreObject *o, const void *event_info, void *user_data)
197 dbg("Phonebook init received from modem");
199 _get_support_list(o);
204 static void _on_response_select(TcorePending *p, int data_len, const void *data, void *user_data)
206 const TcoreATResponse *resp = data;
207 UserRequest *ur = NULL;
208 enum tcore_request_command req_cmd = TREQ_UNKNOWN;
209 int *selected_pb = user_data;
211 dbg(" Function entry ");
213 ur = tcore_pending_ref_user_request(p);
215 dbg("error - current ur is NULL");
219 req_cmd = tcore_user_request_get_command(ur);
220 dbg("origin treq command [%x]", req_cmd);
222 if(resp->success > VAL_ZERO) {
223 CoreObject *o = NULL;
224 o = tcore_pending_ref_core_object(p);
227 tcore_phonebook_set_selected_type(o, *selected_pb);
230 case TREQ_PHONEBOOK_GETCOUNT:
233 case TREQ_PHONEBOOK_GETMETAINFO:
236 case TREQ_PHONEBOOK_GETUSIMINFO:
237 s_get_usim_info(o, ur);
239 case TREQ_PHONEBOOK_READRECORD:
240 s_read_record(o, ur);
242 case TREQ_PHONEBOOK_UPDATERECORD:
243 s_update_record(o, ur);
245 case TREQ_PHONEBOOK_DELETERECORD:
246 s_delete_record(o, ur);
249 dbg("not handled treq cmd[%d]", req_cmd);
258 case TREQ_PHONEBOOK_GETCOUNT:
260 struct tresp_phonebook_get_count resp_getcount;
261 dbg("error TREQ_PHONEBOOK_GETCOUNT");
262 memset(&resp_getcount, 0x00, sizeof(struct tresp_phonebook_get_count));
263 resp_getcount.result = PB_FAIL;
264 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_phonebook_get_count), &resp_getcount);
267 case TREQ_PHONEBOOK_GETMETAINFO:
269 dbg("error TREQ_PHONEBOOK_GETMETAINFO");
272 case TREQ_PHONEBOOK_GETUSIMINFO:
274 dbg("error TREQ_PHONEBOOK_GETUSIMINFO");
277 case TREQ_PHONEBOOK_READRECORD:
279 struct tresp_phonebook_read_record resp_readrecord;
280 dbg("error TREQ_PHONEBOOK_READRECORD");
282 memset(&resp_readrecord, 0x00, sizeof(struct tresp_phonebook_read_record));
283 resp_readrecord.result = PB_FAIL;
284 resp_readrecord.phonebook_type = *selected_pb;
285 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_phonebook_read_record), &resp_readrecord);
288 case TREQ_PHONEBOOK_UPDATERECORD:
290 struct tresp_phonebook_update_record resp_updaterecord;
291 dbg("error TREQ_PHONEBOOK_UPDATERECORD");
292 memset(&resp_updaterecord, 0x00, sizeof(struct tresp_phonebook_update_record));
293 resp_updaterecord.result = PB_FAIL;
294 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_phonebook_update_record), &resp_updaterecord);
297 case TREQ_PHONEBOOK_DELETERECORD:
299 struct tresp_phonebook_delete_record resp_deleterecord;
300 dbg("error TREQ_PHONEBOOK_DELETERECORD");
301 memset(&resp_deleterecord, 0x00, sizeof(struct tresp_phonebook_delete_record));
302 resp_deleterecord.result = PB_FAIL;
303 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_phonebook_delete_record), &resp_deleterecord);
307 dbg("not handled treq cmd[%d]", req_cmd);
315 dbg(" Function exit");
318 static void _on_response_getindexlist(TcorePending *p, int data_len, const void *data, void *user_data)
320 const TcoreATResponse *resp = data;
321 UserRequest *ur = NULL;
322 struct tresp_phonebook_read_record resp_readrecord;
323 int *selected_pb = user_data;
329 dbg(" Function entry ");
331 ur = tcore_pending_ref_user_request(p);
333 dbg("error - current ur is NULL");
336 memset(&resp_readrecord, 0x00, sizeof(struct tresp_phonebook_read_record));
337 resp_readrecord.result = PB_FAIL;
338 resp_readrecord.phonebook_type = *selected_pb;
340 if(resp->success > 0)
342 CoreObject *o = NULL;
343 o = tcore_pending_ref_core_object(p);
346 tcore_phonebook_set_selected_type(o, *selected_pb);
348 total_lines = g_slist_length(resp->lines);
349 dbg("Total number of PB entry %d\n", total_lines);
350 if (total_lines < 1) {
351 msg("invalid message");
355 __pbindex.indexlist = (int*)malloc(__pbindex.used_count * sizeof(int));
356 if(__pbindex.indexlist == NULL){
357 dbg("Failed to allocate memory");
361 resp_readrecord.result = PB_SUCCESS;
362 for (count = 0; count < total_lines; count++) {
363 /* Take each line response at a time & parse it */
364 line = tcore_at_tok_nth(resp->lines, count);
365 tokens = tcore_at_tok_new(line);
366 __pbindex.indexlist[count] = atoi(g_slist_nth_data(tokens, 0));
367 dbg("__pbindex.indexlist[%d] = %d", count, __pbindex.indexlist[count]);
368 tcore_at_tok_free(tokens);
371 __pbindex.indexlist_populated = 1;
372 s_read_record(o, ur);
381 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_phonebook_read_record), &resp_readrecord);
385 dbg(" Function exit");
388 static void on_response_get_count(TcorePending *p, int data_len, const void *data, void *user_data)
390 const TcoreATResponse *resp = data;
391 UserRequest *ur = NULL;
393 const char *temp = NULL;
394 struct tresp_phonebook_get_count res;
396 dbg(" Function entry ");
398 ur = tcore_pending_ref_user_request(p);
400 dbg("error - current ur is NULL");
404 memset(&res, 0x00, sizeof(struct tresp_phonebook_get_count));
405 res.result = PB_FAIL;
407 if(resp->success > VAL_ZERO) {
410 temp = (const char*)resp->lines->data;
411 tokens = tcore_at_tok_new(temp);
412 if (g_slist_length(tokens) < VAL_THREE) {
413 //No of tokens must be three. We cannot proceed without used and total count.
414 msg("invalid message");
418 res.result = PB_SUCCESS;
420 temp = (const char*)g_slist_nth_data(tokens, VAL_ZERO);
421 pbtype = util_removeQuotes((void*)temp);
422 res.type = _get_phonebook_enum(pbtype);
424 if(NULL != g_slist_nth_data(tokens, VAL_ONE)){
425 res.used_count = atoi(g_slist_nth_data(tokens, VAL_ONE));
426 __pbindex.used_count = res.used_count;
427 dbg("used_count %d", __pbindex.used_count);
430 if(NULL != g_slist_nth_data(tokens, VAL_TWO)){
431 res.total_count = atoi(g_slist_nth_data(tokens, VAL_TWO));
432 __pbindex.total_count = res.total_count;
434 dbg("used count = %d, total count= %d", res.used_count, res.total_count);
442 tcore_at_tok_free(tokens);
443 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_phonebook_get_count), &res);
444 dbg(" Function exit");
447 static void on_response_get_info(TcorePending *p, int data_len, const void *data, void *user_data)
449 struct tresp_phonebook_get_info res = {0,};
450 const TcoreATResponse *resp = data;
451 UserRequest *ur = NULL;
454 int *selected_pb = (int*)user_data;
456 dbg(" Function entry ");
458 ur = tcore_pending_ref_user_request(p);
460 dbg("error - current ur is NULL");
464 memset(&res, 0x00, sizeof(struct tresp_phonebook_get_info));
465 res.result = PB_FAIL;
466 res.type = *selected_pb;
468 if(resp->success > VAL_ZERO) {
471 line = (const char*)resp->lines->data;
472 tokens = tcore_at_tok_new(line);
473 if (g_slist_length(tokens) < VAL_ONE) {
474 msg("invalid message");
478 res.result = PB_SUCCESS;
480 res.number_length_max = atoi(g_slist_nth_data(tokens, VAL_ZERO));
481 res.text_length_max = atoi(g_slist_nth_data(tokens, VAL_ONE));
482 dbg("number_length_max %d text_length_max %d",res.number_length_max,res.text_length_max);
488 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_phonebook_get_info), &res);
491 tcore_at_tok_free(tokens);
492 dbg(" Function exit");
496 static void on_response_read_record(TcorePending *p, int data_len, const void *data, void *user_data)
498 const TcoreATResponse *resp = data;
499 UserRequest *ur = NULL;
502 struct tresp_phonebook_read_record res;
503 int num_len = VAL_ZERO;
504 int name_len = VAL_ZERO;
505 int num_plan = VAL_ZERO;
508 int *selected_pb = (int*)user_data;
510 dbg(" Function entry ");
512 ur = tcore_pending_ref_user_request(p);
514 dbg("error - current ur is NULL");
518 memset(&res, 0x00, sizeof(struct tresp_phonebook_read_record));
519 res.result = PB_FAIL;
520 res.phonebook_type = *selected_pb;
522 if(resp->success > VAL_ZERO) {
525 line = (const char*)resp->lines->data;
526 tokens = tcore_at_tok_new(line);
527 if (g_slist_length(tokens) < VAL_ONE) {
528 msg("invalid message");
533 res.result = PB_SUCCESS;
534 res.index = atoi(g_slist_nth_data(tokens, 0));
535 __pbindex.current_index++;
536 if(__pbindex.current_index >= __pbindex.used_count){
541 dbg("__pbindex.current_index %d", __pbindex.current_index);
542 res.next_index = __pbindex.indexlist[__pbindex.current_index];
544 num_plan = atoi(g_slist_nth_data(tokens, 2));
545 res.ton = _find_num_plan(num_plan);
547 /*Remove the quotes("") from the number string*/
548 temp = g_slist_nth_data(tokens, 1);
549 member = util_removeQuotes((void*)temp);
550 memcpy(res.number, member, strlen(member));
551 dbg("number %s - %d", res.number, strlen((const char*)res.number));
555 /*Remove the quotes("") from the name string*/
556 temp = g_slist_nth_data(tokens, 3);
557 member = util_removeQuotes((void*)temp);
558 memcpy(res.name, member, strlen(member));
559 dbg("name %s - %d", res.name, strlen((const char*)res.name));
562 res.dcs = PB_TEXT_ASCII;
563 res.name_len = strlen((const char*)res.name);
564 if(NULL != g_slist_nth_data(tokens, VAL_FOUR)) {
565 if(atoi(g_slist_nth_data(tokens, VAL_FOUR)) == VAL_ZERO) {
566 dbg("phonebook entry not hidden");
569 dbg("phonebook entry hidden");
573 if(NULL != g_slist_nth_data(tokens, VAL_SIX)){
574 num_len = strlen(g_slist_nth_data(tokens, VAL_SIX));
575 snprintf((char *)res.anr1, num_len+1, "%s", (char*)g_slist_nth_data(tokens, VAL_SIX));
578 if(NULL != g_slist_nth_data(tokens, VAL_SEVEN)){
579 num_plan = atoi(g_slist_nth_data(tokens, VAL_SEVEN));
580 res.anr1_ton = _find_num_plan(num_plan);
583 if(NULL != g_slist_nth_data(tokens, VAL_NINE)){
584 name_len = strlen(g_slist_nth_data(tokens, VAL_NINE));
585 memcpy(res.email1, g_slist_nth_data(tokens, VAL_NINE), name_len);
593 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_phonebook_read_record), &res);
596 tcore_at_tok_free(tokens);
597 dbg(" Function exit");
601 static void on_response_update_record(TcorePending *p, int data_len, const void *data, void *user_data)
603 const TcoreATResponse *resp = data;
604 UserRequest *ur = NULL;
605 struct tresp_phonebook_update_record res;
606 dbg(" Function entry ");
608 if(resp->success > VAL_ZERO) {
610 res.result = PB_SUCCESS;
614 res.result = PB_FAIL;
617 ur = tcore_pending_ref_user_request(p);
619 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_phonebook_update_record),
623 dbg("error - current ur is NULL");
625 dbg(" Function exit");
628 static void on_response_delete_record(TcorePending *p, int data_len, const void *data, void *user_data)
630 const TcoreATResponse *resp = data;
631 UserRequest *ur = NULL;
632 struct tresp_phonebook_delete_record res;
634 dbg(" Function entry ");
636 if(resp->success > VAL_ZERO) {
638 res.result = PB_SUCCESS;
642 res.result = PB_FAIL;
645 ur = tcore_pending_ref_user_request(p);
647 tcore_user_request_send_response(ur, _find_resp_command(ur), sizeof(struct tresp_phonebook_delete_record), &res);
650 dbg("error - current ur is NULL");
652 dbg(" Function exit");
655 static void _response_get_support_list(TcorePending *p, int data_len, const void *data, void *user_data)
657 const TcoreATResponse *resp = data;
663 struct tnoti_phonebook_status noti_data = {0,};
665 dbg(" Function entry ");
667 o = tcore_pending_ref_core_object(p);
669 dbg("error - core object is null");
673 noti_data.b_init = FALSE;
675 if(resp->success > VAL_ZERO) {
678 line = (const char*)resp->lines->data;
679 tokens = tcore_at_tok_new(line);
680 if (g_slist_length(tokens) < VAL_ONE) {
681 msg("invalid message");
686 temp = (char*)g_slist_nth_data(tokens, VAL_ZERO);
687 pbtype = strtok(temp, "(,)");
688 while(pbtype != NULL) {
689 temp = util_removeQuotes((void*)pbtype);
690 dbg("pbtype %s", temp);
691 if (VAL_ZERO == strcmp(temp, "FD")) {
692 dbg("SIM fixed-dialing phonebook");
693 noti_data.support_list.b_fdn = VAL_ONE;
695 else if (VAL_ZERO == strcmp(temp, "SN")) {
696 dbg("Service Dialing Number");
697 noti_data.support_list.b_sdn = VAL_ONE;
699 else if (VAL_ZERO == strcmp(temp, "SM")) {
700 dbg("2G SIM ADN phonebook");
701 noti_data.support_list.b_adn = VAL_ONE;
703 else if (VAL_ZERO == strcmp(temp, "LD")) {
704 dbg("SIM/UICC last-dialling-phonebook");
706 else if (VAL_ZERO == strcmp(temp, "ON")) {
707 dbg("SIM (or MT) own numbers (MSISDNs) list");
709 else if (VAL_ZERO == strcmp(temp, "BL")) {
710 dbg("Blacklist phonebook");
712 else if (VAL_ZERO == strcmp(temp, "EC")) {
713 dbg("SIM emergency-call-codes phonebook");
715 else if (VAL_ZERO == strcmp(temp, "AP")) {
716 dbg("Selected application phonebook");
718 else if (VAL_ZERO == strcmp(temp, "BN")) {
719 dbg("SIM barred-dialling-number");
721 pbtype = strtok (NULL, "(,)");
725 noti_data.b_init = TRUE;
726 tcore_phonebook_set_support_list(o, ¬i_data.support_list);
727 tcore_phonebook_set_status(o, noti_data.b_init);
731 tcore_phonebook_set_status(o, noti_data.b_init);
734 tcore_server_send_notification(tcore_plugin_ref_server(tcore_object_ref_plugin(o)), o, TNOTI_PHONEBOOK_STATUS,
735 sizeof(struct tnoti_phonebook_status), ¬i_data);
736 tcore_at_tok_free(tokens);
737 dbg(" Function exit");
740 static TReturn _get_support_list(CoreObject *o)
742 TcoreHal *hal = NULL;
743 TcoreATRequest *req = NULL;
744 TcorePending *pending = NULL;
745 char *cmd_str = NULL;
747 dbg(" Function entry ");
750 return TCORE_RETURN_EINVAL;
753 hal = tcore_object_get_hal(o);
754 pending = tcore_pending_new(o, VAL_ZERO);
756 cmd_str = g_strdup_printf("AT+CPBS=?");
757 req = tcore_at_request_new(cmd_str, "+CPBS:", TCORE_AT_SINGLELINE);
758 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
760 tcore_pending_set_request_data(pending, VAL_ZERO, req);
761 tcore_pending_set_response_callback(pending, _response_get_support_list, NULL);
763 tcore_hal_send_request(hal, pending);
766 dbg(" Function exit");
767 return TCORE_RETURN_SUCCESS;
770 static TReturn _select(CoreObject *o, UserRequest *ur, enum tel_phonebook_type pbt)
772 TcoreHal *hal = NULL;
773 TcoreATRequest *req = NULL;
774 TcorePending *pending = NULL;
775 char *cmd_str = NULL;
776 const struct treq_phonebook_get_count *req_data;
778 char *phonebook_type = NULL;
779 UserRequest *ur_dup = NULL;
781 dbg(" Function entry ");
784 return TCORE_RETURN_EINVAL;
786 req_data = tcore_user_request_ref_data(ur, NULL);
787 ur_dup = tcore_user_request_ref(ur);
789 phonebook_type = (char*)_get_phonebook_type(req_data->phonebook_type);
790 if(NULL == phonebook_type){
791 err("phonebook_type is NULL");
792 return TCORE_RETURN_FAILURE;
795 pb_type = calloc(sizeof(enum tel_phonebook_type),VAL_ONE);
796 if(pb_type == NULL) {
797 err("Failed to allocate memory");
798 return TCORE_RETURN_FAILURE;
802 cmd_str = g_strdup_printf("AT+CPBS=\"%s\"", phonebook_type);
803 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_NO_RESULT);
804 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
806 hal = tcore_object_get_hal(o);
807 pending = tcore_pending_new(o, VAL_ZERO);
808 tcore_pending_set_request_data(pending, VAL_ZERO, req);
809 tcore_pending_set_response_callback(pending, _on_response_select, (void*)pb_type);
810 tcore_pending_link_user_request(pending, ur_dup);
812 tcore_hal_send_request(hal, pending);
814 free(phonebook_type);
816 dbg(" Function exit");
817 return TCORE_RETURN_SUCCESS;
820 static TReturn _getindexlist(CoreObject *o, UserRequest *ur, enum tel_phonebook_type pbt)
822 TcoreHal *hal = NULL;
823 TcoreATRequest *req = NULL;
824 TcorePending *pending = NULL;
825 char *cmd_str = NULL;
826 const struct treq_phonebook_get_count *req_data;
829 UserRequest *ur_dup = NULL;
831 dbg(" Function entry ");
834 return TCORE_RETURN_EINVAL;
836 pb_type = calloc(sizeof(enum tel_phonebook_type),1);
837 if(pb_type == NULL) {
838 err("Failed to allocate memory");
839 return TCORE_RETURN_FAILURE;
843 req_data = tcore_user_request_ref_data(ur, NULL);
844 ur_dup = tcore_user_request_ref(ur);
846 cmd_str = g_strdup_printf("AT+CPBR=%d,%d", start_index, __pbindex.total_count);
847 req = tcore_at_request_new(cmd_str, "+CPBR:", TCORE_AT_MULTILINE);
848 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
850 hal = tcore_object_get_hal(o);
851 pending = tcore_pending_new(o, 0);
853 tcore_pending_set_request_data(pending, 0, req);
854 tcore_pending_set_response_callback(pending, _on_response_getindexlist, (void*)pb_type);
855 tcore_pending_link_user_request(pending, ur_dup);
856 tcore_hal_send_request(hal, pending);
859 dbg(" Function exit");
860 return TCORE_RETURN_SUCCESS;
863 static TReturn s_get_count(CoreObject *o, UserRequest *ur)
865 TcoreHal *hal = NULL;
866 TcoreATRequest *req = NULL;
867 TcorePending *pending = NULL;
868 char *cmd_str = NULL;
869 const struct treq_phonebook_get_count *req_data = NULL;
870 enum tel_phonebook_type pbt = PB_TYPE_UNKNOWNN;
872 dbg("Function Entry");
874 return TCORE_RETURN_EINVAL;
876 req_data = tcore_user_request_ref_data(ur, NULL);
877 pbt = tcore_phonebook_get_selected_type(o);
878 if (req_data->phonebook_type != pbt) {
879 dbg("req pb[%d] is different with tcore pb[%d]", req_data->phonebook_type, pbt);
880 return _select(o, ur, req_data->phonebook_type);
883 cmd_str = g_strdup_printf("AT+CPBS?");
884 req = tcore_at_request_new(cmd_str, "+CPBS:", TCORE_AT_SINGLELINE);
885 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
887 hal = tcore_object_get_hal(o);
888 pending = tcore_pending_new(o, VAL_ZERO);
890 tcore_pending_set_request_data(pending, VAL_ZERO, req);
891 tcore_pending_set_response_callback(pending, on_response_get_count, hal);
892 tcore_pending_link_user_request(pending, ur);
894 tcore_hal_send_request(hal, pending);
897 dbg("Function exit");
898 return TCORE_RETURN_SUCCESS;
901 static TReturn s_get_info(CoreObject *o, UserRequest *ur)
903 TcoreHal *hal = NULL;
904 TcoreATRequest *req = NULL;
905 TcorePending *pending = NULL;
906 char *cmd_str = NULL;
907 const struct treq_phonebook_get_info *req_data = NULL;
908 enum tel_phonebook_type pbt = PB_TYPE_UNKNOWNN;
911 dbg(" Function entry ");
914 return TCORE_RETURN_EINVAL;
916 req_data = tcore_user_request_ref_data(ur, NULL);
917 pbt = tcore_phonebook_get_selected_type(o);
918 if (req_data->phonebook_type != pbt) {
919 dbg("req pb[%d] is different with tcore pb[%d]", req_data->phonebook_type, pbt);
920 return _select(o, ur, req_data->phonebook_type);
923 pb_type = calloc(sizeof(enum tel_phonebook_type),VAL_ONE);
924 if(pb_type == NULL) {
925 err("Failed to allocate memory");
926 return TCORE_RETURN_FAILURE;
929 dbg("pb_type %d", *pb_type);
931 cmd_str = g_strdup_printf("AT+CPBF=?");
932 req = tcore_at_request_new(cmd_str, "+CPBF:", TCORE_AT_SINGLELINE);
933 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
935 hal = tcore_object_get_hal(o);
936 pending = tcore_pending_new(o, VAL_ZERO);
938 tcore_pending_set_request_data(pending, VAL_ZERO, req);
939 tcore_pending_set_response_callback(pending, on_response_get_info, (void*)pb_type);
940 tcore_pending_link_user_request(pending, ur);
942 tcore_hal_send_request(hal, pending);
945 dbg(" Function exit");
946 return TCORE_RETURN_SUCCESS;
950 static TReturn s_get_usim_info(CoreObject *o, UserRequest *ur)
952 dbg("NOT IMPLEMENTED");
954 return TCORE_RETURN_SUCCESS;
957 static TReturn s_read_record(CoreObject *o, UserRequest *ur)
960 TcoreATRequest *req = NULL;
961 TcorePending *pending = NULL;
962 char *cmd_str = NULL;
963 const struct treq_phonebook_read_record *req_data = NULL;
964 enum tel_phonebook_type pbt = PB_TYPE_UNKNOWNN;
967 dbg(" Function entry ");
970 return TCORE_RETURN_EINVAL;
972 req_data = tcore_user_request_ref_data(ur, NULL);
973 pbt = tcore_phonebook_get_selected_type(o);
974 if (req_data->phonebook_type != pbt) {
975 dbg("req pb[%d] is different with tcore pb[%d]", req_data->phonebook_type, pbt);
976 return _select(o, ur, req_data->phonebook_type);
978 if(!__pbindex.indexlist_populated){
979 return _getindexlist(o, ur, req_data->phonebook_type);
981 pb_type = calloc(sizeof(enum tel_phonebook_type),VAL_ONE);
982 if(pb_type == NULL) {
983 err("Failed to allocate memory");
984 return TCORE_RETURN_FAILURE;
987 dbg("pb_type %d", *pb_type);
988 cmd_str = g_strdup_printf("AT+CPBR=%d", __pbindex.indexlist[__pbindex.current_index]);
989 req = tcore_at_request_new(cmd_str, "+CPBR", TCORE_AT_MULTILINE);
990 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
992 hal = tcore_object_get_hal(o);
993 pending = tcore_pending_new(o, VAL_ZERO);
995 tcore_pending_set_request_data(pending, VAL_ZERO, req);
996 tcore_pending_set_response_callback(pending, on_response_read_record, (void*)pb_type);
997 tcore_pending_link_user_request(pending, ur);
999 tcore_hal_send_request(hal, pending);
1002 dbg(" Function exit");
1003 return TCORE_RETURN_SUCCESS;
1006 static TReturn s_update_record(CoreObject *o, UserRequest *ur)
1008 TcoreHal *hal = NULL;
1009 TcoreATRequest *req = NULL;
1010 TcorePending *pending = NULL;
1011 char *cmd_str = NULL;
1012 const struct treq_phonebook_update_record *req_data = NULL;
1013 enum tel_phonebook_type pbt = PB_TYPE_UNKNOWNN;
1015 dbg(" Function entry ");
1018 return TCORE_RETURN_EINVAL;
1020 req_data = tcore_user_request_ref_data(ur, NULL);
1021 pbt = tcore_phonebook_get_selected_type(o);
1022 if (req_data->phonebook_type != pbt) {
1023 dbg("req pb[%d] is different with tcore pb[%d]", req_data->phonebook_type, pbt);
1024 return _select(o, ur, req_data->phonebook_type);
1027 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);
1028 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
1029 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1031 hal = tcore_object_get_hal(o);
1032 pending = tcore_pending_new(o, VAL_ZERO);
1034 tcore_pending_set_request_data(pending, VAL_ZERO, req);
1035 tcore_pending_set_response_callback(pending, on_response_update_record, hal);
1036 tcore_pending_link_user_request(pending, ur);
1038 tcore_hal_send_request(hal, pending);
1041 dbg(" Function exit");
1042 return TCORE_RETURN_SUCCESS;
1045 static TReturn s_delete_record(CoreObject *o, UserRequest *ur)
1047 TcoreHal *hal = NULL;
1048 TcoreATRequest *req = NULL;
1049 TcorePending *pending = NULL;
1050 char *cmd_str = NULL;
1051 const struct treq_phonebook_delete_record *req_data;
1052 enum tel_phonebook_type pbt = PB_TYPE_UNKNOWNN;
1054 dbg(" Function entry ");
1057 return TCORE_RETURN_EINVAL;
1059 req_data = tcore_user_request_ref_data(ur, NULL);
1060 pbt = tcore_phonebook_get_selected_type(o);
1061 if (req_data->phonebook_type != pbt) {
1062 dbg("req pb[%d] is different with tcore pb[%d]", req_data->phonebook_type, pbt);
1063 return _select(o, ur, req_data->phonebook_type);
1066 cmd_str = g_strdup_printf("AT+CPBW=%d", req_data->index);
1067 req = tcore_at_request_new(cmd_str, NULL, TCORE_AT_SINGLELINE);
1068 dbg("cmd : %s, prefix(if any) :%s, cmd_len : %d", req->cmd, req->prefix, strlen(req->cmd));
1070 hal = tcore_object_get_hal(o);
1071 pending = tcore_pending_new(o, VAL_ZERO);
1073 tcore_pending_set_request_data(pending, VAL_ZERO, req);
1074 tcore_pending_set_response_callback(pending, on_response_delete_record, hal);
1075 tcore_pending_link_user_request(pending, ur);
1077 tcore_hal_send_request(hal, pending);
1080 dbg(" Function exit");
1081 return TCORE_RETURN_SUCCESS;
1084 static struct tcore_phonebook_operations phonebook_ops = {
1085 .get_count = s_get_count,
1086 .get_info = s_get_info,
1087 .get_usim_info = s_get_usim_info,
1088 .read_record = s_read_record,
1089 .update_record = s_update_record,
1090 .delete_record = s_delete_record,
1093 gboolean s_phonebook_init(TcorePlugin *cp, CoreObject *co_phonebook)
1097 tcore_phonebook_override_ops(co_phonebook, &phonebook_ops);
1099 tcore_object_override_callback(co_phonebook, "+PBREADY", on_event_phonebook_status, NULL);
1106 void s_phonebook_exit(TcorePlugin *cp, CoreObject *co_phonebook)