Tizen 2.1 base
[platform/core/telephony/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 = CALL_ERROR_NONE;
515         else
516                 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
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 = CALL_ERROR_NONE;
541         else
542                 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
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 = CALL_ERROR_NONE;
570         else
571                 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
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 = CALL_ERROR_NONE;
600         else
601                 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
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 = CALL_ERROR_NONE;
631         else
632                 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
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 = CALL_ERROR_NONE;
682         else
683                 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
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 = CALL_ERROR_NONE;
713         else
714                 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
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 = CALL_ERROR_NONE;
742         else
743                 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
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 = CALL_ERROR_NONE;
771         else
772                 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
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 = CALL_ERROR_NONE;
801         else
802                 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
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 = CALL_ERROR_NONE;
850         else
851                 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
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 = CALL_ERROR_NONE;
881         else
882                 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
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 = CALL_ERROR_NONE;
949         else
950                 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
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 = CALL_ERROR_NONE;
980         else
981                 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
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 = CALL_ERROR_NONE;
1029         else
1030                 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
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 = CALL_ERROR_NONE;
1057         else
1058                 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
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 ( countCalls > countValidCalls )
1134                                 countValidCalls++;
1135
1136                         if (err != 0) {
1137                                 continue;
1138                         }
1139
1140                         co = tcore_call_object_find_by_id( o, call_list[i].info.id );
1141                         if ( !co ) {
1142                                 co = tcore_call_object_new( o, call_list[i].info.id );
1143                                 if ( !co ) {
1144                                         dbg("error : tcore_call_object_new [ id : %d ]", call_list[i].info.id);
1145                                         continue ;
1146                                 }
1147                         }
1148
1149                         tcore_call_object_set_type( co, _call_type( call_list[i].info.type ) );
1150                         tcore_call_object_set_direction( co, call_list[i].info.direction );
1151                         tcore_call_object_set_multiparty_state( co, _call_is_in_mpty(call_list[i].info.mpty) );
1152                         tcore_call_object_set_cli_info( co, CALL_CLI_MODE_DEFAULT, call_list[i].number );
1153
1154                         _call_branch_by_status( plugin, co, call_list[i].info.status );
1155
1156                         i++;
1157
1158                         if ( i == countCalls )
1159                                 break;
1160                 }
1161         }
1162
1163         ReleaseResponse();
1164 }
1165
1166 static int _callFromCLCCLine(char *line, struct CLCC_call_t*p_call)
1167 {
1168         //+CLCC: 1,0,2,0,0,\"+18005551212\",145
1169         //     index,isMT,state,mode,isMpty(,number,TOA)?
1170
1171     int err;
1172     int state;
1173         int mode;
1174         int isMT;
1175         char* num;
1176
1177         err = at_tok_start(&line);
1178         if (err < 0) goto error;
1179
1180         //id
1181         err = at_tok_nextint(&line, &(p_call->info.id));
1182         if (err < 0) goto error;
1183         dbg("id : [%d]\n", p_call->info.id );
1184         //MO/MTcall
1185         err = at_tok_nextint(&line, &isMT);
1186         if (err < 0) goto error;
1187
1188         if(isMT ==0)
1189                 p_call->info.direction = TCORE_CALL_DIRECTION_OUTGOING;
1190         else
1191                 p_call->info.direction = TCORE_CALL_DIRECTION_INCOMING;
1192
1193         dbg("direction : [ %d ]\n", p_call->info.direction);
1194
1195         //state
1196         err = at_tok_nextint(&line, &state);
1197         if (err < 0) goto error;
1198
1199         switch(state){
1200                 case 0: //active
1201                         p_call->info.status = TCORE_CALL_STATUS_ACTIVE;
1202                         break;
1203                 case 1:
1204                         p_call->info.status = TCORE_CALL_STATUS_HELD;
1205                         break;
1206                 case 2:
1207                         p_call->info.status = TCORE_CALL_STATUS_DIALING;
1208                         break;
1209                 case 3:
1210                         p_call->info.status = TCORE_CALL_STATUS_ALERT;
1211                         break;
1212                 case 4:
1213                         p_call->info.status = TCORE_CALL_STATUS_INCOMING;
1214                         break;
1215                 case 5:
1216                         p_call->info.status = TCORE_CALL_STATUS_WAITING;
1217                         break;
1218         }
1219         dbg("status     : [%d]\n", p_call->info.status );
1220
1221         //mode
1222         err = at_tok_nextint(&line, &mode);
1223         if (err < 0) goto error;
1224
1225         switch(mode)
1226         {
1227                 case 0:
1228                         p_call->info.type       = TCORE_CALL_TYPE_VOICE;
1229                         break;
1230
1231                 case 1:
1232                         p_call->info.type       = TCORE_CALL_TYPE_VIDEO;
1233                         break;
1234
1235                 default:        // only Voice/VT call is supported in CS. treat other unknown calls as error
1236                         dbg("invalid type : [%d]\n", mode );
1237                         goto error;
1238                         break;
1239         }
1240         dbg("type : [%d]\n", p_call->info.type );
1241
1242
1243         err = at_tok_nextint(&line, &(p_call->info.mpty));
1244     if (err < 0) goto error;
1245         dbg("mpty       : [%d]\n", p_call->info.mpty );
1246
1247         if (at_tok_hasmore(&line)) {
1248                 err = at_tok_nextstr(&line, &num);
1249
1250                 /* tolerate null here */
1251                 if (err < 0) return 0;
1252
1253                 memcpy(p_call->number, num, strlen(num));
1254                 dbg("number     : [ %s ]\n", p_call->number );
1255
1256                 p_call->info.num_len = strlen(num);
1257                 dbg("num_len : [0x%x]\n", p_call->info.num_len );
1258
1259                 err = at_tok_nextint(&line, &(p_call->info.num_type));
1260                 if (err < 0) goto error;
1261                 dbg("num_type : [0x%x]\n", p_call->info.num_type );
1262
1263         }
1264
1265     return 0;
1266
1267 error:
1268     err("invalid CLCC line\n");
1269     return -1;
1270 }
1271
1272 // NOTIFICATION
1273
1274 static gboolean on_notification_call_waiting( CoreObject *o, const void *data, void *user_data )
1275 {
1276         TcorePlugin* plugin = NULL;
1277         char* cmd = NULL, *num = NULL;
1278         CallObject *co, *dupco = 0;
1279         int id, status, err, type, mpty,direction;
1280         GSList* pList = NULL;
1281 #define LINE_DEFAULT 0
1282
1283         dbg("call waiting noti : %s", cmd);
1284         plugin = tcore_object_ref_plugin(o);
1285
1286         cmd = (char*)data;
1287
1288         at_tok_start(&cmd);
1289
1290         err = at_tok_nextint(&cmd,&id);
1291         err = at_tok_nextint(&cmd,&direction);
1292         err = at_tok_nextint(&cmd,&status);
1293         err = at_tok_nextint(&cmd,&type);
1294         err = at_tok_nextint(&cmd,&mpty);
1295
1296         if(at_tok_hasmore(&cmd)){
1297                 err = at_tok_nextstr(&cmd,&num);
1298                 dbg("id: %d, direction : %d, status : %d, type :%d, mpty : %d, num : %s", id,direction,status, type, mpty, num);
1299         }
1300         else    {
1301                 dbg("id: %d, direction : %d, status : %d, type :%d, mpty : %d, num : NULL", id,direction,status, type, mpty);
1302         }
1303 // check call with incoming status already exist
1304         pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_WAITING);
1305         if(pList != NULL){
1306                 dbg("waiting call already exist. skip");
1307                 return TRUE;
1308         }
1309
1310         pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
1311         if(pList != NULL){
1312                 dbg("incoming call already exist. skip");
1313                 return TRUE;
1314         }
1315
1316         dupco = tcore_call_object_find_by_id(o, id);
1317         if(dupco!= NULL){
1318                 dbg("co with same id already exist. skip");
1319                 return TRUE;
1320         }
1321
1322 // make new co, add to list
1323         co = tcore_call_object_new( o, id);
1324         if ( !co ) {
1325                 dbg("[ error ] co is NULL");
1326                 return TRUE;
1327         }
1328
1329         tcore_call_object_set_type(co, _call_type(type));
1330         tcore_call_object_set_multiparty_state(co,_call_is_in_mpty(mpty));
1331         tcore_call_object_set_direction(co, TCORE_CALL_DIRECTION_INCOMING);
1332         tcore_call_object_set_cli_info(co, TCORE_CALL_CLI_MODE_DEFAULT,  num);
1333         tcore_call_object_set_active_line(co, LINE_DEFAULT);
1334
1335         _call_list_get( o, co );
1336
1337         return TRUE;
1338 }
1339
1340 static gboolean on_notification_call_incoming( CoreObject *o, const void *data, void *user_data )
1341 {
1342         TcorePlugin* plugin = NULL;
1343         char* cmd = NULL, *num = NULL;
1344         CallObject *co, *dupco = 0;
1345         int id, status, err, type, mpty,direction;
1346         GSList* pList = NULL;
1347 #define LINE_DEFAULT 0
1348
1349         dbg("call incoming noti : %s", cmd);
1350         plugin = tcore_object_ref_plugin(o);
1351
1352         cmd = (char*)data;
1353
1354         at_tok_start(&cmd);
1355
1356         err = at_tok_nextint(&cmd,&id);
1357         err = at_tok_nextint(&cmd,&direction);
1358         err = at_tok_nextint(&cmd,&status);
1359         err = at_tok_nextint(&cmd,&type);
1360         err = at_tok_nextint(&cmd,&mpty);
1361
1362         if(at_tok_hasmore(&cmd))        {
1363                 err = at_tok_nextstr(&cmd,&num);
1364                 dbg("id: %d, direction : %d, status : %d, type :%d, mpty : %d, num : %s", id,direction,status, type, mpty, num);
1365         }
1366         else    {
1367                 dbg("id: %d, direction : %d, status : %d, type :%d, mpty : %d, num : NULL", id,direction,status, type, mpty);
1368         }
1369 // check call with incoming status already exist
1370         pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
1371         if(pList != NULL){
1372                 dbg("incoming call already exist. skip");
1373                 return TRUE;
1374         }
1375
1376         dupco = tcore_call_object_find_by_id(o, id);
1377         if(dupco!= NULL){
1378                 dbg("co with same id already exist. skip");
1379                 return TRUE;
1380         }
1381
1382 // make new co, add to list
1383         co = tcore_call_object_new( o, id);
1384         if ( !co ) {
1385                 dbg("[ error ] co is NULL");
1386                 return TRUE;
1387         }
1388
1389         tcore_call_object_set_type(co, _call_type(type));
1390         tcore_call_object_set_multiparty_state(co,_call_is_in_mpty(mpty));
1391         tcore_call_object_set_direction(co, TCORE_CALL_DIRECTION_INCOMING);
1392         tcore_call_object_set_cli_info(co, TCORE_CALL_CLI_MODE_DEFAULT,  num);
1393         tcore_call_object_set_active_line(co, LINE_DEFAULT);
1394
1395         _call_list_get( o, co );
1396
1397         return TRUE;
1398 }
1399
1400 static gboolean on_notification_call_status( CoreObject *o, const void *data, void *user_data)
1401 {
1402         char* cmd = NULL, *num = NULL;
1403         TcorePlugin*    p  = 0;
1404         CallObject*                     co = 0;
1405         int id, status, type, mpty,direction;
1406         int err;
1407
1408         enum tcore_call_status co_status;
1409
1410         p       = tcore_object_ref_plugin( o );
1411         cmd = (char*)data;
1412
1413         at_tok_start(&cmd);
1414
1415         err = at_tok_nextint(&cmd,&id);
1416         err = at_tok_nextint(&cmd,&direction);
1417         err = at_tok_nextint(&cmd,&status);
1418         err = at_tok_nextint(&cmd,&type);
1419         err = at_tok_nextint(&cmd,&mpty);
1420
1421         if (at_tok_hasmore(&cmd)) {
1422                 err = at_tok_nextstr(&cmd,&num);
1423                 dbg("id: %d, direction : %d, status : %d, type :%d, mpty : %d, num : %s", id,direction,status, type, mpty, num);
1424         }
1425         else {
1426                 dbg("id: %d, direction : %d, status : %d, type :%d, mpty : %d, num : NULL", id,direction,status, type, mpty);
1427         }
1428
1429         co_status = _call_status(status);
1430
1431         switch (co_status) {
1432                 case CALL_STATUS_ACTIVE:{
1433
1434                 dbg("call(%d) status : [ ACTIVE ]", id);
1435                 co      = tcore_call_object_find_by_id(o,id);
1436                 if ( !co ) {
1437                         dbg("co is NULL");
1438                         return TRUE;
1439                 }
1440                 _call_status_active( p, co );
1441
1442                 } break;
1443                 case CALL_STATUS_HELD:
1444                 break;
1445                 case CALL_STATUS_DIALING:
1446                 {
1447                 dbg("call(%d) status : [ dialing ]", id);
1448                 co      = tcore_call_object_find_by_id(o,id);
1449                 if ( !co ) {
1450                         co = tcore_call_object_new( o, id );
1451                         if ( !co ) {
1452                                 dbg("error : tcore_call_object_new [ id : %d ]", id);
1453                                 return TRUE;
1454                         }
1455                 }
1456
1457                 tcore_call_object_set_type( co, _call_type(type) );
1458                 tcore_call_object_set_direction( co, TCORE_CALL_DIRECTION_OUTGOING );
1459
1460                 _call_status_dialing( p, co );
1461                 }
1462                 break;
1463                 case CALL_STATUS_ALERT:
1464                 {
1465
1466                 dbg("call(%d) status : [ alert ]", id);
1467                 co      = tcore_call_object_find_by_id(o, id);
1468                 if ( !co ) {
1469                         dbg("co is NULL");
1470                         return TRUE;
1471                 }
1472
1473                 _call_list_get( o, co );
1474
1475                 } break;
1476                 case CALL_STATUS_INCOMING:
1477                 case CALL_STATUS_WAITING:
1478                 break;
1479                 case CALL_STATUS_IDLE: {
1480
1481                                 dbg("call(%d) status : [ release ]", id);
1482
1483                                 co      = tcore_call_object_find_by_id( o, id );
1484                                 if ( !co )
1485                                         dbg("co is NULL");
1486
1487                                 p       = tcore_object_ref_plugin( o );
1488                                 if ( !p )
1489                                         dbg("plugin is NULL");
1490
1491                                 _call_status_idle( p, co );
1492
1493                         } break;
1494
1495                 default:
1496                         break;
1497         }
1498
1499         return TRUE;
1500 }
1501
1502 static TReturn s_call_outgoing( CoreObject *o, UserRequest *ur )
1503 {
1504         TcorePlugin*                    p = NULL;
1505         CallObject*                                     co = 0;
1506         struct treq_call_dial*          data = 0;
1507         char*                                           raw_str= NULL;
1508         char*                                           cmd_str = NULL;
1509     const char *cclir;
1510         struct ATReqMetaInfo metainfo;
1511         int info_len =0;
1512         enum tcore_call_cli_mode clir = CALL_CLI_MODE_DEFAULT;
1513
1514         gboolean                                        ret = FALSE;
1515
1516         data    = (struct treq_call_dial*)tcore_user_request_ref_data( ur, 0 );
1517         p               = tcore_object_ref_plugin( o );
1518
1519         clir = _get_clir_status( data->number );
1520
1521 //Compose ATCmd string
1522         switch (clir)
1523         {
1524                 case TCORE_CALL_CLI_MODE_PRESENT:
1525                         cclir = "I";
1526                 break;  /*invocation*/
1527                 case TCORE_CALL_CLI_MODE_RESTRICT:
1528                         cclir = "i";
1529                 break;  /*suppression*/
1530                 case TCORE_CALL_CLI_MODE_DEFAULT:
1531                 default:
1532                         cclir = "";
1533                 break;   /*subscription default*/
1534         }
1535
1536         raw_str = g_strdup_printf("ATD%s%s;", data->number, cclir);
1537         cmd_str = g_strdup_printf("%s%s",raw_str,"\r");
1538
1539         memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
1540
1541 //set metainfo
1542         metainfo.type = NO_RESULT;
1543         metainfo.responsePrefix[0] ='\0';
1544         info_len = sizeof(struct ATReqMetaInfo);
1545
1546         tcore_user_request_set_metainfo(ur, info_len, &metainfo);
1547
1548         ret = _call_request_message ( o, ur, cmd_str, strlen(cmd_str), on_confirmation_call_outgoing, co);
1549
1550         free(raw_str);
1551         free(cmd_str);
1552
1553         if ( !ret ) {
1554                 tcore_call_object_free( o, co );
1555                 return TCORE_RETURN_FAILURE;
1556         }
1557
1558         return TCORE_RETURN_SUCCESS;
1559 }
1560
1561 static TReturn s_call_answer( CoreObject *o, UserRequest *ur )
1562 {
1563         CallObject*                                     co = 0;
1564         struct treq_call_answer*        data = 0;
1565         gboolean                                        ret = FALSE;
1566         char*                                           cmd_str = NULL;
1567         struct ATReqMetaInfo metainfo ;
1568         unsigned int info_len =0;
1569
1570         data = (struct treq_call_answer*)tcore_user_request_ref_data( ur, 0 );
1571
1572         co = tcore_call_object_find_by_id( o, data->id );
1573
1574         memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
1575
1576 //set metainfo
1577         metainfo.type = NO_RESULT;
1578         metainfo.responsePrefix[0] = '\0';
1579         info_len = sizeof(struct ATReqMetaInfo);
1580
1581         tcore_user_request_set_metainfo(ur, info_len, &metainfo);
1582
1583         if ( data->type == CALL_ANSWER_TYPE_ACCEPT ) {
1584
1585                 cmd_str = g_strdup_printf("%s%s","ATA","\r");
1586                 ret = _call_request_message ( o, ur, (void*)cmd_str, strlen(cmd_str), on_confirmation_call_accept, co);
1587                 free(cmd_str);
1588                 if ( !ret )
1589                         return TCORE_RETURN_FAILURE;
1590
1591         } else {
1592
1593                 switch ( data->type ) {
1594                         case CALL_ANSWER_TYPE_REJECT: {
1595                                 dbg("call answer reject");
1596                                 tcore_call_control_answer_reject( o, ur, on_confirmation_call_reject, co );
1597                         } break;
1598
1599                         case CALL_ANSWER_TYPE_REPLACE: {
1600                                 dbg("call answer replace");
1601                                 tcore_call_control_answer_replace( o, ur, on_confirmation_call_replace, co );
1602                         } break;
1603
1604                         case CALL_ANSWER_TYPE_HOLD_ACCEPT: {
1605                                 dbg("call answer hold and accept");
1606                                 tcore_call_control_answer_hold_and_accept( o, ur, on_confirmation_call_hold_and_accept, co );
1607                         } break;
1608
1609                         default :
1610                                 dbg("[ error ] wrong answer type [ %d ]", data->type);
1611                                 return TCORE_RETURN_FAILURE;
1612                 }
1613         }
1614
1615         return TCORE_RETURN_SUCCESS;
1616 }
1617
1618 static TReturn s_call_release( CoreObject *o, UserRequest *ur )
1619 {
1620         CallObject*                                     co = 0;
1621
1622         struct treq_call_end*           data = 0;
1623         gboolean                                        ret = FALSE;
1624         UserRequest* ur_dup = 0;
1625
1626         char*                                   chld0_cmd = NULL;
1627         char*                                   chld1_cmd = NULL;
1628         struct ATReqMetaInfo metainfo1 ;
1629         struct ATReqMetaInfo  metainfo2 ;
1630         unsigned int info_len1, info_len2 =0;
1631
1632         data = (struct treq_call_end*)tcore_user_request_ref_data( ur, 0 );
1633
1634         co = tcore_call_object_find_by_id( o, data->id );
1635
1636         if ( data->type == CALL_END_TYPE_ALL ) {
1637
1638         //releaseAll do not exist on legacy request. send CHLD=0, CHLD=1 in sequence
1639         chld0_cmd = g_strdup("AT+CHLD=0\r");
1640         chld1_cmd = g_strdup("AT+CHLD=1\r");
1641
1642         memset(&metainfo1, 0, sizeof(struct ATReqMetaInfo));
1643         memset(&metainfo2, 0, sizeof(struct ATReqMetaInfo));
1644
1645
1646 //set metainfo
1647                 metainfo1.type = NO_RESULT;
1648                 metainfo1.responsePrefix[0] = '\0';
1649                 info_len1 = sizeof(struct ATReqMetaInfo);
1650
1651 //set metainfo
1652                 metainfo2.type = NO_RESULT;
1653                 metainfo2.responsePrefix[0] = '\0';
1654                 info_len2 = sizeof(struct ATReqMetaInfo);
1655
1656                 ur_dup = tcore_user_request_new(NULL, NULL);
1657
1658                 tcore_user_request_set_metainfo(ur_dup, info_len1, &metainfo1);
1659                 tcore_user_request_set_metainfo(ur, info_len2, &metainfo2);
1660
1661                 ret = _call_request_message(o, ur_dup, chld0_cmd, strlen(chld0_cmd), on_confirmation_call_endall, NULL);
1662                 free(chld0_cmd);
1663                 if ( !ret )
1664                         return TCORE_RETURN_FAILURE;
1665
1666                 ret = _call_request_message(o, ur, chld1_cmd, strlen(chld1_cmd), on_confirmation_call_release_all, co);
1667                 free(chld1_cmd);
1668                 if ( !ret )
1669                         return TCORE_RETURN_FAILURE;
1670
1671         } else {
1672
1673                 switch ( data->type ) {
1674                         case CALL_END_TYPE_DEFAULT: {
1675                                 int id = 0;
1676                                 id = tcore_call_object_get_id( co );
1677
1678                                 dbg("call end call id [%d]", id);
1679                                 tcore_call_control_end_specific( o, ur, id, on_confirmation_call_release_specific, co );
1680                         } break;
1681
1682                         case CALL_END_TYPE_ACTIVE_ALL: {
1683
1684                                 dbg("call end all active");
1685                                 tcore_call_control_end_all_active( o, ur, on_confirmation_call_release_all_active, co );
1686                         } break;
1687
1688                         case TCORE_CALL_END_ALL_HELD: {
1689
1690                                 dbg("call end all held");
1691                                 tcore_call_control_end_all_held( o, ur, on_confirmation_call_release_all_held, co );
1692                         } break;
1693
1694                         default :
1695                                 dbg("[ error ] wrong end type [ %d ]", data->type);
1696                                 return TCORE_RETURN_FAILURE;
1697                 }
1698
1699         }
1700
1701         return TCORE_RETURN_SUCCESS;
1702 }
1703
1704 static TReturn s_call_hold( CoreObject *o, UserRequest *ur )
1705 {
1706         struct treq_call_hold *hold = 0;
1707         CallObject *co = 0;
1708
1709         hold = (struct treq_call_hold*)tcore_user_request_ref_data( ur, 0 );
1710
1711         dbg("call id : [ %d ]", hold->id);
1712
1713         co = tcore_call_object_find_by_id( o, hold->id );
1714
1715         tcore_call_control_hold( o, ur, on_confirmation_call_hold, co );
1716
1717         return TCORE_RETURN_SUCCESS;
1718 }
1719
1720 static TReturn s_call_active( CoreObject *o, UserRequest *ur )
1721 {
1722         struct treq_call_active *active = 0;
1723         CallObject *co = 0;
1724
1725         active = (struct treq_call_active*)tcore_user_request_ref_data( ur, 0 );
1726
1727         dbg("call id : [ %d ]", active->id);
1728
1729         co = tcore_call_object_find_by_id( o, active->id );
1730
1731         tcore_call_control_active( o, ur, on_confirmation_call_active, co );
1732
1733         return TCORE_RETURN_SUCCESS;
1734 }
1735
1736 static TReturn s_call_swap( CoreObject *o, UserRequest *ur )
1737 {
1738         struct treq_call_swap *swap = 0;
1739         CallObject *co = 0;
1740         swap = (struct treq_call_swap*)tcore_user_request_ref_data( ur, 0 );
1741
1742         dbg("call id : [ %d ]", swap->id);
1743
1744         co = tcore_call_object_find_by_id( o, swap->id );
1745
1746         tcore_call_control_swap( o, ur, on_confirmation_call_swap, co );
1747
1748         return TCORE_RETURN_SUCCESS;
1749 }
1750
1751 static TReturn s_call_join( CoreObject *o, UserRequest *ur )
1752 {
1753         struct treq_call_join *join = 0;
1754         CallObject *co = 0;
1755
1756         join = (struct treq_call_join*)tcore_user_request_ref_data( ur, 0 );
1757
1758         dbg("call id : [ %d ]", join->id);
1759
1760         co = tcore_call_object_find_by_id( o, join->id );
1761
1762         tcore_call_control_join( o, ur, on_confirmation_call_join, co );
1763
1764         return TCORE_RETURN_SUCCESS;
1765 }
1766
1767 static TReturn s_call_split( CoreObject *o, UserRequest *ur )
1768 {
1769         struct treq_call_split *split = 0;
1770         CallObject *co = 0;
1771
1772         split = (struct treq_call_split*)tcore_user_request_ref_data( ur, 0 );
1773
1774         co = tcore_call_object_find_by_id ( o, split->id );
1775
1776         tcore_call_control_split( o, ur, split->id, on_confirmation_call_split, co );
1777
1778         return TCORE_RETURN_SUCCESS;
1779 }
1780
1781 static TReturn s_call_deflect( CoreObject *o, UserRequest *ur )
1782 {
1783         struct treq_call_deflect *deflect = 0;
1784         CallObject *co = 0;
1785
1786         deflect = (struct treq_call_deflect*)tcore_user_request_ref_data( ur, 0 );
1787
1788         co = tcore_call_object_find_by_number( o, deflect->number );
1789
1790         tcore_call_control_deflect( o, ur, deflect->number, on_confirmation_call_deflect, co );
1791
1792         return TCORE_RETURN_SUCCESS;
1793 }
1794
1795 static TReturn s_call_transfer( CoreObject *o, UserRequest *ur )
1796 {
1797         struct treq_call_transfer *transfer = 0;
1798         CallObject *co = 0;
1799
1800         transfer = (struct treq_call_transfer*)tcore_user_request_ref_data( ur, 0 );
1801
1802         dbg("call id : [ %d ]", transfer->id);
1803
1804         co = tcore_call_object_find_by_id( o, transfer->id );
1805
1806         tcore_call_control_transfer( o, ur, on_confirmation_call_transfer, co );
1807
1808         return TCORE_RETURN_SUCCESS;
1809 }
1810
1811 static TReturn s_call_send_dtmf( CoreObject *o, UserRequest *ur )
1812 {
1813         return TCORE_RETURN_SUCCESS;
1814 }
1815
1816 static TReturn s_call_set_sound_path( CoreObject *o, UserRequest *ur )
1817 {
1818
1819         return TCORE_RETURN_SUCCESS;
1820 }
1821
1822 static TReturn s_call_set_sound_volume_level( CoreObject *o, UserRequest *ur )
1823 {
1824
1825         return TCORE_RETURN_SUCCESS;
1826 }
1827
1828 static TReturn s_call_get_sound_volume_level( CoreObject *o, UserRequest *ur )
1829 {
1830
1831         return TCORE_RETURN_SUCCESS;
1832 }
1833
1834 static TReturn s_call_mute( CoreObject *o, UserRequest *ur )
1835 {
1836
1837         return TCORE_RETURN_SUCCESS;
1838 }
1839
1840 static TReturn s_call_unmute( CoreObject *o, UserRequest *ur )
1841 {
1842
1843         return TCORE_RETURN_SUCCESS;
1844 }
1845
1846 static TReturn s_call_get_mute_status( CoreObject *o, UserRequest *ur )
1847 {
1848
1849         return TCORE_RETURN_SUCCESS;
1850 }
1851
1852 static struct tcore_call_operations call_ops = {
1853         .dial                                   = s_call_outgoing,
1854         .answer                                 = s_call_answer,
1855         .end                                    = s_call_release,
1856         .hold                                   = s_call_hold,
1857         .active                                 = s_call_active,
1858         .swap                                   = s_call_swap,
1859         .join                                   = s_call_join,
1860         .split                                  = s_call_split,
1861         .deflect                                = s_call_deflect,
1862         .transfer                               = s_call_transfer,
1863         .send_dtmf                              = s_call_send_dtmf,
1864         .set_sound_path                 = s_call_set_sound_path,
1865         .set_sound_volume_level = s_call_set_sound_volume_level,
1866         .get_sound_volume_level = s_call_get_sound_volume_level,
1867         .mute                                   = s_call_mute,
1868         .unmute                                 = s_call_unmute,
1869         .get_mute_status                = s_call_get_mute_status,
1870 };
1871
1872
1873 static void s_call_info_mo_waiting( CoreObject *o )
1874 {
1875         CallObject *co = 0;
1876         int id = 0;
1877
1878         TcorePlugin *p = 0;
1879         p = tcore_object_ref_plugin(o);
1880
1881         co = tcore_call_object_current_on_mo_processing( o );
1882         if ( !co ) {
1883                 dbg("[ error ] can't find call object!");
1884                 return ;
1885         }
1886
1887         id = tcore_call_object_get_id( co );
1888
1889         tcore_server_send_notification( tcore_plugin_ref_server(p),
1890                                                                 tcore_plugin_ref_core_object(p, "call"),
1891                                                                 TNOTI_CALL_INFO_WAITING,
1892                                                                 sizeof(unsigned int),
1893                                                                 (void*)&id      );
1894 }
1895
1896 static void s_call_info_mo_forwarded( CoreObject *o )
1897 {
1898         CallObject *co = 0;
1899         int id = 0;
1900
1901         TcorePlugin *p = 0;
1902         p = tcore_object_ref_plugin(o);
1903
1904         co = tcore_call_object_current_on_mo_processing( o );
1905         if ( !co ) {
1906                 dbg("[ error ] can't find call object!");
1907                 return ;
1908         }
1909         id = tcore_call_object_get_id( co );
1910
1911         tcore_server_send_notification( tcore_plugin_ref_server(p),
1912                                                                 tcore_plugin_ref_core_object(p, "call"),
1913                                                                 TNOTI_CALL_INFO_FORWARDED,
1914                                                                 sizeof(unsigned int),
1915                                                                 (void*)&id      );
1916 }
1917
1918 static void s_call_info_mo_barred_incoming( CoreObject *o )
1919 {
1920         CallObject *co = 0;
1921         int id = 0;
1922
1923         TcorePlugin *p = 0;
1924         p = tcore_object_ref_plugin(o);
1925
1926         co = tcore_call_object_current_on_mo_processing( o );
1927         if ( !co ) {
1928                 dbg("[ error ] can't find call object!");
1929                 return ;
1930         }
1931         id = tcore_call_object_get_id( co );
1932
1933         tcore_server_send_notification( tcore_plugin_ref_server(p),
1934                                                                 tcore_plugin_ref_core_object(p, "call"),
1935                                                                 TNOTI_CALL_INFO_BARRED_INCOMING,
1936                                                                 sizeof(unsigned int),
1937                                                                 (void*)&id      );
1938 }
1939
1940 static void s_call_info_mo_barred_outgoing( CoreObject *o )
1941 {
1942         CallObject *co = 0;
1943         int id = 0;
1944
1945         TcorePlugin *p = 0;
1946         p = tcore_object_ref_plugin(o);
1947
1948         co = tcore_call_object_current_on_mo_processing( o );
1949         if ( !co ) {
1950                 dbg("[ error ] can't find call object!");
1951                 return ;
1952         }
1953         id = tcore_call_object_get_id( co );
1954
1955         tcore_server_send_notification( tcore_plugin_ref_server(p),
1956                                                                 tcore_plugin_ref_core_object(p, "call"),
1957                                                                 TNOTI_CALL_INFO_BARRED_OUTGOING,
1958                                                                 sizeof(unsigned int),
1959                                                                 (void*)&id      );
1960 }
1961
1962 static void s_call_info_mo_deflected( CoreObject *o )
1963 {
1964         CallObject *co = 0;
1965         int id = 0;
1966
1967         TcorePlugin *p = 0;
1968         p = tcore_object_ref_plugin(o);
1969
1970         co = tcore_call_object_current_on_mo_processing( o );
1971         if ( !co ) {
1972                 dbg("[ error ] can't find call object!");
1973                 return ;
1974         }
1975         id = tcore_call_object_get_id( co );
1976
1977         tcore_server_send_notification( tcore_plugin_ref_server(p),
1978                                                                 tcore_plugin_ref_core_object(p, "call"),
1979                                                                 TNOTI_CALL_INFO_DEFLECTED,
1980                                                                 sizeof(unsigned int),
1981                                                                 (void*)&id      );
1982 }
1983
1984 static void s_call_info_mo_clir_suppression_reject( CoreObject *o )
1985 {
1986         CallObject *co = 0;
1987         int id = 0;
1988
1989         TcorePlugin *p = 0;
1990         p = tcore_object_ref_plugin(o);
1991
1992         co = tcore_call_object_current_on_mo_processing( o );
1993         if ( !co ) {
1994                 dbg("[ error ] can't find call object!");
1995                 return ;
1996         }
1997         id = tcore_call_object_get_id( co );
1998
1999         tcore_server_send_notification( tcore_plugin_ref_server(p),
2000                                                                 tcore_plugin_ref_core_object(p, "call"),
2001                                                                 TNOTI_CALL_INFO_CLIR_SUPPRESSION_REJECT,
2002                                                                 sizeof(unsigned int),
2003                                                                 (void*)&id      );
2004 }
2005
2006 static void s_call_info_mo_cfu( CoreObject *o )
2007 {
2008         CallObject *co = 0;
2009         int id = 0;
2010
2011         TcorePlugin *p = 0;
2012         p = tcore_object_ref_plugin(o);
2013
2014         co = tcore_call_object_current_on_mo_processing( o );
2015         if ( !co ) {
2016                 dbg("[ error ] can't find call object!");
2017                 return ;
2018         }
2019         id = tcore_call_object_get_id( co );
2020
2021         tcore_server_send_notification( tcore_plugin_ref_server(p),
2022                                                                 tcore_plugin_ref_core_object(p, "call"),
2023                                                                 TNOTI_CALL_INFO_FORWARD_UNCONDITIONAL,
2024                                                                 sizeof(unsigned int),
2025                                                                 (void*)&id      );
2026 }
2027
2028 static void s_call_info_mo_cfc( CoreObject *o )
2029 {
2030         CallObject *co = 0;
2031         int id = 0;
2032
2033         TcorePlugin *p = 0;
2034         p = tcore_object_ref_plugin(o);
2035
2036         co = tcore_call_object_current_on_mo_processing( o );
2037         if ( !co ) {
2038                 dbg("[ error ] can't find call object!");
2039                 return ;
2040         }
2041         id = tcore_call_object_get_id( co );
2042
2043         tcore_server_send_notification( tcore_plugin_ref_server(p),
2044                                                                 tcore_plugin_ref_core_object(p, "call"),
2045                                                                 TNOTI_CALL_INFO_FORWARD_CONDITIONAL,
2046                                                                 sizeof(unsigned int),
2047                                                                 (void*)&id      );
2048 }
2049
2050 static void s_call_info_mt_cli( CoreObject *o, enum tcore_call_cli_mode mode, char* number )
2051 {
2052         CallObject *co = 0;
2053
2054         co = tcore_call_object_current_on_mt_processing( o );
2055         if ( !co ) {
2056                 dbg("[ error ] can't find call object!");
2057                 return ;
2058         }
2059         tcore_call_object_set_cli_info( co, mode, number );
2060 }
2061
2062 static void s_call_info_mt_cna( CoreObject *o, enum tcore_call_cna_mode mode, char* name, int dcs )
2063 {
2064         CallObject *co = 0;
2065
2066         co = tcore_call_object_current_on_mt_processing( o );
2067         if ( !co ) {
2068                 dbg("[ error ] can't find call object!");
2069                 return ;
2070         }
2071         tcore_call_object_set_cna_info( co, mode, name, dcs );
2072 }
2073
2074 static void s_call_info_mt_forwarded_call( CoreObject *o, char* number )
2075 {
2076         CallObject *co = 0;
2077         int id = 0;
2078
2079         TcorePlugin *p = 0;
2080         p = tcore_object_ref_plugin(o);
2081
2082         co = tcore_call_object_current_on_mt_processing( o );
2083         if ( !co ) {
2084                 dbg("[ error ] can't find call object!");
2085                 return ;
2086         }
2087
2088         id = tcore_call_object_get_id( co );
2089
2090         tcore_server_send_notification( tcore_plugin_ref_server(p),
2091                                                                 tcore_plugin_ref_core_object(p, "call"),
2092                                                                 TNOTI_CALL_INFO_FORWARDED_CALL,
2093                                                                 sizeof(unsigned int),
2094                                                                 (void*)&id      );
2095 }
2096
2097 static void s_call_info_mt_deflected_call( CoreObject *o, char* number )
2098 {
2099         CallObject *co = 0;
2100         int id = 0;
2101
2102         TcorePlugin *p = 0;
2103         p = tcore_object_ref_plugin(o);
2104
2105         co = tcore_call_object_current_on_mt_processing( o );
2106         if ( !co ) {
2107                 dbg("[ error ] can't find call object!");
2108                 return ;
2109         }
2110
2111         id = tcore_call_object_get_id( co );
2112
2113         tcore_server_send_notification( tcore_plugin_ref_server(p),
2114                                                                 tcore_plugin_ref_core_object(p, "call"),
2115                                                                 TNOTI_CALL_INFO_DEFLECTED_CALL,
2116                                                                 sizeof(unsigned int),
2117                                                                 (void*)&id      );
2118 }
2119
2120 static void s_call_info_mt_transfered( CoreObject *o, char* number )
2121 {
2122         CallObject *co = 0;
2123         int id = 0;
2124
2125         TcorePlugin *p = 0;
2126         p = tcore_object_ref_plugin(o);
2127
2128         co = tcore_call_object_current_on_mt_processing( o );
2129         if ( !co ) {
2130                 dbg("[ error ] can't find call object!");
2131                 return ;
2132         }
2133
2134         id = tcore_call_object_get_id( co );
2135
2136         tcore_server_send_notification( tcore_plugin_ref_server(p),
2137                                                                 tcore_plugin_ref_core_object(p, "call"),
2138                                                                 TNOTI_CALL_INFO_TRANSFERED_CALL,
2139                                                                 sizeof(unsigned int),
2140                                                                 (void*)&id      );
2141 }
2142
2143 static void s_call_info_held( CoreObject *o, char* number )
2144 {
2145         CallObject *co = 0;
2146         int id = 0;
2147
2148         TcorePlugin *p = 0;
2149         p = tcore_object_ref_plugin(o);
2150
2151         co = tcore_call_object_find_by_number( o, number );
2152         if ( !co ) {
2153                 dbg("[ error ] can't find call object!");
2154                 return ;
2155         }
2156
2157         id = tcore_call_object_get_id( co );
2158
2159         tcore_server_send_notification( tcore_plugin_ref_server(p),
2160                                                                 tcore_plugin_ref_core_object(p, "call"),
2161                                                                 TNOTI_CALL_INFO_HELD,
2162                                                                 sizeof(unsigned int),
2163                                                                 (void*)&id      );
2164 }
2165
2166 static void s_call_info_active( CoreObject *o, char* number )
2167 {
2168         CallObject *co = 0;
2169         int id = 0;
2170
2171         TcorePlugin *p = 0;
2172         p = tcore_object_ref_plugin(o);
2173
2174         co = tcore_call_object_find_by_number( o, number );
2175         if ( !co ) {
2176                 dbg("[ error ] can't find call object!");
2177                 return ;
2178         }
2179
2180         id = tcore_call_object_get_id( co );
2181
2182         tcore_server_send_notification( tcore_plugin_ref_server(p),
2183                                                                 tcore_plugin_ref_core_object(p, "call"),
2184                                                                 TNOTI_CALL_INFO_ACTIVE,
2185                                                                 sizeof(unsigned int),
2186                                                                 (void*)&id      );
2187 }
2188
2189 static void s_call_info_joined( CoreObject *o, char* number )
2190 {
2191         CallObject *co = 0;
2192         int id = 0;
2193
2194         TcorePlugin *p = 0;
2195         p = tcore_object_ref_plugin(o);
2196
2197         co = tcore_call_object_find_by_number( o, number );
2198         if ( !co ) {
2199                 dbg("[ error ] can't find call object!");
2200                 return ;
2201         }
2202
2203         id = tcore_call_object_get_id( co );
2204
2205         tcore_server_send_notification( tcore_plugin_ref_server(p),
2206                                                                 tcore_plugin_ref_core_object(p, "call"),
2207                                                                 TNOTI_CALL_INFO_JOINED,
2208                                                                 sizeof(unsigned int),
2209                                                                 (void*)&id      );
2210 }
2211
2212 static void s_call_info_released_on_hold( CoreObject *o, char* number )
2213 {
2214         CallObject *co = 0;
2215         int id = 0;
2216
2217         TcorePlugin *p = 0;
2218         p = tcore_object_ref_plugin(o);
2219
2220         co = tcore_call_object_find_by_number( o, number );
2221         if ( !co ) {
2222                 dbg("[ error ] can't find call object!");
2223                 return ;
2224         }
2225
2226         id = tcore_call_object_get_id( co );
2227
2228         tcore_server_send_notification( tcore_plugin_ref_server(p),
2229                                                                 tcore_plugin_ref_core_object(p, "call"),
2230                                                                 TNOTI_CALL_INFO_RELEASED_ON_HOLD,
2231                                                                 sizeof(unsigned int),
2232                                                                 (void*)&id      );
2233 }
2234
2235 static void s_call_info_transfer_alert( CoreObject *o, char* number )
2236 {
2237         CallObject *co = 0;
2238         int id = 0;
2239
2240         TcorePlugin *p = 0;
2241         p = tcore_object_ref_plugin(o);
2242
2243         co = tcore_call_object_find_by_number( o, number );
2244         if ( !co ) {
2245                 dbg("[ error ] can't find call object!");
2246                 return ;
2247         }
2248
2249         id = tcore_call_object_get_id( co );
2250
2251         tcore_server_send_notification( tcore_plugin_ref_server(p),
2252                                                                 tcore_plugin_ref_core_object(p, "call"),
2253                                                                 TNOTI_CALL_INFO_TRANSFER_ALERT,
2254                                                                 sizeof(unsigned int),
2255                                                                 (void*)&id      );
2256 }
2257
2258 static void s_call_info_transfered( CoreObject *o, char* number )
2259 {
2260         CallObject *co = 0;
2261         int id = 0;
2262
2263         TcorePlugin *p = 0;
2264         p = tcore_object_ref_plugin(o);
2265
2266         co = tcore_call_object_find_by_number( o, number );
2267         if ( !co ) {
2268                 dbg("[ error ] can't find call object!");
2269                 return ;
2270         }
2271
2272         id = tcore_call_object_get_id( co );
2273
2274         tcore_server_send_notification( tcore_plugin_ref_server(p),
2275                                                                 tcore_plugin_ref_core_object(p, "call"),
2276                                                                 TNOTI_CALL_INFO_TRANSFERED,
2277                                                                 sizeof(unsigned int),
2278                                                                 (void*)&id      );
2279 }
2280
2281 static void s_call_info_cf_check_message( CoreObject *o, char* number )
2282 {
2283         CallObject *co = 0;
2284         int id = 0;
2285
2286         TcorePlugin *p = 0;
2287         p = tcore_object_ref_plugin(o);
2288
2289         co = tcore_call_object_find_by_number( o, number );
2290         if ( !co ) {
2291                 dbg("[ error ] can't find call object!");
2292                 return ;
2293         }
2294
2295         id = tcore_call_object_get_id( co );
2296
2297         tcore_server_send_notification( tcore_plugin_ref_server(p),
2298                                                                 tcore_plugin_ref_core_object(p, "call"),
2299                                                                 TNOTI_CALL_INFO_CF_CHECK_MESSAGE,
2300                                                                 sizeof(unsigned int),
2301                                                                 (void*)&id      );
2302 }
2303
2304
2305 static struct tcore_call_information_operations call_information_ops = {
2306         .mo_call_col                            = 0,
2307         .mo_call_waiting                        = s_call_info_mo_waiting,
2308         .mo_call_cug                            = 0,
2309         .mo_call_forwarded                      = s_call_info_mo_forwarded,
2310         .mo_call_barred_incoming        = s_call_info_mo_barred_incoming,
2311         .mo_call_barred_outgoing        = s_call_info_mo_barred_outgoing,
2312         .mo_call_deflected                      = s_call_info_mo_deflected,
2313         .mo_call_clir_suppression_reject = s_call_info_mo_clir_suppression_reject,
2314         .mo_call_cfu                            = s_call_info_mo_cfu,
2315         .mo_call_cfc                            = s_call_info_mo_cfc,
2316         .mt_call_cli                            = s_call_info_mt_cli,
2317         .mt_call_cna                            = s_call_info_mt_cna,
2318         .mt_call_forwarded_call         = s_call_info_mt_forwarded_call,
2319         .mt_call_cug_call                       = 0,
2320         .mt_call_deflected_call         = s_call_info_mt_deflected_call,
2321         .mt_call_transfered                     = s_call_info_mt_transfered,
2322         .call_held                                      = s_call_info_held,
2323         .call_active                            = s_call_info_active,
2324         .call_joined                            = s_call_info_joined,
2325         .call_released_on_hold          = s_call_info_released_on_hold,
2326         .call_transfer_alert            = s_call_info_transfer_alert,
2327         .call_transfered                        = s_call_info_transfered,
2328         .call_cf_check_message          = s_call_info_cf_check_message,
2329 };
2330
2331 gboolean s_call_init(TcorePlugin *p, TcoreHal *h)
2332 {
2333         CoreObject *o = NULL;
2334 //      TcoreHal *h = NULL;
2335         struct property_call_info *data = NULL;
2336
2337         o = tcore_call_new(p, "call", &call_ops, h);
2338         if (!o)
2339                 return FALSE;
2340
2341         tcore_call_information_set_operations( o, &call_information_ops );
2342
2343         tcore_object_add_callback( o, EVENT_CALL_STATUS, on_notification_call_status, NULL );
2344         tcore_object_add_callback( o, EVENT_CALL_INCOMING, on_notification_call_incoming, NULL );
2345         tcore_object_add_callback( o, EVENT_CALL_WAITING, on_notification_call_waiting, NULL );
2346
2347         data = calloc( sizeof(struct property_call_info *), 1);
2348         tcore_plugin_link_property(p, "CALL", data);
2349
2350         return TRUE;
2351 }
2352
2353 void s_call_exit( TcorePlugin *p )
2354 {
2355         CoreObject *o;
2356 //      TcoreHal *h;
2357         struct property_network_info *data;
2358
2359         o = tcore_plugin_ref_core_object(p, "call");
2360
2361         data = tcore_plugin_ref_property(p, "CALL");
2362         if (data)
2363                 free(data);
2364
2365         tcore_call_free(o);
2366 }