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;
55 __imc_phonebook_convert_cme_error_tel_phonebook_result(const TcoreAtResponse *at_resp)
57 TelPbResult result = TEL_PB_RESULT_FAILURE;
58 GSList *tokens = NULL;
63 if (!at_resp || !at_resp->lines) {
64 err("Invalid response data");
68 line = (const gchar *)at_resp->lines->data;
69 tokens = tcore_at_tok_new(line);
70 if (g_slist_length(tokens) > 0) {
74 resp_str = g_slist_nth_data(tokens, 0);
76 err("Invalid CME Error data");
77 tcore_at_tok_free(tokens);
80 cme_err = atoi(resp_str);
81 dbg("CME Error: [%d]", cme_err);
85 result = TEL_PB_RESULT_OPERATION_NOT_PERMITTED;
89 result = TEL_PB_RESULT_OPERATION_NOT_SUPPORTED;
93 result = TEL_PB_RESULT_PIN2_REQUIRED;
97 result = TEL_PB_RESULT_PUK2_REQUIRED;
101 result = TEL_PB_RESULT_MEMORY_FAILURE;
105 result = TEL_PB_RESULT_INVALID_INDEX;
109 result = TEL_PB_RESULT_INVALID_PARAMETER;
113 result = TEL_PB_RESULT_UNKNOWN_FAILURE;
117 result = TEL_PB_RESULT_FAILURE;
120 tcore_at_tok_free(tokens);
125 static gboolean __imc_phonebook_get_sim_type(CoreObject *co_pb,
126 TelSimCardType *sim_type)
130 tcore_check_return_value_assert(co_pb != NULL, FALSE);
131 tcore_check_return_value_assert(sim_type != NULL, FALSE);
133 plugin = tcore_object_ref_plugin(co_pb);
134 co_sim = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SIM);
135 return tcore_sim_get_type(co_sim, sim_type);
138 static gboolean __imc_phonebook_get_pb_type_str(TelPbType pb_type,
139 gchar **req_type_str)
141 tcore_check_return_value_assert(req_type_str != NULL, FALSE);
145 *req_type_str = g_strdup("FD");
149 *req_type_str = g_strdup("SM");
152 *req_type_str = g_strdup("SN");
159 static gboolean __imc_phonebook_check_and_select_type(CoreObject *co,
160 TelPbType req_type, gchar **set_pb_cmd)
162 TelPbList *support_list;
163 TelPbType current_type;
165 /* Check whether pb_type is supported or not */
166 tcore_phonebook_get_support_list(co, &support_list);
167 if ((req_type == TEL_PB_FDN && support_list->fdn == FALSE)
168 || (req_type == TEL_PB_ADN && support_list->adn == FALSE)
169 || (req_type == TEL_PB_SDN && support_list->sdn == FALSE)
170 || (req_type == TEL_PB_USIM && support_list->usim == FALSE)) {
171 err("Not supported pb_type");
172 g_free(support_list);
175 g_free(support_list);
177 /* Check Current type & Request type */
178 tcore_phonebook_get_selected_type(co, ¤t_type);
179 if (current_type != req_type) {
180 gchar *req_type_str = NULL;
181 __imc_phonebook_get_pb_type_str(req_type, &req_type_str);
182 dbg("Add AT-Command to change [%s] Type", req_type_str);
183 /* Select Phonebook type */
184 *set_pb_cmd = g_strdup_printf("AT+CPBS=\"%s\";", req_type_str);
186 *set_pb_cmd = g_strdup_printf("AT");
192 static gboolean __imc_phonebook_get_index_list_by_type(CoreObject *co,
193 TelPbType pb_type, GSList **list)
195 PrivateInfo *private_info = tcore_object_ref_user_data(co);
196 tcore_check_return_value_assert(private_info != NULL, FALSE);
200 if (private_info->used_index_fdn_valid != TRUE)
202 *list = private_info->used_index_fdn;
205 if (private_info->used_index_adn_valid != TRUE)
207 *list = private_info->used_index_adn;
210 if (private_info->used_index_sdn_valid != TRUE)
212 *list = private_info->used_index_sdn;
215 if (private_info->used_index_usim_valid != TRUE)
217 *list = private_info->used_index_usim;
224 static void __imc_phonebook_check_used_index(CoreObject *co,
225 TelPbType pb_type, guint req_index, guint *used_index)
229 /* Get used_index list by req_type */
230 if (__imc_phonebook_get_index_list_by_type(co, pb_type, &list) != TRUE) {
231 err("used_index list is NOT valid");
232 *used_index = req_index;
236 /* Use first used_index in case req_index is not used */
237 *used_index = (guint)g_slist_nth_data(list, 0);
239 if ((guint)list->data == req_index) {
240 /* req_index is equal to one of used_index */
241 *used_index = req_index;
244 list = g_slist_next(list);
248 static gint __imc_phonebook_compare_index(gconstpointer a, gconstpointer b)
250 guint index1 = (guint)a;
251 guint index2 = (guint)b;
253 return index1 - index2;
256 static void on_response_imc_phonebook_get_used_index(TcorePending *p,
257 guint data_len, const void *data, void *user_data)
259 const TcoreAtResponse *at_resp = data;
260 ImcRespCbData *resp_cb_data = user_data;
261 CoreObject *co = tcore_pending_ref_core_object(p);
262 tcore_check_return_assert(at_resp != NULL);
263 tcore_check_return_assert(resp_cb_data != NULL);
267 if (at_resp->success != TRUE) {
274 if (at_resp->lines == NULL) {
275 err("at_resp->lines is NULL");
277 GSList *lines = at_resp->lines;
279 GSList **list = NULL;
280 PrivateInfo *private_info = tcore_object_ref_user_data(co);
281 tcore_check_return_assert(private_info != NULL);
283 /* Select used_index_list by req_type */
284 req_type = (TelPbType *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
287 list = &private_info->used_index_fdn;
288 private_info->used_index_fdn_valid = TRUE;
291 list = &private_info->used_index_adn;
292 private_info->used_index_adn_valid = TRUE;
295 list = &private_info->used_index_sdn;
296 private_info->used_index_sdn_valid = TRUE;
299 list = &private_info->used_index_usim;
300 private_info->used_index_usim_valid = TRUE;
305 const gchar *line = lines->data;
306 GSList *tokens = NULL;
309 dbg("Line: [%s]", line);
311 tokens = tcore_at_tok_new(line);
312 if (tokens == NULL) {
313 err("tokens is NULL");
317 /* Get only used_index */
318 temp = g_slist_nth_data(tokens, 0);
320 /* Insert used_index in PrivateInfo sorted in ascending */
321 *list = g_slist_insert_sorted(*list, (gpointer)atoi(temp),
322 __imc_phonebook_compare_index);
324 tcore_at_tok_free(tokens);
327 lines = g_slist_next(lines);
329 dbg("pb_type: [%d], used_index Length: [%d]",
330 *req_type, g_slist_length(*list));
334 static void __imc_phonebook_get_used_index(CoreObject *co, TelPbType pb_type, guint max_index)
337 ImcRespCbData *resp_cb_data;
338 TelReturn ret = TEL_RETURN_FAILURE;
343 at_cmd = g_strdup_printf("AT+CPBR=1,%d", max_index);
345 /* Response callback data */
346 resp_cb_data = imc_create_resp_cb_data(NULL, NULL,
347 (void *)&pb_type, sizeof(TelPbType));
349 /* Send Request to Modem */
350 ret = tcore_at_prepare_and_send_request(co,
352 TCORE_AT_COMMAND_TYPE_MULTILINE,
354 on_response_imc_phonebook_get_used_index, resp_cb_data,
355 on_send_imc_request, NULL);
356 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get Used Index");
362 static void on_response_imc_phonebook_get_support_list(TcorePending *p,
363 guint data_len, const void *data, void *user_data)
365 const TcoreAtResponse *at_resp = data;
366 CoreObject *co = tcore_pending_ref_core_object(p);
367 TelPbInitInfo init_info = {0, };
368 tcore_check_return_assert(at_resp != NULL);
372 if (at_resp->success != TRUE) {
379 if (at_resp->lines == NULL) {
380 err("at_resp->lines is NULL");
383 const gchar *line = (const gchar *)at_resp->lines->data;
384 GSList *tokens = NULL;
388 dbg("Line: [%s]", line);
390 tokens = tcore_at_tok_new(line);
391 if (tokens == NULL) {
392 err("tokens is NULL");
396 pb_type_list = g_slist_nth_data(tokens, 0);
397 pb_type = strtok(pb_type_list, "(,)");
399 pb_type = tcore_at_tok_extract(pb_type);
400 if (g_strcmp0(pb_type, "FD") == 0) {
401 init_info.pb_list.fdn = TRUE;
402 } else if (g_strcmp0(pb_type, "SN") == 0) {
403 init_info.pb_list.sdn = TRUE;
404 } else if (g_strcmp0(pb_type, "SM") == 0) {
405 TelSimCardType sim_type;
406 __imc_phonebook_get_sim_type(co, &sim_type);
407 if (sim_type == TEL_SIM_CARD_TYPE_USIM)
408 init_info.pb_list.usim = TRUE;
410 init_info.pb_list.adn = TRUE;
413 /* Get Next pb_type */
414 pb_type = strtok(NULL, "(,)");
416 tcore_at_tok_free(tokens);
419 dbg("FDN: [%s], ADN: [%s], SDN: [%s], USIM: [%s]",
420 init_info.pb_list.fdn ? "TRUE" : "FALSE",
421 init_info.pb_list.adn ? "TRUE" : "FALSE",
422 init_info.pb_list.sdn ? "TRUE" : "FALSE",
423 init_info.pb_list.usim ? "TRUE" : "FALSE");
425 init_info.init_status = TRUE;
426 tcore_phonebook_set_support_list(co, &init_info.pb_list);
427 tcore_phonebook_set_status(co, init_info.init_status);
429 /* Send Notification */
430 tcore_object_send_notification(co,
431 TCORE_NOTIFICATION_PHONEBOOK_STATUS,
432 sizeof(TelPbInitInfo), &init_info);
436 * Operation - get_support_list
439 * AT-Command: AT+CPBS=?
442 * Success: (Single line)
443 * (list of supported <storage>s)
446 * +CME ERROR: <error>
448 static void __imc_phonebook_get_support_list(CoreObject *co)
454 /* Send Request to Modem */
455 ret = tcore_at_prepare_and_send_request(co,
456 "AT+CPBS=?", "+CPBS",
457 TCORE_AT_COMMAND_TYPE_SINGLELINE,
459 on_response_imc_phonebook_get_support_list, NULL,
460 on_send_imc_request, NULL);
461 IMC_CHECK_REQUEST_RET(ret, NULL, "Get Support List");
464 static gboolean on_notification_imc_phonebook_status(CoreObject *co,
465 const void *event_info, void *user_data)
467 dbg("Phonebook Init Completed");
469 /* Get Supported list */
470 __imc_phonebook_get_support_list(co);
475 static void on_response_imc_phonebook_get_info(TcorePending *p,
476 guint data_len, const void *data, void *user_data)
478 const TcoreAtResponse *at_resp = data;
479 ImcRespCbData *resp_cb_data = user_data;
480 CoreObject *co = tcore_pending_ref_core_object(p);
481 TelPbResult result = TEL_PB_RESULT_FAILURE;
482 TelPbInfo pb_info = {0, };
483 tcore_check_return_assert(at_resp != NULL);
484 tcore_check_return_assert(resp_cb_data != NULL);
488 if (at_resp->success != TRUE) {
490 result = __imc_phonebook_convert_cme_error_tel_phonebook_result(at_resp);
496 if (at_resp->lines == NULL) {
497 err("at_resp->lines is NULL");
499 GSList *lines = at_resp->lines;
501 GSList *tokens = NULL;
503 gint used = 0, total = 0;
504 gint nlen = 0, tlen = 0;
506 PrivateInfo *private_info;
508 /* +CPBS: <storage>[,<used>][,total] */
509 line = g_slist_nth_data(lines, 0);
510 dbg("First Line: [%s]", line);
511 tokens = tcore_at_tok_new(line);
512 if (tokens == NULL) {
513 err("tokens is NULL");
518 temp = g_slist_nth_data(tokens, 1);
521 /* Get total_count */
522 temp = g_slist_nth_data(tokens, 2);
526 tcore_at_tok_free(tokens);
528 /* +CPBF: [<nlength>],[<tlength>],[<glength>],[<slength>],[<elength>] */
529 line = g_slist_nth_data(lines, 1);
530 dbg("Second Line: [%s]", line);
531 tokens = tcore_at_tok_new(line);
532 if (tokens == NULL) {
533 err("tokens is NULL");
537 /* Get number Length */
538 temp = g_slist_nth_data(tokens, 0);
541 /* Get text Length */
542 temp = g_slist_nth_data(tokens, 1);
546 /* Set Response Data */
547 req_type = (TelPbType *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
548 pb_info.pb_type = *req_type;
549 if (*req_type == TEL_PB_USIM) {
550 pb_info.info_u.usim.max_count = total;
551 pb_info.info_u.usim.used_count = used;
552 pb_info.info_u.usim.max_num_len = nlen;
553 pb_info.info_u.usim.max_text_len = tlen;
554 /* Get group name Length */
555 temp = g_slist_nth_data(tokens, 2);
557 pb_info.info_u.usim.max_gas_len = atoi(temp);
558 /* Get second name Length */
559 temp = g_slist_nth_data(tokens, 3);
561 pb_info.info_u.usim.max_sne_len = atoi(temp);
562 /* Get email Length */
563 temp = g_slist_nth_data(tokens, 4);
565 pb_info.info_u.usim.max_email_len = atoi(temp);
567 pb_info.info_u.sim.max_count = total;
568 pb_info.info_u.sim.used_count = used;
569 pb_info.info_u.sim.max_num_len = nlen;
570 pb_info.info_u.sim.max_text_len = tlen;
573 /* Set Request type in PrivateObject */
574 tcore_phonebook_set_selected_type(co, *req_type);
575 result = TEL_PB_RESULT_SUCCESS;
576 tcore_at_tok_free(tokens);
578 /* If don't have valid used_index, get used_index by req_type */
579 private_info = tcore_object_ref_user_data(co);
580 if ((*req_type == TEL_PB_FDN && private_info->used_index_fdn_valid == FALSE)
581 || (*req_type == TEL_PB_ADN && private_info->used_index_adn_valid == FALSE)
582 || (*req_type == TEL_PB_SDN && private_info->used_index_sdn_valid == FALSE)
583 || (*req_type == TEL_PB_USIM && private_info->used_index_usim_valid == FALSE))
584 __imc_phonebook_get_used_index(co, *req_type, total);
588 /* Invoke callback */
589 if (resp_cb_data->cb)
590 resp_cb_data->cb(co, (gint)result, &pb_info, resp_cb_data->cb_data);
592 /* Free callback data */
593 imc_destroy_resp_cb_data(resp_cb_data);
596 static void on_response_imc_phonebook_read_record(TcorePending *p,
597 guint data_len, const void *data, void *user_data)
599 const TcoreAtResponse *at_resp = data;
600 ImcRespCbData *resp_cb_data = user_data;
601 CoreObject *co = tcore_pending_ref_core_object(p);
602 TelPbResult result = TEL_PB_RESULT_FAILURE;
603 GSList *tokens = NULL;
604 gchar *index = NULL, *number = NULL, *name = NULL;
605 TelPbReadRecord read_record = {0, };
606 tcore_check_return_assert(at_resp != NULL);
607 tcore_check_return_assert(resp_cb_data != NULL);
611 if (at_resp->success != TRUE) {
613 result = __imc_phonebook_convert_cme_error_tel_phonebook_result(at_resp);
619 if (at_resp->lines == NULL) {
620 err("at_resp->lines is NULL");
622 const gchar *line = (const gchar *)at_resp->lines->data;
626 dbg("Line: [%s]", line);
628 tokens = tcore_at_tok_new(line);
629 if (tokens == NULL) {
630 err("tokens is NULL");
635 index = g_slist_nth_data(tokens, 0);
642 number = g_slist_nth_data(tokens, 1);
644 number = tcore_at_tok_extract(number);
651 name = g_slist_nth_data(tokens, 3);
653 name = tcore_at_tok_extract(name);
659 /* Set Request type in PrivateObject */
660 req_type = (TelPbType *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
661 tcore_phonebook_set_selected_type(co, *req_type);
663 /* Set Response Data */
664 read_record.index = atoi(index);
665 read_record.pb_type = *req_type;
667 /* Get used_index list by req_type */
668 if (__imc_phonebook_get_index_list_by_type(co, *req_type, &list) == TRUE) {
670 if ((guint)list->data == read_record.index) {
671 if ((list = g_slist_next(list)) != NULL) {
672 /* If exist, set next_index */
673 read_record.next_index = (guint)list->data;
674 dbg("next_index is [%u]", read_record.next_index);
676 /* read_record.index is the end of used_index */
677 read_record.next_index = -1;
678 dbg("End of used_index");
682 list = g_slist_next(list);
686 read_record.next_index = 0;
689 if (*req_type == TEL_PB_USIM) {
690 gchar *hidden, *group, *anr, *sne, *email;
692 /* Get Name and Number */
693 g_strlcpy(read_record.rec_u.usim.name, name, TEL_PB_TEXT_MAX_LEN + 1);
694 g_strlcpy(read_record.rec_u.usim.number, number, TEL_PB_NUMBER_MAX_LEN + 1);
697 hidden = g_slist_nth_data(tokens, 4);
699 read_record.rec_u.usim.hidden = atoi(hidden);
703 group = g_slist_nth_data(tokens, 5);
705 group = tcore_at_tok_extract(group);
706 g_strlcpy(read_record.rec_u.usim.grp_name, group, TEL_PB_TEXT_MAX_LEN + 1);
711 anr = g_slist_nth_data(tokens, 6);
713 anr = tcore_at_tok_extract(anr);
715 g_strlcpy(read_record.rec_u.usim.anr[0].number,
716 anr, TEL_PB_NUMBER_MAX_LEN + 1);
717 read_record.rec_u.usim.anr_count = 1;
723 sne = g_slist_nth_data(tokens, 8);
725 sne = tcore_at_tok_extract(sne);
726 g_strlcpy(read_record.rec_u.usim.sne, sne, TEL_PB_TEXT_MAX_LEN + 1);
731 email = g_slist_nth_data(tokens, 9);
733 email = tcore_at_tok_extract(email);
735 g_strlcpy(read_record.rec_u.usim.email[0], email, TEL_PB_TEXT_MAX_LEN + 1);
736 read_record.rec_u.usim.email_count = 1;
742 /* Get Name and Number */
743 g_strlcpy(read_record.rec_u.sim.name, name, TEL_PB_TEXT_MAX_LEN + 1);
744 g_strlcpy(read_record.rec_u.sim.number, number, TEL_PB_NUMBER_MAX_LEN + 1);
747 result = TEL_PB_RESULT_SUCCESS;
751 /* Invoke callback */
752 if (resp_cb_data->cb)
753 resp_cb_data->cb(co, (gint)result, &read_record, resp_cb_data->cb_data);
755 /* Free callback data */
756 imc_destroy_resp_cb_data(resp_cb_data);
759 tcore_at_tok_free(tokens);
764 static void on_response_imc_phonebook_update_record(TcorePending *p,
765 guint data_len, const void *data, void *user_data)
767 const TcoreAtResponse *at_resp = data;
768 ImcRespCbData *resp_cb_data = user_data;
769 CoreObject *co = tcore_pending_ref_core_object(p);
770 TelPbUpdateRecord *req_data;
771 TelPbResult result = TEL_PB_RESULT_FAILURE;
773 tcore_check_return_assert(at_resp != NULL);
774 tcore_check_return_assert(resp_cb_data != NULL);
778 if (at_resp->success != TRUE) {
780 result = __imc_phonebook_convert_cme_error_tel_phonebook_result(at_resp);
785 result = TEL_PB_RESULT_SUCCESS;
787 /* Set Request type in PrivateObject */
788 req_data = (TelPbUpdateRecord *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
789 tcore_phonebook_set_selected_type(co, req_data->pb_type);
791 /* Get used_index list by req_type */
792 if (__imc_phonebook_get_index_list_by_type(co,
793 req_data->pb_type, &list) != TRUE) {
794 err("used_index list is NOT valid");
796 list = g_slist_insert_sorted(list, (gpointer)req_data->index,
797 __imc_phonebook_compare_index);
798 dbg("list: [0x%x]", list);
802 /* Invoke callback */
803 if (resp_cb_data->cb)
804 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
806 /* Free callback data */
807 imc_destroy_resp_cb_data(resp_cb_data);
810 static void on_response_imc_phonebook_delete_record(TcorePending *p,
811 guint data_len, const void *data, void *user_data)
813 const TcoreAtResponse *at_resp = data;
814 ImcRespCbData *resp_cb_data = user_data;
815 CoreObject *co = tcore_pending_ref_core_object(p);
816 TelPbRecordInfo *req_data;
818 TelPbResult result = TEL_PB_RESULT_FAILURE;
819 tcore_check_return_assert(at_resp != NULL);
820 tcore_check_return_assert(resp_cb_data != NULL);
824 if (at_resp->success != TRUE) {
826 result = __imc_phonebook_convert_cme_error_tel_phonebook_result(at_resp);
831 result = TEL_PB_RESULT_SUCCESS;
833 /* Set Request type in PrivateObject */
834 req_data = (TelPbRecordInfo *)IMC_GET_DATA_FROM_RESP_CB_DATA(resp_cb_data);
835 tcore_phonebook_set_selected_type(co, req_data->pb_type);
837 /* Get used_index list by req_type */
838 if (__imc_phonebook_get_index_list_by_type(co,
839 req_data->pb_type, &list) != TRUE) {
840 err("used_index list is NOT valid");
842 list = g_slist_remove(list, (gconstpointer)req_data->index);
843 dbg("Remove index: [%u], list: [0x%x]", req_data->index, list);
847 /* Invoke callback */
848 if (resp_cb_data->cb)
849 resp_cb_data->cb(co, (gint)result, NULL, resp_cb_data->cb_data);
851 /* Free callback data */
852 imc_destroy_resp_cb_data(resp_cb_data);
856 * Operation - get_info
859 * AT-Command: AT+CPBS?;+CPBF=?
862 * Success: (Multi line)
863 * +CPBS: <storage>[,<used>][,total]
864 * +CPBF: [<nlength>],[<tlength>],[<glength>],[<slength>],[<elength>]
867 * <nlength> Maximum length of field <number>
868 * <tlength> Maximum length of field <text>
869 * <glength> Maximum length of field <group>
870 * <slength> Maximum length of field <secondtext>
871 * <elength> Maximum length of field <email>
874 * +CME ERROR: <error>
876 static TelReturn imc_phonebook_get_info(CoreObject *co,
877 const TelPbType pb_type,
878 TcoreObjectResponseCallback cb, void *cb_data)
882 ImcRespCbData *resp_cb_data;
883 TelReturn ret = TEL_RETURN_FAILURE;
887 /* Check whether pb_type is supported or not, and Select pb_type */
888 if (__imc_phonebook_check_and_select_type(co, pb_type, &set_pb_cmd) != TRUE) {
893 at_cmd = g_strdup_printf("%s+CPBS?;+CPBF=?", set_pb_cmd);
895 /* Response callback data */
896 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
897 (void *)&pb_type, sizeof(TelPbType));
899 /* Send Request to Modem */
900 ret = tcore_at_prepare_and_send_request(co,
902 TCORE_AT_COMMAND_TYPE_MULTILINE,
904 on_response_imc_phonebook_get_info, resp_cb_data,
905 on_send_imc_request, NULL);
906 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Get Info");
916 * Operation - read_record
919 * AT-Command: AT+CPBR=<index>
922 * 1 Integer type values in range of location numbers of phonebook memory
926 * Success: (Single line);
927 * +CPBR: <index>,<number>,<type>,<text>[,<hidden>][,<group>]
928 * [,<adnumber>][,<adtype>][,<secondtext>][,<email>]]
931 * <number> String type phone number of format <type>
932 * <type> Type of address octet in integer format
933 * <text> String type field of maximum length <tlength>
934 * <hidden> Indicates if the entry is hidden or not – only available,
935 * if a UICC with an active USIM application is present
936 * 0 Phonebook entry not hidden
937 * 1 Phonebook entry hidden
938 * <group> String type field of maximum length <glength>
939 * <adnumber> String type phone number of format <adtype>
940 * <adtype> Type of address octet in integer format
941 * <secondtext> String type field of maximum length <slength>
942 * <email> String type field of maximum length <elength>
945 * +CME ERROR: <error>
947 static TelReturn imc_phonebook_read_record(CoreObject *co,
948 const TelPbRecordInfo *record,
949 TcoreObjectResponseCallback cb, void *cb_data)
953 ImcRespCbData *resp_cb_data;
954 guint used_index = 0;
955 TelReturn ret = TEL_RETURN_FAILURE;
959 /* Check whether pb_type is supported or not, and Select pb_type */
960 if (__imc_phonebook_check_and_select_type(co, record->pb_type, &set_pb_cmd) != TRUE) {
964 /* Check whether index is used or not */
965 __imc_phonebook_check_used_index(co, record->pb_type, record->index, &used_index);
968 at_cmd = g_strdup_printf("%s+CPBR=%u", set_pb_cmd, used_index);
970 /* Response callback data */
971 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
972 (void *)&(record->pb_type), sizeof(TelPbType));
974 /* Send Request to Modem */
975 ret = tcore_at_prepare_and_send_request(co,
977 TCORE_AT_COMMAND_TYPE_SINGLELINE,
979 on_response_imc_phonebook_read_record, resp_cb_data,
980 on_send_imc_request, NULL);
981 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Read Record");
991 * Operation - update_record
994 * AT-Command: AT+CPBW=[<index>][,<number>[,<type>[,<text>[,<group>[,<adnumber>
995 * [,<adtype>[,<secondtext>[,<email>[,<hidden>]]]]]]]]]
997 * ... same read_record Operation
1000 * Success: (No Result)
1003 * +CME ERROR: <error>
1005 static TelReturn imc_phonebook_update_record(CoreObject *co,
1006 const TelPbUpdateRecord *req_data,
1007 TcoreObjectResponseCallback cb, void *cb_data)
1011 ImcRespCbData *resp_cb_data;
1012 TelReturn ret = TEL_RETURN_FAILURE;
1016 /* Check whether pb_type is supported or not, and Select pb_type */
1017 if (__imc_phonebook_check_and_select_type(co, req_data->pb_type, &set_pb_cmd) != TRUE) {
1021 /* Set AT-Command according pb_type */
1022 if (req_data->pb_type == TEL_PB_USIM) {
1023 at_cmd = g_strdup_printf("%s+CPBW=%u,\"%s\",,\"%s\",\"%s\",\"%s\",,\"%s\",\"%s\",%d",
1024 set_pb_cmd, req_data->index,
1025 req_data->rec_u.usim.number, req_data->rec_u.usim.name,
1026 req_data->rec_u.usim.grp_name, req_data->rec_u.usim.anr[0].number,
1027 req_data->rec_u.usim.sne, req_data->rec_u.usim.email[0],
1028 req_data->rec_u.usim.hidden);
1030 at_cmd = g_strdup_printf("%s+CPBW=%u,\"%s\",,\"%s\"",
1031 set_pb_cmd, req_data->index,
1032 req_data->rec_u.sim.number,
1033 req_data->rec_u.sim.name);
1036 /* Response callback data */
1037 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
1038 (void *)req_data, sizeof(TelPbUpdateRecord));
1040 /* Send Request to Modem */
1041 ret = tcore_at_prepare_and_send_request(co,
1043 TCORE_AT_COMMAND_TYPE_NO_RESULT,
1045 on_response_imc_phonebook_update_record, resp_cb_data,
1046 on_send_imc_request, NULL);
1047 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Update Record");
1049 /* Free resources */
1057 * Operation - delete_record
1060 * AT-Command: AT+CPBW=<index>
1063 * 1 Integer type values in range of location numbers of phonebook memory
1067 * Success: (No Result)
1070 * +CME ERROR: <error>
1072 static TelReturn imc_phonebook_delete_record(CoreObject *co,
1073 const TelPbRecordInfo *record,
1074 TcoreObjectResponseCallback cb, void *cb_data)
1078 ImcRespCbData *resp_cb_data;
1079 TelReturn ret = TEL_RETURN_FAILURE;
1083 /* Check whether pb_type is supported or not, and Select pb_type */
1084 if (__imc_phonebook_check_and_select_type(co, record->pb_type, &set_pb_cmd) != TRUE) {
1089 at_cmd = g_strdup_printf("%s+CPBW=%u", set_pb_cmd, record->index);
1091 /* Response callback data */
1092 resp_cb_data = imc_create_resp_cb_data(cb, cb_data,
1093 (void *)record, sizeof(TelPbRecordInfo));
1095 /* Send Request to Modem */
1096 ret = tcore_at_prepare_and_send_request(co,
1098 TCORE_AT_COMMAND_TYPE_NO_RESULT,
1100 on_response_imc_phonebook_delete_record, resp_cb_data,
1101 on_send_imc_request, NULL);
1102 IMC_CHECK_REQUEST_RET(ret, resp_cb_data, "Delete Record");
1104 /* Free resources */
1111 /* Phonebook Operations */
1112 static TcorePbOps imc_phonebook_ops = {
1113 .get_info = imc_phonebook_get_info,
1114 .read_record = imc_phonebook_read_record,
1115 .update_record = imc_phonebook_update_record,
1116 .delete_record = imc_phonebook_delete_record,
1119 gboolean imc_phonebook_init(TcorePlugin *p, CoreObject *co)
1121 PrivateInfo *private_info;
1125 /* Set PrivateInfo */
1126 private_info = tcore_malloc0(sizeof(PrivateInfo));
1127 tcore_object_link_user_data(co, private_info);
1129 /* Set operations */
1130 tcore_phonebook_set_ops(co, &imc_phonebook_ops);
1133 tcore_object_add_callback(co, "+PBREADY", on_notification_imc_phonebook_status, NULL);
1139 void imc_phonebook_exit(TcorePlugin *p, CoreObject *co)
1141 PrivateInfo *private_info;
1143 private_info = tcore_object_ref_user_data(co);
1144 tcore_check_return_assert(private_info != NULL);
1146 /* Free PrivateInfo */
1147 g_slist_free_full(private_info->used_index_fdn, g_free);
1148 g_slist_free_full(private_info->used_index_adn, g_free);
1149 g_slist_free_full(private_info->used_index_sdn, g_free);
1150 g_slist_free_full(private_info->used_index_usim, g_free);
1151 tcore_free(private_info);