add exception code for g_variant_iter_free()
[profile/ivi/tel-plugin-dbus_tapi.git] / src / phonebook.c
1 /*
2  * tel-plugin-socket-communicator
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Ja-young Gu <jygu@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 <string.h>
23 #include <stdlib.h>
24 #include <errno.h>
25 #include <glib-object.h>
26
27 #include <tcore.h>
28 #include <server.h>
29 #include <plugin.h>
30 #include <hal.h>
31 #include <communicator.h>
32 #include <core_object.h>
33 #include <queue.h>
34 #include <user_request.h>
35 #include <util.h>
36 #include <co_phonebook.h>
37 #include <co_sim.h>
38
39 #include "generated-code.h"
40 #include "common.h"
41
42 static gboolean on_phonebook_get_init_status(TelephonyPhonebook *phonebook, GDBusMethodInvocation *invocation, gpointer user_data)
43 {
44         struct custom_data *ctx = user_data;
45         gboolean pb_status = FALSE;
46         struct tel_phonebook_support_list *list = NULL;
47         GSList *co_list = NULL;
48         CoreObject *co_pb = NULL;
49         TcorePlugin *plugin = NULL;
50
51         dbg("Func Entrance");
52
53         plugin = tcore_server_find_plugin(ctx->server, TCORE_PLUGIN_DEFAULT);
54         co_list = tcore_plugin_get_core_objects_bytype(plugin, CORE_OBJECT_TYPE_PHONEBOOK);
55         if (!co_list) {
56                 dbg("error- co_list is NULL");
57         }
58         co_pb = (CoreObject *)co_list->data;
59         g_slist_free(co_list);
60
61         if (!co_pb) {
62                 dbg("error- co_pb is NULL");
63         }
64
65         pb_status = tcore_phonebook_get_status(co_pb);
66         list = tcore_phonebook_get_support_list(co_pb);
67
68         telephony_phonebook_complete_get_init_status(phonebook, invocation,
69                         pb_status,
70                         list->b_fdn,
71                         list->b_adn,
72                         list->b_sdn,
73                         list->b_usim,
74                         list->b_aas,
75                         list->b_gas);
76
77         return TRUE;
78 }
79
80 static gboolean on_phonebook_get_count(TelephonyPhonebook *phonebook, GDBusMethodInvocation *invocation, gint arg_req_type, gpointer user_data)
81 {
82         struct custom_data *ctx = user_data;
83         UserRequest *ur = NULL;
84
85         struct treq_phonebook_get_count pb_count;
86
87         ur = MAKE_UR(ctx, phonebook, invocation);
88         memset(&pb_count, 0, sizeof(struct treq_phonebook_get_count));
89
90         pb_count.phonebook_type = arg_req_type;
91
92         tcore_user_request_set_data(ur, sizeof(struct treq_phonebook_get_count), &pb_count);
93         tcore_user_request_set_command(ur, TREQ_PHONEBOOK_GETCOUNT);
94         tcore_communicator_dispatch_request(ctx->comm, ur);
95
96         return TRUE;
97 }
98
99 static gboolean on_phonebook_get_info(TelephonyPhonebook *phonebook, GDBusMethodInvocation *invocation, gint arg_req_type, gpointer user_data)
100 {
101         struct custom_data *ctx = user_data;
102         UserRequest *ur = NULL;
103
104         struct treq_phonebook_get_info pb_info;
105
106         ur = MAKE_UR(ctx, phonebook, invocation);
107         memset(&pb_info, 0, sizeof(struct treq_phonebook_get_info));
108
109         pb_info.phonebook_type = arg_req_type;
110
111         tcore_user_request_set_data(ur, sizeof(struct treq_phonebook_get_info), &pb_info);
112         tcore_user_request_set_command(ur, TREQ_PHONEBOOK_GETMETAINFO);
113         tcore_communicator_dispatch_request(ctx->comm, ur);
114
115         return TRUE;
116 }
117
118 static gboolean on_phonebook_get_usim_info(TelephonyPhonebook *phonebook, GDBusMethodInvocation *invocation, gpointer user_data)
119 {
120         struct custom_data *ctx = user_data;
121         UserRequest *ur = NULL;
122         ur = MAKE_UR(ctx, phonebook, invocation);
123         tcore_user_request_set_data(ur, 0, NULL);
124         tcore_user_request_set_command(ur, TREQ_PHONEBOOK_GETUSIMINFO);
125         tcore_communicator_dispatch_request(ctx->comm, ur);
126         return TRUE;
127 }
128
129 static gboolean on_phonebook_read_record(TelephonyPhonebook *phonebook, GDBusMethodInvocation *invocation,
130                 gint arg_req_type, gint arg_index, gpointer user_data)
131 {
132         struct custom_data *ctx = user_data;
133         UserRequest *ur = NULL;
134
135         struct treq_phonebook_read_record pb_read;
136
137         ur = MAKE_UR(ctx, phonebook, invocation);
138         memset(&pb_read, 0, sizeof(struct treq_phonebook_read_record));
139
140         pb_read.index = (unsigned short)arg_index;
141         pb_read.phonebook_type = arg_req_type;
142
143         tcore_user_request_set_data(ur, sizeof(struct treq_phonebook_read_record), &pb_read);
144         tcore_user_request_set_command(ur, TREQ_PHONEBOOK_READRECORD);
145         tcore_communicator_dispatch_request(ctx->comm, ur);
146
147         return TRUE;
148 }
149
150 static gboolean on_phonebook_update_record(TelephonyPhonebook *phonebook, GDBusMethodInvocation *invocation,
151                 gint arg_type, gint arg_index, const gchar *arg_name, gint arg_dcs,
152                 const gchar *arg_number, gint arg_ton, const gchar *arg_number2, gint arg_number2_ton,
153                 const gchar *arg_number3,gint arg_number3_ton, const gchar *arg_number4, gint arg_number4_ton,
154                 const gchar *arg_email1, const gchar *arg_email2, const gchar *arg_email3, const gchar *arg_email4,
155                 gint arg_group_index, gpointer user_data)
156 {
157         struct custom_data *ctx = user_data;
158         UserRequest *ur = NULL;
159
160         struct treq_phonebook_update_record pb_update;
161
162         ur = MAKE_UR(ctx, phonebook, invocation);
163         memset(&pb_update, 0, sizeof(struct treq_phonebook_update_record));
164
165         dbg("arg_type[%d]",arg_type);
166         dbg("arg_index[%d]",arg_index);
167         dbg("arg_name[%s]",arg_name);
168         dbg("arg_dcs[%d]",arg_dcs);
169         dbg("arg_number[%s]",arg_number);
170         dbg("arg_ton[%d]",arg_ton);
171
172         pb_update.index = (unsigned short)arg_index;
173         pb_update.phonebook_type = arg_type;
174
175         if(strlen(arg_name)){
176                 snprintf((char *)pb_update.name, strlen(arg_name)+1, "%s", arg_name);
177                 pb_update.dcs = arg_dcs;
178         }
179
180         if(strlen(arg_number)){
181                 snprintf((char *)pb_update.number, strlen(arg_number)+1, "%s", arg_number);
182                 pb_update.ton = arg_ton;
183         }
184
185         if(strlen(arg_number2)){
186                 snprintf((char *)pb_update.anr1, strlen(arg_number2)+1, "%s", arg_number2);
187                 pb_update.anr1_ton = arg_number2_ton;
188         }
189
190         if(strlen(arg_number3)){
191                 snprintf((char *)pb_update.anr1, strlen(arg_number3)+1, "%s", arg_number3);
192                 pb_update.anr1_ton = arg_number3_ton;
193         }
194
195         if(strlen(arg_number4)){
196                 snprintf((char *)pb_update.anr1, strlen(arg_number4)+1, "%s", arg_number4);
197                 pb_update.anr1_ton = arg_number4_ton;
198         }
199
200         pb_update.group_index = (unsigned short)arg_group_index;
201
202         tcore_user_request_set_data(ur, sizeof(struct treq_phonebook_update_record), &pb_update);
203         tcore_user_request_set_command(ur, TREQ_PHONEBOOK_UPDATERECORD);
204         tcore_communicator_dispatch_request(ctx->comm, ur);
205
206         return TRUE;
207 }
208
209 static gboolean on_phonebook_delete_record(TelephonyPhonebook *phonebook, GDBusMethodInvocation *invocation,
210                 gint arg_type, gint arg_index, gpointer user_data)
211 {
212         struct custom_data *ctx = user_data;
213         UserRequest *ur = NULL;
214
215         struct treq_phonebook_delete_record pb_delete;
216
217         ur = MAKE_UR(ctx, phonebook, invocation);
218         memset(&pb_delete, 0, sizeof(struct treq_phonebook_delete_record));
219
220         pb_delete.index = (unsigned short)arg_index;
221         pb_delete.phonebook_type = arg_type;
222
223         tcore_user_request_set_data(ur, sizeof(struct treq_phonebook_delete_record), &pb_delete);
224         tcore_user_request_set_command(ur, TREQ_PHONEBOOK_DELETERECORD);
225         tcore_communicator_dispatch_request(ctx->comm, ur);
226
227         return TRUE;
228 }
229
230 gboolean dbus_plugin_setup_phonebook_interface(TelephonyObjectSkeleton *object, struct custom_data *ctx)
231 {
232         TelephonyPhonebook *phonebook;
233
234         phonebook = telephony_phonebook_skeleton_new();
235         telephony_object_skeleton_set_phonebook(object, phonebook);
236         g_object_unref(phonebook);
237
238         dbg("phonebook = %p", phonebook);
239
240         g_signal_connect (phonebook,
241                         "handle-get-init-status",
242                         G_CALLBACK (on_phonebook_get_init_status),
243                         ctx);
244
245         g_signal_connect (phonebook,
246                         "handle-get-count",
247                         G_CALLBACK (on_phonebook_get_count),
248                         ctx);
249
250         g_signal_connect (phonebook,
251                         "handle-get-info",
252                         G_CALLBACK (on_phonebook_get_info),
253                         ctx);
254
255         g_signal_connect (phonebook,
256                         "handle-get-usim-meta-info",
257                         G_CALLBACK (on_phonebook_get_usim_info),
258                         ctx);
259
260         g_signal_connect (phonebook,
261                         "handle-read-record",
262                         G_CALLBACK (on_phonebook_read_record),
263                         ctx);
264
265         g_signal_connect (phonebook,
266                         "handle-update-record",
267                         G_CALLBACK (on_phonebook_update_record),
268                         ctx);
269
270         g_signal_connect (phonebook,
271                         "handle-delete-record",
272                         G_CALLBACK (on_phonebook_delete_record),
273                         ctx);
274
275         return TRUE;
276 }
277
278 gboolean dbus_plugin_phonebook_response(struct custom_data *ctx, UserRequest *ur,
279                 struct dbus_request_info *dbus_info, enum tcore_response_command command,
280                 unsigned int data_len, const void *data)
281 {
282         const struct tresp_phonebook_get_count *resp_pbcnt = data;
283         const struct tresp_phonebook_get_info *resp_entry = data;
284         const struct tresp_phonebook_get_usim_info *resp_capa = data;
285         const struct tresp_phonebook_read_record *resp_pbread = data;
286         const struct tresp_phonebook_update_record *resp_pbupdate = data;
287         const struct tresp_phonebook_delete_record *resp_pbdelete = data;
288
289         dbg("application command = [0x%x], data_len = %d", command, data_len);
290
291         switch (command) {
292                 case TRESP_PHONEBOOK_GETCOUNT:
293                         dbg("dbus comm - TRESP_PHONEBOOK_GETCOUNT");
294                         dbg("used[%d]total[%d]", resp_pbcnt->used_count, resp_pbcnt->total_count);
295                         telephony_phonebook_complete_get_count(dbus_info->interface_object, dbus_info->invocation,
296                                         resp_pbcnt->result, resp_pbcnt->type, resp_pbcnt->used_count, resp_pbcnt->total_count);
297                         break;
298
299                 case TRESP_PHONEBOOK_GETMETAINFO:
300                         dbg("dbus comm - TRESP_PHONEBOOK_GETMETAINFO");
301                         dbg("index min[%d]max[%d], num len max[%d] text len max[%d]", resp_entry->index_min, resp_entry->index_max, resp_entry->number_length_max, resp_entry->text_length_max);
302                         telephony_phonebook_complete_get_info(dbus_info->interface_object, dbus_info->invocation,
303                                         resp_entry->result, resp_entry->type, resp_entry->index_min, resp_entry->index_max,
304                                         resp_entry->number_length_max, resp_entry->text_length_max);
305                         break;
306
307                 case TRESP_PHONEBOOK_GETUSIMINFO:{
308                         GVariant *gv = NULL;
309                         GVariantBuilder b;
310                         int i;
311                         dbg("resp comm - TRESP_PHONEBOOK_GETUSIMINFO");
312                         g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}"));
313
314                         for(i=0;i < resp_capa->field_count; i++){
315                                 g_variant_builder_open(&b,G_VARIANT_TYPE("a{sv}"));
316                                 g_variant_builder_add(&b, "{sv}", "filed_type", g_variant_new_int32(resp_capa->field_list[i].field));
317                                 g_variant_builder_add(&b, "{sv}", "index_max", g_variant_new_int32(resp_capa->field_list[i].index_max));
318                                 g_variant_builder_add(&b, "{sv}", "text_max", g_variant_new_int32(resp_capa->field_list[i].text_max));
319                                 g_variant_builder_add(&b, "{sv}", "used_count", g_variant_new_int32(resp_capa->field_list[i].used_count));
320                                 g_variant_builder_close(&b);
321                         }
322                         gv = g_variant_builder_end(&b);
323
324                         telephony_phonebook_complete_get_usim_meta_info (dbus_info->interface_object, dbus_info->invocation,
325                                         resp_capa->result,
326                                         gv);
327                         g_variant_unref(gv);
328                 }
329                         break;
330
331                 case TRESP_PHONEBOOK_READRECORD:
332                         dbg("dbus comm - TRESP_PHONEBOOK_READRECORD");
333                         dbg("resp_pbread->index[%d]",resp_pbread->index );
334                         dbg("resp_pbread->next_index[%d]",resp_pbread->next_index );
335                         dbg("resp_pbread->name[%s]",resp_pbread->name );
336                         dbg("resp_pbread->dcs[%d]",resp_pbread->dcs );
337                         dbg("resp_pbread->number[%s]",resp_pbread->number );
338                         dbg("resp_pbread->ton[%d]",resp_pbread->ton );
339
340                         telephony_phonebook_complete_read_record(dbus_info->interface_object, dbus_info->invocation,
341                                         resp_pbread->result, resp_pbread->phonebook_type, resp_pbread->index, resp_pbread->next_index, (const gchar *)resp_pbread->name,
342                                         resp_pbread->dcs, (const gchar *)resp_pbread->number, resp_pbread->ton, (const gchar *)resp_pbread->anr1, resp_pbread->anr1_ton,
343                                         (const gchar *)resp_pbread->anr2, resp_pbread->anr2_ton, (const gchar *)resp_pbread->anr3, resp_pbread->anr3_ton,
344                                         (const gchar *)resp_pbread->email1, (const gchar *)resp_pbread->email2, (const gchar *)resp_pbread->email3, (const gchar *)resp_pbread->email4, resp_pbread->group_index);
345                         break;
346
347                 case TRESP_PHONEBOOK_UPDATERECORD:
348                         dbg("dbus comm - TRESP_PHONEBOOK_UPDATERECORD");
349                         telephony_phonebook_complete_update_record(dbus_info->interface_object, dbus_info->invocation,resp_pbupdate->result);
350                         break;
351
352                 case TRESP_PHONEBOOK_DELETERECORD:
353                         dbg("dbus comm - TRESP_PHONEBOOK_DELETERECORD");
354                         telephony_phonebook_complete_delete_record(dbus_info->interface_object, dbus_info->invocation, resp_pbdelete->result);
355                         break;
356
357                 default:
358                         dbg("not handled cmd[0x%x]", command);
359                         break;
360         }
361
362         return TRUE;
363 }
364
365 gboolean dbus_plugin_phonebook_notification(struct custom_data *ctx, const char *plugin_name,
366                 TelephonyObjectSkeleton *object, enum tcore_notification_command command,
367                 unsigned int data_len, const void *data)
368 {
369         TelephonyPhonebook *phonebook;
370         const struct tnoti_phonebook_status *n_pb_status = data;
371
372         if (!object) {
373                 dbg("object is NULL");
374                 return FALSE;
375         }
376
377         phonebook = telephony_object_peek_phonebook(TELEPHONY_OBJECT(object));
378         dbg("phonebook = %p", phonebook);
379
380         switch (command) {
381                 case TNOTI_PHONEBOOK_STATUS :
382                         telephony_phonebook_emit_status(phonebook, n_pb_status->b_init);
383                         break;
384
385                 default:
386                         dbg("not handled cmd[0x%x]", command);
387                         break;
388         }
389
390         return TRUE;
391 }