Revert manifest to default one
[profile/ivi/tel-plugin-atmodem.git] / src / s_call.c
1 /*
2  * tel-plugin-atmodem
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Hayoon Ko <hayoon.ko@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 <hal.h>
29 #include <core_object.h>
30 #include <plugin.h>
31 #include <queue.h>
32 #include <server.h>
33 #include <co_call.h>
34 #include <user_request.h>
35
36 #include "s_common.h"
37 #include "s_call.h"
38
39 #include "atchannel.h"
40 #include "at_tok.h"
41
42
43 extern struct ATResponse *sp_response;
44 extern char *s_responsePrefix;
45 extern enum ATCommandType s_type;
46
47 struct CLCC_call_t {
48         struct CLCC_call_info_t {
49                 int                             id;
50                 enum tcore_call_direction       direction;
51                 enum tcore_call_status          status;
52                 enum tcore_call_type            type;
53                 int     mpty;
54                 int     num_len;
55                 int     num_type;
56         } info;
57         char number[90];
58 };
59
60
61 static gboolean _call_request_message( CoreObject *o, UserRequest* ur, char* cmd_string,
62                                                                                                 unsigned int cmd_length, void* on_resp, void* user_data);
63
64 static void             _call_status_idle( TcorePlugin *p, CallObject *co );
65 static void             _call_status_active( TcorePlugin *p, CallObject *co );
66 static void             _call_status_dialing( TcorePlugin *p, CallObject *co );
67 static void             _call_status_alert( TcorePlugin *p, CallObject *co );
68 static void             _call_status_incoming( TcorePlugin *p, CallObject *co );
69 static void             _call_status_waiting( TcorePlugin *p, CallObject *co );
70
71 static void             _call_branch_by_status( TcorePlugin *p, CallObject *co, unsigned int status );
72 static enum tcore_call_type _call_type( int type );
73 static enum tcore_call_status _call_status(unsigned int status);
74 static gboolean _call_is_in_mpty(int mpty);
75
76 static TReturn  _call_list_get( CoreObject *o, CallObject *co );
77
78 static void             on_confirmation_call_message_send( TcorePending *p, gboolean result, void *user_data ); // from Kernel
79
80 static void             on_response_call_list_get(TcorePending *p, int data_len, const void *data, void *user_data);
81 static gboolean on_notification_call_waiting( CoreObject *o, const void *data, void *user_data );
82 static gboolean on_notification_call_incoming( CoreObject *o, const void *data, void *user_data );
83 static gboolean on_notification_call_status( CoreObject *o, const void *data, void *user_data);
84
85
86 static int _callFromCLCCLine(char *line, struct CLCC_call_t *p_call);
87
88
89 static enum tcore_call_cli_mode _get_clir_status( char *num )
90 {
91         enum tcore_call_cli_mode clir = CALL_CLI_MODE_DEFAULT;
92
93         if( !strncmp( num, "*31#", 4 ) )
94                 return TCORE_CALL_CLI_MODE_RESTRICT;
95
96         if( !strncmp( num, "#31#", 4 ) )
97                 return TCORE_CALL_CLI_MODE_PRESENT;
98
99         return clir;
100 }
101
102
103 static enum tcore_call_status _call_status(unsigned int status)
104 {
105         switch(status)
106         {
107                 case 0:
108                         return TCORE_CALL_STATUS_ACTIVE;
109         case 1:
110                         return TCORE_CALL_STATUS_HELD;
111         case 2:
112                         return TCORE_CALL_STATUS_DIALING;
113                 case 3:
114                         return TCORE_CALL_STATUS_ALERT;
115                 case 4:
116                         return TCORE_CALL_STATUS_INCOMING;
117                 case 5:
118                         return TCORE_CALL_STATUS_WAITING;
119                 case 6:
120                         return TCORE_CALL_STATUS_DIALING; //connecting not exist. set to dialing
121         case 7:
122                         return TCORE_CALL_STATUS_IDLE;
123
124                 default:
125                         return TCORE_CALL_STATUS_IDLE;
126                 break;
127         }
128
129         return TCORE_CALL_STATUS_IDLE;
130 }
131
132 static gboolean _call_is_in_mpty(int mpty)
133 {
134         switch(mpty){
135                 case 0:
136                         return FALSE;
137                 break;
138
139                 case 1:
140                         return TRUE;
141
142                 default:
143                 break;
144         }
145         return FALSE;
146 }
147
148 static enum tcore_call_type _call_type(int type )
149 {
150         switch (type) {
151         case 0:
152                 return TCORE_CALL_TYPE_VOICE;
153         case 1:
154                 return TCORE_CALL_TYPE_VIDEO;
155         default:
156                 break;
157         }
158
159         return TCORE_CALL_TYPE_VOICE;
160 }
161
162 static gboolean _call_request_message(  CoreObject *o,
163                                                                                 UserRequest *ur,
164                                                                                 char *cmd_string,
165                                                                                 unsigned int cmd_len,
166                                                                                 void* on_resp,
167                                                                                 void* user_data)
168 {
169         TcorePending *pending = NULL;
170         TcorePlugin *p = NULL;
171         TcoreHal *h = NULL;
172
173         unsigned int info_len = 0;
174         info_len = sizeof(struct ATReqMetaInfo);
175
176         dbg("_call_request_message - cmd : %s, cmdlen :%d (including '\r')",cmd_string, cmd_len);
177
178
179         pending = tcore_pending_new(o, ID_RESERVED_AT);
180         tcore_pending_set_request_data(pending, cmd_len, cmd_string);
181         tcore_pending_set_timeout(pending, 0);
182         tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
183
184         if ( on_resp )
185                 tcore_pending_set_response_callback(pending, on_resp, user_data);
186
187         tcore_pending_set_send_callback(pending, on_confirmation_call_message_send, NULL);
188
189         if ( !ur ) {
190                 dbg("[ check ] ur is NULL, is this internal request??");
191         } else {
192                 tcore_pending_link_user_request(pending, ur);
193         }
194
195         p = tcore_object_ref_plugin(o);
196         h = tcore_object_get_hal(o);
197
198         tcore_hal_send_request(h, pending);
199
200         return TRUE;
201 }
202
203 static void _call_status_idle( TcorePlugin *p, CallObject *co )
204 {
205         struct tnoti_call_status_idle data;
206
207         dbg("call id [%d], call status [%d]", tcore_call_object_get_id(co), tcore_call_object_get_status(co));
208
209         if ( tcore_call_object_get_status( co ) != TCORE_CALL_STATUS_IDLE ) {
210
211                 CoreObject *o = 0;
212                 //int id = 0;
213
214                 o = tcore_plugin_ref_core_object(p, "call");
215
216                 data.type = tcore_call_object_get_type( co );
217                 dbg("data.type : [%d]", data.type );
218
219                 data.id = tcore_call_object_get_id( co );
220                 dbg("data.id : [%d]", data.id );
221
222                 tcore_call_object_set_status( co, TCORE_CALL_STATUS_IDLE );
223
224                 tcore_server_send_notification( tcore_plugin_ref_server(p),
225                                                                         o,
226                                                                         TNOTI_CALL_STATUS_IDLE,
227                                                                         sizeof(struct tnoti_call_status_idle),
228                                                                         (void*)&data    );
229
230                 tcore_call_object_free( o, co );
231         } else {
232
233                 dbg("[ error ] call object was not free");
234         }
235 }
236
237 static void _call_status_dialing( TcorePlugin *p, CallObject *co )
238 {
239         CoreObject* o = 0;
240
241         struct tnoti_call_status_dialing data;
242
243         o = tcore_plugin_ref_core_object( p, "call");
244
245         if ( tcore_call_object_get_status( co ) != TCORE_CALL_STATUS_DIALING ) {
246
247                 data.type = tcore_call_object_get_type( co );
248                 dbg("data.type : [%d]", data.type );
249
250                 data.id = tcore_call_object_get_id( co );
251                 dbg("data.id : [%d]", data.id );
252
253                 tcore_call_object_set_status( co, TCORE_CALL_STATUS_DIALING );
254
255                 tcore_server_send_notification( tcore_plugin_ref_server(p),
256                                                                         tcore_plugin_ref_core_object(p, "call"),
257                                                                         TNOTI_CALL_STATUS_DIALING,
258                                                                         sizeof(struct tnoti_call_status_dialing),
259                                                                         (void*)&data );
260
261         }
262
263 #if 0
264         _call_list_get( o, co );
265 #endif
266 }
267
268 static void _call_status_alert( TcorePlugin *p, CallObject *co )
269 {
270         CoreObject* o = 0;
271         struct tnoti_call_status_alert data;
272
273         o = tcore_plugin_ref_core_object( p, "call");
274
275         if ( tcore_call_object_get_status( co ) != TCORE_CALL_STATUS_ALERT ) {
276
277                 data.type = tcore_call_object_get_type( co );
278                 dbg("data.type : [%d]", data.type );
279
280                 data.id = tcore_call_object_get_id( co );
281                 dbg("data.id : [%d]", data.id );
282
283                 tcore_call_object_set_status( co, TCORE_CALL_STATUS_ALERT );
284
285                 tcore_server_send_notification( tcore_plugin_ref_server(p),
286                                                                         tcore_plugin_ref_core_object(p, "call"),
287                                                                         TNOTI_CALL_STATUS_ALERT,
288                                                                         sizeof(struct tnoti_call_status_alert),
289                                                                         (void*)&data );
290
291         }
292
293 #if 0
294         _call_list_get( o, co );
295 #endif
296 }
297
298 static void _call_status_active( TcorePlugin *p, CallObject *co )
299 {
300         struct tnoti_call_status_active data;
301
302         if ( tcore_call_object_get_status( co ) != TCORE_CALL_STATUS_ACTIVE ) {
303
304                 data.type = tcore_call_object_get_type( co );
305                 dbg("data.type : [%d]", data.type );
306
307                 data.id = tcore_call_object_get_id( co );
308                 dbg("data.id : [%d]", data.id );
309
310                 tcore_call_object_set_status( co, TCORE_CALL_STATUS_ACTIVE );
311
312                 tcore_server_send_notification( tcore_plugin_ref_server(p),
313                                                                         tcore_plugin_ref_core_object(p, "call"),
314                                                                         TNOTI_CALL_STATUS_ACTIVE,
315                                                                         sizeof(struct tnoti_call_status_active),
316                                                                         (void*)&data );
317
318         }
319 }
320
321 static void _call_status_held( TcorePlugin *p, CallObject *co )
322 {
323         struct tnoti_call_status_held data;
324
325         if ( tcore_call_object_get_status( co ) != TCORE_CALL_STATUS_HELD ) {
326
327                 data.type = tcore_call_object_get_type( co );
328                 dbg("data.type : [%d]", data.type );
329
330                 data.id = tcore_call_object_get_id( co );
331                 dbg("data.id : [%d]", data.id );
332
333                 tcore_call_object_set_status( co, TCORE_CALL_STATUS_HELD );
334
335                 tcore_server_send_notification( tcore_plugin_ref_server(p),
336                                                                         tcore_plugin_ref_core_object(p, "call"),
337                                                                         TNOTI_CALL_STATUS_HELD,
338                                                                         sizeof(struct tnoti_call_status_held),
339                                                                         (void*)&data );
340
341         }
342 }
343
344 static void _call_status_incoming( TcorePlugin *p, CallObject *co )
345 {
346         struct tnoti_call_status_incoming data;
347         CoreObject* o = 0;
348         o = tcore_plugin_ref_core_object( p, "call");
349
350         if ( tcore_call_object_get_status( co ) != TCORE_CALL_STATUS_INCOMING ) {
351
352                 tcore_call_object_set_status( co, TCORE_CALL_STATUS_INCOMING );
353
354                 data.type = tcore_call_object_get_type( co );
355                 dbg("data.type : [%d]", data.type );
356
357                 data.id = tcore_call_object_get_id( co );
358                 dbg("data.id : [%d]", data.id );
359
360                 data.cli.mode = tcore_call_object_get_cli_mode( co );
361                 dbg("data.cli.mode : [%d]", data.cli.mode );
362
363                 tcore_call_object_get_number( co, data.cli.number );
364                 dbg("data.cli.number : [%s]", data.cli.number );
365
366                 data.cna.mode = tcore_call_object_get_cna_mode( co );
367                 dbg("data.cna.mode : [%d]", data.cna.mode );
368
369                 tcore_call_object_get_name( co, data.cna.name );
370                 dbg("data.cna.name : [%s]", data.cna.name );
371
372                 data.forward = FALSE; // this is tmp code
373                 data.active_line = tcore_call_object_get_active_line( co );
374                 dbg("data.active_line : [%d]", data.active_line );
375
376                 tcore_server_send_notification( tcore_plugin_ref_server(p),
377                                 tcore_plugin_ref_core_object(p, "call"),
378                                 TNOTI_CALL_STATUS_INCOMING,
379                                 sizeof(struct tnoti_call_status_incoming),
380                                 (void*)&data    );
381         }
382
383 #if 0
384         _call_list_get( o, co );
385 #endif
386
387 }
388
389 static void _call_status_waiting( TcorePlugin *p, CallObject *co )
390 {
391         _call_status_incoming( p, co );
392 }
393
394 static void _call_branch_by_status( TcorePlugin *p, CallObject *co, unsigned int status )
395 {
396         switch ( status ) {
397         case TCORE_CALL_STATUS_IDLE:
398                 _call_status_idle( p, co );
399                 break;
400
401         case TCORE_CALL_STATUS_ACTIVE:
402                 _call_status_active( p, co );
403                 break;
404
405         case TCORE_CALL_STATUS_HELD:
406                 _call_status_held( p, co );
407                 break;
408
409         case TCORE_CALL_STATUS_DIALING:
410                 _call_status_dialing( p, co );
411                 break;
412
413         case TCORE_CALL_STATUS_ALERT:
414                 _call_status_alert( p, co );
415                 break;
416
417         case TCORE_CALL_STATUS_INCOMING:
418                 _call_status_incoming( p, co );
419                 break;
420
421         case TCORE_CALL_STATUS_WAITING:
422                 _call_status_waiting( p, co );
423                 break;
424         }
425 }
426
427
428 static TReturn _call_list_get( CoreObject *o, CallObject *co )
429 {
430         gboolean ret = FALSE;
431         UserRequest* ur = NULL;
432
433         char*   cmd_str = NULL;
434         struct ATReqMetaInfo metainfo;
435         int info_len =0;
436
437         if ( !o )
438                 return TCORE_RETURN_FAILURE;
439
440         ur = tcore_user_request_new(NULL, NULL);
441
442         memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
443
444         metainfo.type = MULTILINE;
445         memcpy(metainfo.responsePrefix,"+CLCC:",strlen("+CLCC:"));
446         info_len = sizeof(struct ATReqMetaInfo);
447         tcore_user_request_set_metainfo(ur, info_len, &metainfo);
448
449         cmd_str = g_strdup("AT+CLCC\r");
450
451         ret = _call_request_message ( o, ur, cmd_str, strlen(cmd_str), on_response_call_list_get, NULL);
452
453         if ( !ret )
454                 return TCORE_RETURN_FAILURE;
455
456         return TCORE_RETURN_SUCCESS;
457 }
458
459
460
461
462 // CONFIRMATION
463
464 static void on_confirmation_call_message_send( TcorePending *p, gboolean result, void *user_data )
465 {
466         UserRequest* ur = NULL;
467         struct ATReqMetaInfo* metainfo = NULL;
468         unsigned int info_len =0;
469         dbg("on_confirmation_call_message_send - msg out from queue. alloc ATRsp buffer & write rspPrefix if needed\n");
470
471         ReleaseResponse(); //release leftover
472 //alloc new sp_response
473
474         sp_response = at_response_new();
475
476         ur = tcore_pending_ref_user_request(p);
477         metainfo = (struct ATReqMetaInfo*)tcore_user_request_ref_metainfo(ur,&info_len);
478
479         if((metainfo->type == SINGLELINE)||
480                         (metainfo->type == MULTILINE))
481         {
482                 //cp rsp prefix
483                 s_responsePrefix = strdup(metainfo->responsePrefix);
484                 dbg("duplicating responsePrefix : %s\n", s_responsePrefix);
485         }
486         else
487         {
488                 s_responsePrefix = NULL;
489         }
490
491 //set atcmd type into s_type
492         s_type = metainfo->type;
493
494         if (result == FALSE) {
495                 /* Fail */
496                 dbg("SEND FAIL");
497         }
498         else {
499                 dbg("SEND OK");
500         }
501 }
502
503 static void on_confirmation_call_outgoing( TcorePending *p, int data_len, const void *data, void *user_data )
504 {
505         CoreObject *o = 0;
506         UserRequest *ur = 0;
507
508         struct tresp_call_dial resp;
509
510         o  = tcore_pending_ref_core_object(p);
511         ur = tcore_pending_ref_user_request(p);
512
513         if(sp_response->success >0)
514                 resp.err = TCORE_RETURN_SUCCESS;
515         else
516                 resp.err = TCORE_RETURN_FAILURE;
517
518         ReleaseResponse();
519
520         if (ur) {
521                 tcore_user_request_send_response(ur, TRESP_CALL_DIAL, sizeof(struct tresp_call_dial), &resp);
522
523         } else {
524                 dbg("[ error ] ur is NULL");
525                 return ;
526         }
527 }
528
529 static void on_confirmation_call_accept( TcorePending *p, int data_len, const void *data, void *user_data )
530 {
531         CoreObject *o = 0;
532         UserRequest *ur = 0;
533
534         struct tresp_call_answer resp;
535
536         o  = tcore_pending_ref_core_object(p);
537         ur = tcore_pending_ref_user_request(p);
538
539         if(sp_response->success >0)
540                 resp.err = TCORE_RETURN_SUCCESS;
541         else
542                 resp.err = TCORE_RETURN_FAILURE;
543
544         ReleaseResponse();
545
546         resp.id   =  tcore_call_object_get_id( (CallObject*)user_data );
547
548         if (ur) {
549                 tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
550
551         } else {
552                 dbg("[ error ] ur is NULL");
553                 return ;
554         }
555 }
556
557
558 static void on_confirmation_call_reject( TcorePending *p, int data_len, const void *data, void *user_data )
559 {
560         CoreObject *o = 0;
561         UserRequest *ur = 0;
562
563         struct tresp_call_answer resp;
564
565         o  = tcore_pending_ref_core_object(p);
566         ur = tcore_pending_ref_user_request(p);
567
568         if(sp_response->success >0)
569                 resp.err = TCORE_RETURN_SUCCESS;
570         else
571                 resp.err = TCORE_RETURN_FAILURE;
572
573         ReleaseResponse();
574
575         resp.id   =  tcore_call_object_get_id( (CallObject*)user_data );
576
577         if (ur) {
578                 tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
579
580         } else {
581                 dbg("[ error ] ur is NULL");
582                 return ;
583         }
584 }
585
586 static void on_confirmation_call_replace( TcorePending *p, int data_len, const void *data, void *user_data )
587 {
588         CoreObject *o = 0;
589         UserRequest *ur = 0;
590
591         struct tresp_call_answer resp;
592
593         o  = tcore_pending_ref_core_object(p);
594         ur = tcore_pending_ref_user_request(p);
595
596         resp.id   =  tcore_call_object_get_id( (CallObject*)user_data );
597
598         if(sp_response->success >0)
599                 resp.err = TCORE_RETURN_SUCCESS;
600         else
601                 resp.err = TCORE_RETURN_FAILURE;
602
603         ReleaseResponse();
604
605
606         if (ur) {
607                 tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
608
609         } else {
610                 dbg("[ error ] ur is NULL");
611                 return ;
612         }
613 }
614
615 static void on_confirmation_call_hold_and_accept( TcorePending *p, int data_len, const void *data, void *user_data )
616 {
617         CoreObject*             o = 0;
618         UserRequest*    ur = 0;
619
620         struct tresp_call_answer resp;
621
622         dbg("ok, function entrance");
623
624         o  = tcore_pending_ref_core_object(p);
625         ur = tcore_pending_ref_user_request(p);
626
627         resp.id   =  tcore_call_object_get_id( (CallObject*)user_data );
628
629         if(sp_response->success >0)
630                 resp.err = TCORE_RETURN_SUCCESS;
631         else
632                 resp.err = TCORE_RETURN_FAILURE;
633
634         ReleaseResponse();
635
636
637         if ( ur ) {
638                 tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
639
640         } else {
641                 dbg("[ error ] ur is NULL");
642                 return ;
643         }
644
645         if ( !resp.err ) {
646
647                 GSList *l = 0;
648                 CallObject *co = 0;
649
650                 l = tcore_call_object_find_by_status( o, TCORE_CALL_STATUS_ACTIVE );
651                 if ( !l ) {
652                         dbg("[ error ] can't find active call");
653                         return ;
654                 }
655
656                 co = (CallObject*)l->data;
657                 if ( !co ) {
658                         dbg("[ error ] can't get active call object");
659                         return ;
660                 }
661
662                 tcore_call_object_set_status( co, TCORE_CALL_STATUS_HELD );
663         }
664 }
665
666 static void on_confirmation_call_release_all( TcorePending *p, int data_len, const void *data, void *user_data )
667 {
668         CoreObject *o = 0;
669         UserRequest *ur = 0;
670
671         struct tresp_call_end resp;
672
673         o  = tcore_pending_ref_core_object(p);
674         ur = tcore_pending_ref_user_request(p);
675
676
677         resp.type = CALL_END_TYPE_ALL;
678         resp.id   =  tcore_call_object_get_id( (CallObject*)user_data );
679
680         if(sp_response->success >0)
681                 resp.err = TCORE_RETURN_SUCCESS;
682         else
683                 resp.err = TCORE_RETURN_FAILURE;
684
685         ReleaseResponse();
686
687         if (ur) {
688                 tcore_user_request_send_response(ur, TRESP_CALL_END, sizeof(struct tresp_call_end), &resp);
689
690         } else {
691                 dbg("[ error ] ur is NULL");
692                 return ;
693         }
694 }
695
696
697
698 static void on_confirmation_call_release_specific( TcorePending *p, int data_len, const void *data, void *user_data )
699 {
700         CoreObject *o = 0;
701         UserRequest *ur = 0;
702
703         struct tresp_call_end resp;
704
705         o  = tcore_pending_ref_core_object(p);
706         ur = tcore_pending_ref_user_request(p);
707
708         resp.type = CALL_END_TYPE_DEFAULT;
709         resp.id   =  tcore_call_object_get_id( (CallObject*)user_data );
710
711         if(sp_response->success >0)
712                 resp.err = TCORE_RETURN_SUCCESS;
713         else
714                 resp.err = TCORE_RETURN_FAILURE;
715
716         ReleaseResponse();
717
718         if (ur) {
719                 tcore_user_request_send_response(ur, TRESP_CALL_END, sizeof(struct tresp_call_end), &resp);
720
721         } else {
722                 dbg("[ error ] ur is NULL");
723                 return ;
724         }
725 }
726
727 static void on_confirmation_call_release_all_active( TcorePending *p, int data_len, const void *data, void *user_data )
728 {
729         CoreObject *o = 0;
730         UserRequest *ur = 0;
731
732         struct tresp_call_end resp;
733
734         o  = tcore_pending_ref_core_object(p);
735         ur = tcore_pending_ref_user_request(p);
736
737         resp.type = CALL_END_TYPE_ACTIVE_ALL;
738         resp.id   =  tcore_call_object_get_id( (CallObject*)user_data );
739
740         if(sp_response->success >0)
741                 resp.err = TCORE_RETURN_SUCCESS;
742         else
743                 resp.err = TCORE_RETURN_FAILURE;
744
745         ReleaseResponse();
746
747         if (ur) {
748                 tcore_user_request_send_response(ur, TRESP_CALL_END, sizeof(struct tresp_call_end), &resp);
749
750         } else {
751                 dbg("[ error ] ur is NULL");
752                 return ;
753         }
754 }
755
756 static void on_confirmation_call_release_all_held( TcorePending *p, int data_len, const void *data, void *user_data )
757 {
758         CoreObject *o = 0;
759         UserRequest *ur = 0;
760
761         struct tresp_call_end resp;
762
763         o  = tcore_pending_ref_core_object(p);
764         ur = tcore_pending_ref_user_request(p);
765
766         resp.type = CALL_END_TYPE_HOLD_ALL;
767         resp.id   =  tcore_call_object_get_id( (CallObject*)user_data );
768
769         if(sp_response->success >0)
770                 resp.err = TCORE_RETURN_SUCCESS;
771         else
772                 resp.err = TCORE_RETURN_FAILURE;
773
774         ReleaseResponse();
775
776         if (ur) {
777                 tcore_user_request_send_response(ur, TRESP_CALL_END, sizeof(struct tresp_call_end), &resp);
778
779         } else {
780                 dbg("[ error ] ur is NULL");
781                 return ;
782         }
783 }
784
785 static void on_confirmation_call_hold( TcorePending *p, int data_len, const void *data, void *user_data )
786 {
787         CoreObject*             o = 0;
788         UserRequest*    ur = 0;
789
790         struct tresp_call_hold resp;
791
792         dbg("ok, function entrance");
793
794         o  = tcore_pending_ref_core_object(p);
795         ur = tcore_pending_ref_user_request(p);
796
797         resp.id   =  tcore_call_object_get_id( (CallObject*)user_data );
798
799         if(sp_response->success >0)
800                 resp.err = TCORE_RETURN_SUCCESS;
801         else
802                 resp.err = TCORE_RETURN_FAILURE;
803
804         ReleaseResponse();
805
806         if ( ur ) {
807                 tcore_user_request_send_response(ur, TRESP_CALL_HOLD, sizeof(struct tresp_call_hold), &resp);
808
809         } else {
810                 dbg("[ error ] ur is NULL");
811                 return ;
812         }
813
814         if ( !resp.err ) {
815
816                 GSList *active = 0;
817                 CallObject *co = 0;
818
819                 active = tcore_call_object_find_by_status( o, TCORE_CALL_STATUS_ACTIVE );
820                 if ( !active ) {
821                         dbg("[ error ] can't find active call");
822                         return ;
823                 }
824
825                 co = (CallObject*)active->data;
826                 if ( !co ) {
827                         dbg("[ error ] can't get active call object");
828                         return ;
829                 }
830
831                 tcore_call_object_set_status( co, TCORE_CALL_STATUS_HELD );
832         }
833
834 }
835
836 static void on_confirmation_call_active( TcorePending *p, int data_len, const void *data, void *user_data )
837 {
838         CoreObject *o = 0;
839         UserRequest *ur = 0;
840
841         struct tresp_call_active resp;
842
843         o  = tcore_pending_ref_core_object(p);
844         ur = tcore_pending_ref_user_request(p);
845
846         resp.id   =  tcore_call_object_get_id( (CallObject*)user_data );
847
848         if(sp_response->success >0)
849                 resp.err = TCORE_RETURN_SUCCESS;
850         else
851                 resp.err = TCORE_RETURN_FAILURE;
852
853         ReleaseResponse();
854
855         if (ur) {
856                 tcore_user_request_send_response(ur, TRESP_CALL_ACTIVE, sizeof(struct tresp_call_active), &resp);
857
858         } else {
859                 dbg("[ error ] ur is NULL");
860                 return ;
861         }
862
863 }
864
865 static void on_confirmation_call_swap( TcorePending *p, int data_len, const void *data, void *user_data )
866 {
867         CoreObject*             o = 0;
868         UserRequest*    ur = 0;
869
870         struct tresp_call_swap resp;
871
872         dbg("ok, function entrance");
873
874         o  = tcore_pending_ref_core_object(p);
875         ur = tcore_pending_ref_user_request(p);
876
877         resp.id   =  tcore_call_object_get_id( (CallObject*)user_data );
878
879         if(sp_response->success >0)
880                 resp.err = TCORE_RETURN_SUCCESS;
881         else
882                 resp.err = TCORE_RETURN_FAILURE;
883
884         ReleaseResponse();
885
886         if ( ur ) {
887                 tcore_user_request_send_response(ur, TRESP_CALL_SWAP, sizeof(struct tresp_call_swap), &resp);
888
889         } else {
890                 dbg("[ error ] ur is NULL");
891                 return ;
892         }
893
894         if ( !resp.err ) {
895
896                 GSList *active = 0, *held = 0;
897                 CallObject *co = 0;
898
899                 held = tcore_call_object_find_by_status( o, TCORE_CALL_STATUS_HELD );
900                 if ( !held ) {
901                         dbg("[ error ] can't find held call");
902                         return ;
903                 }
904
905                 active = tcore_call_object_find_by_status( o, TCORE_CALL_STATUS_ACTIVE );
906                 if ( !active ) {
907                         dbg("[ error ] can't find active call");
908                         return ;
909                 }
910
911                 co = (CallObject*)held->data;
912                 if ( !co ) {
913                         dbg("[ error ] can't get held call object");
914                         return ;
915                 }
916
917                 resp.id  =  tcore_call_object_get_id( co );
918                 tcore_call_object_set_status( co, TCORE_CALL_STATUS_ACTIVE );
919
920                 tcore_user_request_send_response(ur, TRESP_CALL_ACTIVE, sizeof(struct tresp_call_active), &resp);
921
922                 co = (CallObject*)active->data;
923                 if ( !co ) {
924                         dbg("[ error ] can't get active call object");
925                         return ;
926                 }
927
928                 resp.id  =  tcore_call_object_get_id( co );
929                 tcore_call_object_set_status( co, TCORE_CALL_STATUS_HELD );
930
931                 tcore_user_request_send_response(ur, TRESP_CALL_HOLD, sizeof(struct tresp_call_hold), &resp);
932         }
933 }
934
935 static void on_confirmation_call_join( TcorePending *p, int data_len, const void *data, void *user_data )
936 {
937         CoreObject *o = 0;
938         UserRequest *ur = 0;
939
940         struct tresp_call_join resp;
941
942         o  = tcore_pending_ref_core_object(p);
943         ur = tcore_pending_ref_user_request(p);
944
945         resp.id   =  tcore_call_object_get_id( (CallObject*)user_data );
946
947         if(sp_response->success >0)
948                 resp.err = TCORE_RETURN_SUCCESS;
949         else
950                 resp.err = TCORE_RETURN_FAILURE;
951
952         ReleaseResponse();
953
954         if (ur) {
955                 tcore_user_request_send_response(ur, TRESP_CALL_JOIN, sizeof(struct tresp_call_join), &resp);
956
957         } else {
958                 dbg("[ error ] ur is NULL");
959                 return ;
960         }
961 }
962
963 static void on_confirmation_call_split( TcorePending *p, int data_len, const void *data, void *user_data )
964 {
965         CoreObject*             o = 0;
966         UserRequest*    ur = 0;
967
968
969         struct tresp_call_split resp;
970
971         dbg("ok, function entrance");
972
973         o  = tcore_pending_ref_core_object(p);
974         ur = tcore_pending_ref_user_request(p);
975
976         resp.id   =  tcore_call_object_get_id( (CallObject*)user_data );
977
978         if(sp_response->success >0)
979                 resp.err = TCORE_RETURN_SUCCESS;
980         else
981                 resp.err = TCORE_RETURN_FAILURE;
982
983         ReleaseResponse();
984
985         if ( ur ) {
986                 tcore_user_request_send_response(ur, TRESP_CALL_SPLIT, sizeof(struct tresp_call_split), &resp);
987
988         } else {
989                 dbg("[ error ] ur is NULL");
990                 return ;
991         }
992
993         if ( !resp.err ) {
994
995                 GSList *active = 0;
996                 CallObject *co = 0;
997
998                 active = tcore_call_object_find_by_status( o, TCORE_CALL_STATUS_ACTIVE );
999                 if ( !active ) {
1000                         dbg("[ error ] can't find active call");
1001                         return ;
1002                 }
1003
1004                 co = (CallObject*)active->data;
1005                 if ( !co ) {
1006                         dbg("[ error ] can't get active call object");
1007                         return ;
1008                 }
1009
1010                 tcore_call_object_set_status( co, TCORE_CALL_STATUS_HELD );
1011                 tcore_call_object_set_status( (CallObject*)user_data, TCORE_CALL_STATUS_ACTIVE );
1012         }
1013 }
1014
1015 static void on_confirmation_call_deflect( TcorePending *p, int data_len, const void *data, void *user_data )
1016 {
1017         CoreObject *o = 0;
1018         UserRequest *ur = 0;
1019
1020         struct tresp_call_deflect resp;
1021
1022         o  = tcore_pending_ref_core_object(p);
1023         ur = tcore_pending_ref_user_request(p);
1024
1025         resp.id   =  tcore_call_object_get_id( (CallObject*)user_data );
1026
1027         if(sp_response->success >0)
1028                 resp.err = TCORE_RETURN_SUCCESS;
1029         else
1030                 resp.err = TCORE_RETURN_FAILURE;
1031
1032         ReleaseResponse();
1033
1034         if (ur) {
1035                 tcore_user_request_send_response(ur, TRESP_CALL_DEFLECT, sizeof(struct tresp_call_deflect), &resp);
1036
1037         } else {
1038                 dbg("[ error ] ur is NULL");
1039                 return ;
1040         }
1041 }
1042
1043 static void on_confirmation_call_transfer( TcorePending *p, int data_len, const void *data, void *user_data )
1044 {
1045         CoreObject *o = 0;
1046         UserRequest *ur = 0;
1047
1048         struct tresp_call_transfer resp;
1049
1050         o  = tcore_pending_ref_core_object(p);
1051         ur = tcore_pending_ref_user_request(p);
1052
1053         resp.id   =  tcore_call_object_get_id( (CallObject*)user_data );
1054
1055         if(sp_response->success >0)
1056                 resp.err = TCORE_RETURN_SUCCESS;
1057         else
1058                 resp.err = TCORE_RETURN_FAILURE;
1059
1060         ReleaseResponse();
1061
1062         if (ur) {
1063                 tcore_user_request_send_response(ur, TRESP_CALL_TRANSFER, sizeof(struct tresp_call_transfer), &resp);
1064
1065         } else {
1066                 dbg("[ error ] ur is NULL");
1067                 return ;
1068         }
1069 }
1070
1071 // RESPONSE
1072 static void on_confirmation_call_endall( TcorePending *p, int data_len, const void *data, void *user_data )
1073 {
1074         CoreObject*             o = 0;
1075         UserRequest*    ur = 0;
1076
1077         dbg("on_confirmation_call_endall - 1st result. wait for final result");
1078
1079
1080         o  = tcore_pending_ref_core_object(p);
1081         ur = tcore_pending_ref_user_request(p);
1082
1083 //skip response handling - actual result will be handled in on_confirmation_call_request
1084         ReleaseResponse();
1085 }
1086
1087 // RESPONSE
1088
1089 static void on_response_call_list_get(TcorePending *p, int data_len, const void *data, void *user_data)
1090 {
1091         TcorePlugin* plugin = 0;
1092         CoreObject*     o = 0;
1093         CallObject*     co = 0;
1094         struct ATLine *p_cur;
1095
1096         char* cmd= 0;
1097         struct CLCC_call_t*     call_list = 0;
1098
1099         int i = 0, countCalls =0, countValidCalls =0, err =0;
1100
1101
1102         plugin  = tcore_pending_ref_plugin( p );
1103         o               = tcore_pending_ref_core_object( p );
1104
1105         cmd             = (char*)data;
1106
1107
1108         if(sp_response->success > 0)
1109         {
1110
1111                 /* count the calls */
1112                 for (countCalls = 0, p_cur = sp_response->p_intermediates
1113                                 ; p_cur != NULL
1114                                 ; p_cur = p_cur->p_next
1115                         ) {
1116                         countCalls++;
1117                 }
1118                 dbg("total calls : %d",countCalls);
1119
1120                 if(countCalls ==0)
1121                         return;
1122
1123                 call_list       = g_new0( struct CLCC_call_t, countCalls);
1124
1125
1126                 for (countValidCalls = 0, p_cur = sp_response->p_intermediates
1127                                 ; p_cur != NULL
1128                                 ; p_cur = p_cur->p_next)
1129                 {
1130
1131                         err = _callFromCLCCLine( p_cur->line, call_list + countValidCalls );
1132
1133                         if (err != 0) {
1134                                 continue;
1135                         }
1136
1137                         co = tcore_call_object_find_by_id( o, call_list[i].info.id );
1138                         if ( !co ) {
1139                                 co = tcore_call_object_new( o, call_list[i].info.id );
1140                                 if ( !co ) {
1141                                         dbg("error : tcore_call_object_new [ id : %d ]", call_list[i].info.id);
1142                                         continue ;
1143                                 }
1144                         }
1145
1146                         tcore_call_object_set_type( co, _call_type( call_list[i].info.type ) );
1147                         tcore_call_object_set_direction( co, call_list[i].info.direction );
1148                         tcore_call_object_set_multiparty_state( co, _call_is_in_mpty(call_list[i].info.mpty) );
1149                         tcore_call_object_set_cli_info( co, CALL_CLI_MODE_DEFAULT, call_list[i].number );
1150
1151                         _call_branch_by_status( plugin, co, call_list[i].info.status );
1152
1153                 }
1154         }
1155
1156         ReleaseResponse();
1157 }
1158
1159 static int _callFromCLCCLine(char *line, struct CLCC_call_t*p_call)
1160 {
1161         //+CLCC: 1,0,2,0,0,\"+18005551212\",145
1162         //     index,isMT,state,mode,isMpty(,number,TOA)?
1163
1164     int err;
1165     int state;
1166         int mode;
1167         int isMT;
1168         char* num;
1169
1170         err = at_tok_start(&line);
1171         if (err < 0) goto error;
1172
1173         //id
1174         err = at_tok_nextint(&line, &(p_call->info.id));
1175         if (err < 0) goto error;
1176         dbg("id : [%d]\n", p_call->info.id );
1177         //MO/MTcall
1178         err = at_tok_nextint(&line, &isMT);
1179         if (err < 0) goto error;
1180
1181         if(isMT ==0)
1182                 p_call->info.direction = TCORE_CALL_DIRECTION_OUTGOING;
1183         else
1184                 p_call->info.direction = TCORE_CALL_DIRECTION_INCOMING;
1185
1186         dbg("direction : [ %d ]\n", p_call->info.direction);
1187
1188         //state
1189         err = at_tok_nextint(&line, &state);
1190         if (err < 0) goto error;
1191
1192         switch(state){
1193                 case 0: //active
1194                         p_call->info.status = TCORE_CALL_STATUS_ACTIVE;
1195                         break;
1196                 case 1:
1197                         p_call->info.status = TCORE_CALL_STATUS_HELD;
1198                         break;
1199                 case 2:
1200                         p_call->info.status = TCORE_CALL_STATUS_DIALING;
1201                         break;
1202                 case 3:
1203                         p_call->info.status = TCORE_CALL_STATUS_ALERT;
1204                         break;
1205                 case 4:
1206                         p_call->info.status = TCORE_CALL_STATUS_INCOMING;
1207                         break;
1208                 case 5:
1209                         p_call->info.status = TCORE_CALL_STATUS_WAITING;
1210                         break;
1211         }
1212         dbg("status     : [%d]\n", p_call->info.status );
1213
1214         //mode
1215         err = at_tok_nextint(&line, &mode);
1216         if (err < 0) goto error;
1217
1218         switch(mode)
1219         {
1220                 case 0:
1221                         p_call->info.type       = TCORE_CALL_TYPE_VOICE;
1222                         break;
1223
1224                 case 1:
1225                         p_call->info.type       = TCORE_CALL_TYPE_VIDEO;
1226                         break;
1227
1228                 default:        // only Voice/VT call is supported in CS. treat other unknown calls as error
1229                         dbg("invalid type : [%d]\n", mode );
1230                         goto error;
1231                         break;
1232         }
1233         dbg("type : [%d]\n", p_call->info.type );
1234
1235
1236         err = at_tok_nextint(&line, &(p_call->info.mpty));
1237     if (err < 0) goto error;
1238         dbg("mpty       : [%d]\n", p_call->info.mpty );
1239
1240         if (at_tok_hasmore(&line)) {
1241                 err = at_tok_nextstr(&line, &num);
1242
1243                 /* tolerate null here */
1244                 if (err < 0) return 0;
1245
1246                 memcpy(p_call->number, num, strlen(num));
1247                 dbg("number     : [ %s ]\n", p_call->number );
1248
1249                 p_call->info.num_len = strlen(num);
1250                 dbg("num_len : [0x%x]\n", p_call->info.num_len );
1251
1252                 err = at_tok_nextint(&line, &(p_call->info.num_type));
1253                 if (err < 0) goto error;
1254                 dbg("num_type : [0x%x]\n", p_call->info.num_type );
1255
1256         }
1257
1258     return 0;
1259
1260 error:
1261     err("invalid CLCC line\n");
1262     return -1;
1263 }
1264
1265 // NOTIFICATION
1266
1267 static gboolean on_notification_call_waiting( CoreObject *o, const void *data, void *user_data )
1268 {
1269         TcorePlugin* plugin = NULL;
1270         char* cmd = NULL, *num = NULL;
1271         CallObject *co, *dupco = 0;
1272         int id, status, err, type, mpty,direction;
1273         GSList* pList = NULL;
1274 #define LINE_DEFAULT 0
1275
1276         dbg("call waiting noti : %s", cmd);
1277         plugin = tcore_object_ref_plugin(o);
1278
1279         cmd = (char*)data;
1280
1281         at_tok_start(&cmd);
1282
1283         err = at_tok_nextint(&cmd,&id);
1284         err = at_tok_nextint(&cmd,&direction);
1285         err = at_tok_nextint(&cmd,&status);
1286         err = at_tok_nextint(&cmd,&type);
1287         err = at_tok_nextint(&cmd,&mpty);
1288
1289         if(at_tok_hasmore(&cmd)){
1290                 err = at_tok_nextstr(&cmd,&num);
1291                 dbg("id: %d, direction : %d, status : %d, type :%d, mpty : %d, num : %s", id,direction,status, type, mpty, num);
1292         }
1293         else    {
1294                 dbg("id: %d, direction : %d, status : %d, type :%d, mpty : %d, num : NULL", id,direction,status, type, mpty);
1295         }
1296 // check call with incoming status already exist
1297         pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_WAITING);
1298         if(pList != NULL){
1299                 dbg("waiting call already exist. skip");
1300                 return TRUE;
1301         }
1302
1303         pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
1304         if(pList != NULL){
1305                 dbg("incoming call already exist. skip");
1306                 return TRUE;
1307         }
1308
1309         dupco = tcore_call_object_find_by_id(o, id);
1310         if(dupco!= NULL){
1311                 dbg("co with same id already exist. skip");
1312                 return TRUE;
1313         }
1314
1315 // make new co, add to list
1316         co = tcore_call_object_new( o, id);
1317         if ( !co ) {
1318                 dbg("[ error ] co is NULL");
1319                 return TRUE;
1320         }
1321
1322         tcore_call_object_set_type(co, _call_type(type));
1323         tcore_call_object_set_multiparty_state(co,_call_is_in_mpty(mpty));
1324         tcore_call_object_set_direction(co, TCORE_CALL_DIRECTION_INCOMING);
1325         tcore_call_object_set_cli_info(co, TCORE_CALL_CLI_MODE_DEFAULT,  num);
1326         tcore_call_object_set_active_line(co, LINE_DEFAULT);
1327
1328         _call_list_get( o, co );
1329
1330         return TRUE;
1331 }
1332
1333 static gboolean on_notification_call_incoming( CoreObject *o, const void *data, void *user_data )
1334 {
1335         TcorePlugin* plugin = NULL;
1336         char* cmd = NULL, *num = NULL;
1337         CallObject *co, *dupco = 0;
1338         int id, status, err, type, mpty,direction;
1339         GSList* pList = NULL;
1340 #define LINE_DEFAULT 0
1341
1342         dbg("call incoming noti : %s", cmd);
1343         plugin = tcore_object_ref_plugin(o);
1344
1345         cmd = (char*)data;
1346
1347         at_tok_start(&cmd);
1348
1349         err = at_tok_nextint(&cmd,&id);
1350         err = at_tok_nextint(&cmd,&direction);
1351         err = at_tok_nextint(&cmd,&status);
1352         err = at_tok_nextint(&cmd,&type);
1353         err = at_tok_nextint(&cmd,&mpty);
1354
1355         if(at_tok_hasmore(&cmd))        {
1356                 err = at_tok_nextstr(&cmd,&num);
1357                 dbg("id: %d, direction : %d, status : %d, type :%d, mpty : %d, num : %s", id,direction,status, type, mpty, num);
1358         }
1359         else    {
1360                 dbg("id: %d, direction : %d, status : %d, type :%d, mpty : %d, num : NULL", id,direction,status, type, mpty);
1361         }
1362 // check call with incoming status already exist
1363         pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
1364         if(pList != NULL){
1365                 dbg("incoming call already exist. skip");
1366                 return TRUE;
1367         }
1368
1369         dupco = tcore_call_object_find_by_id(o, id);
1370         if(dupco!= NULL){
1371                 dbg("co with same id already exist. skip");
1372                 return TRUE;
1373         }
1374
1375 // make new co, add to list
1376         co = tcore_call_object_new( o, id);
1377         if ( !co ) {
1378                 dbg("[ error ] co is NULL");
1379                 return TRUE;
1380         }
1381
1382         tcore_call_object_set_type(co, _call_type(type));
1383         tcore_call_object_set_multiparty_state(co,_call_is_in_mpty(mpty));
1384         tcore_call_object_set_direction(co, TCORE_CALL_DIRECTION_INCOMING);
1385         tcore_call_object_set_cli_info(co, TCORE_CALL_CLI_MODE_DEFAULT,  num);
1386         tcore_call_object_set_active_line(co, LINE_DEFAULT);
1387
1388         _call_list_get( o, co );
1389
1390         return TRUE;
1391 }
1392
1393 static gboolean on_notification_call_status( CoreObject *o, const void *data, void *user_data)
1394 {
1395         char* cmd = NULL, *num = NULL;
1396         TcorePlugin*    p  = 0;
1397         CallObject*                     co = 0;
1398         int id, status, type, mpty,direction;
1399         int err;
1400
1401         enum tcore_call_status co_status;
1402
1403         p       = tcore_object_ref_plugin( o );
1404         cmd = (char*)data;
1405
1406         at_tok_start(&cmd);
1407
1408         err = at_tok_nextint(&cmd,&id);
1409         err = at_tok_nextint(&cmd,&direction);
1410         err = at_tok_nextint(&cmd,&status);
1411         err = at_tok_nextint(&cmd,&type);
1412         err = at_tok_nextint(&cmd,&mpty);
1413
1414         if (at_tok_hasmore(&cmd)) {
1415                 err = at_tok_nextstr(&cmd,&num);
1416                 dbg("id: %d, direction : %d, status : %d, type :%d, mpty : %d, num : %s", id,direction,status, type, mpty, num);
1417         }
1418         else {
1419                 dbg("id: %d, direction : %d, status : %d, type :%d, mpty : %d, num : NULL", id,direction,status, type, mpty);
1420         }
1421
1422         co_status = _call_status(status);
1423
1424         switch (co_status) {
1425                 case CALL_STATUS_ACTIVE:{
1426
1427                 dbg("call(%d) status : [ ACTIVE ]", id);
1428                 co      = tcore_call_object_find_by_id(o,id);
1429                 if ( !co ) {
1430                         dbg("co is NULL");
1431                         return TRUE;
1432                 }
1433                 _call_status_active( p, co );
1434
1435                 } break;
1436                 case CALL_STATUS_HELD:
1437                 break;
1438                 case CALL_STATUS_DIALING:
1439                 {
1440                 dbg("call(%d) status : [ dialing ]", id);
1441                 co      = tcore_call_object_find_by_id(o,id);
1442                 if ( !co ) {
1443                         co = tcore_call_object_new( o, id );
1444                         if ( !co ) {
1445                                 dbg("error : tcore_call_object_new [ id : %d ]", id);
1446                                 return TRUE;
1447                         }
1448                 }
1449
1450                 tcore_call_object_set_type( co, _call_type(type) );
1451                 tcore_call_object_set_direction( co, TCORE_CALL_DIRECTION_OUTGOING );
1452
1453                 _call_status_dialing( p, co );
1454                 }
1455                 break;
1456                 case CALL_STATUS_ALERT:
1457                 {
1458
1459                 dbg("call(%d) status : [ alert ]", id);
1460                 co      = tcore_call_object_find_by_id(o, id);
1461                 if ( !co ) {
1462                         dbg("co is NULL");
1463                         return TRUE;
1464                 }
1465
1466                 _call_list_get( o, co );
1467
1468                 } break;
1469                 case CALL_STATUS_INCOMING:
1470                 case CALL_STATUS_WAITING:
1471                 break;
1472                 case CALL_STATUS_IDLE: {
1473
1474                                 dbg("call(%d) status : [ release ]", id);
1475
1476                                 co      = tcore_call_object_find_by_id( o, id );
1477                                 if ( !co )
1478                                         dbg("co is NULL");
1479
1480                                 p       = tcore_object_ref_plugin( o );
1481                                 if ( !p )
1482                                         dbg("plugin is NULL");
1483
1484                                 _call_status_idle( p, co );
1485
1486                         } break;
1487
1488                 default:
1489                         break;
1490         }
1491
1492         return TRUE;
1493 }
1494
1495 static TReturn s_call_outgoing( CoreObject *o, UserRequest *ur )
1496 {
1497         TcorePlugin*                    p = NULL;
1498         CallObject*                                     co = 0;
1499         struct treq_call_dial*          data = 0;
1500         char*                                           raw_str= NULL;
1501         char*                                           cmd_str = NULL;
1502     const char *cclir;
1503         struct ATReqMetaInfo metainfo;
1504         int info_len =0;
1505         enum tcore_call_cli_mode clir = CALL_CLI_MODE_DEFAULT;
1506
1507         gboolean                                        ret = FALSE;
1508
1509         data    = (struct treq_call_dial*)tcore_user_request_ref_data( ur, 0 );
1510         p               = tcore_object_ref_plugin( o );
1511
1512         clir = _get_clir_status( data->number );
1513
1514 //Compose ATCmd string
1515         switch (clir)
1516         {
1517                 case TCORE_CALL_CLI_MODE_PRESENT:
1518                         cclir = "I";
1519                 break;  /*invocation*/
1520                 case TCORE_CALL_CLI_MODE_RESTRICT:
1521                         cclir = "i";
1522                 break;  /*suppression*/
1523                 case TCORE_CALL_CLI_MODE_DEFAULT:
1524                 default:
1525                         cclir = "";
1526                 break;   /*subscription default*/
1527         }
1528
1529         raw_str = g_strdup_printf("ATD%s%s;", data->number, cclir);
1530         cmd_str = g_strdup_printf("%s%s",raw_str,"\r");
1531
1532         memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
1533
1534 //set metainfo
1535         metainfo.type = NO_RESULT;
1536         metainfo.responsePrefix[0] ='\0';
1537         info_len = sizeof(struct ATReqMetaInfo);
1538
1539         tcore_user_request_set_metainfo(ur, info_len, &metainfo);
1540
1541         ret = _call_request_message ( o, ur, cmd_str, strlen(cmd_str), on_confirmation_call_outgoing, co);
1542
1543         free(raw_str);
1544         free(cmd_str);
1545
1546         if ( !ret ) {
1547                 tcore_call_object_free( o, co );
1548                 return TCORE_RETURN_FAILURE;
1549         }
1550
1551         return TCORE_RETURN_SUCCESS;
1552 }
1553
1554 static TReturn s_call_answer( CoreObject *o, UserRequest *ur )
1555 {
1556         CallObject*                                     co = 0;
1557         struct treq_call_answer*        data = 0;
1558         gboolean                                        ret = FALSE;
1559         char*                                           cmd_str = NULL;
1560         struct ATReqMetaInfo metainfo ;
1561         unsigned int info_len =0;
1562
1563         data = (struct treq_call_answer*)tcore_user_request_ref_data( ur, 0 );
1564
1565         co = tcore_call_object_find_by_id( o, data->id );
1566
1567         memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
1568
1569 //set metainfo
1570         metainfo.type = NO_RESULT;
1571         metainfo.responsePrefix[0] = '\0';
1572         info_len = sizeof(struct ATReqMetaInfo);
1573
1574         tcore_user_request_set_metainfo(ur, info_len, &metainfo);
1575
1576         if ( data->type == CALL_ANSWER_TYPE_ACCEPT ) {
1577
1578                 cmd_str = g_strdup_printf("%s%s","ATA","\r");
1579                 ret = _call_request_message ( o, ur, (void*)cmd_str, strlen(cmd_str), on_confirmation_call_accept, co);
1580                 free(cmd_str);
1581                 if ( !ret )
1582                         return TCORE_RETURN_FAILURE;
1583
1584         } else {
1585
1586                 switch ( data->type ) {
1587                         case CALL_ANSWER_TYPE_REJECT: {
1588                                 dbg("call answer reject");
1589                                 tcore_call_control_answer_reject( o, ur, on_confirmation_call_reject, co );
1590                         } break;
1591
1592                         case CALL_ANSWER_TYPE_REPLACE: {
1593                                 dbg("call answer replace");
1594                                 tcore_call_control_answer_replace( o, ur, on_confirmation_call_replace, co );
1595                         } break;
1596
1597                         case CALL_ANSWER_TYPE_HOLD_ACCEPT: {
1598                                 dbg("call answer hold and accept");
1599                                 tcore_call_control_answer_hold_and_accept( o, ur, on_confirmation_call_hold_and_accept, co );
1600                         } break;
1601
1602                         default :
1603                                 dbg("[ error ] wrong answer type [ %d ]", data->type);
1604                                 return TCORE_RETURN_FAILURE;
1605                 }
1606         }
1607
1608         return TCORE_RETURN_SUCCESS;
1609 }
1610
1611 static TReturn s_call_release( CoreObject *o, UserRequest *ur )
1612 {
1613         CallObject*                                     co = 0;
1614
1615         struct treq_call_end*           data = 0;
1616         gboolean                                        ret = FALSE;
1617         UserRequest* ur_dup = 0;
1618
1619         char*                                   chld0_cmd = NULL;
1620         char*                                   chld1_cmd = NULL;
1621         struct ATReqMetaInfo metainfo1 ;
1622         struct ATReqMetaInfo  metainfo2 ;
1623         unsigned int info_len1, info_len2 =0;
1624
1625         data = (struct treq_call_end*)tcore_user_request_ref_data( ur, 0 );
1626
1627         co = tcore_call_object_find_by_id( o, data->id );
1628
1629         if ( data->type == CALL_END_TYPE_ALL ) {
1630
1631         //releaseAll do not exist on legacy request. send CHLD=0, CHLD=1 in sequence
1632         chld0_cmd = g_strdup("AT+CHLD=0\r");
1633         chld1_cmd = g_strdup("AT+CHLD=1\r");
1634
1635         memset(&metainfo1, 0, sizeof(struct ATReqMetaInfo));
1636         memset(&metainfo2, 0, sizeof(struct ATReqMetaInfo));
1637
1638
1639 //set metainfo
1640                 metainfo1.type = NO_RESULT;
1641                 metainfo1.responsePrefix[0] = '\0';
1642                 info_len1 = sizeof(struct ATReqMetaInfo);
1643
1644 //set metainfo
1645                 metainfo2.type = NO_RESULT;
1646                 metainfo2.responsePrefix[0] = '\0';
1647                 info_len2 = sizeof(struct ATReqMetaInfo);
1648
1649                 ur_dup = tcore_user_request_new(NULL, NULL);
1650
1651                 tcore_user_request_set_metainfo(ur_dup, info_len1, &metainfo1);
1652                 tcore_user_request_set_metainfo(ur, info_len2, &metainfo2);
1653
1654                 ret = _call_request_message(o, ur_dup, chld0_cmd, strlen(chld0_cmd), on_confirmation_call_endall, NULL);
1655                 free(chld0_cmd);
1656                 if ( !ret )
1657                         return TCORE_RETURN_FAILURE;
1658
1659                 ret = _call_request_message(o, ur, chld1_cmd, strlen(chld1_cmd), on_confirmation_call_release_all, co);
1660                 free(chld1_cmd);
1661                 if ( !ret )
1662                         return TCORE_RETURN_FAILURE;
1663
1664         } else {
1665
1666                 switch ( data->type ) {
1667                         case CALL_END_TYPE_DEFAULT: {
1668                                 int id = 0;
1669                                 id = tcore_call_object_get_id( co );
1670
1671                                 dbg("call end call id [%d]", id);
1672                                 tcore_call_control_end_specific( o, ur, id, on_confirmation_call_release_specific, co );
1673                         } break;
1674
1675                         case CALL_END_TYPE_ACTIVE_ALL: {
1676
1677                                 dbg("call end all active");
1678                                 tcore_call_control_end_all_active( o, ur, on_confirmation_call_release_all_active, co );
1679                         } break;
1680
1681                         case TCORE_CALL_END_ALL_HELD: {
1682
1683                                 dbg("call end all held");
1684                                 tcore_call_control_end_all_held( o, ur, on_confirmation_call_release_all_held, co );
1685                         } break;
1686
1687                         default :
1688                                 dbg("[ error ] wrong end type [ %d ]", data->type);
1689                                 return TCORE_RETURN_FAILURE;
1690                 }
1691
1692         }
1693
1694         return TCORE_RETURN_SUCCESS;
1695 }
1696
1697 static TReturn s_call_hold( CoreObject *o, UserRequest *ur )
1698 {
1699         struct treq_call_hold *hold = 0;
1700         CallObject *co = 0;
1701
1702         hold = (struct treq_call_hold*)tcore_user_request_ref_data( ur, 0 );
1703
1704         dbg("call id : [ %d ]", hold->id);
1705
1706         co = tcore_call_object_find_by_id( o, hold->id );
1707
1708         tcore_call_control_hold( o, ur, on_confirmation_call_hold, co );
1709
1710         return TCORE_RETURN_SUCCESS;
1711 }
1712
1713 static TReturn s_call_active( CoreObject *o, UserRequest *ur )
1714 {
1715         struct treq_call_active *active = 0;
1716         CallObject *co = 0;
1717
1718         active = (struct treq_call_active*)tcore_user_request_ref_data( ur, 0 );
1719
1720         dbg("call id : [ %d ]", active->id);
1721
1722         co = tcore_call_object_find_by_id( o, active->id );
1723
1724         tcore_call_control_active( o, ur, on_confirmation_call_active, co );
1725
1726         return TCORE_RETURN_SUCCESS;
1727 }
1728
1729 static TReturn s_call_swap( CoreObject *o, UserRequest *ur )
1730 {
1731         struct treq_call_swap *swap = 0;
1732         CallObject *co = 0;
1733         swap = (struct treq_call_swap*)tcore_user_request_ref_data( ur, 0 );
1734
1735         dbg("call id : [ %d ]", swap->id);
1736
1737         co = tcore_call_object_find_by_id( o, swap->id );
1738
1739         tcore_call_control_swap( o, ur, on_confirmation_call_swap, co );
1740
1741         return TCORE_RETURN_SUCCESS;
1742 }
1743
1744 static TReturn s_call_join( CoreObject *o, UserRequest *ur )
1745 {
1746         struct treq_call_join *join = 0;
1747         CallObject *co = 0;
1748
1749         join = (struct treq_call_join*)tcore_user_request_ref_data( ur, 0 );
1750
1751         dbg("call id : [ %d ]", join->id);
1752
1753         co = tcore_call_object_find_by_id( o, join->id );
1754
1755         tcore_call_control_join( o, ur, on_confirmation_call_join, co );
1756
1757         return TCORE_RETURN_SUCCESS;
1758 }
1759
1760 static TReturn s_call_split( CoreObject *o, UserRequest *ur )
1761 {
1762         struct treq_call_split *split = 0;
1763         CallObject *co = 0;
1764
1765         split = (struct treq_call_split*)tcore_user_request_ref_data( ur, 0 );
1766
1767         co = tcore_call_object_find_by_id ( o, split->id );
1768
1769         tcore_call_control_split( o, ur, split->id, on_confirmation_call_split, co );
1770
1771         return TCORE_RETURN_SUCCESS;
1772 }
1773
1774 static TReturn s_call_deflect( CoreObject *o, UserRequest *ur )
1775 {
1776         struct treq_call_deflect *deflect = 0;
1777         CallObject *co = 0;
1778
1779         deflect = (struct treq_call_deflect*)tcore_user_request_ref_data( ur, 0 );
1780
1781         co = tcore_call_object_find_by_number( o, deflect->number );
1782
1783         tcore_call_control_deflect( o, ur, deflect->number, on_confirmation_call_deflect, co );
1784
1785         return TCORE_RETURN_SUCCESS;
1786 }
1787
1788 static TReturn s_call_transfer( CoreObject *o, UserRequest *ur )
1789 {
1790         struct treq_call_transfer *transfer = 0;
1791         CallObject *co = 0;
1792
1793         transfer = (struct treq_call_transfer*)tcore_user_request_ref_data( ur, 0 );
1794
1795         dbg("call id : [ %d ]", transfer->id);
1796
1797         co = tcore_call_object_find_by_id( o, transfer->id );
1798
1799         tcore_call_control_transfer( o, ur, on_confirmation_call_transfer, co );
1800
1801         return TCORE_RETURN_SUCCESS;
1802 }
1803
1804 static TReturn s_call_send_dtmf( CoreObject *o, UserRequest *ur )
1805 {
1806         return TCORE_RETURN_SUCCESS;
1807 }
1808
1809 static TReturn s_call_set_sound_path( CoreObject *o, UserRequest *ur )
1810 {
1811
1812         return TCORE_RETURN_SUCCESS;
1813 }
1814
1815 static TReturn s_call_set_sound_volume_level( CoreObject *o, UserRequest *ur )
1816 {
1817
1818         return TCORE_RETURN_SUCCESS;
1819 }
1820
1821 static TReturn s_call_get_sound_volume_level( CoreObject *o, UserRequest *ur )
1822 {
1823
1824         return TCORE_RETURN_SUCCESS;
1825 }
1826
1827 static TReturn s_call_mute( CoreObject *o, UserRequest *ur )
1828 {
1829
1830         return TCORE_RETURN_SUCCESS;
1831 }
1832
1833 static TReturn s_call_unmute( CoreObject *o, UserRequest *ur )
1834 {
1835
1836         return TCORE_RETURN_SUCCESS;
1837 }
1838
1839 static TReturn s_call_get_mute_status( CoreObject *o, UserRequest *ur )
1840 {
1841
1842         return TCORE_RETURN_SUCCESS;
1843 }
1844
1845 static struct tcore_call_operations call_ops = {
1846         .dial                                   = s_call_outgoing,
1847         .answer                                 = s_call_answer,
1848         .end                                    = s_call_release,
1849         .hold                                   = s_call_hold,
1850         .active                                 = s_call_active,
1851         .swap                                   = s_call_swap,
1852         .join                                   = s_call_join,
1853         .split                                  = s_call_split,
1854         .deflect                                = s_call_deflect,
1855         .transfer                               = s_call_transfer,
1856         .send_dtmf                              = s_call_send_dtmf,
1857         .set_sound_path                 = s_call_set_sound_path,
1858         .set_sound_volume_level = s_call_set_sound_volume_level,
1859         .get_sound_volume_level = s_call_get_sound_volume_level,
1860         .mute                                   = s_call_mute,
1861         .unmute                                 = s_call_unmute,
1862         .get_mute_status                = s_call_get_mute_status,
1863 };
1864
1865
1866 static void s_call_info_mo_waiting( CoreObject *o )
1867 {
1868         CallObject *co = 0;
1869         int id = 0;
1870
1871         TcorePlugin *p = 0;
1872         p = tcore_object_ref_plugin(o);
1873
1874         co = tcore_call_object_current_on_mo_processing( o );
1875         if ( !co ) {
1876                 dbg("[ error ] can't find call object!");
1877                 return ;
1878         }
1879
1880         id = tcore_call_object_get_id( co );
1881
1882         tcore_server_send_notification( tcore_plugin_ref_server(p),
1883                                                                 tcore_plugin_ref_core_object(p, "call"),
1884                                                                 TNOTI_CALL_INFO_WAITING,
1885                                                                 sizeof(unsigned int),
1886                                                                 (void*)&id      );
1887 }
1888
1889 static void s_call_info_mo_forwarded( CoreObject *o )
1890 {
1891         CallObject *co = 0;
1892         int id = 0;
1893
1894         TcorePlugin *p = 0;
1895         p = tcore_object_ref_plugin(o);
1896
1897         co = tcore_call_object_current_on_mo_processing( o );
1898         if ( !co ) {
1899                 dbg("[ error ] can't find call object!");
1900                 return ;
1901         }
1902         id = tcore_call_object_get_id( co );
1903
1904         tcore_server_send_notification( tcore_plugin_ref_server(p),
1905                                                                 tcore_plugin_ref_core_object(p, "call"),
1906                                                                 TNOTI_CALL_INFO_FORWARDED,
1907                                                                 sizeof(unsigned int),
1908                                                                 (void*)&id      );
1909 }
1910
1911 static void s_call_info_mo_barred_incoming( CoreObject *o )
1912 {
1913         CallObject *co = 0;
1914         int id = 0;
1915
1916         TcorePlugin *p = 0;
1917         p = tcore_object_ref_plugin(o);
1918
1919         co = tcore_call_object_current_on_mo_processing( o );
1920         if ( !co ) {
1921                 dbg("[ error ] can't find call object!");
1922                 return ;
1923         }
1924         id = tcore_call_object_get_id( co );
1925
1926         tcore_server_send_notification( tcore_plugin_ref_server(p),
1927                                                                 tcore_plugin_ref_core_object(p, "call"),
1928                                                                 TNOTI_CALL_INFO_BARRED_INCOMING,
1929                                                                 sizeof(unsigned int),
1930                                                                 (void*)&id      );
1931 }
1932
1933 static void s_call_info_mo_barred_outgoing( CoreObject *o )
1934 {
1935         CallObject *co = 0;
1936         int id = 0;
1937
1938         TcorePlugin *p = 0;
1939         p = tcore_object_ref_plugin(o);
1940
1941         co = tcore_call_object_current_on_mo_processing( o );
1942         if ( !co ) {
1943                 dbg("[ error ] can't find call object!");
1944                 return ;
1945         }
1946         id = tcore_call_object_get_id( co );
1947
1948         tcore_server_send_notification( tcore_plugin_ref_server(p),
1949                                                                 tcore_plugin_ref_core_object(p, "call"),
1950                                                                 TNOTI_CALL_INFO_BARRED_OUTGOING,
1951                                                                 sizeof(unsigned int),
1952                                                                 (void*)&id      );
1953 }
1954
1955 static void s_call_info_mo_deflected( CoreObject *o )
1956 {
1957         CallObject *co = 0;
1958         int id = 0;
1959
1960         TcorePlugin *p = 0;
1961         p = tcore_object_ref_plugin(o);
1962
1963         co = tcore_call_object_current_on_mo_processing( o );
1964         if ( !co ) {
1965                 dbg("[ error ] can't find call object!");
1966                 return ;
1967         }
1968         id = tcore_call_object_get_id( co );
1969
1970         tcore_server_send_notification( tcore_plugin_ref_server(p),
1971                                                                 tcore_plugin_ref_core_object(p, "call"),
1972                                                                 TNOTI_CALL_INFO_DEFLECTED,
1973                                                                 sizeof(unsigned int),
1974                                                                 (void*)&id      );
1975 }
1976
1977 static void s_call_info_mo_clir_suppression_reject( CoreObject *o )
1978 {
1979         CallObject *co = 0;
1980         int id = 0;
1981
1982         TcorePlugin *p = 0;
1983         p = tcore_object_ref_plugin(o);
1984
1985         co = tcore_call_object_current_on_mo_processing( o );
1986         if ( !co ) {
1987                 dbg("[ error ] can't find call object!");
1988                 return ;
1989         }
1990         id = tcore_call_object_get_id( co );
1991
1992         tcore_server_send_notification( tcore_plugin_ref_server(p),
1993                                                                 tcore_plugin_ref_core_object(p, "call"),
1994                                                                 TNOTI_CALL_INFO_CLIR_SUPPRESSION_REJECT,
1995                                                                 sizeof(unsigned int),
1996                                                                 (void*)&id      );
1997 }
1998
1999 static void s_call_info_mo_cfu( CoreObject *o )
2000 {
2001         CallObject *co = 0;
2002         int id = 0;
2003
2004         TcorePlugin *p = 0;
2005         p = tcore_object_ref_plugin(o);
2006
2007         co = tcore_call_object_current_on_mo_processing( o );
2008         if ( !co ) {
2009                 dbg("[ error ] can't find call object!");
2010                 return ;
2011         }
2012         id = tcore_call_object_get_id( co );
2013
2014         tcore_server_send_notification( tcore_plugin_ref_server(p),
2015                                                                 tcore_plugin_ref_core_object(p, "call"),
2016                                                                 TNOTI_CALL_INFO_FORWARD_UNCONDITIONAL,
2017                                                                 sizeof(unsigned int),
2018                                                                 (void*)&id      );
2019 }
2020
2021 static void s_call_info_mo_cfc( CoreObject *o )
2022 {
2023         CallObject *co = 0;
2024         int id = 0;
2025
2026         TcorePlugin *p = 0;
2027         p = tcore_object_ref_plugin(o);
2028
2029         co = tcore_call_object_current_on_mo_processing( o );
2030         if ( !co ) {
2031                 dbg("[ error ] can't find call object!");
2032                 return ;
2033         }
2034         id = tcore_call_object_get_id( co );
2035
2036         tcore_server_send_notification( tcore_plugin_ref_server(p),
2037                                                                 tcore_plugin_ref_core_object(p, "call"),
2038                                                                 TNOTI_CALL_INFO_FORWARD_CONDITIONAL,
2039                                                                 sizeof(unsigned int),
2040                                                                 (void*)&id      );
2041 }
2042
2043 static void s_call_info_mt_cli( CoreObject *o, enum tcore_call_cli_mode mode, char* number )
2044 {
2045         CallObject *co = 0;
2046
2047         co = tcore_call_object_current_on_mt_processing( o );
2048         if ( !co ) {
2049                 dbg("[ error ] can't find call object!");
2050                 return ;
2051         }
2052         tcore_call_object_set_cli_info( co, mode, number );
2053 }
2054
2055 static void s_call_info_mt_cna( CoreObject *o, enum tcore_call_cna_mode mode, char* name, int dcs )
2056 {
2057         CallObject *co = 0;
2058
2059         co = tcore_call_object_current_on_mt_processing( o );
2060         if ( !co ) {
2061                 dbg("[ error ] can't find call object!");
2062                 return ;
2063         }
2064         tcore_call_object_set_cna_info( co, mode, name, dcs );
2065 }
2066
2067 static void s_call_info_mt_forwarded_call( CoreObject *o, char* number )
2068 {
2069         CallObject *co = 0;
2070         int id = 0;
2071
2072         TcorePlugin *p = 0;
2073         p = tcore_object_ref_plugin(o);
2074
2075         co = tcore_call_object_current_on_mt_processing( o );
2076         if ( !co ) {
2077                 dbg("[ error ] can't find call object!");
2078                 return ;
2079         }
2080
2081         id = tcore_call_object_get_id( co );
2082
2083         tcore_server_send_notification( tcore_plugin_ref_server(p),
2084                                                                 tcore_plugin_ref_core_object(p, "call"),
2085                                                                 TNOTI_CALL_INFO_FORWARDED_CALL,
2086                                                                 sizeof(unsigned int),
2087                                                                 (void*)&id      );
2088 }
2089
2090 static void s_call_info_mt_deflected_call( CoreObject *o, char* number )
2091 {
2092         CallObject *co = 0;
2093         int id = 0;
2094
2095         TcorePlugin *p = 0;
2096         p = tcore_object_ref_plugin(o);
2097
2098         co = tcore_call_object_current_on_mt_processing( o );
2099         if ( !co ) {
2100                 dbg("[ error ] can't find call object!");
2101                 return ;
2102         }
2103
2104         id = tcore_call_object_get_id( co );
2105
2106         tcore_server_send_notification( tcore_plugin_ref_server(p),
2107                                                                 tcore_plugin_ref_core_object(p, "call"),
2108                                                                 TNOTI_CALL_INFO_DEFLECTED_CALL,
2109                                                                 sizeof(unsigned int),
2110                                                                 (void*)&id      );
2111 }
2112
2113 static void s_call_info_mt_transfered( CoreObject *o, char* number )
2114 {
2115         CallObject *co = 0;
2116         int id = 0;
2117
2118         TcorePlugin *p = 0;
2119         p = tcore_object_ref_plugin(o);
2120
2121         co = tcore_call_object_current_on_mt_processing( o );
2122         if ( !co ) {
2123                 dbg("[ error ] can't find call object!");
2124                 return ;
2125         }
2126
2127         id = tcore_call_object_get_id( co );
2128
2129         tcore_server_send_notification( tcore_plugin_ref_server(p),
2130                                                                 tcore_plugin_ref_core_object(p, "call"),
2131                                                                 TNOTI_CALL_INFO_TRANSFERED_CALL,
2132                                                                 sizeof(unsigned int),
2133                                                                 (void*)&id      );
2134 }
2135
2136 static void s_call_info_held( CoreObject *o, char* number )
2137 {
2138         CallObject *co = 0;
2139         int id = 0;
2140
2141         TcorePlugin *p = 0;
2142         p = tcore_object_ref_plugin(o);
2143
2144         co = tcore_call_object_find_by_number( o, number );
2145         if ( !co ) {
2146                 dbg("[ error ] can't find call object!");
2147                 return ;
2148         }
2149
2150         id = tcore_call_object_get_id( co );
2151
2152         tcore_server_send_notification( tcore_plugin_ref_server(p),
2153                                                                 tcore_plugin_ref_core_object(p, "call"),
2154                                                                 TNOTI_CALL_INFO_HELD,
2155                                                                 sizeof(unsigned int),
2156                                                                 (void*)&id      );
2157 }
2158
2159 static void s_call_info_active( CoreObject *o, char* number )
2160 {
2161         CallObject *co = 0;
2162         int id = 0;
2163
2164         TcorePlugin *p = 0;
2165         p = tcore_object_ref_plugin(o);
2166
2167         co = tcore_call_object_find_by_number( o, number );
2168         if ( !co ) {
2169                 dbg("[ error ] can't find call object!");
2170                 return ;
2171         }
2172
2173         id = tcore_call_object_get_id( co );
2174
2175         tcore_server_send_notification( tcore_plugin_ref_server(p),
2176                                                                 tcore_plugin_ref_core_object(p, "call"),
2177                                                                 TNOTI_CALL_INFO_ACTIVE,
2178                                                                 sizeof(unsigned int),
2179                                                                 (void*)&id      );
2180 }
2181
2182 static void s_call_info_joined( CoreObject *o, char* number )
2183 {
2184         CallObject *co = 0;
2185         int id = 0;
2186
2187         TcorePlugin *p = 0;
2188         p = tcore_object_ref_plugin(o);
2189
2190         co = tcore_call_object_find_by_number( o, number );
2191         if ( !co ) {
2192                 dbg("[ error ] can't find call object!");
2193                 return ;
2194         }
2195
2196         id = tcore_call_object_get_id( co );
2197
2198         tcore_server_send_notification( tcore_plugin_ref_server(p),
2199                                                                 tcore_plugin_ref_core_object(p, "call"),
2200                                                                 TNOTI_CALL_INFO_JOINED,
2201                                                                 sizeof(unsigned int),
2202                                                                 (void*)&id      );
2203 }
2204
2205 static void s_call_info_released_on_hold( CoreObject *o, char* number )
2206 {
2207         CallObject *co = 0;
2208         int id = 0;
2209
2210         TcorePlugin *p = 0;
2211         p = tcore_object_ref_plugin(o);
2212
2213         co = tcore_call_object_find_by_number( o, number );
2214         if ( !co ) {
2215                 dbg("[ error ] can't find call object!");
2216                 return ;
2217         }
2218
2219         id = tcore_call_object_get_id( co );
2220
2221         tcore_server_send_notification( tcore_plugin_ref_server(p),
2222                                                                 tcore_plugin_ref_core_object(p, "call"),
2223                                                                 TNOTI_CALL_INFO_RELEASED_ON_HOLD,
2224                                                                 sizeof(unsigned int),
2225                                                                 (void*)&id      );
2226 }
2227
2228 static void s_call_info_transfer_alert( CoreObject *o, char* number )
2229 {
2230         CallObject *co = 0;
2231         int id = 0;
2232
2233         TcorePlugin *p = 0;
2234         p = tcore_object_ref_plugin(o);
2235
2236         co = tcore_call_object_find_by_number( o, number );
2237         if ( !co ) {
2238                 dbg("[ error ] can't find call object!");
2239                 return ;
2240         }
2241
2242         id = tcore_call_object_get_id( co );
2243
2244         tcore_server_send_notification( tcore_plugin_ref_server(p),
2245                                                                 tcore_plugin_ref_core_object(p, "call"),
2246                                                                 TNOTI_CALL_INFO_TRANSFER_ALERT,
2247                                                                 sizeof(unsigned int),
2248                                                                 (void*)&id      );
2249 }
2250
2251 static void s_call_info_transfered( CoreObject *o, char* number )
2252 {
2253         CallObject *co = 0;
2254         int id = 0;
2255
2256         TcorePlugin *p = 0;
2257         p = tcore_object_ref_plugin(o);
2258
2259         co = tcore_call_object_find_by_number( o, number );
2260         if ( !co ) {
2261                 dbg("[ error ] can't find call object!");
2262                 return ;
2263         }
2264
2265         id = tcore_call_object_get_id( co );
2266
2267         tcore_server_send_notification( tcore_plugin_ref_server(p),
2268                                                                 tcore_plugin_ref_core_object(p, "call"),
2269                                                                 TNOTI_CALL_INFO_TRANSFERED,
2270                                                                 sizeof(unsigned int),
2271                                                                 (void*)&id      );
2272 }
2273
2274 static void s_call_info_cf_check_message( CoreObject *o, char* number )
2275 {
2276         CallObject *co = 0;
2277         int id = 0;
2278
2279         TcorePlugin *p = 0;
2280         p = tcore_object_ref_plugin(o);
2281
2282         co = tcore_call_object_find_by_number( o, number );
2283         if ( !co ) {
2284                 dbg("[ error ] can't find call object!");
2285                 return ;
2286         }
2287
2288         id = tcore_call_object_get_id( co );
2289
2290         tcore_server_send_notification( tcore_plugin_ref_server(p),
2291                                                                 tcore_plugin_ref_core_object(p, "call"),
2292                                                                 TNOTI_CALL_INFO_CF_CHECK_MESSAGE,
2293                                                                 sizeof(unsigned int),
2294                                                                 (void*)&id      );
2295 }
2296
2297
2298 static struct tcore_call_information_operations call_information_ops = {
2299         .mo_call_col                            = 0,
2300         .mo_call_waiting                        = s_call_info_mo_waiting,
2301         .mo_call_cug                            = 0,
2302         .mo_call_forwarded                      = s_call_info_mo_forwarded,
2303         .mo_call_barred_incoming        = s_call_info_mo_barred_incoming,
2304         .mo_call_barred_outgoing        = s_call_info_mo_barred_outgoing,
2305         .mo_call_deflected                      = s_call_info_mo_deflected,
2306         .mo_call_clir_suppression_reject = s_call_info_mo_clir_suppression_reject,
2307         .mo_call_cfu                            = s_call_info_mo_cfu,
2308         .mo_call_cfc                            = s_call_info_mo_cfc,
2309         .mt_call_cli                            = s_call_info_mt_cli,
2310         .mt_call_cna                            = s_call_info_mt_cna,
2311         .mt_call_forwarded_call         = s_call_info_mt_forwarded_call,
2312         .mt_call_cug_call                       = 0,
2313         .mt_call_deflected_call         = s_call_info_mt_deflected_call,
2314         .mt_call_transfered                     = s_call_info_mt_transfered,
2315         .call_held                                      = s_call_info_held,
2316         .call_active                            = s_call_info_active,
2317         .call_joined                            = s_call_info_joined,
2318         .call_released_on_hold          = s_call_info_released_on_hold,
2319         .call_transfer_alert            = s_call_info_transfer_alert,
2320         .call_transfered                        = s_call_info_transfered,
2321         .call_cf_check_message          = s_call_info_cf_check_message,
2322 };
2323
2324 gboolean s_call_init(TcorePlugin *p, TcoreHal *h)
2325 {
2326         CoreObject *o = NULL;
2327 //      TcoreHal *h = NULL;
2328         struct property_call_info *data = NULL;
2329
2330         o = tcore_call_new(p, "call", &call_ops, h);
2331         if (!o)
2332                 return FALSE;
2333
2334         tcore_call_information_set_operations( o, &call_information_ops );
2335
2336         tcore_object_add_callback( o, EVENT_CALL_STATUS, on_notification_call_status, NULL );
2337         tcore_object_add_callback( o, EVENT_CALL_INCOMING, on_notification_call_incoming, NULL );
2338         tcore_object_add_callback( o, EVENT_CALL_WAITING, on_notification_call_waiting, NULL );
2339
2340         data = calloc( sizeof(struct property_call_info *), 1);
2341         tcore_plugin_link_property(p, "CALL", data);
2342
2343         return TRUE;
2344 }
2345
2346 void s_call_exit( TcorePlugin *p )
2347 {
2348         CoreObject *o;
2349 //      TcoreHal *h;
2350         struct property_network_info *data;
2351
2352         o = tcore_plugin_ref_core_object(p, "call");
2353
2354         data = tcore_plugin_ref_property(p, "CALL");
2355         if (data)
2356                 free(data);
2357
2358         tcore_call_free(o);
2359 }