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