4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hayoon Ko <hayoon.ko@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
29 #include <core_object.h>
34 #include <user_request.h>
39 #include "atchannel.h"
43 extern struct ATResponse *sp_response;
44 extern char *s_responsePrefix;
45 extern enum ATCommandType s_type;
48 struct CLCC_call_info_t {
50 enum tcore_call_direction direction;
51 enum tcore_call_status status;
52 enum tcore_call_type type;
61 static gboolean _call_request_message( CoreObject *o, UserRequest* ur, char* cmd_string,
62 unsigned int cmd_length, void* on_resp, void* user_data);
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 );
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);
76 static TReturn _call_list_get( CoreObject *o, CallObject *co );
78 static void on_confirmation_call_message_send( TcorePending *p, gboolean result, void *user_data ); // from Kernel
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);
86 static int _callFromCLCCLine(char *line, struct CLCC_call_t *p_call);
89 static enum tcore_call_cli_mode _get_clir_status( char *num )
91 enum tcore_call_cli_mode clir = CALL_CLI_MODE_DEFAULT;
93 if( !strncmp( num, "*31#", 4 ) )
94 return TCORE_CALL_CLI_MODE_RESTRICT;
96 if( !strncmp( num, "#31#", 4 ) )
97 return TCORE_CALL_CLI_MODE_PRESENT;
103 static enum tcore_call_status _call_status(unsigned int status)
108 return TCORE_CALL_STATUS_ACTIVE;
110 return TCORE_CALL_STATUS_HELD;
112 return TCORE_CALL_STATUS_DIALING;
114 return TCORE_CALL_STATUS_ALERT;
116 return TCORE_CALL_STATUS_INCOMING;
118 return TCORE_CALL_STATUS_WAITING;
120 return TCORE_CALL_STATUS_DIALING; //connecting not exist. set to dialing
122 return TCORE_CALL_STATUS_IDLE;
125 return TCORE_CALL_STATUS_IDLE;
129 return TCORE_CALL_STATUS_IDLE;
132 static gboolean _call_is_in_mpty(int mpty)
148 static enum tcore_call_type _call_type(int type )
152 return TCORE_CALL_TYPE_VOICE;
154 return TCORE_CALL_TYPE_VIDEO;
159 return TCORE_CALL_TYPE_VOICE;
162 static gboolean _call_request_message( CoreObject *o,
165 unsigned int cmd_len,
169 TcorePending *pending = NULL;
172 unsigned int info_len = 0;
173 info_len = sizeof(struct ATReqMetaInfo);
175 dbg("_call_request_message - cmd : %s, cmdlen :%d (including '\r')",cmd_string, cmd_len);
178 pending = tcore_pending_new(o, ID_RESERVED_AT);
179 tcore_pending_set_request_data(pending, cmd_len, cmd_string);
180 tcore_pending_set_timeout(pending, 0);
181 tcore_pending_set_priority(pending, TCORE_PENDING_PRIORITY_DEFAULT);
184 tcore_pending_set_response_callback(pending, on_resp, user_data);
186 tcore_pending_set_send_callback(pending, on_confirmation_call_message_send, NULL);
189 dbg("[ check ] ur is NULL, is this internal request??");
191 tcore_pending_link_user_request(pending, ur);
194 h = tcore_object_get_hal(o);
196 tcore_hal_send_request(h, pending);
201 static void _call_status_idle( TcorePlugin *p, CallObject *co )
203 struct tnoti_call_status_idle data;
206 o = tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL);
207 dbg("call id [%d], call status [%d]", tcore_call_object_get_id(co), tcore_call_object_get_status(co));
209 if ( tcore_call_object_get_status( co ) != TCORE_CALL_STATUS_IDLE ) {
210 data.type = tcore_call_object_get_type( co );
211 dbg("data.type : [%d]", data.type );
213 data.id = tcore_call_object_get_id( co );
214 dbg("data.id : [%d]", data.id );
216 tcore_call_object_set_status( co, TCORE_CALL_STATUS_IDLE );
218 tcore_server_send_notification( tcore_plugin_ref_server(p),
220 TNOTI_CALL_STATUS_IDLE,
221 sizeof(struct tnoti_call_status_idle),
224 tcore_call_object_free( o, co );
226 dbg("call object was freed");
227 tcore_call_object_free(o, co);
231 static void _call_status_dialing( TcorePlugin *p, CallObject *co )
235 struct tnoti_call_status_dialing data;
237 o = tcore_plugin_ref_core_object( p, CORE_OBJECT_TYPE_CALL);
239 if ( tcore_call_object_get_status( co ) != TCORE_CALL_STATUS_DIALING ) {
241 data.type = tcore_call_object_get_type( co );
242 dbg("data.type : [%d]", data.type );
244 data.id = tcore_call_object_get_id( co );
245 dbg("data.id : [%d]", data.id );
247 tcore_call_object_set_status( co, TCORE_CALL_STATUS_DIALING );
249 tcore_server_send_notification( tcore_plugin_ref_server(p),
250 tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
251 TNOTI_CALL_STATUS_DIALING,
252 sizeof(struct tnoti_call_status_dialing),
258 _call_list_get( o, co );
262 static void _call_status_alert( TcorePlugin *p, CallObject *co )
265 struct tnoti_call_status_alert data;
267 o = tcore_plugin_ref_core_object( p, CORE_OBJECT_TYPE_CALL);
269 if ( tcore_call_object_get_status( co ) != TCORE_CALL_STATUS_ALERT ) {
271 data.type = tcore_call_object_get_type( co );
272 dbg("data.type : [%d]", data.type );
274 data.id = tcore_call_object_get_id( co );
275 dbg("data.id : [%d]", data.id );
277 tcore_call_object_set_status( co, TCORE_CALL_STATUS_ALERT );
279 tcore_server_send_notification( tcore_plugin_ref_server(p),
280 tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
281 TNOTI_CALL_STATUS_ALERT,
282 sizeof(struct tnoti_call_status_alert),
288 _call_list_get( o, co );
292 static void _call_status_active( TcorePlugin *p, CallObject *co )
294 struct tnoti_call_status_active data;
296 if ( tcore_call_object_get_status( co ) != TCORE_CALL_STATUS_ACTIVE ) {
298 data.type = tcore_call_object_get_type( co );
299 dbg("data.type : [%d]", data.type );
301 data.id = tcore_call_object_get_id( co );
302 dbg("data.id : [%d]", data.id );
304 tcore_call_object_set_status( co, TCORE_CALL_STATUS_ACTIVE );
306 tcore_server_send_notification( tcore_plugin_ref_server(p),
307 tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
308 TNOTI_CALL_STATUS_ACTIVE,
309 sizeof(struct tnoti_call_status_active),
315 static void _call_status_held( TcorePlugin *p, CallObject *co )
317 struct tnoti_call_status_held data;
319 if ( tcore_call_object_get_status( co ) != TCORE_CALL_STATUS_HELD ) {
321 data.type = tcore_call_object_get_type( co );
322 dbg("data.type : [%d]", data.type );
324 data.id = tcore_call_object_get_id( co );
325 dbg("data.id : [%d]", data.id );
327 tcore_call_object_set_status( co, TCORE_CALL_STATUS_HELD );
329 tcore_server_send_notification( tcore_plugin_ref_server(p),
330 tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
331 TNOTI_CALL_STATUS_HELD,
332 sizeof(struct tnoti_call_status_held),
338 static void _call_status_incoming( TcorePlugin *p, CallObject *co )
340 struct tnoti_call_status_incoming data;
342 o = tcore_plugin_ref_core_object( p, CORE_OBJECT_TYPE_CALL);
344 if ( tcore_call_object_get_status( co ) != TCORE_CALL_STATUS_INCOMING ) {
346 tcore_call_object_set_status( co, TCORE_CALL_STATUS_INCOMING );
348 data.type = tcore_call_object_get_type( co );
349 dbg("data.type : [%d]", data.type );
351 data.id = tcore_call_object_get_id( co );
352 dbg("data.id : [%d]", data.id );
354 data.cli.mode = tcore_call_object_get_cli_mode( co );
355 dbg("data.cli.mode : [%d]", data.cli.mode );
357 tcore_call_object_get_number( co, data.cli.number );
358 dbg("data.cli.number : [%s]", data.cli.number );
360 data.cna.mode = tcore_call_object_get_cna_mode( co );
361 dbg("data.cna.mode : [%d]", data.cna.mode );
363 tcore_call_object_get_name( co, data.cna.name );
364 dbg("data.cna.name : [%s]", data.cna.name );
366 data.forward = FALSE; // this is tmp code
367 data.active_line = tcore_call_object_get_active_line( co );
368 dbg("data.active_line : [%d]", data.active_line );
370 tcore_server_send_notification( tcore_plugin_ref_server(p),
371 tcore_plugin_ref_core_object(p, CORE_OBJECT_TYPE_CALL),
372 TNOTI_CALL_STATUS_INCOMING,
373 sizeof(struct tnoti_call_status_incoming),
379 static void _call_status_waiting( TcorePlugin *p, CallObject *co )
381 _call_status_incoming( p, co );
384 static void _call_branch_by_status( TcorePlugin *p, CallObject *co, unsigned int status )
387 case TCORE_CALL_STATUS_IDLE:
388 _call_status_idle( p, co );
391 case TCORE_CALL_STATUS_ACTIVE:
392 _call_status_active( p, co );
395 case TCORE_CALL_STATUS_HELD:
396 _call_status_held( p, co );
399 case TCORE_CALL_STATUS_DIALING:
400 _call_status_dialing( p, co );
403 case TCORE_CALL_STATUS_ALERT:
404 _call_status_alert( p, co );
407 case TCORE_CALL_STATUS_INCOMING:
408 _call_status_incoming( p, co );
411 case TCORE_CALL_STATUS_WAITING:
412 _call_status_waiting( p, co );
418 static TReturn _call_list_get( CoreObject *o, CallObject *co )
420 gboolean ret = FALSE;
421 UserRequest* ur = NULL;
423 char* cmd_str = NULL;
424 struct ATReqMetaInfo metainfo;
428 return TCORE_RETURN_FAILURE;
430 ur = tcore_user_request_new(NULL, NULL);
432 memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
434 metainfo.type = MULTILINE;
435 memcpy(metainfo.responsePrefix,"+CLCC:",strlen("+CLCC:"));
436 info_len = sizeof(struct ATReqMetaInfo);
437 tcore_user_request_set_metainfo(ur, info_len, &metainfo);
439 cmd_str = g_strdup("AT+CLCC\r");
441 ret = _call_request_message ( o, ur, cmd_str, strlen(cmd_str), on_response_call_list_get, NULL);
444 return TCORE_RETURN_FAILURE;
446 return TCORE_RETURN_SUCCESS;
454 static void on_confirmation_call_message_send( TcorePending *p, gboolean result, void *user_data )
456 UserRequest* ur = NULL;
457 struct ATReqMetaInfo* metainfo = NULL;
458 unsigned int info_len =0;
459 dbg("on_confirmation_call_message_send - msg out from queue. alloc ATRsp buffer & write rspPrefix if needed\n");
461 ReleaseResponse(); //release leftover
462 //alloc new sp_response
464 sp_response = at_response_new();
466 ur = tcore_pending_ref_user_request(p);
467 metainfo = (struct ATReqMetaInfo*)tcore_user_request_ref_metainfo(ur,&info_len);
469 if((metainfo->type == SINGLELINE)||
470 (metainfo->type == MULTILINE))
473 s_responsePrefix = strdup(metainfo->responsePrefix);
474 dbg("duplicating responsePrefix : %s\n", s_responsePrefix);
478 s_responsePrefix = NULL;
481 //set atcmd type into s_type
482 s_type = metainfo->type;
484 if (result == FALSE) {
493 static void on_confirmation_call_outgoing( TcorePending *p, int data_len, const void *data, void *user_data )
498 struct tresp_call_dial resp;
500 o = tcore_pending_ref_core_object(p);
501 ur = tcore_pending_ref_user_request(p);
503 if(sp_response->success >0)
504 resp.err = CALL_ERROR_NONE;
506 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
511 tcore_user_request_send_response(ur, TRESP_CALL_DIAL, sizeof(struct tresp_call_dial), &resp);
514 dbg("[ error ] ur is NULL");
519 static void on_confirmation_call_accept( TcorePending *p, int data_len, const void *data, void *user_data )
524 struct tresp_call_answer resp;
526 o = tcore_pending_ref_core_object(p);
527 ur = tcore_pending_ref_user_request(p);
529 if(sp_response->success >0)
530 resp.err = CALL_ERROR_NONE;
532 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
536 resp.id = tcore_call_object_get_id( (CallObject*)user_data );
539 tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
542 dbg("[ error ] ur is NULL");
548 static void on_confirmation_call_reject( TcorePending *p, int data_len, const void *data, void *user_data )
553 struct tresp_call_answer resp;
555 o = tcore_pending_ref_core_object(p);
556 ur = tcore_pending_ref_user_request(p);
558 if(sp_response->success >0)
559 resp.err = CALL_ERROR_NONE;
561 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
565 resp.id = tcore_call_object_get_id( (CallObject*)user_data );
568 tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
571 dbg("[ error ] ur is NULL");
576 static void on_confirmation_call_replace( TcorePending *p, int data_len, const void *data, void *user_data )
581 struct tresp_call_answer resp;
583 o = tcore_pending_ref_core_object(p);
584 ur = tcore_pending_ref_user_request(p);
586 resp.id = tcore_call_object_get_id( (CallObject*)user_data );
588 if(sp_response->success >0)
589 resp.err = CALL_ERROR_NONE;
591 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
597 tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
600 dbg("[ error ] ur is NULL");
605 static void on_confirmation_call_hold_and_accept( TcorePending *p, int data_len, const void *data, void *user_data )
610 struct tresp_call_answer resp;
612 dbg("ok, function entrance");
614 o = tcore_pending_ref_core_object(p);
615 ur = tcore_pending_ref_user_request(p);
617 resp.id = tcore_call_object_get_id( (CallObject*)user_data );
619 if(sp_response->success >0)
620 resp.err = CALL_ERROR_NONE;
622 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
628 tcore_user_request_send_response(ur, TRESP_CALL_ANSWER, sizeof(struct tresp_call_answer), &resp);
631 dbg("[ error ] ur is NULL");
640 l = tcore_call_object_find_by_status( o, TCORE_CALL_STATUS_ACTIVE );
642 dbg("[ error ] can't find active call");
646 co = (CallObject*)l->data;
648 dbg("[ error ] can't get active call object");
652 tcore_call_object_set_status( co, TCORE_CALL_STATUS_HELD );
656 static void on_confirmation_call_release_all( TcorePending *p, int data_len, const void *data, void *user_data )
661 struct tresp_call_end resp;
663 o = tcore_pending_ref_core_object(p);
664 ur = tcore_pending_ref_user_request(p);
667 resp.type = CALL_END_TYPE_ALL;
668 resp.id = tcore_call_object_get_id( (CallObject*)user_data );
670 if(sp_response->success >0)
671 resp.err = CALL_ERROR_NONE;
673 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
678 tcore_user_request_send_response(ur, TRESP_CALL_END, sizeof(struct tresp_call_end), &resp);
681 dbg("[ error ] ur is NULL");
688 static void on_confirmation_call_release_specific( TcorePending *p, int data_len, const void *data, void *user_data )
693 struct tresp_call_end resp;
695 o = tcore_pending_ref_core_object(p);
696 ur = tcore_pending_ref_user_request(p);
698 resp.type = CALL_END_TYPE_DEFAULT;
699 resp.id = tcore_call_object_get_id( (CallObject*)user_data );
701 if(sp_response->success >0)
702 resp.err = CALL_ERROR_NONE;
704 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
709 tcore_user_request_send_response(ur, TRESP_CALL_END, sizeof(struct tresp_call_end), &resp);
712 dbg("[ error ] ur is NULL");
717 static void on_confirmation_call_release_all_active( TcorePending *p, int data_len, const void *data, void *user_data )
722 struct tresp_call_end resp;
724 o = tcore_pending_ref_core_object(p);
725 ur = tcore_pending_ref_user_request(p);
727 resp.type = CALL_END_TYPE_ACTIVE_ALL;
728 resp.id = tcore_call_object_get_id( (CallObject*)user_data );
730 if(sp_response->success >0)
731 resp.err = CALL_ERROR_NONE;
733 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
738 tcore_user_request_send_response(ur, TRESP_CALL_END, sizeof(struct tresp_call_end), &resp);
741 dbg("[ error ] ur is NULL");
746 static void on_confirmation_call_release_all_held( TcorePending *p, int data_len, const void *data, void *user_data )
751 struct tresp_call_end resp;
753 o = tcore_pending_ref_core_object(p);
754 ur = tcore_pending_ref_user_request(p);
756 resp.type = CALL_END_TYPE_HOLD_ALL;
757 resp.id = tcore_call_object_get_id( (CallObject*)user_data );
759 if(sp_response->success >0)
760 resp.err = CALL_ERROR_NONE;
762 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
767 tcore_user_request_send_response(ur, TRESP_CALL_END, sizeof(struct tresp_call_end), &resp);
770 dbg("[ error ] ur is NULL");
775 static void on_confirmation_call_hold( TcorePending *p, int data_len, const void *data, void *user_data )
780 struct tresp_call_hold resp;
782 dbg("ok, function entrance");
784 o = tcore_pending_ref_core_object(p);
785 ur = tcore_pending_ref_user_request(p);
787 resp.id = tcore_call_object_get_id( (CallObject*)user_data );
789 if(sp_response->success >0)
790 resp.err = CALL_ERROR_NONE;
792 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
797 tcore_user_request_send_response(ur, TRESP_CALL_HOLD, sizeof(struct tresp_call_hold), &resp);
800 dbg("[ error ] ur is NULL");
809 active = tcore_call_object_find_by_status( o, TCORE_CALL_STATUS_ACTIVE );
811 dbg("[ error ] can't find active call");
815 co = (CallObject*)active->data;
817 dbg("[ error ] can't get active call object");
821 tcore_call_object_set_status( co, TCORE_CALL_STATUS_HELD );
826 static void on_confirmation_call_active( TcorePending *p, int data_len, const void *data, void *user_data )
831 struct tresp_call_active resp;
833 o = tcore_pending_ref_core_object(p);
834 ur = tcore_pending_ref_user_request(p);
836 resp.id = tcore_call_object_get_id( (CallObject*)user_data );
838 if(sp_response->success >0)
839 resp.err = CALL_ERROR_NONE;
841 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
846 tcore_user_request_send_response(ur, TRESP_CALL_ACTIVE, sizeof(struct tresp_call_active), &resp);
849 dbg("[ error ] ur is NULL");
855 static void on_confirmation_call_swap( TcorePending *p, int data_len, const void *data, void *user_data )
860 struct tresp_call_swap resp;
862 dbg("ok, function entrance");
864 o = tcore_pending_ref_core_object(p);
865 ur = tcore_pending_ref_user_request(p);
867 resp.id = tcore_call_object_get_id( (CallObject*)user_data );
869 if(sp_response->success >0)
870 resp.err = CALL_ERROR_NONE;
872 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
877 tcore_user_request_send_response(ur, TRESP_CALL_SWAP, sizeof(struct tresp_call_swap), &resp);
880 dbg("[ error ] ur is NULL");
886 GSList *active = 0, *held = 0;
889 held = tcore_call_object_find_by_status( o, TCORE_CALL_STATUS_HELD );
891 dbg("[ error ] can't find held call");
895 active = tcore_call_object_find_by_status( o, TCORE_CALL_STATUS_ACTIVE );
897 dbg("[ error ] can't find active call");
901 co = (CallObject*)held->data;
903 dbg("[ error ] can't get held call object");
907 resp.id = tcore_call_object_get_id( co );
908 tcore_call_object_set_status( co, TCORE_CALL_STATUS_ACTIVE );
910 tcore_user_request_send_response(ur, TRESP_CALL_ACTIVE, sizeof(struct tresp_call_active), &resp);
912 co = (CallObject*)active->data;
914 dbg("[ error ] can't get active call object");
918 resp.id = tcore_call_object_get_id( co );
919 tcore_call_object_set_status( co, TCORE_CALL_STATUS_HELD );
921 tcore_user_request_send_response(ur, TRESP_CALL_HOLD, sizeof(struct tresp_call_hold), &resp);
925 static void on_confirmation_call_join( TcorePending *p, int data_len, const void *data, void *user_data )
930 struct tresp_call_join resp;
932 o = tcore_pending_ref_core_object(p);
933 ur = tcore_pending_ref_user_request(p);
935 resp.id = tcore_call_object_get_id( (CallObject*)user_data );
937 if(sp_response->success >0)
938 resp.err = CALL_ERROR_NONE;
940 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
945 tcore_user_request_send_response(ur, TRESP_CALL_JOIN, sizeof(struct tresp_call_join), &resp);
948 dbg("[ error ] ur is NULL");
953 static void on_confirmation_call_split( TcorePending *p, int data_len, const void *data, void *user_data )
959 struct tresp_call_split resp;
961 dbg("ok, function entrance");
963 o = tcore_pending_ref_core_object(p);
964 ur = tcore_pending_ref_user_request(p);
966 resp.id = tcore_call_object_get_id( (CallObject*)user_data );
968 if(sp_response->success >0)
969 resp.err = CALL_ERROR_NONE;
971 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
976 tcore_user_request_send_response(ur, TRESP_CALL_SPLIT, sizeof(struct tresp_call_split), &resp);
979 dbg("[ error ] ur is NULL");
988 active = tcore_call_object_find_by_status( o, TCORE_CALL_STATUS_ACTIVE );
990 dbg("[ error ] can't find active call");
994 co = (CallObject*)active->data;
996 dbg("[ error ] can't get active call object");
1000 tcore_call_object_set_status( co, TCORE_CALL_STATUS_HELD );
1001 tcore_call_object_set_status( (CallObject*)user_data, TCORE_CALL_STATUS_ACTIVE );
1005 static void on_confirmation_call_deflect( TcorePending *p, int data_len, const void *data, void *user_data )
1008 UserRequest *ur = 0;
1010 struct tresp_call_deflect resp;
1012 o = tcore_pending_ref_core_object(p);
1013 ur = tcore_pending_ref_user_request(p);
1015 resp.id = tcore_call_object_get_id( (CallObject*)user_data );
1017 if(sp_response->success >0)
1018 resp.err = CALL_ERROR_NONE;
1020 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
1025 tcore_user_request_send_response(ur, TRESP_CALL_DEFLECT, sizeof(struct tresp_call_deflect), &resp);
1028 dbg("[ error ] ur is NULL");
1033 static void on_confirmation_call_transfer( TcorePending *p, int data_len, const void *data, void *user_data )
1036 UserRequest *ur = 0;
1038 struct tresp_call_transfer resp;
1040 o = tcore_pending_ref_core_object(p);
1041 ur = tcore_pending_ref_user_request(p);
1043 resp.id = tcore_call_object_get_id( (CallObject*)user_data );
1045 if(sp_response->success >0)
1046 resp.err = CALL_ERROR_NONE;
1048 resp.err = CALL_ERROR_SERVICE_UNAVAIL;
1053 tcore_user_request_send_response(ur, TRESP_CALL_TRANSFER, sizeof(struct tresp_call_transfer), &resp);
1056 dbg("[ error ] ur is NULL");
1062 static void on_confirmation_call_endall( TcorePending *p, int data_len, const void *data, void *user_data )
1065 UserRequest* ur = 0;
1067 dbg("on_confirmation_call_endall - 1st result. wait for final result");
1070 o = tcore_pending_ref_core_object(p);
1071 ur = tcore_pending_ref_user_request(p);
1073 //skip response handling - actual result will be handled in on_confirmation_call_request
1079 static void on_response_call_list_get(TcorePending *p, int data_len, const void *data, void *user_data)
1081 TcorePlugin* plugin = 0;
1084 struct ATLine *p_cur;
1087 struct CLCC_call_t* call_list = 0;
1089 int i = 0, countCalls =0, countValidCalls =0, err =0;
1092 plugin = tcore_pending_ref_plugin( p );
1093 o = tcore_pending_ref_core_object( p );
1098 if(sp_response->success > 0)
1101 /* count the calls */
1102 for (countCalls = 0, p_cur = sp_response->p_intermediates
1104 ; p_cur = p_cur->p_next
1108 dbg("total calls : %d",countCalls);
1113 call_list = g_new0( struct CLCC_call_t, countCalls);
1116 for (countValidCalls = 0, p_cur = sp_response->p_intermediates
1118 ; p_cur = p_cur->p_next)
1121 err = _callFromCLCCLine( p_cur->line, &call_list[countValidCalls] );
1123 if ( countCalls > countValidCalls )
1130 co = tcore_call_object_find_by_id( o, call_list[i].info.id );
1132 co = tcore_call_object_new( o, call_list[i].info.id );
1134 dbg("error : tcore_call_object_new [ id : %d ]", call_list[i].info.id);
1139 tcore_call_object_set_type( co, _call_type( call_list[i].info.type ) );
1140 tcore_call_object_set_direction( co, call_list[i].info.direction );
1141 tcore_call_object_set_multiparty_state( co, _call_is_in_mpty(call_list[i].info.mpty) );
1142 tcore_call_object_set_cli_info( co, CALL_CLI_MODE_DEFAULT, call_list[i].number );
1144 _call_branch_by_status( plugin, co, call_list[i].info.status );
1148 if ( i == countCalls )
1156 static int _callFromCLCCLine(char *line, struct CLCC_call_t*p_call)
1158 //+CLCC: 1,0,2,0,0,\"+18005551212\",145
1159 // index,isMT,state,mode,isMpty(,number,TOA)?
1167 err = at_tok_start(&line);
1168 if (err < 0) goto error;
1171 err = at_tok_nextint(&line, &(p_call->info.id));
1172 if (err < 0) goto error;
1173 dbg("id : [%d]\n", p_call->info.id );
1175 err = at_tok_nextint(&line, &isMT);
1176 if (err < 0) goto error;
1179 p_call->info.direction = TCORE_CALL_DIRECTION_OUTGOING;
1181 p_call->info.direction = TCORE_CALL_DIRECTION_INCOMING;
1183 dbg("direction : [ %d ]\n", p_call->info.direction);
1186 err = at_tok_nextint(&line, &state);
1187 if (err < 0) goto error;
1191 p_call->info.status = TCORE_CALL_STATUS_ACTIVE;
1194 p_call->info.status = TCORE_CALL_STATUS_HELD;
1197 p_call->info.status = TCORE_CALL_STATUS_DIALING;
1200 p_call->info.status = TCORE_CALL_STATUS_ALERT;
1203 p_call->info.status = TCORE_CALL_STATUS_INCOMING;
1206 p_call->info.status = TCORE_CALL_STATUS_WAITING;
1209 dbg("status : [%d]\n", p_call->info.status );
1212 err = at_tok_nextint(&line, &mode);
1213 if (err < 0) goto error;
1218 p_call->info.type = TCORE_CALL_TYPE_VOICE;
1222 p_call->info.type = TCORE_CALL_TYPE_VIDEO;
1225 default: // only Voice/VT call is supported in CS. treat other unknown calls as error
1226 dbg("invalid type : [%d]\n", mode );
1230 dbg("type : [%d]\n", p_call->info.type );
1233 err = at_tok_nextint(&line, &(p_call->info.mpty));
1234 if (err < 0) goto error;
1235 dbg("mpty : [%d]\n", p_call->info.mpty );
1237 if (at_tok_hasmore(&line)) {
1238 err = at_tok_nextstr(&line, &num);
1240 /* tolerate null here */
1241 if (err < 0) return 0;
1243 memcpy(p_call->number, num, strlen(num));
1244 dbg("number : [ %s ]\n", p_call->number );
1246 p_call->info.num_len = strlen(num);
1247 dbg("num_len : [0x%x]\n", p_call->info.num_len );
1249 err = at_tok_nextint(&line, &(p_call->info.num_type));
1250 if (err < 0) goto error;
1251 dbg("num_type : [0x%x]\n", p_call->info.num_type );
1258 err("invalid CLCC line\n");
1264 static gboolean on_notification_call_waiting( CoreObject *o, const void *data, void *user_data )
1266 TcorePlugin* plugin = NULL;
1267 char* cmd = NULL, *num = NULL;
1268 CallObject *co, *dupco = 0;
1269 int id, status, err, type, mpty,direction;
1270 GSList* pList = NULL;
1271 #define LINE_DEFAULT 0
1273 dbg("call waiting noti : %s", cmd);
1274 plugin = tcore_object_ref_plugin(o);
1280 err = at_tok_nextint(&cmd,&id);
1281 err = at_tok_nextint(&cmd,&direction);
1282 err = at_tok_nextint(&cmd,&status);
1283 err = at_tok_nextint(&cmd,&type);
1284 err = at_tok_nextint(&cmd,&mpty);
1286 if(at_tok_hasmore(&cmd)){
1287 err = at_tok_nextstr(&cmd,&num);
1288 dbg("id: %d, direction : %d, status : %d, type :%d, mpty : %d, num : %s", id,direction,status, type, mpty, num);
1291 dbg("id: %d, direction : %d, status : %d, type :%d, mpty : %d, num : NULL", id,direction,status, type, mpty);
1293 // check call with incoming status already exist
1294 pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_WAITING);
1296 dbg("waiting call already exist. skip");
1300 pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
1302 dbg("incoming call already exist. skip");
1306 dupco = tcore_call_object_find_by_id(o, id);
1308 dbg("co with same id already exist. skip");
1312 // make new co, add to list
1313 co = tcore_call_object_new( o, id);
1315 dbg("[ error ] co is NULL");
1319 tcore_call_object_set_type(co, _call_type(type));
1320 tcore_call_object_set_multiparty_state(co,_call_is_in_mpty(mpty));
1321 tcore_call_object_set_direction(co, TCORE_CALL_DIRECTION_INCOMING);
1322 tcore_call_object_set_cli_info(co, TCORE_CALL_CLI_MODE_DEFAULT, num);
1323 tcore_call_object_set_active_line(co, LINE_DEFAULT);
1325 _call_status_incoming(plugin, co);
1330 static gboolean on_notification_call_incoming( CoreObject *o, const void *data, void *user_data )
1332 TcorePlugin* plugin = NULL;
1333 char* cmd = NULL, *num = NULL;
1334 CallObject *co, *dupco = 0;
1335 int id, status, err, type, mpty,direction;
1336 GSList* pList = NULL;
1337 #define LINE_DEFAULT 0
1339 dbg("call incoming noti : %s", cmd);
1340 plugin = tcore_object_ref_plugin(o);
1346 err = at_tok_nextint(&cmd,&id);
1347 err = at_tok_nextint(&cmd,&direction);
1348 err = at_tok_nextint(&cmd,&status);
1349 err = at_tok_nextint(&cmd,&type);
1350 err = at_tok_nextint(&cmd,&mpty);
1352 if(at_tok_hasmore(&cmd)) {
1353 err = at_tok_nextstr(&cmd,&num);
1354 dbg("id: %d, direction : %d, status : %d, type :%d, mpty : %d, num : %s", id,direction,status, type, mpty, num);
1357 dbg("id: %d, direction : %d, status : %d, type :%d, mpty : %d, num : NULL", id,direction,status, type, mpty);
1359 // check call with incoming status already exist
1360 pList = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
1362 dbg("incoming call already exist. skip");
1366 dupco = tcore_call_object_find_by_id(o, id);
1368 dbg("co with same id already exist. skip");
1372 // make new co, add to list
1373 co = tcore_call_object_new( o, id);
1375 dbg("[ error ] co is NULL");
1379 tcore_call_object_set_type(co, _call_type(type));
1380 tcore_call_object_set_multiparty_state(co,_call_is_in_mpty(mpty));
1381 tcore_call_object_set_direction(co, TCORE_CALL_DIRECTION_INCOMING);
1382 tcore_call_object_set_cli_info(co, TCORE_CALL_CLI_MODE_DEFAULT, num);
1383 tcore_call_object_set_active_line(co, LINE_DEFAULT);
1385 _call_status_incoming(plugin, co);
1390 static gboolean on_notification_call_status( CoreObject *o, const void *data, void *user_data)
1392 char* cmd = NULL, *num = NULL;
1395 int id, status, type, mpty,direction;
1398 enum tcore_call_status co_status;
1400 p = tcore_object_ref_plugin( o );
1405 err = at_tok_nextint(&cmd,&id);
1406 err = at_tok_nextint(&cmd,&direction);
1407 err = at_tok_nextint(&cmd,&status);
1408 err = at_tok_nextint(&cmd,&type);
1409 err = at_tok_nextint(&cmd,&mpty);
1411 if (at_tok_hasmore(&cmd)) {
1412 err = at_tok_nextstr(&cmd,&num);
1413 dbg("id: %d, direction : %d, status : %d, type :%d, mpty : %d, num : %s", id,direction,status, type, mpty, num);
1416 dbg("id: %d, direction : %d, status : %d, type :%d, mpty : %d, num : NULL", id,direction,status, type, mpty);
1419 co_status = _call_status(status);
1421 switch (co_status) {
1422 case CALL_STATUS_ACTIVE:{
1424 dbg("call(%d) status : [ ACTIVE ]", id);
1425 co = tcore_call_object_find_by_id(o,id);
1430 _call_status_active( p, co );
1433 case CALL_STATUS_HELD:
1435 case CALL_STATUS_DIALING:
1437 dbg("call(%d) status : [ dialing ]", id);
1438 co = tcore_call_object_find_by_id(o,id);
1440 co = tcore_call_object_new( o, id );
1442 dbg("error : tcore_call_object_new [ id : %d ]", id);
1447 tcore_call_object_set_type( co, _call_type(type) );
1448 tcore_call_object_set_direction( co, TCORE_CALL_DIRECTION_OUTGOING );
1450 _call_status_dialing( p, co );
1453 case CALL_STATUS_ALERT:
1456 dbg("call(%d) status : [ alert ]", id);
1457 co = tcore_call_object_find_by_id(o, id);
1463 _call_list_get( o, co );
1466 case CALL_STATUS_INCOMING:
1467 case CALL_STATUS_WAITING:
1469 case CALL_STATUS_IDLE: {
1471 dbg("call(%d) status : [ release ]", id);
1473 co = tcore_call_object_find_by_id( o, id );
1477 p = tcore_object_ref_plugin( o );
1479 dbg("plugin is NULL");
1481 _call_status_idle( p, co );
1492 static TReturn s_call_outgoing( CoreObject *o, UserRequest *ur )
1494 TcorePlugin* p = NULL;
1496 struct treq_call_dial* data = 0;
1497 char* raw_str= NULL;
1498 char* cmd_str = NULL;
1500 struct ATReqMetaInfo metainfo;
1502 enum tcore_call_cli_mode clir = CALL_CLI_MODE_DEFAULT;
1504 gboolean ret = FALSE;
1506 data = (struct treq_call_dial*)tcore_user_request_ref_data( ur, 0 );
1507 p = tcore_object_ref_plugin( o );
1509 clir = _get_clir_status( data->number );
1511 //Compose ATCmd string
1514 case TCORE_CALL_CLI_MODE_PRESENT:
1516 break; /*invocation*/
1517 case TCORE_CALL_CLI_MODE_RESTRICT:
1519 break; /*suppression*/
1520 case TCORE_CALL_CLI_MODE_DEFAULT:
1523 break; /*subscription default*/
1526 raw_str = g_strdup_printf("ATD%s%s;", data->number, cclir);
1527 cmd_str = g_strdup_printf("%s%s",raw_str,"\r");
1529 memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
1532 metainfo.type = NO_RESULT;
1533 metainfo.responsePrefix[0] ='\0';
1534 info_len = sizeof(struct ATReqMetaInfo);
1536 tcore_user_request_set_metainfo(ur, info_len, &metainfo);
1538 ret = _call_request_message ( o, ur, cmd_str, strlen(cmd_str), on_confirmation_call_outgoing, co);
1544 tcore_call_object_free( o, co );
1545 return TCORE_RETURN_FAILURE;
1548 return TCORE_RETURN_SUCCESS;
1551 static TReturn s_call_answer( CoreObject *o, UserRequest *ur )
1554 struct treq_call_answer* data = 0;
1555 gboolean ret = FALSE;
1556 char* cmd_str = NULL;
1557 struct ATReqMetaInfo metainfo ;
1558 unsigned int info_len =0;
1560 data = (struct treq_call_answer*)tcore_user_request_ref_data( ur, 0 );
1562 co = tcore_call_object_find_by_id( o, data->id );
1564 memset(&metainfo, 0, sizeof(struct ATReqMetaInfo));
1567 metainfo.type = NO_RESULT;
1568 metainfo.responsePrefix[0] = '\0';
1569 info_len = sizeof(struct ATReqMetaInfo);
1571 tcore_user_request_set_metainfo(ur, info_len, &metainfo);
1573 if ( data->type == CALL_ANSWER_TYPE_ACCEPT ) {
1575 cmd_str = g_strdup_printf("%s%s","ATA","\r");
1576 ret = _call_request_message ( o, ur, (void*)cmd_str, strlen(cmd_str), on_confirmation_call_accept, co);
1579 return TCORE_RETURN_FAILURE;
1583 switch ( data->type ) {
1584 case CALL_ANSWER_TYPE_REJECT: {
1585 dbg("call answer reject");
1586 tcore_call_control_answer_reject( o, ur, on_confirmation_call_reject, co );
1589 case CALL_ANSWER_TYPE_REPLACE: {
1590 dbg("call answer replace");
1591 tcore_call_control_answer_replace( o, ur, on_confirmation_call_replace, co );
1594 case CALL_ANSWER_TYPE_HOLD_ACCEPT: {
1595 dbg("call answer hold and accept");
1596 tcore_call_control_answer_hold_and_accept( o, ur, on_confirmation_call_hold_and_accept, co );
1600 dbg("[ error ] wrong answer type [ %d ]", data->type);
1601 return TCORE_RETURN_FAILURE;
1605 return TCORE_RETURN_SUCCESS;
1608 static TReturn s_call_release( CoreObject *o, UserRequest *ur )
1612 struct treq_call_end* data = 0;
1613 gboolean ret = FALSE;
1614 UserRequest* ur_dup = 0;
1616 char* chld0_cmd = NULL;
1617 char* chld1_cmd = NULL;
1618 struct ATReqMetaInfo metainfo1 ;
1619 struct ATReqMetaInfo metainfo2 ;
1620 unsigned int info_len1, info_len2 =0;
1622 data = (struct treq_call_end*)tcore_user_request_ref_data( ur, 0 );
1624 co = tcore_call_object_find_by_id( o, data->id );
1626 if ( data->type == CALL_END_TYPE_ALL ) {
1628 //releaseAll do not exist on legacy request. send CHLD=0, CHLD=1 in sequence
1629 chld0_cmd = g_strdup("AT+CHLD=0\r");
1630 chld1_cmd = g_strdup("AT+CHLD=1\r");
1632 memset(&metainfo1, 0, sizeof(struct ATReqMetaInfo));
1633 memset(&metainfo2, 0, sizeof(struct ATReqMetaInfo));
1637 metainfo1.type = NO_RESULT;
1638 metainfo1.responsePrefix[0] = '\0';
1639 info_len1 = sizeof(struct ATReqMetaInfo);
1642 metainfo2.type = NO_RESULT;
1643 metainfo2.responsePrefix[0] = '\0';
1644 info_len2 = sizeof(struct ATReqMetaInfo);
1646 ur_dup = tcore_user_request_new(NULL, NULL);
1648 tcore_user_request_set_metainfo(ur_dup, info_len1, &metainfo1);
1649 tcore_user_request_set_metainfo(ur, info_len2, &metainfo2);
1651 ret = _call_request_message(o, ur_dup, chld0_cmd, strlen(chld0_cmd), on_confirmation_call_endall, NULL);
1654 return TCORE_RETURN_FAILURE;
1656 ret = _call_request_message(o, ur, chld1_cmd, strlen(chld1_cmd), on_confirmation_call_release_all, co);
1659 return TCORE_RETURN_FAILURE;
1663 switch ( data->type ) {
1664 case CALL_END_TYPE_DEFAULT: {
1666 id = tcore_call_object_get_id( co );
1668 dbg("call end call id [%d]", id);
1669 tcore_call_control_end_specific( o, ur, id, on_confirmation_call_release_specific, co );
1672 case CALL_END_TYPE_ACTIVE_ALL: {
1674 dbg("call end all active");
1675 tcore_call_control_end_all_active( o, ur, on_confirmation_call_release_all_active, co );
1678 case TCORE_CALL_END_ALL_HELD: {
1680 dbg("call end all held");
1681 tcore_call_control_end_all_held( o, ur, on_confirmation_call_release_all_held, co );
1685 dbg("[ error ] wrong end type [ %d ]", data->type);
1686 return TCORE_RETURN_FAILURE;
1691 return TCORE_RETURN_SUCCESS;
1694 static TReturn s_call_hold( CoreObject *o, UserRequest *ur )
1696 struct treq_call_hold *hold = 0;
1698 GSList *list_active, *list_incoming, *list_held;
1700 hold = (struct treq_call_hold*)tcore_user_request_ref_data( ur, 0 );
1703 * When Incoming Call and Outgoing Call operates concurrently with one
1704 * already exist Call. Telephony intend to having one Active Call and
1705 * one Incoming Call. But, at that time, Application does not received
1706 * Incoming Call Notification. Therefore, Application call
1707 * tel_hold_call() to hold already exist Active Call. At this point,
1708 * Telephony should reject the request of tel_hold_call() because
1709 * tel_hold_call() sends AT+CHLD=2 which means "place active call on
1710 * hold and accepts the incoming call".
1712 list_active = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_ACTIVE);
1713 list_incoming = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_INCOMING);
1714 list_held = tcore_call_object_find_by_status(o, TCORE_CALL_STATUS_HELD);
1715 if (!(list_active != NULL && list_incoming == NULL && list_held == NULL)) {
1716 struct tresp_call_hold resp;
1718 dbg("Hold Call operation is not allowed");
1720 resp.err = CALL_ERROR_SERVICE_NOT_ALLOWED;
1722 tcore_user_request_send_response(ur, TRESP_CALL_HOLD, sizeof(resp), &resp);
1724 return TCORE_RETURN_FAILURE;
1727 dbg("call id : [ %d ]", hold->id);
1729 co = tcore_call_object_find_by_id( o, hold->id );
1731 tcore_call_control_hold( o, ur, on_confirmation_call_hold, co );
1733 return TCORE_RETURN_SUCCESS;
1736 static TReturn s_call_active( CoreObject *o, UserRequest *ur )
1738 struct treq_call_active *active = 0;
1741 active = (struct treq_call_active*)tcore_user_request_ref_data( ur, 0 );
1743 dbg("call id : [ %d ]", active->id);
1745 co = tcore_call_object_find_by_id( o, active->id );
1747 tcore_call_control_active( o, ur, on_confirmation_call_active, co );
1749 return TCORE_RETURN_SUCCESS;
1752 static TReturn s_call_swap( CoreObject *o, UserRequest *ur )
1754 struct treq_call_swap *swap = 0;
1756 swap = (struct treq_call_swap*)tcore_user_request_ref_data( ur, 0 );
1758 dbg("call id : [ %d ]", swap->id);
1760 co = tcore_call_object_find_by_id( o, swap->id );
1762 tcore_call_control_swap( o, ur, on_confirmation_call_swap, co );
1764 return TCORE_RETURN_SUCCESS;
1767 static TReturn s_call_join( CoreObject *o, UserRequest *ur )
1769 struct treq_call_join *join = 0;
1772 join = (struct treq_call_join*)tcore_user_request_ref_data( ur, 0 );
1774 dbg("call id : [ %d ]", join->id);
1776 co = tcore_call_object_find_by_id( o, join->id );
1778 tcore_call_control_join( o, ur, on_confirmation_call_join, co );
1780 return TCORE_RETURN_SUCCESS;
1783 static TReturn s_call_split( CoreObject *o, UserRequest *ur )
1785 struct treq_call_split *split = 0;
1788 split = (struct treq_call_split*)tcore_user_request_ref_data( ur, 0 );
1790 co = tcore_call_object_find_by_id ( o, split->id );
1792 tcore_call_control_split( o, ur, split->id, on_confirmation_call_split, co );
1794 return TCORE_RETURN_SUCCESS;
1797 static TReturn s_call_deflect( CoreObject *o, UserRequest *ur )
1799 struct treq_call_deflect *deflect = 0;
1802 deflect = (struct treq_call_deflect*)tcore_user_request_ref_data( ur, 0 );
1804 co = tcore_call_object_find_by_number( o, deflect->number );
1806 tcore_call_control_deflect( o, ur, deflect->number, on_confirmation_call_deflect, co );
1808 return TCORE_RETURN_SUCCESS;
1811 static TReturn s_call_transfer( CoreObject *o, UserRequest *ur )
1813 struct treq_call_transfer *transfer = 0;
1816 transfer = (struct treq_call_transfer*)tcore_user_request_ref_data( ur, 0 );
1818 dbg("call id : [ %d ]", transfer->id);
1820 co = tcore_call_object_find_by_id( o, transfer->id );
1822 tcore_call_control_transfer( o, ur, on_confirmation_call_transfer, co );
1824 return TCORE_RETURN_SUCCESS;
1827 static TReturn s_call_send_dtmf( CoreObject *o, UserRequest *ur )
1829 return TCORE_RETURN_SUCCESS;
1832 static TReturn s_call_set_sound_path( CoreObject *o, UserRequest *ur )
1835 return TCORE_RETURN_SUCCESS;
1838 static TReturn s_call_set_sound_volume_level( CoreObject *o, UserRequest *ur )
1841 return TCORE_RETURN_SUCCESS;
1844 static TReturn s_call_get_sound_volume_level( CoreObject *o, UserRequest *ur )
1847 return TCORE_RETURN_SUCCESS;
1850 static TReturn s_call_mute( CoreObject *o, UserRequest *ur )
1853 return TCORE_RETURN_SUCCESS;
1856 static TReturn s_call_unmute( CoreObject *o, UserRequest *ur )
1859 return TCORE_RETURN_SUCCESS;
1862 static TReturn s_call_get_mute_status( CoreObject *o, UserRequest *ur )
1865 return TCORE_RETURN_SUCCESS;
1868 static struct tcore_call_operations call_ops = {
1869 .dial = s_call_outgoing,
1870 .answer = s_call_answer,
1871 .end = s_call_release,
1872 .hold = s_call_hold,
1873 .active = s_call_active,
1874 .swap = s_call_swap,
1875 .join = s_call_join,
1876 .split = s_call_split,
1877 .deflect = s_call_deflect,
1878 .transfer = s_call_transfer,
1879 .send_dtmf = s_call_send_dtmf,
1880 .set_sound_path = s_call_set_sound_path,
1881 .set_sound_volume_level = s_call_set_sound_volume_level,
1882 .get_sound_volume_level = s_call_get_sound_volume_level,
1883 .mute = s_call_mute,
1884 .unmute = s_call_unmute,
1885 .get_mute_status = s_call_get_mute_status,
1888 gboolean s_call_init(TcorePlugin *cp, CoreObject *co)
1890 tcore_call_override_ops(co, &call_ops, NULL);
1892 tcore_object_override_callback( co, EVENT_CALL_STATUS, on_notification_call_status, NULL );
1893 tcore_object_override_callback( co, EVENT_CALL_INCOMING, on_notification_call_incoming, NULL );
1894 tcore_object_override_callback( co, EVENT_CALL_WAITING, on_notification_call_waiting, NULL );
1899 void s_call_exit(TcorePlugin *cp, CoreObject *co)