4 * Copyright (c) 2013 Samsung Electronics Co. Ltd. All rights reserved.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
28 #include <core_object.h>
34 #include <co_phonebook.h>
37 #include "imc_phonebook.h"
38 #include "imc_common.h"
41 GSList *used_index_fdn;
42 gboolean used_index_fdn_valid;
44 GSList *used_index_adn;
45 gboolean used_index_adn_valid;
47 GSList *used_index_sdn;
48 gboolean used_index_sdn_valid;
50 GSList *used_index_usim;
51 gboolean used_index_usim_valid;
54 static gboolean __imc_phonebook_get_sim_type(CoreObject *co_pb,
55 TelSimCardType *sim_type)
59 tcore_check_return_value_assert(co_pb != NULL, FALSE);
60 tcore_check_return_value_assert(sim_type != NULL, FALSE);
62 plugin = tcore_object_ref_plugin(co_pb);
63 co_sim = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SIM);
64 return tcore_sim_get_type(co_sim, sim_type);
67 static gboolean __imc_phonebook_get_pb_type_str(TelPbType pb_type,
70 tcore_check_return_value_assert(req_type_str != NULL, FALSE);
74 *req_type_str = g_strdup("FD");
78 *req_type_str = g_strdup("SM");
81 *req_type_str = g_strdup("SN");
88 static gboolean __imc_phonebook_check_and_select_type(CoreObject *co,
89 TelPbType req_type, gchar **set_pb_cmd)
91 TelPbList *support_list;
92 TelPbType current_type;
94 /* Check whether pb_type is supported or not */
95 tcore_phonebook_get_support_list(co, &support_list);
96 if ((req_type == TEL_PB_FDN && support_list->fdn == FALSE)
97 || (req_type == TEL_PB_ADN && support_list->adn == FALSE)
98 || (req_type == TEL_PB_SDN && support_list->sdn == FALSE)
99 || (req_type == TEL_PB_USIM && support_list->usim == FALSE)) {
100 err("Not supported pb_type");
101 g_free(support_list);
104 g_free(support_list);
106 /* Check Current type & Request type */
107 tcore_phonebook_get_selected_type(co, ¤t_type);
108 if (current_type != req_type) {
109 gchar *req_type_str = NULL;
110 __imc_phonebook_get_pb_type_str(req_type, &req_type_str);
111 dbg("Add AT-Command to change [%s] Type", req_type_str);
112 /* Select Phonebook type */
113 *set_pb_cmd = g_strdup_printf("AT+CPBS=\"%s\";", req_type_str);
115 *set_pb_cmd = g_strdup_printf("AT");
121 static gboolean __imc_phonebook_get_index_list_by_type(CoreObject *co,
122 TelPbType pb_type, GSList **list)
124 PrivateInfo *private_info = tcore_object_ref_user_data(co);
125 tcore_check_return_value_assert(private_info != NULL, FALSE);
129 if (private_info->used_index_fdn_valid != TRUE)
131 *list = private_info->used_index_fdn;
134 if (private_info->used_index_adn_valid != TRUE)
136 *list = private_info->used_index_adn;
139 if (private_info->used_index_sdn_valid != TRUE)
141 *list = private_info->used_index_sdn;
144 if (private_info->used_index_usim_valid != TRUE)
146 *list = private_info->used_index_usim;
153 static void __imc_phonebook_check_used_index(CoreObject *co,
154 TelPbType pb_type, guint req_index, guint *used_index)
158 /* Get used_index list by req_type */
159 if (__imc_phonebook_get_index_list_by_type(co, pb_type, &list) != TRUE) {
160 err("used_index list is NOT valid");
161 *used_index = req_index;
165 /* Use first used_index in case req_index is not used */
166 *used_index = (guint)g_slist_nth_data(list, 0);
168 if ((guint)list->data == req_index) {
169 /* req_index is equal to one of used_index */
170 *used_index = req_index;
173 list = g_slist_next(list);
177 static gint __imc_phonebook_compare_index(gconstpointer a, gconstpointer b)
179 guint index1 = (guint)a;
180 guint index2 = (guint)b;
182 return index1 - index2;
185 static void on_response_imc_phonebook_get_used_index(TcorePending *p,
186 guint data_len, const void *data, void *user_data)
188 const TcoreAtResponse *at_resp = data;
189 ImcRespCbData *resp_cb_data = user_data;
190 CoreObject *co = tcore_pending_ref_core_object(p);
191 tcore_check_return_assert(at_resp != NULL);
192 tcore_check_return_assert(resp_cb_data != NULL);
196 if (at_resp->success != TRUE) {
203 if (at_resp->lines == NULL) {
204 err("at_resp->lines is NULL");
206 GSList *lines = at_resp->lines;
208 GSList **list = NULL;
209 PrivateInfo *private_info = tcore_object_ref_user_data(co);
210 tcore_check_return_assert(private_info != NULL);
212 /* Select used_index_list by req_type */
213 req_type = (TelPbType *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
216 list = &private_info->used_index_fdn;
217 private_info->used_index_fdn_valid = TRUE;
220 list = &private_info->used_index_adn;
221 private_info->used_index_adn_valid = TRUE;
224 list = &private_info->used_index_sdn;
225 private_info->used_index_sdn_valid = TRUE;
228 list = &private_info->used_index_usim;
229 private_info->used_index_usim_valid = TRUE;
234 const gchar *line = lines->data;
235 GSList *tokens = NULL;
238 dbg("Line: [%s]", line);
240 tokens = tcore_at_tok_new(line);
241 if (tokens == NULL) {
242 err("tokens is NULL");
246 /* Get only used_index */
247 temp = g_slist_nth_data(tokens, 0);
249 /* Insert used_index in PrivateInfo sorted in ascending */
250 *list = g_slist_insert_sorted(*list, (gpointer)atoi(temp),
251 __imc_phonebook_compare_index);
253 tcore_at_tok_free(tokens);
256 lines = g_slist_next(lines);
258 dbg("pb_type: [%d], used_index Length: [%d]",
259 *req_type, g_slist_length(*list));
263 static void __imc_phonebook_get_used_index(CoreObject *co, TelPbType pb_type, guint max_index)
266 ImcRespCbData *resp_cb_data;
267 TelReturn ret = TEL_RETURN_FAILURE;
272 at_cmd = g_strdup_printf("AT+CPBR=1,%d", max_index);
274 /* Response callback data */
275 resp_cb_data = imc_create_resp_cb_data(NULL, NULL,
276 (void *)&pb_type, sizeof(TelPbType));
278 /* Send Request to Modem */
279 ret = tcore_at_prepare_and_send_request(co,
281 TCORE_AT_COMMAND_TYPE_MULTILINE,
283 on_response_imc_phonebook_get_used_index, resp_cb_data,
284 on_send_imc_request, NULL);
285 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get Used Index");
291 static void on_response_imc_phonebook_get_support_list(TcorePending *p,
292 guint data_len, const void *data, void *user_data)
294 const TcoreAtResponse *at_resp = data;
295 CoreObject *co = tcore_pending_ref_core_object(p);
296 TelPbInitInfo init_info = {0, };
297 tcore_check_return_assert(at_resp != NULL);
301 if (at_resp->success != TRUE) {
308 if (at_resp->lines == NULL) {
309 err("at_resp->lines is NULL");
312 const gchar *line = (const gchar *)at_resp->lines->data;
313 GSList *tokens = NULL;
317 dbg("Line: [%s]", line);
319 tokens = tcore_at_tok_new(line);
320 if (tokens == NULL) {
321 err("tokens is NULL");
325 pb_type_list = g_slist_nth_data(tokens, 0);
326 pb_type = strtok(pb_type_list, "(,)");
328 pb_type = tcore_at_tok_extract(pb_type);
329 if (g_strcmp0(pb_type, "FD") == 0) {
330 init_info.pb_list.fdn = TRUE;
331 } else if (g_strcmp0(pb_type, "SN") == 0) {
332 init_info.pb_list.sdn = TRUE;
333 } else if (g_strcmp0(pb_type, "SM") == 0) {
334 TelSimCardType sim_type;
335 __imc_phonebook_get_sim_type(co, &sim_type);
336 if (sim_type == TEL_SIM_CARD_TYPE_USIM)
337 init_info.pb_list.usim = TRUE;
339 init_info.pb_list.adn = TRUE;
342 /* Get Next pb_type */
343 pb_type = strtok(NULL, "(,)");
345 tcore_at_tok_free(tokens);
348 dbg("FDN: [%s], ADN: [%s], SDN: [%s], USIM: [%s]",
349 init_info.pb_list.fdn ? "TRUE" : "FALSE",
350 init_info.pb_list.adn ? "TRUE" : "FALSE",
351 init_info.pb_list.sdn ? "TRUE" : "FALSE",
352 init_info.pb_list.usim ? "TRUE" : "FALSE");
354 init_info.init_status = TRUE;
355 tcore_phonebook_set_support_list(co, &init_info.pb_list);
356 tcore_phonebook_set_status(co, init_info.init_status);
358 /* Send Notification */
359 tcore_object_send_notification(co,
360 TCORE_NOTIFICATION_PHONEBOOK_STATUS,
361 sizeof(TelPbInitInfo), &init_info);
365 * Operation - get_support_list
368 * AT-Command: AT+CPBS=?
371 * Success: (Single line)
372 * (list of supported <storage>s)
375 * +CME ERROR: <error>
377 static void __imc_phonebook_get_support_list(CoreObject *co)
383 /* Send Request to Modem */
384 ret = tcore_at_prepare_and_send_request(co,
385 "AT+CPBS=?", "+CPBS",
386 TCORE_AT_COMMAND_TYPE_SINGLELINE,
388 on_response_imc_phonebook_get_support_list, NULL,
389 on_send_imc_request, NULL);
390 IMC_CHECK_REQUEST_RET(ret, NULL, "Get Support List");
393 static gboolean on_notification_imc_phonebook_status(CoreObject *co,
394 const void *event_info, void *user_data)
396 dbg("Phonebook Init Completed");
398 /* Get Supported list */
399 __imc_phonebook_get_support_list(co);
404 static void on_response_imc_phonebook_get_info(TcorePending *p,
405 guint data_len, const void *data, void *user_data)
407 const TcoreAtResponse *at_resp = data;
408 ImcRespCbData *resp_cb_data = user_data;
409 CoreObject *co = tcore_pending_ref_core_object(p);
410 TelPbResult result = TEL_PB_RESULT_FAILURE;
411 TelPbInfo pb_info = {0, };
412 tcore_check_return_assert(at_resp != NULL);
413 tcore_check_return_assert(resp_cb_data != NULL);
417 if (at_resp->success != TRUE) {
424 if (at_resp->lines == NULL) {
425 err("at_resp->lines is NULL");
427 GSList *lines = at_resp->lines;
429 GSList *tokens = NULL;
431 gint used = 0, total = 0;
432 gint nlen = 0, tlen = 0;
434 PrivateInfo *private_info;
436 /* +CPBS: <storage>[,<used>][,total] */
437 line = g_slist_nth_data(lines, 0);
438 dbg("First Line: [%s]", line);
439 tokens = tcore_at_tok_new(line);
440 if (tokens == NULL) {
441 err("tokens is NULL");
446 temp = g_slist_nth_data(tokens, 1);
449 /* Get total_count */
450 temp = g_slist_nth_data(tokens, 2);
454 tcore_at_tok_free(tokens);
456 /* +CPBF: [<nlength>],[<tlength>],[<glength>],[<slength>],[<elength>] */
457 line = g_slist_nth_data(lines, 1);
458 dbg("Second Line: [%s]", line);
459 tokens = tcore_at_tok_new(line);
460 if (tokens == NULL) {
461 err("tokens is NULL");
465 /* Get number Length */
466 temp = g_slist_nth_data(tokens, 0);
469 /* Get text Length */
470 temp = g_slist_nth_data(tokens, 1);
474 /* Set Response Data */
475 req_type = (TelPbType *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
476 pb_info.pb_type = *req_type;
477 if (*req_type == TEL_PB_USIM) {
478 pb_info.info_u.usim.max_count = total;
479 pb_info.info_u.usim.used_count = used;
480 pb_info.info_u.usim.max_num_len = nlen;
481 pb_info.info_u.usim.max_text_len = tlen;
482 /* Get group name Length */
483 temp = g_slist_nth_data(tokens, 2);
485 pb_info.info_u.usim.max_gas_len = atoi(temp);
486 /* Get second name Length */
487 temp = g_slist_nth_data(tokens, 3);
489 pb_info.info_u.usim.max_sne_len = atoi(temp);
490 /* Get email Length */
491 temp = g_slist_nth_data(tokens, 4);
493 pb_info.info_u.usim.max_email_len = atoi(temp);
495 pb_info.info_u.sim.max_count = total;
496 pb_info.info_u.sim.used_count = used;
497 pb_info.info_u.sim.max_num_len = nlen;
498 pb_info.info_u.sim.max_text_len = tlen;
501 /* Set Request type in PrivateObject */
502 tcore_phonebook_set_selected_type(co, *req_type);
503 result = TEL_PB_RESULT_SUCCESS;
504 tcore_at_tok_free(tokens);
506 /* If don't have valid used_index, get used_index by req_type */
507 private_info = tcore_object_ref_user_data(co);
508 if ((*req_type == TEL_PB_FDN && private_info->used_index_fdn_valid == FALSE)
509 || (*req_type == TEL_PB_ADN && private_info->used_index_adn_valid == FALSE)
510 || (*req_type == TEL_PB_SDN && private_info->used_index_sdn_valid == FALSE)
511 || (*req_type == TEL_PB_USIM && private_info->used_index_usim_valid == FALSE))
512 __imc_phonebook_get_used_index(co, *req_type, total);
516 /* Invoke callback */
517 if (resp_cb_data->cb)
518 resp_cb_data->cb(co, (gint)result, &pb_info, resp_cb_data->cb_data);
520 /* Free callback data */
521 imc_destroy_resp_cb_data(resp_cb_data);
524 static void on_response_imc_phonebook_read_record(TcorePending *p,
525 guint data_len, const void *data, void *user_data)
527 const TcoreAtResponse *at_resp = data;
528 ImcRespCbData *resp_cb_data = user_data;
529 CoreObject *co = tcore_pending_ref_core_object(p);
530 TelPbResult result = TEL_PB_RESULT_FAILURE;
531 GSList *tokens = NULL;
532 gchar *index = NULL, *number = NULL, *name = NULL;
533 TelPbReadRecord read_record = {0, };
534 tcore_check_return_assert(at_resp != NULL);
535 tcore_check_return_assert(resp_cb_data != NULL);
539 if (at_resp->success != TRUE) {
546 if (at_resp->lines == NULL) {
547 err("at_resp->lines is NULL");
549 const gchar *line = (const gchar *)at_resp->lines->data;
553 dbg("Line: [%s]", line);
555 tokens = tcore_at_tok_new(line);
556 if (tokens == NULL) {
557 err("tokens is NULL");
562 index = g_slist_nth_data(tokens, 0);
569 number = g_slist_nth_data(tokens, 1);
571 number = tcore_at_tok_extract(number);
578 name = g_slist_nth_data(tokens, 3);
580 name = tcore_at_tok_extract(name);
586 /* Set Request type in PrivateObject */
587 req_type = (TelPbType *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
588 tcore_phonebook_set_selected_type(co, *req_type);
590 /* Set Response Data */
591 read_record.index = atoi(index);
592 read_record.pb_type = *req_type;
594 /* Get used_index list by req_type */
595 if (__imc_phonebook_get_index_list_by_type(co, *req_type, &list) == TRUE) {
597 if ((guint)list->data == read_record.index) {
598 if ((list = g_slist_next(list)) != NULL) {
599 /* If exist, set next_index */
600 read_record.next_index = (guint)list->data;
601 dbg("next_index is [%u]", read_record.next_index);
603 /* read_record.index is the end of used_index */
604 read_record.next_index = -1;
605 dbg("End of used_index");
609 list = g_slist_next(list);
613 read_record.next_index = 0;
616 if (*req_type == TEL_PB_USIM) {
617 gchar *hidden, *group, *anr, *sne, *email;
619 /* Get Name and Number */
620 g_strlcpy(read_record.rec_u.usim.name, name, TEL_PB_TEXT_MAX_LEN + 1);
621 g_strlcpy(read_record.rec_u.usim.number, number, TEL_PB_NUMBER_MAX_LEN + 1);
624 hidden = g_slist_nth_data(tokens, 4);
626 read_record.rec_u.usim.hidden = atoi(hidden);
630 group = g_slist_nth_data(tokens, 5);
632 group = tcore_at_tok_extract(group);
633 g_strlcpy(read_record.rec_u.usim.grp_name, group, TEL_PB_TEXT_MAX_LEN + 1);
638 anr = g_slist_nth_data(tokens, 6);
640 anr = tcore_at_tok_extract(anr);
642 g_strlcpy(read_record.rec_u.usim.anr[0].number,
643 anr, TEL_PB_NUMBER_MAX_LEN + 1);
644 read_record.rec_u.usim.anr_count = 1;
650 sne = g_slist_nth_data(tokens, 8);
652 sne = tcore_at_tok_extract(sne);
653 g_strlcpy(read_record.rec_u.usim.sne, sne, TEL_PB_TEXT_MAX_LEN + 1);
658 email = g_slist_nth_data(tokens, 9);
660 email = tcore_at_tok_extract(email);
662 g_strlcpy(read_record.rec_u.usim.email[0], email, TEL_PB_TEXT_MAX_LEN + 1);
663 read_record.rec_u.usim.email_count = 1;
669 /* Get Name and Number */
670 g_strlcpy(read_record.rec_u.sim.name, name, TEL_PB_TEXT_MAX_LEN + 1);
671 g_strlcpy(read_record.rec_u.sim.number, number, TEL_PB_NUMBER_MAX_LEN + 1);
674 result = TEL_PB_RESULT_SUCCESS;
678 /* Invoke callback */
679 if (resp_cb_data->cb)
680 resp_cb_data->cb(co, (gint)result, &read_record, resp_cb_data->cb_data);
682 /* Free callback data */
683 imc_destroy_resp_cb_data(resp_cb_data);
686 tcore_at_tok_free(tokens);
691 static void on_response_imc_phonebook_update_record(TcorePending *p,
692 guint data_len, const void *data, void *user_data)
694 const TcoreAtResponse *at_resp = data;
695 ImcRespCbData *resp_cb_data = user_data;
696 CoreObject *co = tcore_pending_ref_core_object(p);
697 TelPbUpdateRecord *req_data;
698 TelPbResult result = TEL_PB_RESULT_FAILURE;
700 tcore_check_return_assert(at_resp != NULL);
701 tcore_check_return_assert(resp_cb_data != NULL);
705 if (at_resp->success != TRUE) {
711 result = TEL_PB_RESULT_SUCCESS;
713 /* Set Request type in PrivateObject */
714 req_data = (TelPbUpdateRecord *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
715 tcore_phonebook_set_selected_type(co, req_data->pb_type);
717 /* Get used_index list by req_type */
718 if (__imc_phonebook_get_index_list_by_type(co,
719 req_data->pb_type, &list) != TRUE) {
720 err("used_index list is NOT valid");
722 list = g_slist_insert_sorted(list, (gpointer)req_data->index,
723 __imc_phonebook_compare_index);
727 /* Invoke callback */
728 if (resp_cb_data->cb)
729 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
731 /* Free callback data */
732 imc_destroy_resp_cb_data(resp_cb_data);
735 static void on_response_imc_phonebook_delete_record(TcorePending *p,
736 guint data_len, const void *data, void *user_data)
738 const TcoreAtResponse *at_resp = data;
739 ImcRespCbData *resp_cb_data = user_data;
740 CoreObject *co = tcore_pending_ref_core_object(p);
741 TelPbRecordInfo *req_data;
743 TelPbResult result = TEL_PB_RESULT_FAILURE;
744 tcore_check_return_assert(at_resp != NULL);
745 tcore_check_return_assert(resp_cb_data != NULL);
749 if (at_resp->success != TRUE) {
755 result = TEL_PB_RESULT_SUCCESS;
757 /* Set Request type in PrivateObject */
758 req_data = (TelPbRecordInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
759 tcore_phonebook_set_selected_type(co, req_data->pb_type);
761 /* Get used_index list by req_type */
762 if (__imc_phonebook_get_index_list_by_type(co,
763 req_data->pb_type, &list) != TRUE) {
764 err("used_index list is NOT valid");
766 list = g_slist_remove(list, (gconstpointer)req_data->index);
767 dbg("Remove index: [%u]", req_data->index);
771 /* Invoke callback */
772 if (resp_cb_data->cb)
773 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
775 /* Free callback data */
776 imc_destroy_resp_cb_data(resp_cb_data);
780 * Operation - get_info
783 * AT-Command: AT+CPBS?;+CPBF=?
786 * Success: (Multi line)
787 * +CPBS: <storage>[,<used>][,total]
788 * +CPBF: [<nlength>],[<tlength>],[<glength>],[<slength>],[<elength>]
791 * <nlength> Maximum length of field <number>
792 * <tlength> Maximum length of field <text>
793 * <glength> Maximum length of field <group>
794 * <slength> Maximum length of field <secondtext>
795 * <elength> Maximum length of field <email>
798 * +CME ERROR: <error>
800 static TelReturn imc_phonebook_get_info(CoreObject *co,
801 const TelPbType pb_type,
802 TcoreObjectResponseCallback cb, void *cb_data)
806 ImcRespCbData *resp_cb_data;
807 TelReturn ret = TEL_RETURN_FAILURE;
811 /* Check whether pb_type is supported or not, and Select pb_type */
812 if (__imc_phonebook_check_and_select_type(co, pb_type, &set_pb_cmd) != TRUE) {
817 at_cmd = g_strdup_printf("%s+CPBS?;+CPBF=?", set_pb_cmd);
819 /* Response callback data */
820 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
821 (void *)&pb_type, sizeof(TelPbType));
823 /* Send Request to Modem */
824 ret = tcore_at_prepare_and_send_request(co,
826 TCORE_AT_COMMAND_TYPE_MULTILINE,
828 on_response_imc_phonebook_get_info, resp_cb_data,
829 on_send_imc_request, NULL);
830 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get Info");
840 * Operation - read_record
843 * AT-Command: AT+CPBR=<index>
846 * 1 Integer type values in range of location numbers of phonebook memory
850 * Success: (Single line);
851 * +CPBR: <index>,<number>,<type>,<text>[,<hidden>][,<group>]
852 * [,<adnumber>][,<adtype>][,<secondtext>][,<email>]]
855 * <number> String type phone number of format <type>
856 * <type> Type of address octet in integer format
857 * <text> String type field of maximum length <tlength>
858 * <hidden> Indicates if the entry is hidden or not – only available,
859 * if a UICC with an active USIM application is present
860 * 0 Phonebook entry not hidden
861 * 1 Phonebook entry hidden
862 * <group> String type field of maximum length <glength>
863 * <adnumber> String type phone number of format <adtype>
864 * <adtype> Type of address octet in integer format
865 * <secondtext> String type field of maximum length <slength>
866 * <email> String type field of maximum length <elength>
869 * +CME ERROR: <error>
871 static TelReturn imc_phonebook_read_record(CoreObject *co,
872 const TelPbRecordInfo *record,
873 TcoreObjectResponseCallback cb, void *cb_data)
877 ImcRespCbData *resp_cb_data;
878 guint used_index = 0;
879 TelReturn ret = TEL_RETURN_FAILURE;
883 /* Check whether pb_type is supported or not, and Select pb_type */
884 if (__imc_phonebook_check_and_select_type(co, record->pb_type, &set_pb_cmd) != TRUE) {
888 /* Check whether index is used or not */
889 __imc_phonebook_check_used_index(co, record->pb_type, record->index, &used_index);
892 at_cmd = g_strdup_printf("%s+CPBR=%u", set_pb_cmd, used_index);
894 /* Response callback data */
895 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
896 (void *)&(record->pb_type), sizeof(TelPbType));
898 /* Send Request to Modem */
899 ret = tcore_at_prepare_and_send_request(co,
901 TCORE_AT_COMMAND_TYPE_SINGLELINE,
903 on_response_imc_phonebook_read_record, resp_cb_data,
904 on_send_imc_request, NULL);
905 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Read Record");
915 * Operation - update_record
918 * AT-Command: AT+CPBW=[<index>][,<number>[,<type>[,<text>[,<group>[,<adnumber>
919 * [,<adtype>[,<secondtext>[,<email>[,<hidden>]]]]]]]]]
921 * ... same read_record Operation
924 * Success: (No Result)
927 * +CME ERROR: <error>
929 static TelReturn imc_phonebook_update_record(CoreObject *co,
930 const TelPbUpdateRecord *req_data,
931 TcoreObjectResponseCallback cb, void *cb_data)
935 ImcRespCbData *resp_cb_data;
936 TelReturn ret = TEL_RETURN_FAILURE;
940 /* Check whether pb_type is supported or not, and Select pb_type */
941 if (__imc_phonebook_check_and_select_type(co, req_data->pb_type, &set_pb_cmd) != TRUE) {
945 /* Set AT-Command according pb_type */
946 if (req_data->pb_type == TEL_PB_USIM) {
947 at_cmd = g_strdup_printf("%s+CPBW=%u,\"%s\",,\"%s\",\"%s\",\"%s\",,\"%s\",\"%s\",%d",
948 set_pb_cmd, req_data->index,
949 req_data->rec_u.usim.number, req_data->rec_u.usim.name,
950 req_data->rec_u.usim.grp_name, req_data->rec_u.usim.anr[0].number,
951 req_data->rec_u.usim.sne, req_data->rec_u.usim.email[0],
952 req_data->rec_u.usim.hidden);
954 at_cmd = g_strdup_printf("%s+CPBW=%u,\"%s\",,\"%s\"",
955 set_pb_cmd, req_data->index,
956 req_data->rec_u.sim.number,
957 req_data->rec_u.sim.name);
960 /* Response callback data */
961 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
962 (void *)req_data, sizeof(TelPbUpdateRecord));
964 /* Send Request to Modem */
965 ret = tcore_at_prepare_and_send_request(co,
967 TCORE_AT_COMMAND_TYPE_NO_RESULT,
969 on_response_imc_phonebook_update_record, resp_cb_data,
970 on_send_imc_request, NULL);
971 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Update Record");
981 * Operation - delete_record
984 * AT-Command: AT+CPBW=<index>
987 * 1 Integer type values in range of location numbers of phonebook memory
991 * Success: (No Result)
994 * +CME ERROR: <error>
996 static TelReturn imc_phonebook_delete_record(CoreObject *co,
997 const TelPbRecordInfo *record,
998 TcoreObjectResponseCallback cb, void *cb_data)
1002 ImcRespCbData *resp_cb_data;
1003 TelReturn ret = TEL_RETURN_FAILURE;
1007 /* Check whether pb_type is supported or not, and Select pb_type */
1008 if (__imc_phonebook_check_and_select_type(co, record->pb_type, &set_pb_cmd) != TRUE) {
1013 at_cmd = g_strdup_printf("%s+CPBW=%u", set_pb_cmd, record->index);
1015 /* Response callback data */
1016 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
1017 (void *)record, sizeof(TelPbRecordInfo));
1019 /* Send Request to Modem */
1020 ret = tcore_at_prepare_and_send_request(co,
1022 TCORE_AT_COMMAND_TYPE_NO_RESULT,
1024 on_response_imc_phonebook_delete_record, resp_cb_data,
1025 on_send_imc_request, NULL);
1026 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Delete Record");
1028 /* Free resources */
1035 /* Phonebook Operations */
1036 static TcorePbOps imc_phonebook_ops = {
1037 .get_info = imc_phonebook_get_info,
1038 .read_record = imc_phonebook_read_record,
1039 .update_record = imc_phonebook_update_record,
1040 .delete_record = imc_phonebook_delete_record,
1043 gboolean imc_phonebook_init(TcorePlugin *p, CoreObject *co)
1045 PrivateInfo *private_info;
1049 /* Set PrivateInfo */
1050 private_info = tcore_malloc0(sizeof(PrivateInfo));
1051 tcore_object_link_user_data(co, private_info);
1053 /* Set operations */
1054 tcore_phonebook_set_ops(co, &imc_phonebook_ops);
1057 tcore_object_add_callback(co, "+PBREADY", on_notification_imc_phonebook_status, NULL);
1063 void imc_phonebook_exit(TcorePlugin *p, CoreObject *co)
1065 PrivateInfo *private_info;
1067 private_info = tcore_object_ref_user_data(co);
1068 tcore_check_return_assert(private_info != NULL);
1070 /* Free PrivateInfo */
1071 g_slist_free_full(private_info->used_index_fdn, g_free);
1072 g_slist_free_full(private_info->used_index_adn, g_free);
1073 g_slist_free_full(private_info->used_index_sdn, g_free);
1074 g_slist_free_full(private_info->used_index_usim, g_free);
1075 tcore_free(private_info);