tizen 2.3.1 release
[framework/telephony/libtcore.git] / src / co_call.c
1 /*
2  * libtcore
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 <stdlib.h>
23 #include <string.h>
24
25 #include <glib.h>
26
27 #include "tcore.h"
28 #include "plugin.h"
29 #include "queue.h"
30 #include "user_request.h"
31 #include "co_call.h"
32
33
34 #define MAX_CALL_OBJECTS                6
35
36 #define _check_null( name, value, err ) { \
37         if ( !value ) { \
38                 dbg("[error] %s : NULL", name ); \
39                 return err; \
40         } \
41 }
42
43 struct call_cli_info {
44         enum tcore_call_cli_mode mode;
45         enum tcore_call_no_cli_cause no_cli_cause;
46         char number[MAX_CALL_NUMBER_LEN];
47         int number_len;
48 };
49
50 struct call_cna_info {
51         enum tcore_call_cna_mode mode;
52         int dcs;
53         char name[MAX_CALL_NAME_LEN];
54         int name_len;
55 };
56
57 struct call_object {
58         enum tcore_call_type type;
59         unsigned int id;
60         enum tcore_call_direction direction;
61         enum tcore_call_status status;
62         gboolean mpty;
63         struct call_cli_info cli;
64         struct call_cna_info cna;
65         unsigned int cug_id;
66         unsigned int active_line;
67         struct call_time { // second
68                 long start;
69                 long end;
70         } time;
71 };
72
73 struct private_object_data {
74         GSList* cobjs;
75         struct tcore_call_operations *ops;
76         struct tcore_call_control_operations *cops;
77         struct tcore_call_information_operations *iops;
78 };
79
80 static void _clone_hook(CoreObject *src, CoreObject *dest)
81 {
82         struct private_object_data *src_po = NULL;
83         struct private_object_data *dest_po = NULL;
84
85         if (!src || !dest)
86                 return;
87
88         dest_po = g_try_new0(struct private_object_data, 1);
89         if (!dest_po) {
90                 tcore_object_link_object(dest, NULL);
91                 return;
92         }
93
94         src_po = tcore_object_ref_object(src);
95         dest_po->ops = src_po->ops;
96
97         tcore_object_link_object(dest, dest_po);
98 }
99
100 static TReturn _dispatcher(CoreObject *o, UserRequest *ur)
101 {
102         enum tcore_request_command command;
103
104         struct private_object_data *po = NULL;
105         po = tcore_object_ref_object(o);
106
107         _check_null( "po", po, TCORE_RETURN_FAILURE);
108         _check_null( "po->ops", po->ops, TCORE_RETURN_FAILURE);
109         _check_null( "ur", ur, TCORE_RETURN_FAILURE);
110
111         command = tcore_user_request_get_command(ur);
112         switch (command) {
113                 case TREQ_CALL_DIAL:
114                         _check_null( "po->ops->dial", po->ops->dial, TCORE_RETURN_FAILURE);
115                         return po->ops->dial(o, ur);
116
117                 case TREQ_CALL_ANSWER:
118                         _check_null( "po->ops->answer", po->ops->answer, TCORE_RETURN_FAILURE);
119                         return po->ops->answer(o, ur);
120
121                 case TREQ_CALL_END:
122                         _check_null( "po->ops->end", po->ops->end, TCORE_RETURN_FAILURE);
123                         return po->ops->end(o, ur);
124
125                 case TREQ_CALL_HOLD:
126                         _check_null( "po->ops->hold", po->ops->hold, TCORE_RETURN_FAILURE);
127                         return po->ops->hold(o, ur);
128
129                 case TREQ_CALL_ACTIVE:
130                         _check_null( "po->ops->active", po->ops->active, TCORE_RETURN_FAILURE);
131                         return po->ops->active(o, ur);
132
133                 case TREQ_CALL_SWAP:
134                         _check_null( "po->ops->swap", po->ops->swap, TCORE_RETURN_FAILURE);
135                         return po->ops->swap(o, ur);
136
137                 case TREQ_CALL_JOIN:
138                         _check_null( "po->ops->join", po->ops->join, TCORE_RETURN_FAILURE);
139                         return po->ops->join(o, ur);
140
141                 case TREQ_CALL_SPLIT:
142                         _check_null( "po->ops->split", po->ops->split, TCORE_RETURN_FAILURE);
143                         return po->ops->split(o, ur);
144
145                 case TREQ_CALL_DEFLECT:
146                         _check_null( "po->ops->deflect", po->ops->deflect, TCORE_RETURN_FAILURE);
147                         return po->ops->deflect(o, ur);
148
149                 case TREQ_CALL_TRANSFER:
150                         _check_null( "po->ops->transfer", po->ops->transfer, TCORE_RETURN_FAILURE);
151                         return po->ops->transfer(o, ur);
152
153                 case TREQ_CALL_START_CONT_DTMF:
154                         _check_null( "po->ops->start_cont_dtmf", po->ops->start_cont_dtmf, TCORE_RETURN_FAILURE);
155                         return po->ops->start_cont_dtmf(o, ur);
156
157                 case TREQ_CALL_STOP_CONT_DTMF:
158                         _check_null( "po->ops->stop_cont_dtmf", po->ops->stop_cont_dtmf, TCORE_RETURN_FAILURE);
159                         return po->ops->stop_cont_dtmf(o, ur);
160
161                 case TREQ_CALL_SEND_BURST_DTMF:
162                         _check_null( "po->ops->send_burst_dtmf", po->ops->send_burst_dtmf, TCORE_RETURN_FAILURE);
163                         return po->ops->send_burst_dtmf(o, ur);
164
165                 case TREQ_CALL_GET_PRIVACY_MODE:
166                         _check_null( "po->ops->get_privacy_mode", po->ops->get_privacy_mode, TCORE_RETURN_FAILURE);
167                         return po->ops->get_privacy_mode(o, ur);
168
169                 case TREQ_CALL_SET_PRIVACY_MODE:
170                         _check_null( "po->ops->set_privacy_mode", po->ops->set_privacy_mode, TCORE_RETURN_FAILURE);
171                         return po->ops->set_privacy_mode(o, ur);
172
173                 case TREQ_CALL_SET_SOUND_PATH:
174                         _check_null( "po->ops->set_sound_path", po->ops->set_sound_path, TCORE_RETURN_FAILURE);
175                         return po->ops->set_sound_path(o, ur);
176
177                 case TREQ_CALL_GET_SOUND_VOLUME_LEVEL:
178                         _check_null( "po->ops->get_sound_volume_level", po->ops->get_sound_volume_level, TCORE_RETURN_FAILURE);
179                         return po->ops->get_sound_volume_level(o, ur);
180
181                 case TREQ_CALL_SET_SOUND_VOLUME_LEVEL:
182                         _check_null( "po->ops->set_sound_volume_level", po->ops->set_sound_volume_level, TCORE_RETURN_FAILURE);
183                         return po->ops->set_sound_volume_level(o, ur);
184
185                 case TREQ_CALL_SET_SOUND_MUTE_STATUS:
186                         _check_null( "po->ops->set_sound_mute_status", po->ops->set_sound_mute_status, TCORE_RETURN_FAILURE);
187                         return po->ops->set_sound_mute_status(o, ur);
188
189                 case TREQ_CALL_GET_SOUND_MUTE_STATUS:
190                         _check_null( "po->ops->get_sound_mute_status", po->ops->get_sound_mute_status, TCORE_RETURN_FAILURE);
191                         return po->ops->get_sound_mute_status(o, ur);
192
193                 case TREQ_CALL_SET_SOUND_RECORDING:
194                         _check_null( "po->ops->set_sound_recording", po->ops->set_sound_recording, TCORE_RETURN_FAILURE);
195                         return po->ops->set_sound_recording(o, ur);
196
197                 case TREQ_CALL_SET_SOUND_EQUALIZATION:
198                         _check_null( "po->ops->set_sound_equalization", po->ops->set_sound_equalization, TCORE_RETURN_FAILURE);
199                         return po->ops->set_sound_equalization(o, ur);
200
201                 case TREQ_CALL_SET_SOUND_NOISE_REDUCTION:
202                         _check_null( "po->ops->set_sound_noise_reduction", po->ops->set_sound_noise_reduction, TCORE_RETURN_FAILURE);
203                         return po->ops->set_sound_noise_reduction(o, ur);
204
205                 case TREQ_CALL_SET_SOUND_CLOCK_STATUS:
206                         _check_null( "po->ops->set_sound_clock_status", po->ops->set_sound_clock_status, TCORE_RETURN_FAILURE);
207                         return po->ops->set_sound_clock_status(o, ur);
208
209                 case TREQ_CALL_SET_PREFERRED_VOICE_SUBSCRIPTION:
210                         _check_null( "po->ops->set_preferred_voice_subscription", po->ops->set_preferred_voice_subscription, TCORE_RETURN_FAILURE);
211                         return po->ops->set_preferred_voice_subscription(o, ur);
212
213                 case TREQ_CALL_GET_PREFERRED_VOICE_SUBSCRIPTION:
214                         _check_null( "po->ops->get_preferred_voice_subscription", po->ops->get_preferred_voice_subscription, TCORE_RETURN_FAILURE);
215                         return po->ops->get_preferred_voice_subscription(o, ur);
216
217                 default:
218                         break;
219         }
220
221         return TCORE_RETURN_SUCCESS;
222 }
223
224 static void _free_hook(CoreObject *o)
225 {
226         struct private_object_data *po = NULL;
227
228         po = tcore_object_ref_object(o);
229         if (!po)
230                 return;
231
232         g_slist_free_full(po->cobjs, g_free);
233         g_free(po);
234
235         tcore_object_link_object(o, NULL);
236 }
237
238 typedef gboolean(*func)(struct call_object* co, void *data);
239 static struct call_object *_find_object(GSList *objs, void* data, func compare)
240 {
241         struct call_object *co = 0;
242         GSList *l = 0;
243
244         _check_null( "objs", objs, 0);
245         _check_null( "compare", compare, 0);
246
247         l = objs;
248         while (l) {
249                 co = (struct call_object*) l->data;
250
251                 if (compare(co, data))
252                         return co;
253
254                 l = g_slist_next( l );
255         }
256
257         return NULL;
258 }
259
260 static GSList* _find_object_all(GSList *objs, void* data, func compare)
261 {
262         struct call_object *co = 0;
263         GSList *l = 0;
264         GSList *ret = 0;
265
266         _check_null( "objs", objs, 0);
267         _check_null( "compare", compare, 0);
268
269         l = objs;
270         while (l) {
271                 co = (struct call_object*) l->data;
272
273                 if (compare(co, data))
274                         ret = g_slist_append(ret, co);
275
276                 l = g_slist_next( l );
277         }
278
279         return ret;
280 }
281
282 static gboolean _compare_by_id(struct call_object* co, void *data)
283 {
284         unsigned int *id = (unsigned int*) data;
285
286         _check_null( "co", co, FALSE);
287         _check_null( "data", data, FALSE);
288
289         if (co->id == *id)
290                 return TRUE;
291
292         return FALSE;
293 }
294
295 static gboolean _compare_by_status(struct call_object* co, void *data)
296 {
297         enum tcore_call_status *ct = (enum tcore_call_status*) data;
298
299         _check_null( "co", co, FALSE);
300         _check_null( "data", data, FALSE);
301
302         if (co->status == *ct)
303                 return TRUE;
304
305         return FALSE;
306 }
307
308 static gboolean _compare_by_number(struct call_object* co, void *data)
309 {
310         char *number = (char*) data;
311
312         _check_null( "co", co, FALSE);
313         _check_null( "data", data, FALSE);
314
315         if (!strcmp(co->cli.number, number))
316                 return TRUE;
317
318         return FALSE;
319 }
320
321 static enum tcore_call_cli_mode _check_cli_mode_by_number(char *num)
322 {
323         _check_null( "num", num, TCORE_CALL_CLI_MODE_DEFAULT);
324
325         if (!strncmp(num, "*31#", 4))
326                 return TCORE_CALL_CLI_MODE_PRESENT;
327
328         if (!strncmp(num, "#31#", 4))
329                 return TCORE_CALL_CLI_MODE_RESTRICT;
330
331         return TCORE_CALL_CLI_MODE_DEFAULT;
332 }
333
334
335 // Call Object API
336
337 struct call_object *tcore_call_object_new(CoreObject *o, int id)
338 {
339         struct private_object_data *po = 0;
340         struct call_object *co = 0;
341
342         po = tcore_object_ref_object(o);
343
344         _check_null( "po", po, 0);
345
346         co = g_new0( struct call_object, 1 );
347
348         if (id > 0) {
349                 if (!_find_object(po->cobjs, (void*) &id, (void*) _compare_by_id))
350                         co->id = id;
351                 else {
352                         dbg("[ error ] call object exist already. [ %d ]", id);
353                         g_free(co);
354                         return NULL;
355                 }
356         }
357         else {
358                 int i = 0;
359
360                 for (i = 1; i <= MAX_CALL_OBJECTS; i++) {       /* 6 is MAX call count */
361                         if (!_find_object(po->cobjs, (void*) &i, (void*) _compare_by_id)) {
362                                 co->id = i;
363                                 break;
364                         }
365                 }
366
367                  /* Free the allocated Core Object if ID is not allocated */
368                 if (i > MAX_CALL_OBJECTS) {
369                         err("[ error ] failed to assign call id");
370                         g_free(co);
371                         return NULL;
372                 }
373         }
374
375         po->cobjs = g_slist_append(po->cobjs, co);
376
377         dbg("new call object id : [%d]", co->id);
378
379         return co;
380 }
381
382 gboolean tcore_call_object_free(CoreObject *o, struct call_object *co)
383 {
384         struct private_object_data *po = NULL;
385         po = tcore_object_ref_object(o);
386
387         _check_null( "po", po, FALSE);
388         _check_null( "po->cobjs", po->cobjs, FALSE);
389         _check_null( "co", co, FALSE);
390
391         po->cobjs = g_slist_remove(po->cobjs, co);
392         g_free(co);
393
394         return TRUE;
395 }
396
397 int tcore_call_object_total_length( CoreObject *o )
398 {
399         struct private_object_data *po = NULL;
400         po = tcore_object_ref_object(o);
401
402         _check_null( "po", po, FALSE);
403         _check_null( "po->cobjs", po->cobjs, FALSE);
404
405         return (int)g_slist_length(po->cobjs);
406 }
407
408 struct call_object *tcore_call_object_current_on_mt_processing(CoreObject *o)
409 {
410         struct private_object_data *po = NULL;
411         struct call_object *call_obj = NULL;
412         GSList *l = 0;
413
414         enum tcore_call_status cs = CALL_STATUS_INCOMING;
415         po = tcore_object_ref_object(o);
416
417         _check_null( "po", po, 0);
418         _check_null( "po->cobjs", po->cobjs, 0);
419
420         l = _find_object_all(po->cobjs, (void*) &cs, (void*) _compare_by_status);
421         if (!l) {
422                 cs = CALL_STATUS_WAITING;
423                 l = _find_object_all(po->cobjs, (void*) &cs, (void*) _compare_by_status);
424                 if (!l)
425                         return 0;
426         }
427
428         call_obj = (struct call_object*) l ->data;
429         g_slist_free(l);
430         return call_obj;
431 }
432
433 struct call_object *tcore_call_object_current_on_mo_processing(CoreObject *o)
434 {
435         struct private_object_data *po = NULL;
436         struct call_object *call_obj = NULL;
437         GSList *l = 0;
438
439         enum tcore_call_status cs = CALL_STATUS_DIALING;
440         po = tcore_object_ref_object(o);
441
442         _check_null( "po", po, 0);
443         _check_null( "po->cobjs", po->cobjs, 0);
444
445         l = _find_object_all(po->cobjs, (void*) &cs, (void*) _compare_by_status);
446         if (!l) {
447                 cs = CALL_STATUS_ALERT;
448                 l = _find_object_all(po->cobjs, (void*) &cs, (void*) _compare_by_status);
449                 if (!l)
450                         return 0;
451         }
452
453         call_obj = (struct call_object*) l ->data;
454         g_slist_free(l);
455         return call_obj;
456 }
457
458 struct call_object *tcore_call_object_find_by_id(CoreObject *o, int id)
459 {
460         struct private_object_data *po = NULL;
461
462         po = tcore_object_ref_object(o);
463
464         _check_null( "po", po, 0);
465         _check_null( "po->cobjs", po->cobjs, 0);
466
467         return _find_object(po->cobjs, (void*) &id, (void*) _compare_by_id);
468 }
469
470 struct call_object *tcore_call_object_find_by_number(CoreObject *o, char *num)
471 {
472         struct private_object_data *po = NULL;
473
474         po = tcore_object_ref_object(o);
475
476         _check_null( "po", po, 0);
477         _check_null( "po->cobjs", po->cobjs, 0);
478         _check_null( "num", num, 0);
479
480         return _find_object(po->cobjs, (void*) num, (void*) _compare_by_number);
481 }
482
483 GSList* tcore_call_object_find_by_status(CoreObject *o, enum tcore_call_status cs)
484 {
485         struct private_object_data *po = NULL;
486
487         po = tcore_object_ref_object(o);
488
489         _check_null( "po", po, 0);
490         _check_null( "po->cobjs", po->cobjs, 0);
491
492         return _find_object_all(po->cobjs, (void*) &cs, (void*) _compare_by_status);
493 }
494
495 int tcore_call_object_get_id(struct call_object *co)
496 {
497         _check_null( "co", co, -1);
498
499         return co->id;
500 }
501
502 gboolean tcore_call_object_set_type(struct call_object *co, enum tcore_call_type ct)
503 {
504         _check_null( "co", co, FALSE);
505
506         co->type = ct;
507         return TRUE;
508 }
509
510 enum tcore_call_type tcore_call_object_get_type(struct call_object *co)
511 {
512         _check_null( "co", co, -1);
513
514         return co->type;
515 }
516
517 gboolean tcore_call_object_set_direction(struct call_object *co, enum tcore_call_direction cd)
518 {
519         _check_null( "co", co, FALSE);
520
521         co->direction = cd;
522         return TRUE;
523 }
524
525 enum tcore_call_direction tcore_call_object_get_direction(struct call_object *co)
526 {
527         _check_null( "co", co, -1);
528
529         return co->direction;
530 }
531
532 gboolean tcore_call_object_set_status(struct call_object *co, enum tcore_call_status cs)
533 {
534         _check_null( "co", co, FALSE);
535
536         co->status = cs;
537         return TRUE;
538 }
539
540 enum tcore_call_status tcore_call_object_get_status(struct call_object *co)
541 {
542         _check_null( "co", co, -1);
543
544         return co->status;
545 }
546
547 gboolean tcore_call_object_set_cli_info(struct call_object *co,
548                                                 enum tcore_call_cli_mode mode, enum tcore_call_no_cli_cause cause,
549                                                 char *num, int num_len)
550 {
551         char *pos = 0;
552
553         _check_null( "co", co, FALSE);
554
555         dbg("num  : %s", num);
556         dbg("mode : 0x%x", mode);
557
558         if (!num) {
559                 co->cli.mode = mode;
560                 if (mode == TCORE_CALL_CLI_MODE_RESTRICT)
561                         co->cli.no_cli_cause = cause;
562                 else
563                         co->cli.no_cli_cause = TCORE_CALL_NO_CLI_CAUSE_NONE;
564
565                 co->cli.number_len = num_len ;
566                 co->cli.number [0] = '\0';
567
568                 return TRUE;
569         }
570
571         pos = num;
572
573         if (mode == TCORE_CALL_CLI_MODE_DEFAULT) {
574                 co->cli.mode = _check_cli_mode_by_number(num);
575
576                 if (co->cli.mode != TCORE_CALL_CLI_MODE_DEFAULT)
577                         pos = (num + 4);
578         }
579         else {
580                 co->cli.mode = mode;
581                 if (mode == TCORE_CALL_CLI_MODE_RESTRICT)
582                         co->cli.no_cli_cause = cause;
583                 else
584                         co->cli.no_cli_cause = TCORE_CALL_NO_CLI_CAUSE_NONE;
585         }
586
587         strncpy(co->cli.number, pos, ((num_len - (pos - num)) + 1));
588         co->cli.number_len = strlen(co->cli.number);
589
590         dbg("co->cli.mode: [0x%x]", co->cli.mode);
591         dbg("co->cli.no_cli_cause: [0x%x]", co->cli.no_cli_cause);
592         dbg("co->cli.number: [%s]", co->cli.number);
593         dbg("co->cli.number_len: [%d]", co->cli.number_len);
594
595         return TRUE;
596 }
597
598 int tcore_call_object_get_number(struct call_object *co, char *num)
599 {
600         _check_null( "co", co, -1);
601         _check_null( "num", num, -1);
602
603         strncpy(num, co->cli.number, MAX_CALL_NUMBER_LEN);
604         return co->cli.number_len;
605 }
606
607 enum tcore_call_cli_mode tcore_call_object_get_cli_mode(struct call_object *co)
608 {
609         _check_null( "co", co, -1);
610         return co->cli.mode;
611 }
612
613 enum tcore_call_no_cli_cause tcore_call_object_get_no_cli_cause(struct call_object *co)
614 {
615         _check_null( "co", co, -1);
616         return co->cli.no_cli_cause;
617 }
618
619
620 gboolean tcore_call_object_set_cna_info(struct call_object *co, enum tcore_call_cna_mode mode, char *name, int dcs)
621 {
622         int len;
623         _check_null( "co", co, FALSE);
624         _check_null( "name", name, FALSE);
625
626         len = strlen(name);
627         if (len >= MAX_CALL_NAME_LEN)
628                 return FALSE;
629
630         strncpy(co->cna.name, name, len);
631         co->cna.name[len] = '\0';
632
633         co->cna.mode = mode;
634
635         return TRUE;
636 }
637
638 int tcore_call_object_get_name(struct call_object *co, char *name)
639 {
640         _check_null( "co", co, -1);
641         _check_null( "name", name, -1);
642
643         strncpy(name, co->cna.name, MAX_CALL_NAME_LEN);
644         return co->cna.name_len;
645 }
646
647 enum tcore_call_cna_mode tcore_call_object_get_cna_mode(struct call_object *co)
648 {
649         _check_null( "co", co, -1);
650
651         return co->cna.mode;
652 }
653
654 gboolean tcore_call_object_set_multiparty_state(struct call_object *co, gboolean is)
655 {
656         _check_null( "co", co, FALSE);
657
658         co->mpty = is;
659         return TRUE;
660 }
661
662 gboolean tcore_call_object_get_multiparty_state(struct call_object *co)
663 {
664         _check_null( "co", co, FALSE);
665
666         return co->mpty;
667 }
668
669 gboolean tcore_call_object_set_active_line(struct call_object *co, unsigned int line)
670 {
671         _check_null( "co", co, FALSE);
672
673         co->active_line = line;
674         return TRUE;
675 }
676
677 int tcore_call_object_get_active_line(struct call_object *co)
678 {
679         _check_null( "co", co, -1);
680
681         return co->active_line;
682 }
683
684 TReturn tcore_call_control_answer_hold_and_accept(CoreObject* o, UserRequest* ur, ConfirmCallback cb, void* user_data)
685 {
686         struct private_object_data *po = NULL;
687         po = tcore_object_ref_object(o);
688
689         _check_null( "po", po, TCORE_RETURN_FAILURE);
690         _check_null( "po->cops", po->cops, TCORE_RETURN_FAILURE);
691
692         return po->cops->answer_hold_and_accept(o, ur, cb, user_data);
693 }
694
695 TReturn tcore_call_control_answer_replace(CoreObject* o, UserRequest* ur, ConfirmCallback cb, void* user_data)
696 {
697         struct private_object_data *po = NULL;
698         po = tcore_object_ref_object(o);
699
700         _check_null( "po", po, TCORE_RETURN_FAILURE);
701         _check_null( "po->cops", po->cops, TCORE_RETURN_FAILURE);
702
703         return po->cops->answer_replace(o, ur, cb, user_data);
704 }
705
706 TReturn tcore_call_control_answer_reject(CoreObject* o, UserRequest* ur, ConfirmCallback cb, void* user_data)
707 {
708         struct private_object_data *po = NULL;
709         po = tcore_object_ref_object(o);
710
711         _check_null( "po", po, TCORE_RETURN_FAILURE);
712         _check_null( "po->cops", po->cops, TCORE_RETURN_FAILURE);
713
714         return po->cops->answer_reject(o, ur, cb, user_data);
715 }
716
717 TReturn tcore_call_control_end_specific(CoreObject* o, UserRequest* ur, const int id, ConfirmCallback cb,
718                 void* user_data)
719 {
720         struct private_object_data *po = NULL;
721         po = tcore_object_ref_object(o);
722
723         _check_null( "po", po, TCORE_RETURN_FAILURE);
724         _check_null( "po->cops", po->cops, TCORE_RETURN_FAILURE);
725
726         return po->cops->end_specific(o, ur, id, cb, user_data);
727 }
728
729 TReturn tcore_call_control_end_all_active(CoreObject* o, UserRequest* ur, ConfirmCallback cb, void* user_data)
730 {
731         struct private_object_data *po = NULL;
732         po = tcore_object_ref_object(o);
733
734         _check_null( "po", po, TCORE_RETURN_FAILURE);
735         _check_null( "po->cops", po->cops, TCORE_RETURN_FAILURE);
736
737         return po->cops->end_all_active(o, ur, cb, user_data);
738 }
739
740 TReturn tcore_call_control_end_all_held(CoreObject* o, UserRequest* ur, ConfirmCallback cb, void* user_data)
741 {
742         struct private_object_data *po = NULL;
743         po = tcore_object_ref_object(o);
744
745         _check_null( "po", po, TCORE_RETURN_FAILURE);
746         _check_null( "po->cops", po->cops, TCORE_RETURN_FAILURE);
747
748         return po->cops->end_all_held(o, ur, cb, user_data);
749 }
750
751 TReturn tcore_call_control_active(CoreObject* o, UserRequest* ur, ConfirmCallback cb, void* user_data)
752 {
753         struct private_object_data *po = NULL;
754         po = tcore_object_ref_object(o);
755
756         _check_null( "po", po, TCORE_RETURN_FAILURE);
757         _check_null( "po->cops", po->cops, TCORE_RETURN_FAILURE);
758
759         return po->cops->active(o, ur, cb, user_data);
760 }
761
762 TReturn tcore_call_control_hold(CoreObject* o, UserRequest* ur, ConfirmCallback cb, void* user_data)
763 {
764         struct private_object_data *po = NULL;
765         po = tcore_object_ref_object(o);
766
767         _check_null( "po", po, TCORE_RETURN_FAILURE);
768         _check_null( "po->cops", po->cops, TCORE_RETURN_FAILURE);
769
770         return po->cops->hold(o, ur, cb, user_data);
771 }
772
773 TReturn tcore_call_control_swap(CoreObject* o, UserRequest* ur, ConfirmCallback cb, void* user_data)
774 {
775         struct private_object_data *po = NULL;
776         po = tcore_object_ref_object(o);
777
778         _check_null( "po", po, TCORE_RETURN_FAILURE);
779         _check_null( "po->cops", po->cops, TCORE_RETURN_FAILURE);
780
781         return po->cops->swap(o, ur, cb, user_data);
782 }
783
784 TReturn tcore_call_control_join(CoreObject* o, UserRequest* ur, ConfirmCallback cb, void* user_data)
785 {
786         struct private_object_data *po = NULL;
787         po = tcore_object_ref_object(o);
788
789         _check_null( "po", po, TCORE_RETURN_FAILURE);
790         _check_null( "po->cops", po->cops, TCORE_RETURN_FAILURE);
791
792         return po->cops->join(o, ur, cb, user_data);
793 }
794
795 TReturn tcore_call_control_split(CoreObject* o, UserRequest* ur, const int id, ConfirmCallback cb, void* user_data)
796 {
797         struct private_object_data *po = NULL;
798         po = tcore_object_ref_object(o);
799
800         _check_null( "po", po, TCORE_RETURN_FAILURE);
801         _check_null( "po->cops", po->cops, TCORE_RETURN_FAILURE);
802
803         return po->cops->split(o, ur, id, cb, user_data);
804 }
805
806 TReturn tcore_call_control_transfer(CoreObject* o, UserRequest* ur, ConfirmCallback cb, void* user_data)
807 {
808         struct private_object_data *po = NULL;
809         po = tcore_object_ref_object(o);
810
811         _check_null( "po", po, TCORE_RETURN_FAILURE);
812         _check_null( "po->cops", po->cops, TCORE_RETURN_FAILURE);
813
814         return po->cops->transfer(o, ur, cb, user_data);
815 }
816
817 TReturn tcore_call_control_deflect(CoreObject* o, UserRequest* ur, const char* number, ConfirmCallback cb,
818                 void* user_data)
819 {
820         struct private_object_data *po = NULL;
821         po = tcore_object_ref_object(o);
822
823         _check_null( "po", po, TCORE_RETURN_FAILURE);
824         _check_null( "po->cops", po->cops, TCORE_RETURN_FAILURE);
825
826         return po->cops->deflect(o, ur, number, cb, user_data);
827 }
828
829 void tcore_call_control_set_operations(CoreObject *o, struct tcore_call_control_operations *ops)
830 {
831         struct private_object_data *po = NULL;
832
833         CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
834
835         po = tcore_object_ref_object(o);
836         if (!po)
837                 return;
838
839         po->cops = ops;
840 }
841
842 void tcore_call_information_mo_col(CoreObject *o, char* number)
843 {
844         struct private_object_data *po = NULL;
845
846         CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
847
848         po = tcore_object_ref_object(o);
849
850         _check_null( "po", po, );
851         _check_null( "po->iops", po->iops,);
852
853         po->iops->mo_call_col(o, number);
854 }
855
856 void tcore_call_information_mo_waiting(CoreObject *o)
857 {
858         struct private_object_data *po = NULL;
859
860         CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
861
862         po = tcore_object_ref_object(o);
863
864         _check_null( "po", po, );
865         _check_null( "po->iops", po->iops,);
866
867         po->iops->mo_call_waiting(o);
868 }
869
870 void tcore_call_information_mo_cug(CoreObject *o, int cug_index)
871 {
872         struct private_object_data *po = NULL;
873
874         CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
875
876         po = tcore_object_ref_object(o);
877
878         _check_null( "po", po, );
879         _check_null( "po->iops", po->iops,);
880
881         po->iops->mo_call_cug(o, cug_index);
882 }
883
884 void tcore_call_information_mo_forwarded(CoreObject *o)
885 {
886         struct private_object_data *po = NULL;
887
888         CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
889
890         po = tcore_object_ref_object(o);
891
892         _check_null( "po", po,);
893         _check_null( "po->iops", po->iops,);
894
895         po->iops->mo_call_forwarded(o);
896 }
897
898 void tcore_call_information_mo_barred_incoming(CoreObject *o)
899 {
900         struct private_object_data *po = NULL;
901
902         CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
903
904         po = tcore_object_ref_object(o);
905
906         _check_null( "po", po,);
907         _check_null( "po->iops", po->iops,);
908
909         po->iops->mo_call_barred_incoming(o);
910 }
911
912 void tcore_call_information_mo_barred_outgoing(CoreObject *o)
913 {
914         struct private_object_data *po = NULL;
915
916         CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
917
918         po = tcore_object_ref_object(o);
919
920         _check_null( "po", po,);
921         _check_null( "po->iops", po->iops,);
922
923         po->iops->mo_call_barred_outgoing(o);
924 }
925
926 void tcore_call_information_mo_deflected(CoreObject *o)
927 {
928         struct private_object_data *po = NULL;
929
930         CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
931
932         po = tcore_object_ref_object(o);
933
934         _check_null( "po", po,);
935         _check_null( "po->iops", po->iops,);
936
937         po->iops->mo_call_deflected(o);
938 }
939
940 void tcore_call_information_mo_clir_suppression_reject(CoreObject *o)
941 {
942         struct private_object_data *po = NULL;
943
944         CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
945
946         po = tcore_object_ref_object(o);
947
948         _check_null( "po", po,);
949         _check_null( "po->iops", po->iops,);
950
951         po->iops->mo_call_clir_suppression_reject(o);
952 }
953
954 void tcore_call_information_mo_cfu(CoreObject *o)
955 {
956         struct private_object_data *po = NULL;
957
958         CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
959
960         po = tcore_object_ref_object(o);
961
962         _check_null( "po", po,);
963         _check_null( "po->iops", po->iops,);
964
965         po->iops->mo_call_cfu(o);
966 }
967
968 void tcore_call_information_mo_cfc(CoreObject *o)
969 {
970         struct private_object_data *po = NULL;
971
972         CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
973
974         po = tcore_object_ref_object(o);
975
976         _check_null( "po", po,);
977         _check_null( "po->iops", po->iops,);
978
979         po->iops->mo_call_cfc(o);
980 }
981
982 void tcore_call_information_mt_cli(CoreObject *o, enum tcore_call_cli_mode mode, char* number)
983 {
984         struct private_object_data *po = NULL;
985
986         CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
987
988         po = tcore_object_ref_object(o);
989
990         _check_null( "po", po, );
991         _check_null( "po->iops", po->iops,);
992
993         po->iops->mt_call_cli(o, mode, number);
994 }
995
996 void tcore_call_information_mt_cna(CoreObject *o, enum tcore_call_cna_mode mode, char* name, int dcs)
997 {
998         struct private_object_data *po = NULL;
999
1000         CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
1001
1002         po = tcore_object_ref_object(o);
1003
1004         _check_null( "po", po,);
1005         _check_null( "po->iops", po->iops,);
1006
1007         po->iops->mt_call_cna(o, mode, name, dcs);
1008 }
1009
1010 void tcore_call_information_mt_forwarded_call(CoreObject *o, char* number)
1011 {
1012         struct private_object_data *po = NULL;
1013
1014         CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
1015
1016         po = tcore_object_ref_object(o);
1017
1018         _check_null( "po", po,);
1019         _check_null( "po->iops", po->iops,);
1020
1021         po->iops->mt_call_forwarded_call(o, number);
1022 }
1023
1024 void tcore_call_information_mt_cug_call(CoreObject *o, int cug_index, char* number)
1025 {
1026         struct private_object_data *po = NULL;
1027
1028         CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
1029
1030         po = tcore_object_ref_object(o);
1031
1032         _check_null( "po", po,);
1033         _check_null( "po->iops", po->iops,);
1034
1035         po->iops->mt_call_cug_call(o, cug_index, number);
1036 }
1037
1038 void tcore_call_information_mt_deflected_call(CoreObject *o, char* number)
1039 {
1040         struct private_object_data *po = NULL;
1041
1042         CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
1043
1044         po = tcore_object_ref_object(o);
1045
1046         _check_null( "po", po,);
1047         _check_null( "po->iops", po->iops,);
1048
1049         po->iops->mt_call_deflected_call(o, number);
1050 }
1051
1052 void tcore_call_information_mt_transfered(CoreObject *o, char* number)
1053 {
1054         struct private_object_data *po = NULL;
1055
1056         CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
1057
1058         po = tcore_object_ref_object(o);
1059
1060         _check_null( "po", po,);
1061         _check_null( "po->iops", po->iops,);
1062
1063         po->iops->mt_call_transfered(o, number);
1064 }
1065
1066 void tcore_call_information_held(CoreObject *o, char* number)
1067 {
1068         struct private_object_data *po = NULL;
1069
1070         CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
1071
1072         po = tcore_object_ref_object(o);
1073
1074         _check_null( "po", po,);
1075         _check_null( "po->iops", po->iops,);
1076
1077         po->iops->call_held(o, number);
1078 }
1079
1080 void tcore_call_information_active(CoreObject *o, char* number)
1081 {
1082         struct private_object_data *po = NULL;
1083
1084         CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
1085
1086         po = tcore_object_ref_object(o);
1087
1088         _check_null( "po", po,);
1089         _check_null( "po->iops", po->iops,);
1090
1091         po->iops->call_active(o, number);
1092 }
1093
1094 void tcore_call_information_joined(CoreObject *o, char* number)
1095 {
1096         struct private_object_data *po = NULL;
1097
1098         CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
1099
1100         po = tcore_object_ref_object(o);
1101
1102         _check_null( "po", po,);
1103         _check_null( "po->iops", po->iops,);
1104
1105         po->iops->call_joined(o, number);
1106 }
1107
1108 void tcore_call_information_released_on_hold(CoreObject *o, char* number)
1109 {
1110         struct private_object_data *po = NULL;
1111
1112         CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
1113
1114         po = tcore_object_ref_object(o);
1115
1116         _check_null( "po", po,);
1117         _check_null( "po->iops", po->iops,);
1118
1119         po->iops->call_released_on_hold(o, number);
1120 }
1121
1122 void tcore_call_information_transfer_alert(CoreObject *o, char* number)
1123 {
1124         struct private_object_data *po = NULL;
1125
1126         CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
1127
1128         po = tcore_object_ref_object(o);
1129
1130         _check_null( "po", po,);
1131         _check_null( "po->iops", po->iops,);
1132
1133         po->iops->call_transfer_alert(o, number);
1134 }
1135
1136 void tcore_call_information_transfered(CoreObject *o, char* number)
1137 {
1138         struct private_object_data *po = NULL;
1139
1140         CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
1141
1142         po = tcore_object_ref_object(o);
1143
1144         _check_null( "po", po,);
1145         _check_null( "po->iops", po->iops,);
1146
1147         po->iops->call_transfered(o, number);
1148 }
1149
1150 void tcore_call_information_cf_check_ss_message(CoreObject *o, char* number)
1151 {
1152         struct private_object_data *po = NULL;
1153
1154         CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
1155
1156         po = tcore_object_ref_object(o);
1157
1158         _check_null( "po", po,);
1159         _check_null( "po->iops", po->iops,);
1160
1161         po->iops->call_cf_check_message(o, number);
1162 }
1163
1164 void tcore_call_information_set_operations(CoreObject *o, struct tcore_call_information_operations *ops)
1165 {
1166         struct private_object_data *po = NULL;
1167
1168         CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
1169
1170         po = tcore_object_ref_object(o);
1171         if (!po)
1172                 return;
1173
1174         po->iops = ops;
1175 }
1176
1177 CoreObject *tcore_call_new(TcorePlugin *p, const char *name, struct tcore_call_operations *ops, TcoreHal *hal)
1178 {
1179         CoreObject *o = NULL;
1180         struct private_object_data *po = NULL;
1181
1182         if (!p)
1183                 return NULL;
1184
1185         o = tcore_object_new(p, name, hal);
1186         if (!o)
1187                 return NULL;
1188
1189         po = g_try_new0(struct private_object_data, 1);
1190         if (po == NULL) {
1191                 tcore_object_free(o);
1192                 return NULL;
1193         }
1194
1195         po->ops = ops;
1196
1197         tcore_object_set_type(o, CORE_OBJECT_TYPE_CALL);
1198         tcore_object_link_object(o, po);
1199         tcore_object_set_free_hook(o, _free_hook);
1200         tcore_object_set_clone_hook(o, _clone_hook);
1201         tcore_object_set_dispatcher(o, _dispatcher);
1202
1203         return o;
1204 }
1205
1206 void tcore_call_free(CoreObject *o)
1207 {
1208         CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
1209         tcore_object_free(o);
1210 }
1211
1212 void tcore_call_set_ops(CoreObject *o, struct tcore_call_operations *ops)
1213 {
1214         struct private_object_data *po = NULL;
1215
1216         CORE_OBJECT_CHECK(o, CORE_OBJECT_TYPE_CALL);
1217
1218         po = (struct private_object_data *)tcore_object_ref_object(o);
1219         if (!po) {
1220                 return;
1221         }
1222
1223         po->ops = ops;
1224 }