1c76dc2b764980ee8828004a885417eab0e6f4da
[platform/core/telephony/tel-plugin-dbus_tapi.git] / src / dtapi_call.c
1 /*
2  * tel-plugin-dbus-tapi
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
25 #include <glib.h>
26
27 #include <tcore.h>
28 #include <plugin.h>
29 #include <server.h>
30 #include <co_call.h>
31
32 #include "generated-code.h"
33 #include "dtapi_common.h"
34
35 static gboolean on_call_dial(TelephonyCall *call,
36         GDBusMethodInvocation *invocation,
37         gint call_type, gint call_ecc, gchar *call_number,
38         gpointer user_data)
39 {
40         struct treq_call_dial req;
41         struct custom_data *ctx = user_data;
42         cynara *p_cynara = ctx->p_cynara;
43
44         memset(&req, 0x0, sizeof(req));
45
46         if (!check_access_control(p_cynara, invocation, AC_CALL, "x"))
47                 return TRUE;
48
49         req.type = call_type;
50         req.ecc = call_ecc;
51
52         if (call_number)
53                 g_strlcpy(req.number, call_number, MAX_CALL_DIAL_NUM_LEN);
54
55         dbg("[%s] Dial number len: [%d] Dial number: [%s]",
56                 GET_CP_NAME(invocation), strlen(req.number), req.number);
57
58         /* Dispatch request */
59         dtapi_dispatch_request(ctx, call, invocation,
60                 TREQ_CALL_DIAL,
61                 &req, sizeof(struct treq_call_dial));
62
63         return TRUE;
64 }
65
66 static gboolean on_call_answer(TelephonyCall *call,
67         GDBusMethodInvocation *invocation,
68         gint call_handle, gint answer_type, gpointer user_data)
69 {
70         struct treq_call_answer req;
71         struct custom_data *ctx = user_data;
72         cynara *p_cynara = ctx->p_cynara;
73
74         if (!check_access_control(p_cynara, invocation, AC_CALL, "x"))
75                 return TRUE;
76
77         req.handle = call_handle;
78         req.type = answer_type;
79
80         dbg("[%s] Call handle: [%d] Answer type: [%s]",
81                 GET_CP_NAME(invocation), req.handle,
82                 (req.type == CALL_ANSWER_TYPE_ACCEPT ? "ACCEPT" :
83                 (req.type == CALL_ANSWER_TYPE_REJECT ? "REJECT" :
84                 (req.type == CALL_ANSWER_TYPE_REPLACE ? "REPLACE" :
85                 (req.type == CALL_ANSWER_TYPE_HOLD_ACCEPT ? "HOLD & ACCEPT" :
86                 "UNKNOWN OPERATION")))));
87
88         /* Dispatch request */
89         dtapi_dispatch_request(ctx, call, invocation,
90                 TREQ_CALL_ANSWER,
91                 &req, sizeof(struct treq_call_answer));
92
93         return TRUE;
94 }
95
96 static gboolean on_call_end(TelephonyCall *call,
97         GDBusMethodInvocation *invocation,
98         gint call_handle, gint end_type, gpointer user_data)
99 {
100         struct treq_call_end req;
101         struct custom_data *ctx = user_data;
102         cynara *p_cynara = ctx->p_cynara;
103
104         if (!check_access_control(p_cynara, invocation, AC_CALL, "x"))
105                 return TRUE;
106
107         req.handle = call_handle;
108         req.type = end_type;
109
110         dbg("[%s] Call handle: [%d] End type: [%s]",
111                 GET_CP_NAME(invocation), req.handle,
112                 (req.type == CALL_END_TYPE_ALL ? "END ALL" :
113                 (req.type == CALL_END_TYPE_ACTIVE_ALL ? "END ALL ACTIVE" :
114                 (req.type == CALL_END_TYPE_HOLD_ALL ? "END ALL HELD" :
115                 (req.type == CALL_END_TYPE_DEFAULT ? "END SPECIFIC" :
116                 "UNKNOWN OPERATION")))));
117
118         /* Dispatch request */
119         dtapi_dispatch_request(ctx, call, invocation,
120                 TREQ_CALL_END, &req, sizeof(struct treq_call_end));
121
122         return TRUE;
123 }
124
125 static gboolean on_call_start_cont_dtmf(TelephonyCall *call,
126         GDBusMethodInvocation *invocation,
127         guchar dtmf_digit, gpointer user_data)
128 {
129         struct treq_call_start_cont_dtmf  req;
130         struct custom_data *ctx = user_data;
131         cynara *p_cynara = ctx->p_cynara;
132
133         if (!check_access_control(p_cynara, invocation, AC_CALL, "x"))
134                 return TRUE;
135
136         memset(&req, 0x0, sizeof(req));
137
138         req.dtmf_digit = dtmf_digit;
139
140         dbg("[%s] DTMF Digit: [%c]", GET_CP_NAME(invocation), req.dtmf_digit);
141
142         /* Dispatch request */
143         dtapi_dispatch_request(ctx, call, invocation,
144                 TREQ_CALL_START_CONT_DTMF,
145                 &req, sizeof(struct treq_call_start_cont_dtmf));
146
147         return TRUE;
148 }
149
150 static gboolean on_call_stop_cont_dtmf(TelephonyCall *call,
151         GDBusMethodInvocation *invocation, gpointer user_data)
152 {
153         struct custom_data *ctx = user_data;
154         cynara *p_cynara = ctx->p_cynara;
155
156         if (!check_access_control(p_cynara, invocation, AC_CALL, "x"))
157                 return TRUE;
158
159         dbg("[%s] Stop DTMF", GET_CP_NAME(invocation));
160
161         /* Dispatch request */
162         dtapi_dispatch_request(ctx, call, invocation,
163                 TREQ_CALL_STOP_CONT_DTMF,
164                 NULL, 0);
165
166         return TRUE;
167 }
168
169 static gboolean on_call_send_burst_dtmf(TelephonyCall *call,
170         GDBusMethodInvocation *invocation,
171         gchar *dtmf_string, gint pulse_width, gint inter_digit_interval, gpointer user_data)
172 {
173         struct treq_call_send_burst_dtmf req;
174         struct custom_data *ctx = user_data;
175         cynara *p_cynara = ctx->p_cynara;
176
177         if (!check_access_control(p_cynara, invocation, AC_CALL, "x"))
178                 return TRUE;
179
180         memset(&req, 0x0, sizeof(req));
181
182         if (dtmf_string) {
183                 g_strlcpy(req.dtmf_string, dtmf_string, MAX_CALL_BURST_DTMF_STRING_LEN + 1);
184         } else {
185                 err("Invalid DTMF string");
186
187                 FAIL_RESPONSE(invocation, "Invalid Input");
188
189                 return TRUE;
190         }
191
192         req.pulse_width = pulse_width;
193         req.inter_digit_interval = inter_digit_interval;
194
195         dbg("[%s] Pulse width: [%d] Inter-digit interval: [%d]",
196                 GET_CP_NAME(invocation),
197                 req.pulse_width, req.inter_digit_interval);
198
199         /* Dispatch request */
200         dtapi_dispatch_request(ctx, call, invocation,
201                 TREQ_CALL_SEND_BURST_DTMF,
202                 &req, sizeof(struct treq_call_send_burst_dtmf));
203
204         return TRUE;
205 }
206
207 static gboolean on_call_active(TelephonyCall *call,
208         GDBusMethodInvocation *invocation,
209         gint call_handle, gpointer user_data)
210 {
211         struct treq_call_active req;
212         struct custom_data *ctx = user_data;
213         cynara *p_cynara = ctx->p_cynara;
214
215         if (!check_access_control(p_cynara, invocation, AC_CALL, "x"))
216                 return TRUE;
217
218         req.handle = call_handle;
219
220         dbg("[%s] Call handle: [%d]", GET_CP_NAME(invocation), req.handle);
221
222         /* Dispatch request */
223         dtapi_dispatch_request(ctx, call, invocation,
224                 TREQ_CALL_ACTIVE,
225                 &req, sizeof(struct treq_call_active));
226
227         return TRUE;
228 }
229
230 static gboolean on_call_hold(TelephonyCall *call,
231         GDBusMethodInvocation *invocation,
232         gint call_handle, gpointer user_data)
233 {
234         struct treq_call_hold req;
235         struct custom_data *ctx = user_data;
236         cynara *p_cynara = ctx->p_cynara;
237
238         if (!check_access_control(p_cynara, invocation, AC_CALL, "x"))
239                 return TRUE;
240
241         req.handle = call_handle;
242
243         dbg("[%s] Call handle: [%d]", GET_CP_NAME(invocation), req.handle);
244
245         /* Dispatch request */
246         dtapi_dispatch_request(ctx, call, invocation,
247                 TREQ_CALL_HOLD,
248                 &req, sizeof(struct treq_call_hold));
249
250         return TRUE;
251 }
252
253 static gboolean on_call_swap(TelephonyCall *call,
254         GDBusMethodInvocation *invocation,
255         gint call_handle, gpointer user_data)
256 {
257         struct treq_call_swap req;
258         struct custom_data *ctx = user_data;
259         cynara *p_cynara = ctx->p_cynara;
260
261         if (!check_access_control(p_cynara, invocation, AC_CALL, "x"))
262                 return TRUE;
263
264         req.handle = call_handle;
265
266         dbg("[%s] Call handle: [%d]", GET_CP_NAME(invocation), req.handle);
267
268         /* Dispatch request */
269         dtapi_dispatch_request(ctx, call, invocation,
270                 TREQ_CALL_SWAP,
271                 &req, sizeof(struct treq_call_swap));
272
273         return TRUE;
274 }
275
276 static gboolean on_call_join(TelephonyCall *call,
277         GDBusMethodInvocation *invocation,
278         gint call_handle, gpointer user_data)
279 {
280         struct treq_call_join req;
281         struct custom_data *ctx = user_data;
282         cynara *p_cynara = ctx->p_cynara;
283
284         if (!check_access_control(p_cynara, invocation, AC_CALL, "x"))
285                 return TRUE;
286
287         req.handle = call_handle;
288
289         dbg("[%s] Call handle: [%d]", GET_CP_NAME(invocation), req.handle);
290
291         /* Dispatch request */
292         dtapi_dispatch_request(ctx, call, invocation,
293                 TREQ_CALL_JOIN,
294                 &req, sizeof(struct treq_call_join));
295
296         return TRUE;
297 }
298
299 static gboolean on_call_split(TelephonyCall *call,
300         GDBusMethodInvocation *invocation,
301         gint call_handle, gpointer user_data)
302 {
303         struct treq_call_split req;
304         struct custom_data *ctx = user_data;
305         cynara *p_cynara = ctx->p_cynara;
306
307         if (!check_access_control(p_cynara, invocation, AC_CALL, "x"))
308                 return TRUE;
309
310         req.handle = call_handle;
311
312         dbg("[%s] Call handle: [%d]", GET_CP_NAME(invocation), req.handle);
313
314         /* Dispatch request */
315         dtapi_dispatch_request(ctx, call, invocation,
316                 TREQ_CALL_SPLIT,
317                 &req, sizeof(struct treq_call_split));
318
319         return TRUE;
320 }
321
322 static gboolean on_call_transfer(TelephonyCall *call,
323         GDBusMethodInvocation *invocation,
324         gint call_handle, gpointer user_data)
325 {
326         struct treq_call_transfer req;
327         struct custom_data *ctx = user_data;
328         cynara *p_cynara = ctx->p_cynara;
329
330         if (!check_access_control(p_cynara, invocation, AC_CALL, "x"))
331                 return TRUE;
332
333         req.handle = call_handle;
334
335         dbg("[%s] Call handle: [%d]", GET_CP_NAME(invocation), req.handle);
336
337         /* Dispatch request */
338         dtapi_dispatch_request(ctx, call, invocation,
339                 TREQ_CALL_TRANSFER,
340                 &req, sizeof(struct treq_call_transfer));
341
342         return TRUE;
343 }
344
345 static gboolean on_call_deflect(TelephonyCall *call,
346         GDBusMethodInvocation *invocation,
347         gchar *call_number, gpointer user_data)
348 {
349         struct treq_call_deflect req = {0};
350         struct custom_data *ctx = user_data;
351         cynara *p_cynara = ctx->p_cynara;
352
353         if (!check_access_control(p_cynara, invocation, AC_CALL, "x"))
354                 return TRUE;
355
356         if (call_number)
357                 g_strlcpy(req.number, call_number, MAX_CALL_DIAL_NUM_LEN);
358
359         dbg("[%s] Call handle: [%d] Number: [%s]", GET_CP_NAME(invocation),
360                 req.handle, req.number);
361
362         /* Dispatch request */
363         dtapi_dispatch_request(ctx, call, invocation,
364                 TREQ_CALL_DEFLECT,
365                 &req, sizeof(struct treq_call_deflect));
366
367         return TRUE;
368 }
369
370 static gboolean on_call_get_privacy_mode(TelephonyCall *call,
371         GDBusMethodInvocation *invocation, gpointer user_data)
372 {
373         struct custom_data *ctx = user_data;
374         cynara *p_cynara = ctx->p_cynara;
375
376         if (!check_access_control(p_cynara, invocation, AC_CALL, "r"))
377                 return TRUE;
378
379         /* Dispatch request */
380         dtapi_dispatch_request(ctx, call, invocation,
381                 TREQ_CALL_GET_PRIVACY_MODE,
382                 NULL, 0);
383
384         return TRUE;
385 }
386
387 static gboolean on_call_set_privacy_mode(TelephonyCall *call,
388         GDBusMethodInvocation *invocation,
389         gint privacy_mode, gpointer user_data)
390 {
391         struct treq_call_set_voice_privacy_mode req;
392         struct custom_data *ctx = user_data;
393         cynara *p_cynara = ctx->p_cynara;
394
395         if (!check_access_control(p_cynara, invocation, AC_CALL, "w"))
396                 return TRUE;
397
398         req.privacy_mode = privacy_mode;
399
400         dbg("[%s] Privacy mode: [%d]", GET_CP_NAME(invocation), req.privacy_mode);
401
402         /* Dispatch request */
403         dtapi_dispatch_request(ctx, call, invocation,
404                 TREQ_CALL_SET_PRIVACY_MODE,
405                 &req, sizeof(struct treq_call_set_voice_privacy_mode));
406
407         return TRUE;
408 }
409
410 static gboolean on_call_get_status(TelephonyCall *call,
411         GDBusMethodInvocation *invocation,
412         gint call_handle, gpointer user_data)
413 {
414         struct custom_data *ctx = user_data;
415         TcorePlugin *plugin = 0;
416         CoreObject *call_co = NULL;
417         CallObject *call_obj = NULL;
418         cynara *p_cynara = ctx->p_cynara;
419
420         gchar call_number[MAX_CALL_NUMBER_LEN];
421         gint call_type;
422         gboolean call_direction;
423         gint call_status;
424         gboolean call_multiparty_state;
425
426         if (!check_access_control(p_cynara, invocation, AC_CALL, "r"))
427                 return TRUE;
428
429         plugin = tcore_server_find_plugin(ctx->server, GET_CP_NAME(invocation));
430         call_co = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_CALL);
431         call_obj = tcore_call_object_find_by_handle(call_co, call_handle);
432         if (!call_obj) {
433                 err("Call object: NULL");
434
435                 FAIL_RESPONSE(invocation, DEFAULT_MSG_REQ_FAILED);
436
437                 return TRUE;
438         }
439
440         dbg("[%s] Call handle: [%d]", GET_CP_NAME(invocation), call_handle);
441
442         memset(call_number, 0x0, MAX_CALL_NUMBER_LEN);
443         tcore_call_object_get_number(call_obj, call_number);
444         call_type = tcore_call_object_get_type(call_obj);
445         call_direction = tcore_call_object_get_direction(call_obj);
446
447         if (call_direction == TCORE_CALL_DIRECTION_OUTGOING)
448                 call_direction = TRUE;
449         else
450                 call_direction = FALSE;
451
452         call_status = tcore_call_object_get_status(call_obj);
453         call_multiparty_state = tcore_call_object_get_multiparty_state(call_obj);
454
455         telephony_call_complete_get_status(call, invocation,
456                 call_handle, call_number, call_type,
457                 call_direction, call_status, call_multiparty_state);
458
459         return TRUE;
460 }
461
462 static gboolean on_call_get_status_all(TelephonyCall *call,
463         GDBusMethodInvocation *invocation, gpointer user_data)
464 {
465         struct custom_data *ctx = user_data;
466         TcorePlugin *plugin = 0;
467         CoreObject *call_co = NULL;
468         CallObject *call_obj = NULL;
469         GSList *list, *tmp;
470
471         GVariant *gv = NULL;
472         GVariantBuilder b;
473         cynara *p_cynara = ctx->p_cynara;
474
475         gint call_id;
476         gint handle;
477         gchar call_number[MAX_CALL_NUMBER_LEN];
478         gint call_type;
479         gboolean call_direction;
480         gint call_status;
481         gboolean call_multiparty_state;
482
483         int len, i;
484
485         if (!check_access_control(p_cynara, invocation, AC_CALL, "r"))
486                 return TRUE;
487
488         plugin = tcore_server_find_plugin(ctx->server, GET_CP_NAME(invocation));
489         call_co = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_CALL);
490
491         g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}"));
492         for (i = 0; i < TCORE_CALL_STATUS_MAX; i++) {
493                 tmp = list = tcore_call_object_find_by_status(call_co, i);
494                 if (list == NULL)
495                         continue;
496
497                 while (tmp) {
498                         call_obj = (CallObject *)tmp->data;
499                         if (!call_obj) {
500                                 err("call object: NULL");
501
502                                 /* Next Call object */
503                                 tmp = g_slist_next(tmp);
504                                 continue;
505                         }
506
507                         handle = tcore_call_object_get_handle(call_obj);
508                         call_id = tcore_call_object_get_id(call_obj);
509
510                         memset(call_number, 0, MAX_CALL_NUMBER_LEN);
511                         len = tcore_call_object_get_number(call_obj, call_number);
512                         if (!len)
513                                 warn("[ CHECK ] NO number: Call handle: [%d]", handle);
514
515                         call_type = tcore_call_object_get_type(call_obj);
516                         call_direction = tcore_call_object_get_direction(call_obj);
517
518                         if (call_direction == TCORE_CALL_DIRECTION_OUTGOING)
519                                 call_direction = TRUE;
520                         else
521                                 call_direction = FALSE;
522
523                         call_status = tcore_call_object_get_status(call_obj);
524                         if ((TCORE_CALL_STATUS_SETUP == call_status)
525                                         || (TCORE_CALL_STATUS_SETUP_PENDING == call_status)) {
526                                 dbg("SETUP/SETUP_PENDING found. This is already notified as " \
527                                         "dialing status to applicaiton, so change it to 'Dialing' ");
528                                 call_status = TCORE_CALL_STATUS_DIALING;
529                         }
530
531                         call_multiparty_state = tcore_call_object_get_multiparty_state(call_obj);
532
533                         dbg("Call handle: [%d] Call ID: [%d] Call number: [%s] Call number len: [%d]",
534                                 handle, call_id, call_number, len);
535                         dbg("Call Type: [%s] Call Direction: [%s] Call Status: [%s] Multi-Party Call: [%s]",
536                                 call_type == TCORE_CALL_TYPE_VOICE ? "VOICE" :
537                                 (call_type == TCORE_CALL_TYPE_VIDEO ? "VIDEO" :
538                                 (call_type == TCORE_CALL_TYPE_E911 ? "E911" :
539                                 (call_type == TCORE_CALL_TYPE_STDOTASP ? "STDOTASP" :
540                                 (call_type == TCORE_CALL_TYPE_NONSTDOTASP ? "NONSTDOTASP" : "UNKNOWN")))),
541                                 (call_direction == TRUE ? "MO" : "MT"),
542                                 (call_status == TCORE_CALL_STATUS_IDLE ? "IDLE" :
543                                 (call_status == TCORE_CALL_STATUS_ACTIVE ? "ACTIVE" :
544                                 (call_status == TCORE_CALL_STATUS_HELD ? "HELD" :
545                                 (call_status == TCORE_CALL_STATUS_DIALING ? "DIALING" :
546                                 (call_status == TCORE_CALL_STATUS_ALERT ? "ALERT" :
547                                 (call_status == TCORE_CALL_STATUS_INCOMING ? "INCOMING" :
548                                 (call_status == TCORE_CALL_STATUS_WAITING ? "WAITING" :
549                                 (call_status == TCORE_CALL_STATUS_SETUP ? "SETUP" :
550                                 (call_status == TCORE_CALL_STATUS_SETUP_PENDING ? "SETUP_PENDING" : "UNKNOWN"))))))))),
551                                 (call_multiparty_state == 1 ? "YES" : "NO"));
552
553                         g_variant_builder_open(&b, G_VARIANT_TYPE("a{sv}"));
554                         g_variant_builder_add(&b, "{sv}", "call_id",
555                                 g_variant_new_int32(handle));
556                         g_variant_builder_add(&b, "{sv}", "call_number",
557                                 g_variant_new_string(call_number));
558                         g_variant_builder_add(&b, "{sv}", "call_type",
559                                 g_variant_new_int32(call_type));
560                         g_variant_builder_add(&b, "{sv}", "call_direction",
561                                 g_variant_new_boolean(call_direction));
562                         g_variant_builder_add(&b, "{sv}", "call_state",
563                                 g_variant_new_int32(call_status));
564                         g_variant_builder_add(&b, "{sv}", "call_multiparty_state",
565                                 g_variant_new_boolean(call_multiparty_state));
566                         g_variant_builder_close(&b);
567
568                         /* Next Call object */
569                         tmp = g_slist_next(tmp);
570                 }
571
572                 /* Free list */
573                 g_slist_free(list);
574         }
575         gv = g_variant_builder_end(&b);
576
577         telephony_call_complete_get_status_all(call, invocation, gv);
578
579         return TRUE;
580 }
581
582 static gboolean on_call_set_sound_path(TelephonyCall *call,
583         GDBusMethodInvocation *invocation,
584         gint sound_path, gboolean extra_volume_on, gpointer user_data)
585 {
586         struct treq_call_set_sound_path req;
587         struct custom_data *ctx = user_data;
588         cynara *p_cynara = ctx->p_cynara;
589
590         if (!check_access_control(p_cynara, invocation, AC_CALL, "w"))
591                 return TRUE;
592
593         req.path = sound_path;
594         req.extra_volume_on = extra_volume_on;
595
596         dbg("[%s] Sound path: [%d] Extra Volume: [%s]", GET_CP_NAME(invocation),
597                 req.path, (extra_volume_on ? "ON" : "OFF"));
598
599         /* Dispatch request */
600         dtapi_dispatch_request(ctx, call, invocation,
601                 TREQ_CALL_SET_SOUND_PATH,
602                 &req, sizeof(struct treq_call_set_sound_path));
603
604         return TRUE;
605 }
606
607 static gboolean on_call_get_sound_volume_level(TelephonyCall *call,
608         GDBusMethodInvocation *invocation,
609         gint sound_device, gint sound_type, gpointer user_data)
610 {
611         struct treq_call_get_sound_volume_level req;
612         struct custom_data *ctx = user_data;
613         TReturn ret;
614         cynara *p_cynara = ctx->p_cynara;
615
616         if (!check_access_control(p_cynara, invocation, AC_CALL, "r"))
617                 return TRUE;
618
619         req.device = sound_device;
620         req.sound = sound_type;
621
622         dbg("[%s] Sound device: [%d] Sound type: [%d]", GET_CP_NAME(invocation),
623                 req.device, req.sound);
624
625         /* Dispatch request */
626         ret = dtapi_dispatch_request_ex(ctx, call, invocation,
627                 TREQ_CALL_GET_SOUND_VOLUME_LEVEL,
628                 &req, sizeof(struct treq_call_get_sound_volume_level));
629         if (ret != TCORE_RETURN_SUCCESS) {
630                 GVariantBuilder b;
631                 GVariant *result = 0;
632
633                 g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}"));
634                 g_variant_builder_open(&b, G_VARIANT_TYPE("a{sv}"));
635                 g_variant_builder_add(&b, "{sv}", "err", g_variant_new_int32(ret));
636                 g_variant_builder_close(&b);
637                 result = g_variant_builder_end(&b);
638
639                 telephony_call_complete_get_sound_volume_level(call,
640                         invocation, result, ret);
641         }
642
643         return TRUE;
644 }
645
646 static gboolean on_call_set_sound_volume_level(TelephonyCall *call,
647         GDBusMethodInvocation *invocation,
648         gint sound_device, gint sound_type, gint sound_volume,
649         gpointer user_data)
650 {
651         struct treq_call_set_sound_volume_level req;
652         struct custom_data *ctx = user_data;
653         cynara *p_cynara = ctx->p_cynara;
654
655         if (!check_access_control(p_cynara, invocation, AC_CALL, "w"))
656                 return TRUE;
657
658         req.device = sound_device;
659         req.sound = sound_type;
660         req.volume = sound_volume;
661
662         dbg("[%s] Sound device: [%d] Sound type: [%d] Volume level: [%d]",
663                 GET_CP_NAME(invocation),
664                 req.device, req.sound, req.volume);
665
666         /* Dispatch request */
667         dtapi_dispatch_request(ctx, call, invocation,
668                 TREQ_CALL_SET_SOUND_VOLUME_LEVEL,
669                 &req, sizeof(struct treq_call_set_sound_volume_level));
670
671         return TRUE;
672 }
673
674 static gboolean on_call_get_sound_mute_status(TelephonyCall *call,
675         GDBusMethodInvocation *invocation, gpointer user_data)
676 {
677         struct custom_data *ctx = user_data;
678         cynara *p_cynara = ctx->p_cynara;
679
680         if (!check_access_control(p_cynara, invocation, AC_CALL, "r"))
681                 return TRUE;
682
683         /* Dispatch request */
684         dtapi_dispatch_request(ctx, call, invocation,
685                 TREQ_CALL_GET_SOUND_MUTE_STATUS,
686                 NULL, 0);
687
688         return TRUE;
689 }
690
691 static gboolean on_call_set_sound_mute_status(TelephonyCall *call,
692         GDBusMethodInvocation *invocation, gint status, gint path,
693         gpointer user_data)
694 {
695         struct treq_call_set_sound_mute_status req;
696         struct custom_data *ctx = user_data;
697         cynara *p_cynara = ctx->p_cynara;
698
699         if (!check_access_control(p_cynara, invocation, AC_CALL, "w"))
700                 return TRUE;
701
702         req.path = path;
703         req.status = status;
704
705         dbg("[%s] Path: [%s] Mute Status: [%s]", GET_CP_NAME(invocation),
706                 (req.path == CALL_SOUND_MUTE_PATH_TX ? "OUTGOING" :
707                 (req.path == CALL_SOUND_MUTE_PATH_RX ? "INCOMING" :
708                 "BOTH In- & Out-coming")),
709                 (req.status == CALL_SOUND_MUTE_STATUS_OFF ? "OFF" : "ON"));
710
711         /* Dispatch request */
712         dtapi_dispatch_request(ctx, call, invocation,
713                 TREQ_CALL_SET_SOUND_MUTE_STATUS,
714                 &req, sizeof(struct treq_call_set_sound_mute_status));
715
716         return TRUE;
717 }
718
719 static gboolean on_call_set_sound_recording(TelephonyCall *call,
720         GDBusMethodInvocation *invocation,
721         gint recording_state, gpointer user_data)
722 {
723         struct custom_data *ctx = user_data;
724         struct treq_call_set_sound_recording req;
725         cynara *p_cynara = ctx->p_cynara;
726
727         if (!check_access_control(p_cynara, invocation, AC_CALL, "w"))
728                 return TRUE;
729
730         req.state = (gboolean)recording_state;
731
732         dbg("[%s] Recording state: [%s]", GET_CP_NAME(invocation),
733                 (req.state ? "ON" : "OFF"));
734
735         /* Dispatch request */
736         dtapi_dispatch_request(ctx, call, invocation,
737                 TREQ_CALL_SET_SOUND_RECORDING,
738                 &req, sizeof(struct treq_call_set_sound_recording));
739
740         return TRUE;
741 }
742
743 static gboolean on_call_set_sound_equalization(TelephonyCall *call,
744         GDBusMethodInvocation *invocation,
745         gint eq_mode, gint eq_direction, gchar *eq_parameter,
746         gpointer user_data)
747 {
748         struct custom_data *ctx = user_data;
749         struct treq_call_set_sound_equalization req;
750         cynara *p_cynara = ctx->p_cynara;
751
752         if (!check_access_control(p_cynara, invocation, AC_CALL, "w"))
753                 return TRUE;
754
755         req.mode = eq_mode;
756         req.direction = (enum telephony_call_sound_direction)eq_direction;
757         memcpy((char *)req.parameter, (const char *)eq_parameter, (MAX_CALL_EQ_PARAMETER_SIZE * 2));
758
759         dbg("[%s] Equalization mode: [%d] Direction: [%s]",
760                 GET_CP_NAME(invocation), req.mode,
761                 (req.direction == CALL_SOUND_DIRECTION_LEFT ? "LEFT" : "RIGHT"));
762
763         /* Dispatch request */
764         dtapi_dispatch_request(ctx, call, invocation,
765                 TREQ_CALL_SET_SOUND_EQUALIZATION,
766                 &req, sizeof(struct treq_call_set_sound_equalization));
767
768         return TRUE;
769 }
770
771 static gboolean on_call_set_sound_noise_reduction(TelephonyCall *call,
772         GDBusMethodInvocation *invocation,
773         gint nr_state, gpointer user_data)
774 {
775         struct custom_data *ctx = user_data;
776         struct treq_call_set_sound_noise_reduction req;
777         cynara *p_cynara = ctx->p_cynara;
778
779         if (!check_access_control(p_cynara, invocation, AC_CALL, "w"))
780                 return TRUE;
781
782         req.status = (gboolean)nr_state;
783
784         dbg("[%s] NR Status: [%d]", GET_CP_NAME(invocation), req.status);
785
786         /* Dispatch request */
787         dtapi_dispatch_request(ctx, call, invocation,
788                 TREQ_CALL_SET_SOUND_NOISE_REDUCTION,
789                 &req, sizeof(struct treq_call_set_sound_noise_reduction));
790
791         return TRUE;
792 }
793
794 static gboolean on_call_set_sound_clock_status(TelephonyCall *call,
795         GDBusMethodInvocation *invocation,
796         gboolean clock_status, gpointer user_data)
797 {
798         struct custom_data *ctx = user_data;
799         struct treq_call_set_sound_clock_status req;
800         cynara *p_cynara = ctx->p_cynara;
801
802         if (!check_access_control(p_cynara, invocation, AC_CALL, "w"))
803                 return TRUE;
804
805         req.status = clock_status;
806
807         dbg("[%s] Clock Status: [%s]", GET_CP_NAME(invocation),
808                 (req.status ? "ON" : "OFF"));
809
810         /* Dispatch request */
811         dtapi_dispatch_request(ctx, call, invocation,
812                 TREQ_CALL_SET_SOUND_CLOCK_STATUS,
813                 &req, sizeof(struct treq_call_set_sound_clock_status));
814
815         return TRUE;
816 }
817
818 static gboolean on_call_set_preferred_voice_subscription(TelephonyCall *call,
819         GDBusMethodInvocation *invocation,
820         gint preferred_subscription, gpointer user_data)
821 {
822         struct custom_data *ctx = user_data;
823         struct treq_call_set_preferred_voice_subscription req;
824         cynara *p_cynara = ctx->p_cynara;
825
826         if (!check_access_control(p_cynara, invocation, AC_CALL, "w"))
827                 return TRUE;
828
829         req.preferred_subs = preferred_subscription;
830
831         dbg("[%s] Preferred Voice subscription: [%s]", GET_CP_NAME(invocation),
832                 (req.preferred_subs == CALL_PREFERRED_VOICE_SUBS_CURRENT_NETWORK ? "CURRENT NW" :
833                 (req.preferred_subs == CALL_PREFERRED_VOICE_SUBS_ASK_ALWAYS ? "ASK ALWAYS" :
834                 (req.preferred_subs == CALL_PREFERRED_VOICE_SUBS_SIM1 ? "SIM 1" :
835                 (req.preferred_subs == CALL_PREFERRED_VOICE_SUBS_SIM2 ? "SIM 2" :
836                 "UNKNOWN")))));
837
838         /* Dispatch request */
839         dtapi_dispatch_request(ctx, call, invocation,
840                 TREQ_CALL_SET_PREFERRED_VOICE_SUBSCRIPTION,
841                 &req, sizeof(struct treq_call_set_preferred_voice_subscription));
842
843         return TRUE;
844 }
845
846 static gboolean on_call_get_preferred_voice_subscription(TelephonyCall *call,
847         GDBusMethodInvocation *invocation, gpointer user_data)
848 {
849         struct custom_data *ctx = user_data;
850         cynara *p_cynara = ctx->p_cynara;
851
852         if (!check_access_control(p_cynara, invocation, AC_CALL, "r"))
853                 return TRUE;
854
855         /* Dispatch request */
856         dtapi_dispatch_request(ctx, call, invocation,
857                 TREQ_CALL_GET_PREFERRED_VOICE_SUBSCRIPTION,
858                 NULL, 0);
859
860         return TRUE;
861 }
862
863 static gboolean on_call_modify(TelephonyCall *call,
864         GDBusMethodInvocation *invocation,
865         gint call_handle, gint call_type, gpointer user_data)
866 {
867         struct custom_data *ctx = user_data;
868         struct treq_call_modify req = {0};
869         cynara *p_cynara = ctx->p_cynara;
870
871         if (!check_access_control(p_cynara, invocation, AC_CALL, "x"))
872                 return TRUE;
873
874         req.handle = call_handle;
875         req.call_type = call_type;
876
877         dbg("[%s] Call handle: [%d] Call type: [%s]",
878                 GET_CP_NAME(invocation), req.handle,
879                 (req.call_type == CALL_TYPE_VOICE ? "VOICE" :
880                 (req.call_type == CALL_TYPE_VIDEO ? "VIDEO" :
881                 "EMERGENCY")));
882
883         /* Dispatch request */
884         dtapi_dispatch_request(ctx, call, invocation,
885                 TREQ_CALL_MODIFY,
886                 &req, sizeof(struct treq_call_modify));
887
888         return TRUE;
889 }
890
891 static gboolean on_call_confirm_modify(TelephonyCall *call,
892         GDBusMethodInvocation *invocation,
893         gint call_handle, gint confirm_type, gpointer user_data)
894 {
895         struct custom_data *ctx = user_data;
896         struct treq_call_confirm_modify req = {0};
897         cynara *p_cynara = ctx->p_cynara;
898
899         if (!check_access_control(p_cynara, invocation, AC_CALL, "x"))
900                 return TRUE;
901
902         req.handle = call_handle;
903         req.confirm_type = confirm_type;
904
905         dbg("[%s] Call handle: [%d] Confirm type: [%s]",
906                 GET_CP_NAME(invocation), req.handle,
907                 (req.confirm_type == CALL_CONFIRM_TYPE_ACCEPT ? "ACCEPT" :
908                 "REJECT"));
909
910         /* Dispatch request */
911         dtapi_dispatch_request(ctx, call, invocation,
912                 TREQ_CALL_CONFIRM_MODIFY,
913                 &req, sizeof(struct treq_call_confirm_modify));
914
915         return TRUE;
916 }
917
918 gboolean dbus_plugin_setup_call_interface(TelephonyObjectSkeleton *object,
919         struct custom_data *ctx)
920 {
921         TelephonyCall *call;
922
923         call = telephony_call_skeleton_new();
924         telephony_object_skeleton_set_call(object, call);
925         g_object_unref(call);
926
927         dbg("call = %p", call);
928
929         /*
930          * Register signal handlers for CALL interface
931          */
932         g_signal_connect(call,
933                 "handle-dial",
934                 G_CALLBACK(on_call_dial), ctx);
935
936         g_signal_connect(call,
937                 "handle-answer",
938                 G_CALLBACK(on_call_answer), ctx);
939
940         g_signal_connect(call,
941                 "handle-end",
942                 G_CALLBACK(on_call_end), ctx);
943
944         g_signal_connect(call,
945                 "handle-start-cont-dtmf",
946                 G_CALLBACK(on_call_start_cont_dtmf), ctx);
947
948         g_signal_connect(call,
949                 "handle-stop-cont-dtmf",
950                 G_CALLBACK(on_call_stop_cont_dtmf), ctx);
951
952         g_signal_connect(call,
953                 "handle-send-burst-dtmf",
954                 G_CALLBACK(on_call_send_burst_dtmf), ctx);
955
956         g_signal_connect(call,
957                 "handle-active",
958                 G_CALLBACK(on_call_active), ctx);
959
960         g_signal_connect(call,
961                 "handle-hold",
962                 G_CALLBACK(on_call_hold), ctx);
963
964         g_signal_connect(call,
965                 "handle-swap",
966                 G_CALLBACK(on_call_swap), ctx);
967
968         g_signal_connect(call,
969                 "handle-join",
970                 G_CALLBACK(on_call_join), ctx);
971
972         g_signal_connect(call,
973                 "handle-split",
974                 G_CALLBACK(on_call_split), ctx);
975
976         g_signal_connect(call,
977                 "handle-transfer",
978                 G_CALLBACK(on_call_transfer), ctx);
979
980         g_signal_connect(call,
981                 "handle-deflect",
982                 G_CALLBACK(on_call_deflect), ctx);
983
984         g_signal_connect(call,
985                 "handle-get-privacy-mode",
986                 G_CALLBACK(on_call_get_privacy_mode), ctx);
987
988         g_signal_connect(call,
989                 "handle-set-privacy-mode",
990                 G_CALLBACK(on_call_set_privacy_mode), ctx);
991
992         g_signal_connect(call,
993                 "handle-get-status",
994                 G_CALLBACK(on_call_get_status), ctx);
995
996         g_signal_connect(call,
997                 "handle-get-status-all",
998                 G_CALLBACK(on_call_get_status_all), ctx);
999
1000         g_signal_connect(call,
1001                 "handle-set-sound-path",
1002                 G_CALLBACK(on_call_set_sound_path), ctx);
1003
1004         g_signal_connect(call,
1005                 "handle-get-sound-volume-level",
1006                 G_CALLBACK(on_call_get_sound_volume_level), ctx);
1007
1008         g_signal_connect(call,
1009                 "handle-set-sound-volume-level",
1010                 G_CALLBACK(on_call_set_sound_volume_level), ctx);
1011
1012         g_signal_connect(call,
1013                 "handle-get-sound-mute-status",
1014                 G_CALLBACK(on_call_get_sound_mute_status), ctx);
1015
1016         g_signal_connect(call,
1017                 "handle-set-sound-mute-status",
1018                 G_CALLBACK(on_call_set_sound_mute_status), ctx);
1019
1020         g_signal_connect(call,
1021                 "handle-set-sound-recording",
1022                 G_CALLBACK(on_call_set_sound_recording), ctx);
1023
1024         g_signal_connect(call,
1025                 "handle-set-sound-equalization",
1026                 G_CALLBACK(on_call_set_sound_equalization), ctx);
1027
1028         g_signal_connect(call,
1029                 "handle-set-sound-noise-reduction",
1030                 G_CALLBACK(on_call_set_sound_noise_reduction), ctx);
1031
1032         g_signal_connect(call,
1033                 "handle-set-sound-clock-status",
1034                 G_CALLBACK(on_call_set_sound_clock_status), ctx);
1035
1036         g_signal_connect(call,
1037                 "handle-set-preferred-voice-subscription",
1038                 G_CALLBACK(on_call_set_preferred_voice_subscription), ctx);
1039
1040         g_signal_connect(call,
1041                 "handle-get-preferred-voice-subscription",
1042                 G_CALLBACK(on_call_get_preferred_voice_subscription), ctx);
1043
1044         g_signal_connect(call,
1045                 "handle-modify",
1046                 G_CALLBACK(on_call_modify), ctx);
1047
1048         g_signal_connect(call,
1049                 "handle-confirm-modify",
1050                 G_CALLBACK(on_call_confirm_modify), ctx);
1051
1052         return TRUE;
1053 }
1054
1055 gboolean dbus_plugin_call_response(struct custom_data *ctx,
1056         UserRequest *ur, struct dbus_request_info *dbus_info,
1057         enum tcore_response_command command, unsigned int data_len, const void *data)
1058 {
1059         char *cpname = GET_CP_NAME(dbus_info->invocation);
1060
1061         switch (command) {
1062         case TRESP_CALL_DIAL: {
1063                 struct tresp_call_dial *resp = (struct tresp_call_dial *)data;
1064
1065                 dbg("[%s] CALL_DIAL - Result: [%d]",
1066                         cpname, resp->err);
1067
1068                 telephony_call_complete_dial(dbus_info->interface_object,
1069                         dbus_info->invocation, resp->err);
1070         }
1071         break;
1072
1073         case TRESP_CALL_ANSWER: {
1074                 struct tresp_call_answer *resp = (struct tresp_call_answer *)data;
1075
1076                 dbg("[%s] CALL_ANSWER - Result: [%d] Call handle: [%d]",
1077                         cpname, resp->err, resp->handle);
1078
1079                 telephony_call_complete_answer(dbus_info->interface_object,
1080                         dbus_info->invocation, resp->err, resp->handle);
1081         }
1082         break;
1083
1084         case TRESP_CALL_END: {
1085                 struct tresp_call_end *resp = (struct tresp_call_end *)data;
1086
1087                 dbg("[%s] CALL_END - Result: [%d] Call handle: [%d] End type: [%d]",
1088                         cpname, resp->err, resp->handle, resp->type);
1089
1090                 telephony_call_complete_end(dbus_info->interface_object,
1091                         dbus_info->invocation, resp->err, resp->handle, resp->type);
1092         }
1093         break;
1094
1095         case TRESP_CALL_HOLD: {
1096                 struct tresp_call_hold *resp = (struct tresp_call_hold *)data;
1097
1098                 dbg("[%s] CALL_HOLD - Result: [%d] Call handle: [%d]",
1099                         cpname, resp->err, resp->handle);
1100
1101                 telephony_call_complete_hold(dbus_info->interface_object,
1102                         dbus_info->invocation, resp->err, resp->handle);
1103         }
1104         break;
1105
1106         case TRESP_CALL_ACTIVE: {
1107                 struct tresp_call_active *resp = (struct tresp_call_active *)data;
1108
1109                 dbg("[%s] CALL_ACTIVE - Result: [%d] Call handle: [%d]",
1110                         cpname, resp->err, resp->handle);
1111
1112                 telephony_call_complete_active(dbus_info->interface_object,
1113                         dbus_info->invocation, resp->err, resp->handle);
1114         }
1115         break;
1116
1117         case TRESP_CALL_SWAP: {
1118                 struct tresp_call_swap *resp = (struct tresp_call_swap *)data;
1119
1120                 dbg("[%s] CALL_SWAP - Result: [%d] Call handle: [%d]",
1121                         cpname, resp->err, resp->handle);
1122
1123                 telephony_call_complete_swap(dbus_info->interface_object,
1124                         dbus_info->invocation, resp->err, resp->handle);
1125         }
1126         break;
1127
1128         case TRESP_CALL_JOIN: {
1129                 struct tresp_call_join *resp = (struct tresp_call_join *)data;
1130
1131                 dbg("[%s] CALL_JOIN - Result: [%d] Call handle: [%d]",
1132                         cpname, resp->err, resp->handle);
1133
1134                 telephony_call_complete_join(dbus_info->interface_object,
1135                         dbus_info->invocation, resp->err, resp->handle);
1136         }
1137         break;
1138
1139         case TRESP_CALL_SPLIT: {
1140                 struct tresp_call_split *resp = (struct tresp_call_split *)data;
1141
1142                 dbg("[%s] CALL_SPLIT - Result: [%d] Call handle: [%d]",
1143                         cpname, resp->err, resp->handle);
1144
1145                 telephony_call_complete_split(dbus_info->interface_object,
1146                         dbus_info->invocation, resp->err, resp->handle);
1147         }
1148         break;
1149
1150         case TRESP_CALL_DEFLECT: {
1151                 struct tresp_call_deflect *resp = (struct tresp_call_deflect *)data;
1152
1153                 dbg("[%s] CALL_DEFLECT - Result: [%d] Call handle: [%d]",
1154                         cpname, resp->err, resp->handle);
1155
1156                 telephony_call_complete_deflect(dbus_info->interface_object,
1157                         dbus_info->invocation, resp->err);
1158         }
1159         break;
1160
1161         case TRESP_CALL_TRANSFER: {
1162                 struct tresp_call_transfer *resp = (struct tresp_call_transfer *)data;
1163
1164                 dbg("[%s] CALL_TRANSFER - Result: [%d] Call handle: [%d]",
1165                         cpname, resp->err, resp->handle);
1166
1167                 telephony_call_complete_transfer(dbus_info->interface_object,
1168                         dbus_info->invocation, resp->err, resp->handle);
1169         }
1170         break;
1171
1172         case TRESP_CALL_START_CONT_DTMF: {
1173                 struct tresp_call_dtmf *resp = (struct tresp_call_dtmf *)data;
1174
1175                 dbg("[%s] CALL_START_CONT_DTMF - Result: [%d]", cpname, resp->err);
1176
1177                 telephony_call_complete_start_cont_dtmf(dbus_info->interface_object,
1178                         dbus_info->invocation, resp->err);
1179         }
1180         break;
1181
1182         case TRESP_CALL_STOP_CONT_DTMF: {
1183                 struct tresp_call_dtmf *resp = (struct tresp_call_dtmf *)data;
1184
1185                 dbg("[%s] CALL_STOP_CONT_DTMF - Result: [%d]", cpname, resp->err);
1186
1187                 telephony_call_complete_stop_cont_dtmf(dbus_info->interface_object,
1188                         dbus_info->invocation, resp->err);
1189         }
1190         break;
1191
1192         case TRESP_CALL_SEND_BURST_DTMF: {
1193                 struct tresp_call_dtmf *resp = (struct tresp_call_dtmf *)data;
1194
1195                 dbg("[%s] CALL_SEND_BURST_DTMF - Result: [%d]", cpname, resp->err);
1196
1197                 telephony_call_complete_send_burst_dtmf(dbus_info->interface_object,
1198                         dbus_info->invocation, resp->err);
1199         }
1200         break;
1201
1202         case TRESP_CALL_GET_PRIVACY_MODE: {
1203                 struct tresp_call_get_voice_privacy_mode *resp = (struct tresp_call_get_voice_privacy_mode *)data;
1204
1205                 dbg("[%s] CALL_GET_PRIVACY_MODE - Result: [%d] Privacy mode: [%d]",
1206                         cpname, resp->err, resp->privacy_mode);
1207
1208                 telephony_call_complete_get_privacy_mode(dbus_info->interface_object,
1209                         dbus_info->invocation, resp->err, resp->privacy_mode);
1210         }
1211         break;
1212
1213         case TRESP_CALL_SET_PRIVACY_MODE: {
1214                 struct tresp_call_set_voice_privacy_mode *resp = (struct tresp_call_set_voice_privacy_mode *)data;
1215
1216                 dbg("[%s] CALL_SET_PRIVACY_MODE - Result: [%d]", cpname, resp->err);
1217
1218                 telephony_call_complete_set_privacy_mode(dbus_info->interface_object,
1219                         dbus_info->invocation, resp->err);
1220         }
1221         break;
1222
1223         case TRESP_CALL_SET_SOUND_PATH: {
1224                 struct tresp_call_set_sound_path *resp = (struct tresp_call_set_sound_path *)data;
1225
1226                 dbg("[%s] CALL_SET_SOUND_PATH - Result: [%d]", cpname, resp->err);
1227
1228                 telephony_call_complete_set_sound_path(dbus_info->interface_object,
1229                         dbus_info->invocation, resp->err);
1230         }
1231         break;
1232
1233         case TRESP_CALL_SET_SOUND_VOLUME_LEVEL: {
1234                 struct tresp_call_set_sound_volume_level *resp = (struct tresp_call_set_sound_volume_level *)data;
1235
1236                 dbg("[%s] CALL_SET_SOUND_VOLUME_LEVEL  - Result: [%d]", cpname, resp->err);
1237
1238                 telephony_call_complete_set_sound_volume_level(dbus_info->interface_object,
1239                         dbus_info->invocation, resp->err);
1240         }
1241         break;
1242
1243         case TRESP_CALL_GET_SOUND_VOLUME_LEVEL: {
1244                 struct tresp_call_get_sound_volume_level *resp = (struct tresp_call_get_sound_volume_level *)data;
1245                 GVariant *result = 0;
1246                 GVariantBuilder b;
1247                 int i = 0;
1248
1249                 dbg("[%s] CALL_GET_SOUND_VOLUME_LEVEL  - Result: [%d]", cpname, resp->err);
1250
1251                 g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}"));
1252                 g_variant_builder_open(&b, G_VARIANT_TYPE("a{sv}"));
1253
1254                 g_variant_builder_add(&b, "{sv}", "err",
1255                         g_variant_new_int32(resp->err));
1256                 if (!resp->err) {
1257                         dbg("resp->record_num : [%d]", resp->record_num);
1258
1259                         for (i = 0; i < resp->record_num; i++) {
1260                                 dbg("sound_type : [%d], level:[%d]",
1261                                         resp->record[i].sound, resp->record[i].volume);
1262                                 g_variant_builder_add(&b, "{sv}", "type",
1263                                         g_variant_new_int32(resp->record[i].sound));
1264                                 g_variant_builder_add(&b, "{sv}", "level",
1265                                         g_variant_new_int32(resp->record[i].volume));
1266                         }
1267                 }
1268                 g_variant_builder_close(&b);
1269                 result = g_variant_builder_end(&b);
1270
1271                 telephony_call_complete_get_sound_volume_level(dbus_info->interface_object,
1272                         dbus_info->invocation, result, resp->err);
1273         }
1274         break;
1275
1276         case TRESP_CALL_SET_SOUND_MUTE_STATUS: {
1277                 struct tresp_call_set_sound_mute_status *resp = (struct tresp_call_set_sound_mute_status *)data;
1278
1279                 dbg("[%s] CALL_SET_SOUND_MUTE_STATUS  - Result: [%d]", cpname, resp->err);
1280
1281                 telephony_call_complete_set_sound_mute_status(dbus_info->interface_object,
1282                         dbus_info->invocation, resp->err);
1283         }
1284         break;
1285
1286         case TRESP_CALL_GET_SOUND_MUTE_STATUS: {
1287                 struct tresp_call_get_sound_mute_status *resp = (struct tresp_call_get_sound_mute_status *)data;
1288
1289                 dbg("[%s] CALL_GET_SOUND_MUTE_STATUS  - Result: [%d] Path: [%d] Status: [%d]",
1290                         cpname, resp->err, resp->path, resp->status);
1291
1292                 telephony_call_complete_get_sound_mute_status(dbus_info->interface_object,
1293                         dbus_info->invocation, resp->err, resp->path, resp->status);
1294
1295         }
1296         break;
1297
1298         case TRESP_CALL_SET_SOUND_RECORDING: {
1299                 struct tresp_call_set_sound_recording *resp = (struct tresp_call_set_sound_recording *)data;
1300
1301                 dbg("[%s] CALL_SET_SOUND_RECORDING - Result: [%d]", cpname, resp->err);
1302
1303                 telephony_call_complete_set_sound_recording(dbus_info->interface_object,
1304                         dbus_info->invocation, resp->err);
1305
1306         }
1307         break;
1308
1309         case TRESP_CALL_SET_SOUND_EQUALIZATION: {
1310                 struct tresp_call_set_sound_equalization *resp = (struct tresp_call_set_sound_equalization *)data;
1311
1312                 dbg("[%s] CALL_SET_SOUND_EQUALIZATION - Result: [%d]", cpname, resp->err);
1313
1314                 telephony_call_complete_set_sound_equalization(dbus_info->interface_object,
1315                         dbus_info->invocation, resp->err);
1316         }
1317         break;
1318
1319         case TRESP_CALL_SET_SOUND_NOISE_REDUCTION: {
1320                 struct tresp_call_set_sound_noise_reduction *resp = (struct tresp_call_set_sound_noise_reduction *)data;
1321
1322                 dbg("[%s] CALL_SET_SOUND_NOISE_REDUCTION - Result: [%d]", cpname, resp->err);
1323
1324                 telephony_call_complete_set_sound_noise_reduction(dbus_info->interface_object,
1325                         dbus_info->invocation, resp->err);
1326         }
1327         break;
1328
1329         case TRESP_CALL_SET_SOUND_CLOCK_STATUS: {
1330                 struct tresp_call_set_sound_clock_status *resp = (struct tresp_call_set_sound_clock_status *)data;
1331
1332                 dbg("[%s] CALL_SET_SOUND_CLOCK_STATUS - Result: [%d]", cpname, resp->err);
1333
1334                 telephony_call_complete_set_sound_clock_status(dbus_info->interface_object,
1335                         dbus_info->invocation, resp->err);
1336         }
1337         break;
1338
1339         case TRESP_CALL_SET_PREFERRED_VOICE_SUBSCRIPTION: {
1340                 struct tresp_call_set_preferred_voice_subscription *resp = (struct tresp_call_set_preferred_voice_subscription *)data;
1341
1342                 dbg("[%s] CALL_SET_PREFERRED_VOICE_SUBSCRIPTION - Result: [%d]",
1343                         cpname, resp->err);
1344
1345                 telephony_call_complete_set_preferred_voice_subscription(dbus_info->interface_object,
1346                         dbus_info->invocation, resp->err);
1347         }
1348         break;
1349
1350         case TRESP_CALL_GET_PREFERRED_VOICE_SUBSCRIPTION: {
1351                 struct tresp_call_get_preferred_voice_subscription *resp = (struct tresp_call_get_preferred_voice_subscription *)data;
1352
1353                 dbg("[%s] CALL_GET_PREFERRED_VOICE_SUBSCRIPTION - Result: [%d] Preferred Subscription: [%d]",
1354                         cpname, resp->err, resp->preferred_subs);
1355
1356                 telephony_call_complete_get_preferred_voice_subscription(dbus_info->interface_object,
1357                         dbus_info->invocation, resp->preferred_subs, resp->err);
1358         }
1359         break;
1360
1361         case TRESP_CALL_MODIFY: {
1362                 const struct tresp_call_modify *resp = data;
1363
1364                 dbg("[%s] CALL_MODIFY - Result: [%d]", cpname, resp->err);
1365
1366                 telephony_call_complete_modify(dbus_info->interface_object,
1367                         dbus_info->invocation, resp->err);
1368         }
1369         break;
1370
1371         case TRESP_CALL_CONFIRM_MODIFY: {
1372                 const struct tresp_call_confirm_modify *resp = data;
1373
1374                 dbg("[%s] CALL_CONFIRM_MODIFY - Result: [%d]", cpname, resp->err);
1375
1376                 telephony_call_complete_confirm_modify(dbus_info->interface_object,
1377                         dbus_info->invocation, resp->err);
1378         }
1379         break;
1380
1381         default:
1382                 err("Unhandled/Unknown Response: [0x%x]", command);
1383         break;
1384         }
1385
1386         return TRUE;
1387 }
1388
1389 gboolean dbus_plugin_call_notification(struct custom_data *ctx,
1390         CoreObject *source, TelephonyObjectSkeleton *object,
1391         enum tcore_notification_command command, unsigned int data_len, const void *data)
1392 {
1393         TelephonyCall *call;
1394         char *cp_name;
1395
1396         if (!object) {
1397                 dbg("object is NULL");
1398                 return FALSE;
1399         }
1400
1401         if (!data) {
1402                 err("data is NULL");
1403                 return FALSE;
1404         }
1405
1406         cp_name = (char *)tcore_server_get_cp_name_by_plugin(tcore_object_ref_plugin(source));
1407
1408         call = telephony_object_peek_call(TELEPHONY_OBJECT(object));
1409         if (call == NULL) {
1410                 err("call object is NULL!!!");
1411                 return FALSE;
1412         }
1413
1414         switch (command) {
1415         case TNOTI_CALL_STATUS_IDLE: {
1416                 struct tnoti_call_status_idle *idle = (struct tnoti_call_status_idle *)data;
1417
1418                 dbg("[%s] CALL_STATUS_IDLE: [%s]", cp_name,
1419                         (idle->type != CALL_TYPE_VIDEO ? "Voice" : "Video"));
1420
1421                 if (idle->type != CALL_TYPE_VIDEO)
1422                         telephony_call_emit_voice_call_status_idle(call,
1423                                 idle->handle, idle->cause, 0, 0);
1424                 else
1425                         telephony_call_emit_video_call_status_idle(call,
1426                                 idle->handle, idle->cause, 0, 0);
1427         }
1428         break;
1429
1430         case TNOTI_CALL_STATUS_DIALING: {
1431                 struct tnoti_call_status_dialing *dialing = (struct tnoti_call_status_dialing *)data;
1432
1433                 dbg("[%s] CALL_STATUS_DIALING: [%s] Call handle: [%d]", cp_name,
1434                         (dialing->type != CALL_TYPE_VIDEO ? "Voice" : "Video"),
1435                         dialing->handle);
1436
1437                 if (dialing->type != CALL_TYPE_VIDEO)
1438                         telephony_call_emit_voice_call_status_dialing(call, dialing->handle);
1439                 else
1440                         telephony_call_emit_video_call_status_dialing(call, dialing->handle);
1441         }
1442         break;
1443
1444         case TNOTI_CALL_STATUS_ALERT: {
1445                 struct tnoti_call_status_alert *alert = (struct tnoti_call_status_alert *)data;
1446
1447                 dbg("[%s] CALL_STATUS_ALERT: [%s] Call handle: [%d]", cp_name,
1448                         (alert->type != CALL_TYPE_VIDEO ? "Voice" : "Video"),
1449                         alert->handle);
1450
1451                 if (alert->type != CALL_TYPE_VIDEO)
1452                         telephony_call_emit_voice_call_status_alert(call, alert->handle);
1453                 else
1454                         telephony_call_emit_video_call_status_alert(call, alert->handle);
1455         }
1456         break;
1457
1458         case TNOTI_CALL_STATUS_ACTIVE: {
1459                 struct tnoti_call_status_active *active = (struct tnoti_call_status_active *)data;
1460
1461                 dbg("[%s] CALL_STATUS_ACTIVE: [%s] Call handle: [%d]", cp_name,
1462                         (active->type != CALL_TYPE_VIDEO ? "Voice" : "Video"),
1463                         active->handle);
1464
1465                 if (active->type != CALL_TYPE_VIDEO)
1466                         telephony_call_emit_voice_call_status_active(call, active->handle);
1467                 else
1468                         telephony_call_emit_video_call_status_active(call, active->handle);
1469         }
1470         break;
1471
1472         case TNOTI_CALL_STATUS_HELD: {
1473                 struct tnoti_call_status_held *held = (struct tnoti_call_status_held *)data;
1474
1475                 dbg("[%s] CALL_STATUS_HELD: Call handle: [%d]", cp_name,
1476                         held->handle);
1477
1478                 telephony_call_emit_voice_call_status_held(call, held->handle);
1479         }
1480         break;
1481
1482         case TNOTI_CALL_STATUS_INCOMING: {
1483                 struct tnoti_call_status_incoming *incoming = (struct tnoti_call_status_incoming *)data;
1484
1485                 dbg("[%s] CALL_STATUS_INCOMING: [%s] Call handle: [%d]", cp_name,
1486                         (incoming->type != CALL_TYPE_VIDEO ? "Voice" : "Video"),
1487                         incoming->handle);
1488
1489                 if (incoming->type != CALL_TYPE_VIDEO)
1490                         telephony_call_emit_voice_call_status_incoming(call,
1491                                 incoming->handle,
1492                                 incoming->cli.mode,
1493                                 incoming->cli.no_cli_cause,
1494                                 incoming->cli.number,
1495                                 incoming->forward,
1496                                 incoming->active_line,
1497                                 incoming->cna.name);
1498                 else
1499                         telephony_call_emit_video_call_status_incoming(call,
1500                                 incoming->handle,
1501                                 incoming->cli.mode,
1502                                 incoming->cli.no_cli_cause,
1503                                 incoming->cli.number,
1504                                 incoming->forward,
1505                                 incoming->active_line,
1506                                 incoming->cna.name);
1507         }
1508         break;
1509
1510         case TNOTI_CALL_INFO_WAITING: {
1511                 int *id = (int *)data;
1512
1513                 dbg("[%s] CALL_INFO_WAITING: Call handle: [%d]",
1514                         cp_name, (gint)*id);
1515
1516                 telephony_call_emit_waiting(call, (gint)*id);
1517         }
1518         break;
1519
1520         case TNOTI_CALL_INFO_FORWARDED: {
1521                 int *id = (int *)data;
1522
1523                 dbg("[%s] CALL_INFO_FORWARDED: Call handle: [%d]",
1524                         cp_name, (gint)*id);
1525
1526                 telephony_call_emit_forwarded(call, (gint)*id);
1527         }
1528         break;
1529
1530         case TNOTI_CALL_INFO_FORWARDED_CALL: {
1531                 int *id = (int *)data;
1532
1533                 dbg("[%s] CALL_INFO_FORWARDED_CALL: Call handle: [%d]",
1534                         cp_name, (gint)*id);
1535
1536                 telephony_call_emit_forwarded_call(call, (gint)*id);
1537         }
1538         break;
1539
1540         case TNOTI_CALL_INFO_BARRED_INCOMING: {
1541                 int *id = (int *)data;
1542
1543                 dbg("[%s] CALL_INFO_BARRED_INCOMING: Call handle: [%d]",
1544                         cp_name, (gint)*id);
1545
1546                 telephony_call_emit_barred_incoming(call, (gint)*id);
1547         }
1548         break;
1549
1550         case TNOTI_CALL_INFO_BARRED_OUTGOING: {
1551                 int *id = (int *)data;
1552
1553                 dbg("[%s] CALL_INFO_BARRED_OUTGOING: Call handle: [%d]",
1554                         cp_name, (gint)*id);
1555
1556                 telephony_call_emit_barred_outgoing(call, (gint)*id);
1557         }
1558         break;
1559
1560         case TNOTI_CALL_INFO_FORWARD_CONDITIONAL: {
1561                 int *id = (int *)data;
1562
1563                 dbg("[%s] CALL_INFO_FORWARD_CONDITIONAL: Call handle: [%d]",
1564                         cp_name, (gint)*id);
1565
1566                 telephony_call_emit_forward_conditional(call, (gint)*id);
1567         }
1568         break;
1569
1570         case TNOTI_CALL_INFO_FORWARD_UNCONDITIONAL: {
1571                 int *id = (int *)data;
1572
1573                 dbg("[%s] CALL_INFO_FORWARD_UNCONDITIONAL: Call handle: [%d]",
1574                         cp_name, (gint)*id);
1575
1576                 telephony_call_emit_forward_unconditional(call, (gint)*id);
1577         }
1578         break;
1579
1580         case TNOTI_CALL_INFO_HELD: {
1581                 int *id = (int *)data;
1582
1583                 dbg("[%s] CALL_INFO_HELD: Call handle: [%d]",
1584                         cp_name, (gint)*id);
1585
1586                 telephony_call_emit_call_held(call, (gint)*id);
1587         }
1588         break;
1589
1590         case TNOTI_CALL_INFO_ACTIVE: {
1591                 int *id = (int *)data;
1592
1593                 dbg("[%s] CALL_INFO_ACTIVE: Call handle: [%d]",
1594                         cp_name, (gint)*id);
1595
1596                 telephony_call_emit_call_active(call, (gint)*id);
1597         }
1598         break;
1599
1600         case TNOTI_CALL_INFO_JOINED: {
1601                 int *id = (int *)data;
1602
1603                 dbg("[%s] CALL_INFO_JOINED: Call handle: [%d]",
1604                         cp_name, (gint)*id);
1605
1606                 telephony_call_emit_call_joined(call, (gint)*id);
1607         }
1608         break;
1609
1610         case TNOTI_CALL_INFO_PRIVACY_MODE: {
1611                 struct tnoti_call_info_voice_privacy_mode *privacy_info = (struct tnoti_call_info_voice_privacy_mode *)data;
1612
1613                 dbg("[%s] CALL_INFO_PRIVACY_MODE: Privacy mode: [%d]",
1614                         cp_name, privacy_info->privacy_mode);
1615
1616                 telephony_call_emit_call_privacy_mode(call, privacy_info->privacy_mode);
1617         }
1618         break;
1619
1620         case TNOTI_CALL_OTASP_STATUS: {
1621                 struct tnoti_call_otasp_status  *otasp = (struct tnoti_call_otasp_status *)data;
1622
1623                 dbg("[%s] CALL_OTASP_STATUS : status(%d)",
1624                         cp_name, otasp->otasp_status);
1625
1626                 telephony_call_emit_call_otasp_status(call, otasp->otasp_status);
1627         }
1628         break;
1629
1630         case TNOTI_CALL_OTAPA_STATUS: {
1631                 struct tnoti_call_otapa_status  *otapa = (struct tnoti_call_otapa_status *)data;
1632
1633                 dbg("[%s] CALL_OTAPA_STATUS: Status: [%d]",
1634                         cp_name, otapa->otapa_status);
1635
1636                 telephony_call_emit_call_otapa_status(call, otapa->otapa_status);
1637         }
1638         break;
1639
1640         case TNOTI_CALL_SIGNAL_INFO: {
1641                 struct tnoti_call_signal_info *sig_info = (struct tnoti_call_signal_info *)data;
1642                 unsigned int signal;
1643
1644                 if (sig_info->signal_type == CALL_SIGNAL_TYPE_TONE) {
1645                         signal = sig_info->signal.sig_tone_type;
1646                 } else if (sig_info->signal_type == CALL_SIGNAL_TYPE_ISDN_ALERTING) {
1647                         signal = sig_info->signal.sig_isdn_alert_type;
1648                 } else if (sig_info->signal_type == CALL_SIGNAL_TYPE_IS54B_ALERTING) {
1649                         signal = sig_info->signal.sig_is54b_alert_type;
1650                 } else {
1651                         err("Unknown Signal type");
1652                         return FALSE;
1653                 }
1654
1655                 dbg("[%s] CALL_SIGNAL_INFO: Signal type: [%d] Pitch type: [%d] Signal: [%d]",
1656                         cp_name, sig_info->signal_type, sig_info->pitch_type, signal);
1657
1658                 telephony_call_emit_call_signal_info(call,
1659                         sig_info->signal_type, sig_info->pitch_type, signal);
1660         }
1661         break;
1662
1663         case TNOTI_CALL_INFO_REC: {
1664                 struct tnoti_call_info_rec *noti = (struct tnoti_call_info_rec *)data;
1665                 gchar *param = NULL;
1666
1667                 if (noti->rec_info.type == CALL_REC_NAME_INFO) {
1668                         param = g_strdup(noti->rec_info.data.name);
1669                 } else if (noti->rec_info.type == CALL_REC_NUMBER_INFO) {
1670                         param = g_strdup(noti->rec_info.data.number);
1671                 } else {
1672                         err("Unknown rec info type (%d)", noti->rec_info.type);
1673                         return FALSE;
1674                 }
1675
1676                 dbg("[%s] CALL_INFO_REC: id: [%d] type: [%d] param: [%s]",
1677                         cp_name, noti->rec_info.handle, noti->rec_info.type, param);
1678
1679                 telephony_call_emit_call_info_rec(call, noti->rec_info.handle, noti->rec_info.type, param);
1680                 g_free(param);
1681         }
1682         break;
1683
1684         case TNOTI_CALL_SOUND_PATH: {
1685                 struct tnoti_call_sound_path *noti = (struct tnoti_call_sound_path *)data;
1686
1687                 dbg("[%s] CALL_SOUND_PATH: Path: [%d]", cp_name, noti->path);
1688
1689                 telephony_call_emit_call_sound_path(call, noti->path);
1690         }
1691         break;
1692
1693         case TNOTI_CALL_SOUND_RINGBACK_TONE: {
1694                 struct tnoti_call_sound_ringback_tone *noti = (struct tnoti_call_sound_ringback_tone *)data;
1695
1696                 dbg("[%s] CALL_SOUND_RINGBACK_TONE: Status: [%d]",
1697                         cp_name, (gint)noti->status);
1698
1699                 telephony_call_emit_call_sound_ringback_tone(call, (gint)noti->status);
1700         }
1701         break;
1702
1703         case TNOTI_CALL_SOUND_WBAMR: {
1704                 struct tnoti_call_sound_wbamr *noti = (struct tnoti_call_sound_wbamr *)data;
1705
1706                 dbg("[%s] CALL_SOUND_WBAMR: Status: [%d]",
1707                         cp_name, (gint)noti->status);
1708
1709                 telephony_call_emit_call_sound_wbamr(call, (gint)noti->status);
1710         }
1711         break;
1712
1713         case TNOTI_CALL_SOUND_EQUALIZATION: {
1714                 struct tnoti_call_sound_equalization *noti = (struct tnoti_call_sound_equalization *)data;
1715
1716                 dbg("[%s] CALL_SOUND_EQUALIZATION: Direction: [%d]",
1717                         cp_name, (gint)noti->direction);
1718
1719                 telephony_call_emit_call_sound_equalization(call, (gint)noti->mode, (gint)noti->direction);
1720         }
1721         break;
1722
1723         case TNOTI_CALL_SOUND_NOISE_REDUCTION: {
1724                 struct tnoti_call_sound_noise_reduction *noti = (struct tnoti_call_sound_noise_reduction *)data;
1725
1726                 dbg("[%s] CALL_SOUND_NOISE_REDUCTION: Status: [%d]",
1727                         cp_name, (gint)noti->status);
1728
1729                 telephony_call_emit_call_sound_noise_reduction(call, (gint)noti->status);
1730         }
1731         break;
1732
1733         case TNOTI_CALL_SOUND_CLOCK_STATUS: {
1734                 struct tnoti_call_sound_clock_status *noti = (struct tnoti_call_sound_clock_status *)data;
1735
1736                 dbg("[%s] CALL_SOUND_CLOCK_STATUS: Status: [%d]",
1737                         cp_name, (gint)noti->status);
1738
1739                 telephony_call_emit_call_sound_clock_status(call, noti->status);
1740         }
1741         break;
1742
1743         case TNOTI_CALL_PREFERRED_VOICE_SUBSCRIPTION: {
1744                 struct tnoti_call_preferred_voice_subscription *noti = (struct tnoti_call_preferred_voice_subscription *)data;
1745
1746                 dbg("[%s] CALL_PREFERRED_VOICE_SUBSCRIPTION: Subscription: [%d]",
1747                         cp_name, noti->preferred_subs);
1748
1749                 telephony_call_emit_call_preferred_voice_subscription(call, noti->preferred_subs);
1750         }
1751         break;
1752
1753         case TNOTI_CALL_MODIFY_REQUEST: {
1754                 const struct tnoti_call_modify_request *noti = data;
1755
1756                 dbg("[%s] CALL_MODIFY_REQUEST: Call handle: [%d] Call type: [%d]",
1757                         cp_name, noti->handle, noti->call_type);
1758
1759                 telephony_call_emit_call_modify_request(call, noti->handle, noti->call_type);
1760         }
1761         break;
1762
1763         case TNOTI_CALL_INFO_FALLBACK:{
1764                 struct tnoti_call_fallback* noti = (struct tnoti_call_fallback *)data;
1765
1766                 dbg("[%s] CALL_INFO_FALLBACK: Call handle: [%d] Fallback to: [%d]",
1767                         cp_name, noti->handle, noti->fallback_to);
1768
1769                 telephony_call_emit_call_fallback(call, noti->handle, noti->fallback_to);
1770         }
1771         break;
1772
1773         default:
1774                 err("Unhandled/Unknown Notification: [0x%x]", command);
1775         break;
1776         }
1777
1778         return TRUE;
1779 }